如何用Python控制Scrapy的downloader并发量为1实现串行请求

null
如何用Python控制Scrapy的downloader并发量为1实现串行请求

5 回复

current_request
settings 里面的这个选项设置的为 1


要控制Scrapy的downloader并发量为1实现串行请求,直接在settings.py里设置CONCURRENT_REQUESTS = 1就行。不过,Scrapy默认的并发机制在请求间隔很短时,即使并发设为1,也可能快速发出多个请求。如果需要更严格的串行(一个请求完全结束后再发下一个),可以结合CONCURRENT_REQUESTSDOWNLOAD_DELAY

这里是一个完整的示例,演示如何设置并创建一个简单的爬虫来验证串行请求:

1. 项目设置 (settings.py)

BOT_NAME = 'serial_spider'

SPIDER_MODULES = ['serial_spider.spiders']
NEWSPIDER_MODULE = 'serial_spider.spiders'

# 关键设置:将并发请求数设为1
CONCURRENT_REQUESTS = 1

# 可选:添加下载延迟以确保请求完全串行化,防止潜在的瞬时并发
DOWNLOAD_DELAY = 0.5

# 为清晰起见,关闭其他可能影响请求顺序的扩展
AUTOTHROTTLE_ENABLED = False
RETRY_ENABLED = False
COOKIES_ENABLED = False
TELNETCONSOLE_ENABLED = False

# 调整日志级别以便观察请求顺序
LOG_LEVEL = 'INFO'

2. 爬虫代码 (spiders/example_spider.py)

import scrapy
import time

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['httpbin.org']
    start_urls = ['https://httpbin.org/delay/1'] * 5  # 请求5个URL,每个延迟1秒

    def parse(self, response):
        # 输出当前时间戳和请求的URL,以观察请求顺序
        self.logger.info(f'[{time.strftime("%H:%M:%S")}] Fetched: {response.url}')
        yield {
            'url': response.url,
            'time': time.strftime("%H:%M:%S")
        }

3. 运行爬虫 在项目根目录执行:

scrapy crawl example

工作原理

  • CONCURRENT_REQUESTS = 1 会限制Scrapy的下载器同时只能处理一个请求。
  • DOWNLOAD_DELAY = 0.5 在每个请求之间添加一个固定延迟,这能进一步确保请求不会因为处理速度过快而“几乎同时”发出。
  • 爬虫会依次请求5个URL,每个URL模拟1秒延迟。从日志的时间戳可以看出,请求是按顺序一个接一个执行的。

验证串行行为 观察运行输出的日志,你会看到类似这样的顺序,时间戳间隔大约为1秒(网络延迟可能造成微小差异):

[14:30:01] Fetched: https://httpbin.org/delay/1
[14:30:02] Fetched: https://httpbin.org/delay/1
[14:30:03] Fetched: https://httpbin.org/delay/1
...

其他注意事项

  • 如果使用了CONCURRENT_REQUESTS_PER_DOMAINCONCURRENT_REQUESTS_PER_IP,也需要将它们设置为1。
  • 对于极其严格的串行需求(例如,需要等待一个请求的所有后续处理完成后再发下一个),可能需要结合自定义的下载器中间件或使用队列机制,但对于绝大多数场景,CONCURRENT_REQUESTS = 1 加上适当的 DOWNLOAD_DELAY 就足够了。

总结:在settings.py里设置CONCURRENT_REQUESTS = 1

感谢, 我试过了,没有打达到我的预期,难道是因为我自己写了 下载器中间件的缘故。

CONCURRENT_REQUESTS
Default: 16

The maximum number of concurrent (ie. simultaneous) requests that will be performed by the Scrapy downloader.

回到顶部