2009-09-02 5 views
7

웹 사이트를 비동기식으로 읽으려고합니다. 알고있는 한 urllib로는 불가능합니다. 이제 일반 소켓으로 읽기를 시도했지만 HTTP가 나에게 지옥을주고 있습니다. 나는 모든 종류의 펑키 인코딩을 사용합니다. 예를 들어 전송 인코딩 : 청크로 처리 된 모든 것들을 수동으로 구문 분석해야하며, 파이썬이 아닌 C 코딩을하고 싶습니다.asyncore로 웹 사이트 읽기

URLLib와 같은 더 좋은 방법이 비동기식으로 존재하지 않습니까? 이전에 모든 것이 끝났을 때 전체 HTTP 스펙을 다시 구현하는 것 같은 기분이 아닙니다.

현재 옵션이 뒤틀 렸습니다.

인사말,

답변

5

당신이 http://asynchttp.sourceforge.net/ 봤어? 파이썬

'asynchttp' '모듈은'asyncore '및 모듈'선택 '을 기반으로 모듈'asynchat '파이썬 라이브러리의 논리적 확장입니다. 우리의 목표는이다에 대한

"비동기 HTTP 클라이언트 블로킹 소켓을 사용하지 않고 우수한 'httplib'모듈의 기능을 제공합니다. "

프로젝트의 마지막 커밋은 2001-05-29 이었으므로 죽었습니다. 하지만 어쨌든 관심이있을 수 있습니다.

면책 조항 : 본인은 직접 사용하지 않았습니다.

또한 this blog post에는 비동기 HTTP에 대한 정보가 있습니다.

7

당신은 비동기 직접 전화를 구현할 수 있습니다. 각 호출에 대해 새 스레드를 시작하거나 풀에서 스레드를 가져오고 콜백을 사용하여 처리합니다.

당신은 장식과 매우 잘 수행 할 수 있습니다

:

def threaded(callback=lambda *args, **kwargs: None, daemonic=False): 
    """Decorate a function to run in its own thread and report the result 
    by calling callback with it.""" 
    def innerDecorator(func): 
     def inner(*args, **kwargs): 
      target = lambda: callback(func(*args, **kwargs)) 
      t = threading.Thread(target=target) 
      t.setDaemon(daemonic) 
      t.start() 
     return inner 
    return innerDecorator 

@threaded() 
def get_webpage(url): 
    data = urllib.urlopen(url).read() 
    print data 
+2

미안 해요, 내가 말했듯이, 내가 비동기 소켓이 아닌 스레드를합니다. – Tom

+1

나는이 솔루션이 * 훌륭하다고 생각하는 유일한 사람입니까?* 다른 모든 비동기 HTTP 메소드보다 나은 점은 실제적으로 모든 것이 비동기적인 솔루션이라는 것입니다. 'get_webpage'를 원하는 코드로 대체하여 비동기 적으로 수행 할 수 있습니다. – robru

1

제가 가장 먼 곳은 수정 된 asynchttp를 사용했는데, 그 코드북이 제안했습니다. asyncore/asynchat와 asynchttp를 모두 사용하려고 노력했지만 많은 고통이있었습니다. 너무 많은 시간을 들여 버그를 고치려고했다. (handle_read 메소드가 거의 asyncore에서 복사되고 심하게 들여 쓰여졌고 chunked 인코딩으로 두통을 일으켰다.) 또한, asyncore와 asynchat는 Google에서 얻은 힌트에 따라 사용하지 않는 것이 가장 좋습니다.

나는 꼬인 상태로 정착했으나, 분명히 그 질문에 대한 답은 분명하지 않습니다.

또한 응용 프로그램에서 무엇을하려고하는지, 비동기 요청을 원하는지, 스레드가 옵션인지 아닌지, GUI 프로그래밍을하고 있거나 뭔가 다른 것을 할 수 있다면 뭔가 다른 것을 할 수 있는지에 따라 달라질 수 있습니다 , 그것은 항상 좋은 것입니다. 그렇지 않다면 위에서 제안한 스레드 버전에 투표 할 것이므로 훨씬 더 가독성과 유지 보수성이 좋습니다.

1

Asyncore 간단한 HTTP 클라이언트 예는 매우 간단합니다 :

http://docs.python.org/library/asyncore.html

import asyncore, socket 

class HTTPClient(asyncore.dispatcher): 

    def __init__(self, host, path): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.connect((host, 80)) 
     self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path 

    def handle_connect(self): 
     pass 

    def handle_close(self): 
     self.close() 

    def handle_read(self): 
     print self.recv(8192) 

    def writable(self): 
     return (len(self.buffer) > 0) 

    def handle_write(self): 
     sent = self.send(self.buffer) 
     self.buffer = self.buffer[sent:] 


client = HTTPClient('www.python.org', '/') 
asyncore.loop()