4

プロキシとマルチスレッドの使用方法を理解しようとしています。

このコードは機能します:

requester = urllib3.PoolManager(maxsize = 10, headers = self.headers)
thread_pool = workerpool.WorkerPool()

thread_pool.map(grab_wrapper, [item['link'] for item in products])

thread_pool.shutdown()
thread_pool.wait()  

次にgrab_wrapper

requested_page = requester.request('GET', url, assert_same_host = False, headers = self.headers)

ヘッダーは、Accept、Accept-Charset、Accept-Encoding、Accept-Language、および User-Agent で構成されます

ただし、これは本番環境では機能しません。プロキシを通過する必要があるため、承認は必要ありません。

さまざまなことを試しました(proxiesリクエストへの受け渡し、ヘッダーなど)。機能する唯一のものはこれです:

requester = urllib3.proxy_from_url(self._PROXY_URL, maxsize = 7, headers = self.headers)
thread_pool = workerpool.WorkerPool(size = 10)

thread_pool.map(grab_wrapper, [item['link'] for item in products])

thread_pool.shutdown()
thread_pool.wait()  

ここで、プログラムを実行すると、10 個のリクエスト (10 スレッド) が行われ、停止します。エラーも警告もありません。proxy_from_urlこれがプロキシをバイパスできる唯一の方法ですが、WorkerPool一緒に使用することはできないようです。

これら 2 つを組み合わせて作業コードにする方法はありますか? 時間の関係でスクラップなどに書き換えるのは避けたいです。

よろしく

4

2 に答える 2

3

まず第一に、疫病のような urllib を避け、代わりにリクエストを使用することをお勧めし ます
、私はそれをマルチスレッドでは使用していませんが、マルチプロセッシングで使用しており、それは非常にうまく機能しました。把握しなければならない唯一のことは、動的キューまたはワーカーに分散できるかなり固定されたリストがあるかどうかです。 URL のリストを x プロセスに均等に分散する後者の例:

# *** prepare multi processing
nr_processes = 4
chunksize = int(math.ceil(total_nr_urls / float(nr_processes)))
procs = []
# *** start up processes
for i in range(nr_processes):
    start_row = chunksize * i
    end_row = min(chunksize * (i + 1), total_nr_store)
    p = multiprocessing.Process(
            target=url_loop,
            args=(start_row, end_row, str(i), job_id_input))
    procs.append(p)
    p.start()
# *** Wait for all worker processes to finish
for p in procs:
    p.join()

すべての url_loop プロセスは、独自のデータ セットをデータベース内のテーブルに書き出すので、Python でそれらを結合することについて心配する必要はありません。

編集: プロセス間でのデータの共有について -> 詳細については、http: //docs.python.org/2/library/multiprocessing.html ?highlight=multiprocessing#multiprocessing を参照してください。

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]

しかし、ご覧のとおり、基本的にこれらの特殊な型 (値と配列) により、プロセス間でデータを共有できます。代わりに、ラウンドロビンのようなプロセスを実行するキューを探す場合は、JoinableQueue を使用できます。お役に立てれば!

于 2013-03-04T10:32:57.690 に答える
2

thread_pool.map() Try assigning it to a variable:の呼び出しの結果を破棄しているようです。

requester = urllib3.proxy_from_url(PROXY, maxsize=7)
thread_pool = workerpool.WorkerPool(size=10)


def grab_wrapper(url):
    return requester.request('GET', url)


results = thread_pool.map(grab_wrapper, LINKS)

thread_pool.shutdown()
thread_pool.wait()

注: Python 3.2 以降を使用している場合は、concurrent.futures.ThreadPoolExecutor. に似た引用workerpoolですが、標準ライブラリに含まれています。

于 2013-03-07T17:40:39.710 に答える