Python - пример асинхронного/потокового запроса urllib2 с использованием HTTPS
У меня чертовски время, когда асинхронные/потоковые HTTPS-запросы работают с использованием Python urllib2.
Есть ли у кого-нибудь базовый пример, реализующий urllib2.Request, urllib2.build_opener и подкласс urllib2.HTTPSHandler?
Спасибо!
Ответы
Ответ 1
В приведенном ниже коде асинхронно 7 запросов HTTP.
Он не использует потоки, вместо этого он использует асинхронную сеть с библиотекой twisted.
from twisted.web import client
from twisted.internet import reactor, defer
urls = [
'http://www.python.org',
'http://stackoverflow.com',
'http://www.twistedmatrix.com',
'http://www.google.com',
'http://launchpad.net',
'http://github.com',
'http://bitbucket.org',
]
def finish(results):
for result in results:
print 'GOT PAGE', len(result), 'bytes'
reactor.stop()
waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(finish)
reactor.run()
Ответ 2
существует очень простой способ, связанный с обработчиком для urllib2, который вы можете найти здесь: http://pythonquirks.blogspot.co.uk/2009/12/asynchronous-http-request.html
#!/usr/bin/env python
import urllib2
import threading
class MyHandler(urllib2.HTTPHandler):
def http_response(self, req, response):
print "url: %s" % (response.geturl(),)
print "info: %s" % (response.info(),)
for l in response:
print l
return response
o = urllib2.build_opener(MyHandler())
t = threading.Thread(target=o.open, args=('http://www.google.com/',))
t.start()
print "I'm asynchronous!"
t.join()
print "I've ended!"
Ответ 3
вот пример использования urllib2 (с https) и потоков. Каждый поток циклически проходит через список URL-адресов и извлекает ресурс.
import itertools
import urllib2
from threading import Thread
THREADS = 2
URLS = (
'https://foo/bar',
'https://foo/baz',
)
def main():
for _ in range(THREADS):
t = Agent(URLS)
t.start()
class Agent(Thread):
def __init__(self, urls):
Thread.__init__(self)
self.urls = urls
def run(self):
urls = itertools.cycle(self.urls)
while True:
data = urllib2.urlopen(urls.next()).read()
if __name__ == '__main__':
main()
Ответ 4
Для этого вы можете использовать асинхронный ввод-вывод.
requests + gevent= grequests
GRequests позволяет использовать запросы с Gevent для упрощения асинхронных запросов HTTP.
import grequests
urls = [
'http://www.heroku.com',
'http://tablib.org',
'http://httpbin.org',
'http://python-requests.org',
'http://kennethreitz.com'
]
rs = (grequests.get(u) for u in urls)
grequests.map(rs)
Ответ 5
вот код из eventlet
urls = ["http://www.google.com/intl/en_ALL/images/logo.gif",
"https://wiki.secondlife.com/w/images/secondlife.jpg",
"http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif"]
import eventlet
from eventlet.green import urllib2
def fetch(url):
return urllib2.urlopen(url).read()
pool = eventlet.GreenPool()
for body in pool.imap(fetch, urls):
print "got body", len(body)