Вопрос по python – Многопоточность для быстрой загрузки

1

Как я могу скачать несколько ссылок одновременно? Мой скрипт ниже работает, но загружает только по одному за раз, и он очень медленный. Я не могу понять, как включить многопоточность в мой скрипт.

Скрипт Python:

<code>from BeautifulSoup import BeautifulSoup
import lxml.html as html
import urlparse
import os, sys
import urllib2
import re

print ("downloading and parsing Bibles...")
root = html.parse(open('links.html'))
for link in root.findall('//a'):
  url = link.get('href')
  name = urlparse.urlparse(url).path.split('/')[-1]
  dirname = urlparse.urlparse(url).path.split('.')[-1]
  f = urllib2.urlopen(url)
  s = f.read()
  if (os.path.isdir(dirname) == 0): 
    os.mkdir(dirname)
  soup = BeautifulSoup(s)
  articleTag = soup.html.body.article
  converted = str(articleTag)
  full_path = os.path.join(dirname, name)
  open(full_path, 'w').write(converted)
  print(name)
</code>

HTML-файл называетсяlinks.html:

<code><a href="http://www.youversion.com/bible/gen.1.nmv-fas">http://www.youversion.com/bible/gen.1.nmv-fas</a>

<a href="http://www.youversion.com/bible/gen.2.nmv-fas">http://www.youversion.com/bible/gen.2.nmv-fas</a>

<a href="http://www.youversion.com/bible/gen.3.nmv-fas">http://www.youversion.com/bible/gen.3.nmv-fas</a>

<a href="http://www.youversion.com/bible/gen.4.nmv-fas">http://www.youversion.com/bible/gen.4.nmv-fas</a>
</code>
open (full_path, "wb"). write (преобразованный) !!! Вы хотите скачать двоичные файлы User
Вы еще ничего не пробовали, поэтому у вас нет проблемы, с которой мы могли бы помочь. kindall

Ваш Ответ

3   ответа
8

multiprocessing для распараллеливания вещей - почему-то мне это нравится больше, чемthreading

from BeautifulSoup import BeautifulSoup
import lxml.html as html
import urlparse
import os, sys
import urllib2
import re
import multiprocessing


print ("downloading and parsing Bibles...")
def download_stuff(link):
  url = link.get('href')
  name = urlparse.urlparse(url).path.split('/')[-1]
  dirname = urlparse.urlparse(url).path.split('.')[-1]
  f = urllib2.urlopen(url)
  s = f.read()
  if (os.path.isdir(dirname) == 0): 
    os.mkdir(dirname)
  soup = BeautifulSoup(s)
  articleTag = soup.html.body.article
  converted = str(articleTag)
  full_path = os.path.join(dirname, name)
  open(full_path, 'w').write(converted)
  print(name)

root = html.parse(open('links.html'))
links = root.findall('//a')
pool = multiprocessing.Pool(processes=5) #use 5 processes to download the data
output = pool.map(download_stuff,links)  #output is a list of [None,None,...] since download_stuff doesn't return anything
Error: User Rate Limit ExceededmultiprocessingError: User Rate Limit Exceeded
Error: User Rate Limit ExceededAssertionError: invalid Element proxy at 163319020 Blainer
Error: User Rate Limit Exceeded Blainer
2

таких как asyncio и ThreadPoolExecutor.

Вот пример ThreadPoolExecutor (включен в фьючерсы Python)

from concurrent.futures import ThreadPoolExecutor

def download(url, filename):
    ... your dowload function...
    pass

with ThreadPoolExecutor(max_workers=12) as executor:
    future = executor.submit(download, url, filename)
    print(future.result())

Функция submit () отправит задачу в очередь. (управление очередью сделано для вас)

Python version 3.5 and above:
if max_workers is None or not given, it will default to the number of processors on the 
machine, multiplied by 5.

Вы можете установить max_workers, в несколько раз превышающее число ядер ЦП на практике, выполнить несколько тестов, чтобы увидеть, насколько вы можете подняться в зависимости от издержек переключения контекста.

Для получения дополнительной информации: https://docs.python.org/3/library/concurrent.futures.html

1

икипедию

Вы можете использовать

import Queue, thread

# create a Queue.Queue here
queue = Queue.Queue()

print ("downloading and parsing Bibles...")
root = html.parse(open('links.html'))
for link in root.findall('//a'):
  url = link.get('href')
  queue.put(url) # produce




def thrad():
  url = queue.get() # consume
  name = urlparse.urlparse(url).path.split('/')[-1]
  dirname = urlparse.urlparse(url).path.split('.')[-1]
  f = urllib2.urlopen(url)
  s = f.read()
  if (os.path.isdir(dirname) == 0): 
    os.mkdir(dirname)
  soup = BeautifulSoup(s)
  articleTag = soup.html.body.article
  converted = str(articleTag)
  full_path = os.path.join(dirname, name)
  open(full_path, 'wb').write(converted)
  print(name)

thread.start_new(thrad, ()) # start 1 threads
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededshouldError: User Rate Limit Exceededfrom Queue import QueueError: User Rate Limit Exceededfrom threading import ThreadError: User Rate Limit ExceededThread.start_new(thread,())Error: User Rate Limit ExceededthreadingError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededNameError: name 'queue' is not defined Error: User Rate Limit ExceededAttributeError: 'module' object has no attribute 'put' Blainer
Error: User Rate Limit ExceededthreadError: User Rate Limit Exceeded

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