wking's blog

  • 文章分类
    • 日常随笔
    • IT技术
    • 系统封装
    • 大航海时代
  • 关于博主
  1. 首页
  2. 正文

scrapy从低版本更新到>2.14.0版本后需要改动的代码

2026-05-21 57点热度 0人点赞 0条评论

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):
        # 自己的代码
        pass

start_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 spider argument is deprecated, if you need a Spider instance inside them you should get it from the Crawler instance (you may need to refactor your code to save that instance in e.g. the from_crawler() method):
    • the process_request(), process_response() and process_exception() methods of custom downloader middlewaresthe process_spider_input(), process_spider_output(), process_spider_output_async() and process_spider_exception() methods of custom spider middlewaresthe process_item() method of custom pipelinesthe fetch() method of a custom DOWNLOADER
    (issue 6927, issue 6984, issue 7006, issue 7037)

因此,除了删除上述方法的形参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 None

process_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 i

process_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
本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2026-06-01

wking

不管博客型博主

点赞

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

目录
  • spider文件
    • 指定爬取开始网页的函数有变动
      • start_urls变量
      • start_requests方法
  • middlewares中间件
    • 中间件方法的形参有变动
      • 以前传递变量的方法
      • 新的传递变量的方法
  • 爬虫中间件(Spider Middleware)
    • process_spider_output方法
      • 以前的写法
      • 新的写法
    • process_start_requests方法
      • 以前的写法
      • 新的写法
标签聚合
大航海时代 wordpress 一支红杏 C++ win10 linux R6300V2 OneNote

COPYRIGHT © 2010-2025 wkings.blog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang