Python: Чему-то нравится 'карта', которая работает над [закрывшими] обсуждениями

Я был уверен, что в стандартной библиотеке было что-то вроде этого, но кажется, что я был неправ.

У меня есть набор URL, что я хочу urlopen параллельно. Я хочу что-то как встроенное map функция, кроме работы сделана параллельно набором потоков.

Существует ли хороший модуль, который делает это?

26
задан Martijn Pieters 1 September 2016 в 15:08
поделиться

4 ответа

Кто-то порекомендовал мне использовать для этого пакет futures . Я попробовал, и вроде работает.

http://pypi.python.org/pypi/futures

Вот пример:

"Download many URLs in parallel."

import functools
import urllib.request
import futures

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/',
        'http://some-made-up-domain.com/']

def load_url(url, timeout):
    return urllib.request.urlopen(url, timeout=timeout).read()

with futures.ThreadPoolExecutor(50) as executor:
   future_list = executor.run_to_futures(
           [functools.partial(load_url, url, 30) for url in URLS])
11
ответ дан 28 November 2019 в 06:42
поделиться

Модуль Python Queue может вам помочь. Используйте один поток, который использует Queue.put () , чтобы поместить все URL-адреса в очередь, а рабочие потоки просто get () URL-адреса один за другим.

Документы Python: очередь - класс синхронизированной очереди

3
ответ дан 28 November 2019 в 06:42
поделиться

Я бы обернул это функцией (непроверенной):

import itertools
import threading
import urllib2
import Queue

def openurl(url, queue):
    def starter():
        try:
            result = urllib2.urlopen(url)
        except Ecxeption, exc:
            def raiser():
                raise exc
            queue.put((url, raiser))
        else:
            queue.put((url, lambda:result))
    threadind.Thread(target=starter).start()

myurls = ... # the list of urls
myqueue = Queue.Queue()

map(openurl, myurls, itertools.repeat(myqueue))

for each in myurls:
    url, getresult = queue.get()
    try:
        result = getresult()
    except Exception, exc:
        print 'exception raised:' + str(exc)
    else:
        # do stuff with result
0
ответ дан 28 November 2019 в 06:42
поделиться

Есть метод map в multiprocessing.Pool. Это делает несколько процессов.

А если множественные процессы - не ваше блюдо, вы можете использовать multiprocessing.dummy, который использует потоки.

import urllib
import multiprocessing.dummy

p = multiprocessing.dummy.Pool(5)
def f(post):
    return urllib.urlopen('http://stackoverflow.com/questions/%u' % post)

print p.map(f, range(3329361, 3329361 + 5))
42
ответ дан 28 November 2019 в 06:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: