scrapy的安装和基本介绍请看 http://www.jianshu.com/p/a71386fa317a
-
Spider
scrapy的网站爬取需要继承scrapy.Spider类,会根据配置的初始url自动下载网页信息,并调用parse方法,下载的网页信息会通过parse方法的response参数进行传递
例:
class JobboleSpider(scrapy.Spider):
name = 'jobbole' # spider名称
allowed_domains = ['blog.jobbole.com'] # 域名
start_urls = ['http://blog.jobbole.com/all-posts/'] # 其实url
def parse(self, response):
启动方式为
scrapy crawl jobbole # jobbole为spider名称
-
MiddleWare
Spider产生的Request请求会在一系列调度后,流经一个个MiddleWare,最终到达Downloader进行真正的Http的请求并得到相应,我们可以自定义MiddleWare,并在settings文件进行顺序配置,定制化下载前的准备工作,比如加入User-Agent随机切换,Ip代理池的设置,Selenium代理下载等
自定义Middleware需要重载4个函数来做不同的处理
class CustomMiddleWare
# 定义这个方法,Scrapy会把当前的爬虫传递到方法里来
@classmethod
def from_crawler(cls, crawler):
return cls(crawler)
# 处理request请求
def process_request(self, request, spider):
pass
# 处理response请求
def process_response(self, response, spider):
pass
# 处理异常情况
def process_exception(self, response, spider):
pass
settings 配置
# 下载服务管理器
DOWNLOADER_MIDDLEWARES = {
'ArticleSpider.middlewares.RandomUserAgentMiddlware': 100,
# 'ArticleSpider.middlewares.RandomProxyMiddleware': 200,
# 'ArticleSpider.middlewares.JSPageMiddleware': 300,
# 如果自定义了User-Agent的MiddleWare,需要将scrapy的默认Middleware置为None
'ScrapyRedisTest.middlewares.MyCustomDownloaderMiddleware': None,
}
-
Item
使用scrapy.Spider爬取好相关数据后,需要将数据进行保存,数据在scrapy中流转是通过Item来实现,使用Item来定义scray的模型model,需要继承scrapy.Item类
例:
class JobBoleArticleItem(scrapy.Item):
# 使用scrapy.Field进行数据的定义规则
title = scrapy.Field(
input_processor=MapCompose(lambda x:x+"-jobbole",add_jobbole)
)
create_date = scrapy.Field(
input_processor=MapCompose(date_covert)
)
url = scrapy.Field()
url_object_id = scrapy.Field()
front_image_url = scrapy.Field(
output_processor=MapCompose(return_value)
)
front_image_path = scrapy.Field()
praise_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
common_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
fav_nums = scrapy.Field(
input_processor=MapCompose(get_nums)
)
tags = scrapy.Field(
input_processor=MapCompose(remove_comment_tags),
output_processor=Join(",")
)
content = scrapy.Field()
scrapy.Field可以接收input_processor,output_processor等来定义数据的包装规则,MapCompose会依次调用参数方法(参数方法需要接收一个value参数,返回按照相应规则包装好的值)
例如将create_date(str类型)转换成(date类型)
def date_covert(value):
try:
create_date = datetime.datetime.strptime(value,"%Y/%m/%d").date()
except Exception as e:
create_date = datetime.datetime.now().date()
return create_date
...
create_date = scrapy.Field(
input_processor=MapCompose(date_covert)
)
...
可以通过继承ItemLoader类自定义默认的input_processor,output_processor
class ArticleItemLoader(ItemLoader):
#自定义output_processor
default_output_processor = TakeFirst()
Spider 提取相应数据后需要将数据包装成Item
def parse(self, response):
article_item = JobBoleArticleItem()
...
...
yield article_item
-
Pipeline
Spider 讲数据包装成Item以后,scrapy会按照在setting是中配置的顺序进行执行pipeline的类方法,进行数据的持久化或其他的下载操作
每一个Pipeline需要有一个process_item方法,接收一个item参数,做完相应处理后返回item,并在settings.py中配置执行顺序
settings.py
数字小的先执行
ITEM_PIPELINES = {
# 'scrapy.pipelines.images.ImagesPipeline': 1,
'ArticleSpider.pipelines.ArticleImagePipeline':1,
# 'ArticleSpider.pipelines.JsonExporterPipeline': 2,
'ArticleSpider.pipelines.MysqlTwistedPipeline': 2,
}
Pipeline
class ArticlespiderPipeline(object):
def process_item(self, item, spider):
# 做具体的执行逻辑
return item
上面讲的一些Settings的配置,是所有爬虫的统一配置,如果需要在每个爬虫里自定义配置,可以使用custom_settings变量覆盖统一配置
custom_settings = {
"COOKIES_ENABLED": False,
"DOWNLOAD_DELAY": 0
}
网友评论