scrapy从2.14.0版本开始,使用“更多基于协程的 API 替代了基于 Deferred 的 API”,因此,部分代码需要更新以适配最新的>2.14.0版本。
spider文件
指定爬取开始网页的函数有变动
# spider文件
class GamerSpider(scrapy.Spider):
name = "gamer"
allowed_domains = ["abc.com"]
start_urls = ["https://abc.com"] # 以覆盖默认变量值的方式指定开始网页。和start_requests两者选一个即可。
# 以重写方法的方式指定开始网页,和start_urls两者选一个即可。
def start_requests(self):
urls = [
'https://abc.com/index.html',
'https://abc.com/index2.html',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
# 自己的代码
passstart_urls变量
如果是以变量start_urls的方式指定爬取开始网页,则不需要修改。scrapy内部会自动适配。
start_requests方法
如果是以函数start_requests的方式指定爬取开始网页,则要修改函数名,并增加异步关键词。
async def start(self):
urls = [
'https://abc.com/index.html',
'https://abc.com/index2.html',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)middlewares中间件
中间件方法的形参有变动
爬虫中间件(Spider Middleware)、下载器中间件(Downloader Middleware)等所有中间件的部分方法的形参有更新,删除了spider形参。具体的官方说明是:
- For the following user-defined functions and methods requiring a
spiderargument is deprecated, if you need aSpiderinstance inside them you should get it from theCrawlerinstance (you may need to refactor your code to save that instance in e.g. thefrom_crawler()method):(issue 6927, issue 6984, issue 7006, issue 7037)
- the
process_request(),process_response()andprocess_exception()methods of custom downloader middlewarestheprocess_spider_input(),process_spider_output(),process_spider_output_async()andprocess_spider_exception()methods of custom spider middlewarestheprocess_item()method of custom pipelinesthefetch()method of a customDOWNLOADER
因此,除了删除上述方法的形参spider,以前从爬虫文件spider.py向中间件传递变量的方法也相应有变化。
以前传递变量的方法
# 爬虫spider.py
class SimpleSpider(scrapy.Spider):
name = "simple" # 内置变量,覆盖默认值
allowed_domains = ["simple.com"] # 内置变量,覆盖默认值
start_urls = ["https://simple.com"] # 内置变量,覆盖默认值
custom_settings = { # 内置变量,预留为空
'var1': 1,
'var2': 2,
'var3': 3,
}
html_downloaded = 0 # 额外增加的自定义变量
def parse(self, response):
pass
# 中间件middlewares.py
class ADownloaderMiddleware:
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request, spider):
var1 = spider.settings.attributes['var1'].value # 读取custom_settings的var1的值
spider.html_downloaded = spider.html_downloaded + 1 # 更新自定义变量的值
return Noneprocess_request方法通过参数spider,就可以使用spider.py中定义的变量。
新的传递变量的方法
# 中间件middlewares.py的下载器中间件类
class ADownloaderMiddleware:
# 新增__init__方法
def __init__(self, crawler):
self.crawler = crawler # 新增self.crawler类实例属性,并赋值为方法参数crawler
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
# cls实际上就是ADownloaderMiddleware类。此处类实例化,因此调用上面的__init__方法。也因此将from_crawler方法的参数crawler传递给__init__。
s = cls(crawler)
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
return s
def process_request(self, request):
# 读取custom_settings的var1的值
var1 = self.crawler.spider.settings.attributes['var1'].value
# 更新自定义变量的值
self.crawler.spider.html_downloaded = self.crawler.spider.html_downloaded + 1
return None
新增__init__方法。
修改from_crawler方法的s = cls(crawler)语句。
删除形参spider。
推荐使用类似self.crawler.spider.settings.attributes['var1'].value的语句读取变量。
爬虫中间件(Spider Middleware)
如果重写了以下爬虫中间件(Spider Middleware)的方法,则需要更新。没有重写则无需处理。
process_spider_output方法
需要改为异步方法。
以前的写法
def process_spider_output(self, response, result, spider):
for i in result:
yield i新的写法
async def process_spider_output(self, response, result):
async for i in result:
yield iprocess_start_requests方法
该方法已在新版本被弃用,需使用新的方法。
以前的写法
def process_start_requests(self, start_requests, spider):
for r in start_requests:
yield r新的写法
async def process_start(self, start):
# Called with an async iterator over the spider start() method or the
# matching method of an earlier spider middleware.
async for item_or_request in start:
yield item_or_request
文章评论