2016-07-23 43 views
0

我創建了一個非常緩慢的新Scrapy蜘蛛。它每秒只能抓取兩頁,而我創建的其他Scrapy抓取工具的抓取速度更快。緩慢的Scrapy刮刀的原因

我想知道它是什麼可能導致此問題,以及如何解決這個問題。代碼與其他蜘蛛並沒有太大區別,我不確定它是否與問題有關,但如果您認爲它可能涉及到,我會添加它。

事實上,我的印象是請求不是異步的。我從來沒有遇到過這樣的問題,我對Scrapy相當陌生。

編輯

這裏的蜘蛛:

class DatamineSpider(scrapy.Spider): 
    name = "Datamine" 
    allowed_domains = ["domain.com"] 
    start_urls = (
     'http://www.example.com/en/search/results/smth/smth/r101/m2108m', 
    ) 

    def parse(self, response): 
     for href in response.css('.searchListing_details .search_listing_title .searchListing_title a::attr("href")'): 
      url = response.urljoin(href.extract()) 
      yield scrapy.Request(url, callback=self.parse_stuff) 
     next_page = response.css('.pagination .next a::attr("href")') 
     next_url = response.urljoin(next_page.extract()[0]) 
     yield scrapy.Request(next_url, callback=self.parse) 

    def parse_stuff(self, response): 
     item = Item() 
     item['value'] = float(response.xpath('//*[text()="Price" and not(@class)]/../../div[2]/span/text()').extract()[0].split(' ')[1].replace(',','')) 
     item['size'] = float(response.xpath('//*[text()="Area" and not(@class)]/../../div[2]/text()').extract()[0].split(' ')[0].replace(',', '.')) 
     try: 
      item['yep'] = float(response.xpath('//*[text()="yep" and not(@class)]/../../div[2]/text()').extract()[0]) 
     except IndexError: 
      print "NO YEP" 
     else: 
      yield item 
+0

有很多事情可能會導致這種情況。你能提供蜘蛛源和抓取日誌嗎?如果您正在運行unix系統,則可以執行scrapy crawl spider 2&1 spider.log',然後在此處發佈該日誌。 – Granitosaurus

+0

我加了蜘蛛,我會盡快添加日誌,(我現在正在運行它)。當我看日誌時,速度在45到80頁/分鐘之間。 ;( – AimiHat

+0

你可以嘗試發現是代碼是慢速分析代碼,像https://github.com/rkern/line_profiler – Ceppo93

回答

1

只有兩個可能的原因,因爲你的蜘蛛表明你很小心/經歷。

  1. 您的目標網站的響應時間是非常低的
  2. 每個頁面都有1-2只上市的網頁(您使用parse_stuff()解析的)。

極有可能後者是原因。響應時間爲半秒是合理的。這意味着通過遵循分頁(下一個)鏈接,您將實際上每秒抓取2個索引頁。由於您正在瀏覽 - 我猜 - 作爲單個域名,您的最大併發數將是〜min(CONCURRENT_REQUESTS, CONCURRENT_REQUESTS_PER_DOMAIN)。默認設置通常爲8。但是,您將無法利用此併發性,因爲您不會足夠快地創建列表網址。如果.searchListing_details .search_listing_title .searchListing_title a::attr("href")表達式僅創建一個URL,則創建列表URL的速率僅爲2 /秒,而要充分利用併發級別爲8的下載器,則應該創建至少7個URL /索引頁面。

唯一不錯的解決方案是「索引」索引並開始爬行,例如,通過設置許多不重疊的多個類別start_urls。例如。您可能想要並行抓取電視機,洗衣機,立體聲音響或任何其他類別。如果你有4個這樣的類別,並且Scrapy每秒鐘爲他們的「下一個」按鈕點擊2次,那麼你將創建8個列表頁面/秒,粗略地說,你會更好地利用你的下載器。

P.S. next_page.extract()[0] == next_page.extract_first()

離線討論後進行更新:是的......除了速度較慢(無論是由於節流還是由於其服務器容量),我沒有在此網站上看到任何奇怪的現象。一些特定的技巧要走得更快。擊中指數4倍那樣快通過設置4 start_urls而不是1

start_urls = (
    'http://www.domain.com/en/search/results/smth/sale/r176/m3685m', 
    'http://www.domain.com/en/search/results/smth/smth/r176/m3685m/offset_200', 
    'http://www.domain.com/en/search/results/smth/smth/r176/m3685m/offset_400', 
    'http://www.domain.com/en/search/results/smth/smth/r176/m3685m/offset_600' 
) 

然後使用更高的併發,以允許沿平行於裝載多個URL。基本上通過將其設置爲一個很大的值來「去激活」CONCURRENT_REQUESTS_PER_DOMAIN,例如, 1000,然後通過將CONCURRENT_REQUESTS設置爲30來調整併發性。默認情況下,併發性會受到CONCURRENT_REQUESTS_PER_DOMAIN至8的限制,例如,您的情況下,列表頁面的響應時間大於1.2秒,意味着每個頁面最多有6個列表頁面第二次爬行速度。所以打電話給你的蜘蛛是這樣的:

scrapy crawl MySpider -s CONCURRENT_REQUESTS_PER_DOMAIN=1000 -s CONCURRENT_REQUESTS=30 

它應該會做得更好。

還有一件事。我從您的目標網站觀察到,您可以從索引頁面中獲取所需的全部信息,包括Price,Areayep,而無需「點擊」任何列表頁面。由於您不需要使用for href...循環下載所有這些列表頁面,因此這會立即提升10倍的爬網速度。只是從索引頁面解析列表。

+0

謝謝你長期和詳細的答案。每個頁面有大約10個列表頁面,蜘蛛仍然設法達到每分鐘1頁的速度。網站本身可能會限制我的請求嗎?我找不到合理的解釋 – AimiHat