2013-06-11 56 views
0

我在其他問題中使用了以下問題,但是這次我的問題是關於服務器性能問題。所以,我決定提出一個新問題。抓取時遠程服務器性能問題

我嘗試運行下面的蜘蛛。它只需要通過2478頁,但我仍然有性能問題。最初,用以下設置刮掉數據大約需要2.5小時:

LOG_ENABLED = True 
CONCURRENT_REQUESTS_PER_DOMAIN = 2 
RETRY_TIMES = 20 
DOWNLOAD_DELAY = 5 

對我而言,這似乎很慢。爲了加快蜘蛛速度,我設置了HTTPCACHE_ENABLED = True,但在第100頁之後,蜘蛛只返回了「500內部服務器錯誤」,我甚至無法在瀏覽器中查看網頁。

任何想到爲什麼我收到此錯誤?我該怎麼做才能避免這個問題?

我的代碼如下:

from scrapy.spider import BaseSpider 
from scrapy.selector import HtmlXPathSelector 
from scrapy.item import Item, Field 
import re 

class Sale(Item): 
    Adresse = Field() 
    Pris = Field() 
    Salgsdato = Field() 
    SalgsType = Field() 
    KvmPris = Field() 
    Rum = Field() 
    Postnummer = Field() 
    Boligtype = Field() 
    Kvm = Field() 
    Bygget = Field() 

class HouseSpider(BaseSpider): 
    name = 'House' 
    allowed_domains = ["http://boliga.dk/"] 
    start_urls = ['http://www.boliga.dk/salg/resultater?so=1&type=Villa&type=Ejerlejlighed&type=R%%C3%%A6kkehus&type=Fritidshus&type=Landejendom&type=Andet&kom=&amt=&fraPostnr=&tilPostnr=&iPostnr=&gade=&min=&max=&byggetMin=&byggetMax=&minRooms=&maxRooms=&minSize=&maxSize=&minsaledate=1993&maxsaledate=1994&kode=&p=%d' %n for n in xrange(1, 2479, 1)] 

    def parse(self, response): 
     hxs = HtmlXPathSelector(response) 
     sites = hxs.select("id('searchresult')/tr") 
     items = []  
     for site in sites: 
      item = Sale() 
      item['Adresse'] = site.select("td[1]/a[1]/text()").extract() 
      item['Pris'] = site.select("td[2]/text()").extract() 
      item['Salgsdato'] = site.select("td[3]/text()").extract() 
      Temp = site.select("td[4]/text()").extract() 
      Temp = Temp[0] 
      m = re.search('\r\n\t\t\t\t\t(.+?)\r\n\t\t\t\t', Temp) 
      if m: 
       found = m.group(1) 
       item['SalgsType'] = found 
      else: 
       item['SalgsType'] = Temp 
      item['KvmPris'] = site.select("td[5]/text()").extract() 
      item['Rum'] = site.select("td[6]/text()").extract() 
      item['Postnummer'] = site.select("td[7]/text()").extract() 
      item['Boligtype'] = site.select("td[8]/text()").extract() 
      item['Kvm'] = site.select("td[9]/text()").extract() 
      item['Bygget'] = site.select("td[10]/text()").extract() 
      items.append(item) 
     return items 

謝謝!

+0

你指的是什麼「我的服務器」?您是在WSGI應用程序內部運行此代碼還是其他內容?如果是這樣,顯而易見的事情就是在本地解釋器中運行相同的代碼,以便將與服務器相關的任何內容都排除在外。如果問題仍然存在,你有答案,對吧? – abarnert

+0

無論如何,許多Web服務器故意扼殺過度激進的客戶端,因爲(a)他們已經獲得了他們希望您使用的正確的Web服務,(b)他們不希望您在不看到所有信息的情況下閱讀所有信息廣告,(c)他們不希望任何人獲得他們所有的信息,因爲這是他們的實際價值所在,和/或(d)他們不想爲所有帶寬付費。(許多較小的網站使用託管提供商自動調節,但在這種情況下,它基本上是(d)。) – abarnert

+0

@abarnert:我只是從筆記本電腦和互聯網連接運行蜘蛛,所以談論「我的服務器」可能只是我不完全理解正在發生什麼。對於那個很抱歉。 – Mace

回答

0

最初,花了約2.5小時以下設置刮數據:

LOG_ENABLED =真 CONCURRENT_REQUESTS_PER_DOMAIN = 2個 RETRY_TIMES = 20 DOWNLOAD_DELAY = 5

你要求它等待5秒鐘,然後從同一個站點下載連續的頁面。這就是DOWNLOAD_DELAY的含義。它實際上會在2.5到7.5秒之間等待一段隨機時間,有時候它會有兩個同時在飛行中的請求,等等......但是以這種方式下載2478頁的期望值是5 * 2477 = 12385秒= 3: 26:25。

如果設置HTTPCACHE_ENABLED有所作爲,顯然你已經運行了3.5小時,並且大部分仍然在同一個緩存目錄中。 (你不能打破的東西,使得它下載相同的頁面重複,因爲你喂BaseSpider頁面的靜態列表,而不是從parse返回任何Request對象。)


但最簡單的方法調試這個就是把你的所有代碼排除在外。生成一個地址列表,並嘗試下載curlwget或其他東西。

當我嘗試這樣做時,即使請求之間有10秒鐘的延遲,幾乎所有人都花了20秒鐘才能返回500錯誤,其中有幾個從來沒有響應過。這對我來說肯定是一個服務器問題。所以,除了可能聯繫服務器管理員之外,你無能爲力。

+0

不夠公平,但我怎樣才能解決我得到的「500內部服務器錯誤」問題? – Mace

+0

好的,謝謝。現在,我認爲服務器存在問題,但總體而言,'download_delay'是避免服務器問題的最佳/唯一方法? – Mace

+0

@Mace服務器可能有問題,或者它可能最終會暫時阻止您在一段時間內發出太多請求(如果每秒請求數太多,可以有效地用作DoS攻擊)。如果您想阻止您的IP地址被阻止,並且防止潛在的DoS情況,那麼設置下載延遲很有用。延遲越大,腳本將會越慢。 – Anorov