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!"

同时,我的蜘蛛的回调函数是这样的:</p>

  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 []

我的问题是:

  1. 下载器使用的 url 的顺序?just_test1,发出的请求会 just_test2 在全部使用后才被下载 start_urls器使用吗?(我做了一些测试,似乎答案是否定的)
  2. 什么决定顺序?这个顺序为什么以及如何?我们如何控制它?
  3. 这是处理文件中已有这么多网址的好方法吗?还有什么?

非常感谢你!!!

感谢您的回答。但我仍然有点困惑: 默认情况下,Scrapy 使用 LIFO 队列来存储挂起的请求。

  1. 蜘蛛制作的requests回调函数会交给 scheduler谁来做同样的事情start_url's requests?蜘蛛 start_requests()函数只会生成一个迭代器,不会给出真正的请求。
  2. 所有requests(start_url 和回调)会在同一个请求的队列中吗?有多少个队列Scrapy
4

1 回答 1

8

首先,请看这个帖子——我想你会在那里找到所有的答案。

下载器使用的 url 的顺序?just_test1,just_test2 发出的请求只有在所有的start_urls都使用后才会被下载器使用吗?(我做了一些测试,似乎答案是否定的)

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

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)

什么决定顺序?这个顺序为什么以及如何?我们如何控制它?

默认情况下,没有预定义的顺序——你无法知道Requestsfrommake_requests_from_url何时到达——它是异步的。

有关如何控制订单的信息,请参阅此答案。长话短说,您可以使用键(如)覆盖start_requests并标记 yielded 。例如, 的值可以是找到 url 的行号。Requestspriorityyield 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

希望有帮助。

于 2013-06-01T18:52:49.873 回答