0

私はpython 3.4を持っていて、リクエストと他のいくつかの必要なプログラムをWebスクレイプにインストールしました。私の問題は、約 7000 ページ (html/text のみ) をスクレイピングしたいのですが、一度にすべてをスクレイピングしたくないということです。サーバーにアクセスしないように、何らかの遅延が必要です。リクエストが多すぎて、禁止される可能性があります。grequests について聞いたことがありますが、どうやら Python 3.4 には対応していないようです (実際のエラーは vcvarsall.bat が見つからないと言っていますが、ドキュメントでは 3.4 のサポートは見当たりませんでした)。URL 要求を管理できる代​​替プログラムを知っている人はいますか? 言い換えれば、私はすべてをできるだけ速くつかもうとしているのではなく、ゆっくりと着実につかもうとしています。

4

1 に答える 1

1

独自のマルチスレッド プログラムをロールしてリクエストを実行することをお勧めします。この種concurrent.futuresのリクエストをマルチスレッド化するには、特にThreadPoolExecutor. ドキュメントには、単純なマルチスレッド URL リクエストの例もあります。

質問の2番目の部分については、リクエストをどれだけ/どのように制限したいかによって異なります。私にとっては、十分に低いmax_workers引数を設定time.sleepし、関数に待機を含めることで、数万ページをスクレイピングする場合でも問題を回避するのに十分でしたが、これは明らかに、スクレイピングしようとしているサイトに大きく依存します. ただし、ある種のバッチ処理や待機を実装するのは難しくありません。

次のコードはテストされていませんが、出発点になることを願っています。get_url_dataここから、おそらく他の必要なこと (解析、保存など) で (または使用している関数を)変更したいと思うでしょう。

import concurrent.futures as futures
import requests
from requests.exceptions import HTTPError

urllist = ...

def get_url_data(url, session):
    try:
        r = session.get(url, timeout=10)
        r.raise_for_status()
    except HTTPError:
        return None

    return r.text

s = requests.Session()

try:
    with futures.ThreadPoolExecutor(max_workers=5) as ex:
        future_to_url = {ex.submit(get_url_data, url, s): url
                         for url in urlist}

    results = {future_to_url[future]: future.result() 
               for future in futures.as_completed(future_to_url)}
finally:
    s.close() 
于 2014-08-14T06:11:58.943 に答える