如何用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_REQUESTS和DOWNLOAD_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_DOMAIN或CONCURRENT_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.

