python - tutorial - ウェブスクレーパーのスピードアップ




spiders scrapy (3)

あなたのstart_urlsをスピードアップするための1つの回避策は、あなたのstart_urls適切に設定することです。

たとえば、ターゲットデータがhttp://apps.webofknowledge.com/doc=1場合、ドキュメント番号の範囲は1から1000までです。 start_urlsでは、 start_urlsを次のように設定できます。

 start_urls = [
    "http://apps.webofknowledge.com/doc=250",
    "http://apps.webofknowledge.com/doc=750",
]

このようにリクエストは250から751,749まで、 750から751,749同時に開始されるため、 start_urls = ["http://apps.webofknowledge.com/doc=1"]と比べて4倍の速さで取得できます。

私は、非常にシンプルなウェブスクレーパーで、治療法を使って23770のWebページを掻き集めています。 私は治療やPythonにはかなり新しいですが、仕事をするスパイダーを書くことができました。 しかし、実際には遅いです(23770ページをクロールするのに約28時間かかります)。

私は、 scrapyウェブページとメーリングリストとstackoverflowを見てきましたが、初心者のために理解できる高速クローラを書くための一般的な推奨事項を見つけることはできません。 たぶん私の問題は、スパイダー自体ではなく、私がそれを実行する方法です。 すべての提案は歓迎!

必要なら、私のコードを以下に挙げました。

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&kom=&amt=&fraPostnr=&tilPostnr=&iPostnr=&gade=&min=&max=&byggetMin=&byggetMax=&minRooms=&maxRooms=&minSize=&maxSize=&minsaledate=1992&maxsaledate=today&kode=&p=%d' %n for n in xrange(1, 23770, 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

ありがとう!


あなたのコードを見ると、その時間の大半は応答を処理するのではなく、ネットワーク要求に費やされていると言えます。 すべてのヒント@alecxeが彼の答えを提供しますが、私はHTTPCACHE_ENABLED設定を提案します。なぜなら、リクエストをキャッシュし、2回目の実行を避けるからです。 クロールやオフラインでの開発にも役立ちます。 ドキュメントの詳細情報: http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.contrib.downloadermiddleware.httpcache : http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#module-scrapy.contrib.downloadermiddleware.httpcache


試してみるべきことのコレクションがあります:

  • 最新の治療バージョンを使用する(既に使用していない場合)
  • 非標準ミドルウェアが使用されているかどうかを確認する
  • CONCURRENT_REQUESTS_PER_DOMAINCONCURRENT_REQUESTS設定( docs )を増やしてみてください。
  • ロギングを無効にするLOG_ENABLED = Falsedocs
  • アイテムをitemsリストに収集して返すのではなく、ループ内でitemsを返すようにしてください
  • ローカルキャッシュDNSを使用する( このスレッドを参照)
  • このサイトがダウンロードのしきい値を使用していて、ダウンロード速度が制限されていないか確認してください( このスレッドを参照)
  • スパイダー実行中のログCPUとメモリ使用量 - そこに問題がないかどうかを確認する
  • scrapydサービスの下で同じスパイダーを実行してみてください
  • grequests + lxmlパフォーマンスが向上するかどうかを確認してください(このソリューションの実装に関する助けが必要かどうか尋ねてください)
  • Scrapypypy実行してみてScrapypypy実行するを参照してください。

希望が役立ちます。





scrapy-spider