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

时间:2013-06-01 17:57:27

标签: python python-2.7 web-scraping scrapy web-crawler

帮助!阅读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!"

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

我的问题是:

  1. 下载程序使用的网址顺序?是否会提出要求 just_test1just_test2仅在全部使用后由下载程序使用 start_urls被使用了?(我做了一些测试,似乎是 答案是否定的)
  2. 什么决定订单?为什么以及如何订购?我们如何控制它?
  3. 这是处理文件中已有多个网址的好方法吗?还有什么?
  4. 非常感谢!!!

    感谢您的回答。但我仍然有点困惑: By default, Scrapy uses a LIFO queue for storing pending requests.

    1. 由蜘蛛回调函数制作的requests将被赋予 scheduler。谁对start_url's requests做同样的事情?蜘蛛 start_requests()函数只生成迭代器而不给出 真正的要求。
    2. 所有requests(start_url和回调)是否在同一个请求的队列中?Scrapy中有多少个队列?

1 个答案:

答案 0 :(得分:7)

首先,请看这个thread - 我想你会在那里找到所有答案。

  

下载程序使用的网址顺序?是否会提出要求   just_test1,just_test2仅在all之后由下载程序使用   使用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)
  

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

默认情况下,没有预先定义的顺序 - 您无法知道来自Requests的{​​{1}}何时到达 - 它是异步的。

有关如何控制订单的信息,请参阅this answer。 简而言之,您可以覆盖make_requests_from_url并使用start_requests键标记已产生的Requests(例如priority)。例如,yield Request(url, meta={'priority': 0})的值可以是找到网址的行号。

  

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

我认为您应该使用priority方法直接阅读您的文件并生成网址:请参阅this answer

所以,你应该这样做:

start_requests

希望有所帮助。