具有长start_urls列表的Scrapy Crawling URL的顺序和来自spider的urls yiels

YuB*_*ian 6 python web-crawler scrapy web-scraping python-2.7

救命!阅读源代码Scrapy对我来说并不容易.我有一个很长的start_urls清单.它在文件中约为3,000,000.所以,我start_urls这样做:

start_urls = read_urls_from_file(u"XXXX")
def read_urls_from_file(file_path):
    with codecs.open(file_path, u"r", encoding=u"GB18030") as f:
        for line in f:
            try:
                url = line.strip()
                yield url
            except:
                print u"read line:%s from file failed!" % line
                continue
    print u"file read finish!"
Run Code Online (Sandbox Code Playgroud)

MeanWhile,我的蜘蛛的回调函数是这样的:

  def parse(self, response):
        self.log("Visited %s" % response.url)
        return  Request(url=("http://www.baidu.com"), callback=self.just_test1)
    def just_test1(self, response):
        self.log("Visited %s" % response.url)
        return Request(url=("http://www.163.com"), callback=self.just_test2)
    def just_test2(self, response):
        self.log("Visited %s" % response.url)
        return []
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 下载器使用的网址顺序?会提出的要求 just_test1,just_test2 通过下载器只有所有后方可使用 start_urls,使用?(我做了一些测试,似乎答案是没有)
  2. 什么决定订单?为什么以及如何订购?我们怎样才能控制它?
  3. 这是处理已经在文件中的这么多网址的好方法吗?还有什么?

非常感谢你!!!

谢谢你的回答.但我仍然有点困惑: 默认情况下,Scrapy使用LIFO队列来存储待处理的请求.

  1. requests被蜘蛛回调函数做将给予 scheduler.谁做同样的事情start_url's requests?蜘蛛 start_requests()函数只产生一个迭代器没有给真正的请求.
  2. all requests(start_url和callback)是否在同一个请求的队列中?有多少个队列Scrapy

ale*_*cxe 8

首先,请看这个主题 - 我想你会在那里找到所有的答案.

下载器使用的网址顺序?just_test1,just_test2的请求是否仅在使用了所有start_urls之后由下载程序使用?(我做了一些测试,似乎答案是否定的)

你是对的,答案是肯定的No.行为是完全异步的:当蜘蛛启动时,start_requests调用方法():

def start_requests(self):
    for url in self.start_urls:
        yield self.make_requests_from_url(url)

def make_requests_from_url(self, url):
    return Request(url, dont_filter=True)
Run Code Online (Sandbox Code Playgroud)

什么决定订单?为什么以及如何订购?我们怎样才能控制它?

默认情况下,没有预先定义的顺序-你可以不知道什么时候Requestsmake_requests_from_url抵达的-它是异步的.

请参阅此答案,了解如何控制订单.长话短说,你可以覆盖start_requests和标记Requestspriority键(如yield Request(url, meta={'priority': 0})).例如,值priority可以是找到网址的行号.

这是处理已经在文件中的这么多网址的好方法吗?还有什么?

我认为您应该直接在start_requests方法中阅读您的文件并生成网址:请参阅此答案.

所以,你应该像这样做:

def start_requests(self):
    with codecs.open(self.file_path, u"r", encoding=u"GB18030") as f:
        for index, line in enumerate(f):
            try:
                url = line.strip()
                yield Request(url, meta={'priority': index})
            except:
                continue
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 非常感谢!我还是有点困惑。[默认情况下,Scrapy 使用 LIFO 队列来存储待处理的请求。](http://doc.scrapy.org/en/latest/faq.html#does-scrapy-呼吸优先或深度优先)。 (2认同)