18

を使用して、非常に単純な Web スクレーパーで 23770 の Web ページをスクレイピングしていscrapyます。私はスクレイピー、さらにはpythonも初めてですが、仕事をするスパイダーを書くことができました。ただし、非常に遅いです (23770 ページをクロールするのに約 28 時間かかります)。

scrapyWeb ページとメーリング リストとを調べましたが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

ありがとう!

4

4 に答える 4

37

試してみるべきことのコレクションは次のとおりです。

  • 最新のスクレイピー バージョンを使用する (まだ使用していない場合)
  • 非標準のミドルウェアが使用されているかどうかを確認します
  • 設定を増やしてみてCONCURRENT_REQUESTS_PER_DOMAINくださいCONCURRENT_REQUESTSドキュメント
  • ロギングをオフにするLOG_ENABLED = False( docs )
  • アイテムをリストyieldに集めて返すのではなく、ループでアイテムを試してみてくださいitems
  • ローカル キャッシュ DNS を使用する (このスレッドを参照)
  • このサイトがダウンロードしきい値を使用してダウンロード速度を制限しているかどうかを確認してください (このスレッドを参照してください)
  • スパイダーの実行中に CPU とメモリの使用量をログに記録します - そこに問題があるかどうかを確認します
  • Scrapydサービスで同じスパイダーを実行してみてください
  • grequests + lxmlのパフォーマンスが向上するかどうかを確認してください (このソリューションの実装について何か助けが必要かどうか尋ねてください)
  • Scrapyで実行してみてください。PyPy での Scrapy の実行pypyを参照してください

それが役立つことを願っています。

于 2013-06-10T18:46:56.067 に答える
5

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

于 2013-06-10T23:21:25.623 に答える
0

最適化された C# を使用して Web スクレイピングにも取り組んでいますが、CPU バウンドになってしまうため、C に切り替えています。

HTML の解析は CPU データ キャッシュを破壊します。また、C/C++ を使用してのみこの機能にアクセスできるため、CPU が SSE 4.2 をまったく使用していないことを確認してください。

計算を行うと、すぐに計算バウンドになりますが、メモリバウンドではありません。

于 2015-10-18T02:19:54.167 に答える