Scrapy是单线程还是多线程?
在Scrapy中,有一些关于并发的设置,比如CONCURRENT_REQUESTS。这是不是意味着Scrapy的爬虫是多线程的?也就是说,当我运行scrapy crawl my_crawler
的时候,它真的会同时发出多个请求吗?我之所以问这个,是因为我听说Scrapy是单线程的。
4 个回答
Scrapy是一个单线程的框架,但我们可以在同一个爬虫里同时使用多个线程。
请阅读这篇文章。
我们可以使用子进程来运行爬虫。
import subprocess
subprocess.run(["scrapy", "crawl", "quotes", "-o", "quotes_all.json"])
或者
使用CrawlerProcess在同一个进程中运行多个爬虫。
如果你想在一个进程中运行多个爬虫,或者想直接在你的程序中获取和使用抓取到的数据,你需要使用Scrapy的内部API。
# Run the spider with the internal API of Scrapy:
from scrapy.crawler import Crawler, CrawlerProcess
from scrapy.utils.project import get_project_settings
def crawler_func(spider, url):
crawler_process = CrawlerProcess(settings)
crawler_process.crawl(spider, url)
crawler_process.start()
def start_spider(spider, urls):
p = multiprocessing.Pool(100)
return p.map(partial(crawler_func, spider), urls)
Scrapy是一个单线程的框架,这意味着在同一个爬虫里,我们不能同时使用多个线程。不过,我们可以同时创建多个爬虫和数据处理管道,这样就能让整个过程同时进行。Scrapy不支持多线程
,因为它是基于Twisted
构建的,而Twisted
是一个异步HTTP协议框架
。
Scrapy大部分的工作是同步进行的,但处理请求的部分是异步的,也就是说它可以同时处理多个请求。
如果你还没看过这篇文章,我建议你去看看。
http://doc.scrapy.org/en/latest/topics/architecture.html
编辑:我现在意识到问题其实是关于线程的,而不一定是异步的。尽管如此,那条链接还是值得一读的 :)
关于你问的CONCURRENT_REQUESTS,这个设置是用来改变Twisted一次可以处理的请求数量。一旦启动了这么多请求,它会等其中一些完成后再开始新的请求。
Scrapy是单线程的,除了交互式命令行和一些测试,具体可以查看源代码。
它是建立在Twisted之上的,Twisted也是单线程的,并且使用了它自己的一些异步并发功能,比如twisted.internet.interfaces.IReactorThreads.callFromThread
,具体可以查看源代码。