Как следует из названия, я работаю над сайтом, написанным на python, и он делает несколько обращений к модулю urllib2 для чтения веб-сайтов. Я тогда разбираю их с BeautifulSoup.
Поскольку мне приходится читать 5-10 сайтов, загрузка страницы занимает некоторое время.
Мне просто интересно, есть ли способ читать сайты сразу? Или какие-нибудь хитрости, чтобы сделать это быстрее, например, я должен закрывать urllib2.urlopen после каждого чтения или держать его открытым?
Добавлено : также, если бы я просто переключился на php, это было бы быстрее для получения а парси г HTML и XML файлы с других сайтов? Я просто хочу, чтобы он загружался быстрее, в отличие от ~ 20 секунд, которые в настоящее время требуются
Я переписываю приведенный ниже код Dumb Guy, используя современные модули Python, такие как threading
и Queue
.
import threading, urllib2
import Queue
urls_to_load = [
'http://stackoverflow.com/',
'http://slashdot.org/',
'http://www.archive.org/',
'http://www.yahoo.co.jp/',
]
def read_url(url, queue):
data = urllib2.urlopen(url).read()
print('Fetched %s from %s' % (len(data), url))
queue.put(data)
def fetch_parallel():
result = Queue.Queue()
threads = [threading.Thread(target=read_url, args = (url,result)) for url in urls_to_load]
for t in threads:
t.start()
for t in threads:
t.join()
return result
def fetch_sequencial():
result = Queue.Queue()
for url in urls_to_load:
read_url(url,result)
return result
Лучшее время для find_sequencial ()
- 2 секунды. Лучшее время для fetch_parallel ()
- 0,9 секунды.
Также неверно говорить, что поток
бесполезен в Python из-за GIL. Это один из тех случаев, когда поток полезен в Python, потому что потоки заблокированы при вводе-выводе. Как вы можете видеть из моего результата, параллельный случай в 2 раза быстрее.
Как правило, данная конструкция на любом языке не является медленной, пока не будет измерена.
В Python не только время выполнения часто противоречит интуиции, но и инструменты для измерения времени выполнения исключительно хороши.
Scrapy может быть вам полезен. Если вам не нужны все его функции, вы можете просто использовать вместо него twisted twisted.web.client.getPage
. Асинхронный ввод-вывод в одном потоке будет более производительным и легким для отладки, чем все, что использует несколько потоков и блокирует ввод-вывод.
1) Вы открываете один и тот же сайт много раз, или много разных сайтов? Если много разных сайтов, то я думаю urllib2 подойдет. Если один и тот же сайт открывается снова и снова, мне лично повезло с urllib3 http://code.google.com/p/urllib3/
2) BeautifulSoup прост в использовании, но довольно медленный. Если вам придется использовать его, убедитесь, что вы разложили ваши теги, чтобы избавиться от утечек памяти... или это может привести к проблемам с памятью (у меня так было).
Как выглядит ваша память и процессор? Если у вас максимальный процессор, убедитесь, что вы используете действительно тяжелые потоки, так что вы можете работать на более чем 1 ядре.
Как насчет использования pycurl?
Вы можете установить его через apt-get
$ sudo apt-get python-pycurl