2011-04-27 46 views
16

我有一段時間讓異步/線程HTTPS請求使用Python的urllib2工作。Python - 使用HTTPS的urllib2異步/線程請求示例

有沒有人有一個基本的例子,實現urllib2.Request,urllib2.build_opener和urllib2.HTTPSHandler的子類?

謝謝!

+1

歡迎來到SO ...做**你**有一個例子,說明你現在沒有什麼作用嗎?可能比在這裏的答案從頭開始診斷更容易... – 2011-04-27 17:32:45

+2

是否有一個規則,每個問題都必須「調試我的代碼?」我的代碼充滿了對我不想解釋的變量的瘋狂引用,敏感的URL等等。對於知道如何去做的人來說,這是10行代碼。 – SeaTurtle 2011-04-27 21:21:17

+0

我看到沒有接受的答案。你還對此感興趣嗎?我幾天前已經解決了這個問題,所以我可以花時間用代碼編寫詳細的答案。 – MestreLion 2014-07-29 02:19:51

回答

10

以下代碼在同一時間異步執行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() 
+1

寧願不要用扭曲的需求來分發我的腳本。你可以用內建的urllib2.Request,urllib2.build_opener和urllib2.HTTPSHandler的子類來做到這一點嗎? – SeaTurtle 2011-04-27 21:23:13

+0

@SeaTurtle:Twisted是開源的,用純Python編寫。你可以從你的代碼中取出相關的部分幷包含在內。換句話說 - 考慮***扭曲**本身*是如何使用內置插件來實現的例子。 – nosklo 2011-04-28 21:07:09

0

這裏是從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) 
+0

嗨,我寧可不要將我的腳本與一個eventlet要求分開。你可以用內建的urllib2.Request,urllib2.build_opener和urllib2.HTTPSHandler的子類來做到這一點嗎? – SeaTurtle 2011-04-27 21:26:00

+0

不,這是不可能的。而且,如果我是對的,它只能在linux下運行。 – 2011-04-28 11:43:24

5

代碼在這裏是使用的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() 
8

有一個非常簡單的方法,包括對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!" 
+4

我只想提醒一下,儘管這種方法簡單快捷,但當某些事情中斷時(如:URL不可用),它很容易出現問題。 在http://www.ibm.com/developerworks/aix/library/au-threadingpython/上有一個很好的關於線程的初學者指南,其中包含一個非常簡單的Async urllib2解決方案示例。 – stricjux 2012-05-18 12:07:53

1

您可以使用異步IO來做到這一點。

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)