请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

多页面爬取时,如何设置阈值,超过后先进行下载?

我在做测试时,爬取了一个多页面的网站,页面的链接我已经事先抓取到存储入库了,然后抓取数据的时候,读数据库就行。但是我是写在一个死循环里面,不断从数据库取数据,直到全部去完。

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个,先不爬了,先下载数据,抓取详情,数据入库。弄完了再爬取新页面

正在回答 回答被采纳积分+3

1回答

bobby 2021-07-29 16:57:32

你这个问题算是一个不错的问题, 这也是很多其他同学应该会遇到但是没有在意的问题,你要这样理解scrapy:

  1. scrapy可以简单的理解为一个单线程程序,所以你的parse和parse_detail都是在一个线程中运行,也就是说这俩本质上来讲是有先后顺序的,当parse执行完成以后就去执行parse_detail,但是parse很多很猛啊,parse函数只管将自己的url交给scrapy的download下载器,你的url一交出来立马就放入到downloader的队列了

  2. 所以parse函数几乎可以很快将这么多的url全部放入到downloader队列,downloader队列就慢慢从队列从取啊,这个时候由于你的parse函数放入队列的数据太快了,导致全部是都是parse中的url,至于已经提交出去的url由于服务器的响应肯定比本地parse执行慢,所以就有大量的url堆积在downloader的队列中

  3. 所以你其实应该是想将一个url交给downloader后先下载完成然后再继续交出后续的url

  4. 这个其实方案还是挺多的,首先scrapy本身由于只是一个并发框架,所有无法知道你自己想要的顺序是什么,所有可以自己来做

  5. 做法比较简单,你设置一个全局的queue或者使用python自带的condition机制,甚至更简单的方式就是使用一个全部变量比如total, 你在parse中交出去一个或者10个url以后,就一直等着这个queue或者condition是否被通知到了,这个时候你的parse_detail函数就负责去每次将total+1,这样你的parse中不停的while判断total是否达到了10,一旦到达了就立马继续yield新的url

1 回复 有任何疑惑可以回复我~
  • 好的,谢谢老师
    回复 有任何疑惑可以回复我~ 2021-08-02 17:59:19
  • 使用Request的priority参数调优先级会不会更加方便?
    回复 有任何疑惑可以回复我~ 2022-02-12 00:59:53
  • priority 可以提高优先级,但是优先级动态性,比如哪个url的优先级应该设置为多少自己必须能够管理,所以不论是否使用优先级队列,都应该知道scrapy本身的一些原理
    回复 有任何疑惑可以回复我~ 2022-02-13 19:18:23
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信