多页面爬取时,如何设置阈值,超过后先进行下载?
来源:8-3 Requests和Response介绍
weixin_慕盖茨9032018
2021-07-28
我在做测试时,爬取了一个多页面的网站,页面的链接我已经事先抓取到存储入库了,然后抓取数据的时候,读数据库就行。但是我是写在一个死循环里面,不断从数据库取数据,直到全部去完。
while True:
if self.count == self.total_count:
print("download over")
data = self.reload_cursor(self.count)
base_url = "https://www.xxx.info"
code = str(data["journal_link"]).split('/')[-1]
url = base_url + code
meta = {
"journal_code": code,
"baseid": data["baseid"],
"journal_img": data["journal_img"],
"journal_link": data["journal_link"]
}
yield scrapy.Request(url, dont_filter=True, meta=meta)
但是他就一直在那里抓取页面链接,死活跳转不到下载的程序那里。
就想问下,怎么能给他设置个值,比如说爬取50个页面或者100个,先不爬了,先下载数据,抓取详情,数据入库。弄完了再爬取新页面
1回答
-
bobby
2021-07-29
你这个问题算是一个不错的问题, 这也是很多其他同学应该会遇到但是没有在意的问题,你要这样理解scrapy:
scrapy可以简单的理解为一个单线程程序,所以你的parse和parse_detail都是在一个线程中运行,也就是说这俩本质上来讲是有先后顺序的,当parse执行完成以后就去执行parse_detail,但是parse很多很猛啊,parse函数只管将自己的url交给scrapy的download下载器,你的url一交出来立马就放入到downloader的队列了
所以parse函数几乎可以很快将这么多的url全部放入到downloader队列,downloader队列就慢慢从队列从取啊,这个时候由于你的parse函数放入队列的数据太快了,导致全部是都是parse中的url,至于已经提交出去的url由于服务器的响应肯定比本地parse执行慢,所以就有大量的url堆积在downloader的队列中
所以你其实应该是想将一个url交给downloader后先下载完成然后再继续交出后续的url
这个其实方案还是挺多的,首先scrapy本身由于只是一个并发框架,所有无法知道你自己想要的顺序是什么,所有可以自己来做
做法比较简单,你设置一个全局的queue或者使用python自带的condition机制,甚至更简单的方式就是使用一个全部变量比如total, 你在parse中交出去一个或者10个url以后,就一直等着这个queue或者condition是否被通知到了,这个时候你的parse_detail函数就负责去每次将total+1,这样你的parse中不停的while判断total是否达到了10,一旦到达了就立马继续yield新的url
132022-02-13
相似问题