2013-06-01 47 views
4

幫助!閱讀Scrapy的源代碼對我來說並不容易。 我有很長的start_urls名單。它在一個文件中大約是3,000,000。於是,我讓start_urls這樣的:順序的Scrapy爬行URL與長start_urls列表和url從蜘蛛yiels

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

同時,我的蜘蛛的回調函數是這樣的:

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. 這是一個很好的方式來處理已經在文件中的這麼多網址嗎?還有什麼?

非常感謝!

感謝answers.But我還是有點糊塗: 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中有多少個隊列?

回答

6

首先,請看這thread - 我想你會在那裏找到所有的答案。

下載器使用的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) 

什麼決定的順序?爲什麼以及這個訂單如何?我們如何控制 呢?

默認情況下,沒有預先定義的順序 - 你可以不知道什麼時候Requestsmake_requests_from_url將到達 - 這是異步的。

請參閱this answer關於如何控制訂單。長話短說,你可以覆蓋start_requests和標記產生Requestspriority密鑰(如yield Request(url, meta={'priority': 0}))。例如,priority的值可以是找到URL的行號。

這是一個很好的方式來處理已經在 文件中的很多網址嗎?還有什麼?

我想你應該直接在start_requests方法閱讀您的文件和產量的網址:見this answer

所以,你應該做的水木清華這樣的:

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 

希望有所幫助。

+0

非常感謝!我仍然有點困惑。[默認情況下,Scrapy使用LIFO隊列來存儲待處理的請求。](http://doc.scrapy.org/en/latest/faq.html#does -scrapy抓取功能於呼吸第一或深度優先順序)。 –

+0

我補充了我的問題。評論太長了。希望能得到你的答案。非常感謝你! –