Как я могу ускорить получение страниц с urllib2 в Python? - PullRequest
26 голосов
/ 16 августа 2010

У меня есть скрипт, который выбирает несколько веб-страниц и анализирует информацию.

(пример можно увидеть на http://bluedevilbooks.com/search/?DEPT=MATH&CLASS=103&SEC=01)

Я запустил cProfile, и, как я предполагал, urlopen отнимает много времени. Есть ли способ получить страницы быстрее? Или способ получить несколько страниц одновременно? Я сделаю все самое простое, так как я новичок в разработке на Python и в Интернете.

Заранее спасибо! :)

ОБНОВЛЕНИЕ: у меня есть функция с именем fetchURLs(), которую я использую для создания массива нужных мне URL. что-то вроде urls = fetchURLS(). Все URL-адреса представляют собой файлы XML из API Amazon и eBay (что смущает меня, почему загрузка занимает так много времени, может быть, мой веб-хост работает медленно?)

Что мне нужно сделать, это загрузить каждый URL, прочитать каждую страницу и отправить эти данные в другую часть скрипта, которая будет анализировать и отображать данные.

Обратите внимание, что я не могу выполнить последнюю часть, пока ВСЕ страницы не будут извлечены, вот в чем моя проблема.

Кроме того, я считаю, что мой хост ограничивает меня до 25 процессов одновременно, поэтому все, что проще на сервере, было бы неплохо:)


Вот на время:

Sun Aug 15 20:51:22 2010    prof

         211352 function calls (209292 primitive calls) in 22.254 CPU seconds

   Ordered by: internal time
   List reduced from 404 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10   18.056    1.806   18.056    1.806 {_socket.getaddrinfo}
     4991    2.730    0.001    2.730    0.001 {method 'recv' of '_socket.socket' objects}
       10    0.490    0.049    0.490    0.049 {method 'connect' of '_socket.socket' objects}
     2415    0.079    0.000    0.079    0.000 {method 'translate' of 'unicode' objects}
       12    0.061    0.005    0.745    0.062 /usr/local/lib/python2.6/HTMLParser.py:132(goahead)
     3428    0.060    0.000    0.202    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1306(endData)
     1698    0.055    0.000    0.068    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1351(_smartPop)
     4125    0.053    0.000    0.056    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:118(setup)
     1698    0.042    0.000    0.358    0.000 /usr/local/lib/python2.6/HTMLParser.py:224(parse_starttag)
     1698    0.042    0.000    0.275    0.000 /usr/local/lib/python2.6/site-packages/BeautifulSoup.py:1397(unknown_starttag)

Ответы [ 11 ]

0 голосов
/ 16 августа 2010

Получение веб-страниц, очевидно, займет некоторое время, так как вы не получаете доступ ни к чему локальному. Если у вас есть несколько для доступа, вы можете использовать модуль threading для одновременного запуска пары.

Вот очень грубый пример

import threading
import urllib2
import time

urls = ['http://docs.python.org/library/threading.html',
        'http://docs.python.org/library/thread.html',
        'http://docs.python.org/library/multiprocessing.html',
        'http://docs.python.org/howto/urllib2.html']
data1 = []
data2 = []

class PageFetch(threading.Thread):
    def __init__(self, url, datadump):
        self.url = url
        self.datadump = datadump
        threading.Thread.__init__(self)
    def run(self):
        page = urllib2.urlopen(self.url)
        self.datadump.append(page.read()) # don't do it like this.

print "Starting threaded reads:"
start = time.clock()
for url in urls:
    PageFetch(url, data2).start()
while len(data2) < len(urls): pass # don't do this either.
print "...took %f seconds" % (time.clock() - start)

print "Starting sequential reads:"
start = time.clock()
for url in urls:
    page = urllib2.urlopen(url)
    data1.append(page.read())
print "...took %f seconds" % (time.clock() - start)

for i,x in enumerate(data1):
    print len(data1[i]), len(data2[i])

Это был вывод, когда я его запустил:

Starting threaded reads:
...took 2.035579 seconds
Starting sequential reads:
...took 4.307102 seconds
73127 19923
19923 59366
361483 73127
59366 361483

Захват данных из потока путем добавления в список, вероятно, является опрометчивым (очередь лучше), но это показывает, что есть разница.

...