2011-02-10 1 views
11

파이썬에서 매번 매개 변수가 변경되면서 여러 번 웹 서비스에 요청을 보내는 콜백 종류의 기능이 필요합니다. 이러한 요청을 순차적으로 처리하는 대신 동시에 처리하기를 원합니다. 따라서이 함수를 비동기 적으로 호출해야합니다.파이썬에서의 비동기 HTTP 호출

asyncore는 내가 사용하기를 원했던 것처럼 보이지만, 어떻게 작동 하는지를 예를 통해 과장된 것처럼 보였으므로 다른 경로가 있어야하는지 궁금합니다. 모듈/프로세스에 대한 제안 사항은 무엇입니까? 이상적으로 나는 클래스를 생성하는 대신 절차적인 방법으로 이것을 사용하고 싶습니다. 그러나 나는 그것을 해결할 수 없을 것입니다.

+0

Way Overkill. 내가 필요한 것은 스크립트 내에서 동시 http 호출이다 (커맨드 라인 등에서 프로세스를 호출 할 필요가 없다). 콜백 기능 만 있으면되지만 파이썬에서는이 프로세스를 찾을 수 없습니다. 더 많은 연구가 urllib2를 이끌고 있습니다. – kasceled

+1

잔인 함? 스레드는 명령 행에서 프로세스를 호출하는 것과 아무런 관련이 없습니다. – Falmarri

+0

tippytop, 물론 운송을위한 urllib2 .. 그러나 당신은 여전히 ​​그들을 병렬로 스폰 할 필요가 있습니다. 스레딩, 멀티 프로세싱, concurrent.futures 또는 asynch i/o 기반 솔루션을 수행 할 수 있습니다. –

답변

8

Twisted framework은 그 티켓 일뿐입니다. 그러나 당신이 이것을 원하지 않으면, pycurl, libcurl을위한 래퍼를 사용할 수도 있습니다. 그것은 자체 비동기 이벤트 루프를 가지며 콜백을 지원합니다.

+0

필자는 이것을 게시했을 때 pycurl 접근 방식을 취하는 것으로 끝났습니다 (늦게 받아 들여서 죄송합니다). – kasceled

+1

@tippytop Cool. 내 간단한 래퍼에 관심이있을 수도 있습니다. [pycopia.WWW.client] (http://code.google.com/p/pycopia/source/browse/trunk/WWW/pycopia/WWW/client.py) 모듈. – Keith

13

Python 3.2부터는 병렬 작업을 시작하는 데 concurrent.futures을 사용할 수 있습니다.

체크 아웃이 ThreadPoolExecutor 예 :

http://docs.python.org/dev/library/concurrent.futures.html#threadpoolexecutor-example

그것은 HTML을 검색 할 스레드를 생성합니다 그들이 수신 될 때 응답에 역할을합니다.

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 

위의 예는 스레딩을 사용합니다. 오히려 스레드보다, 또한 프로세스의 풀을 사용하는 유사한 ProcessPoolExecutor 있습니다 :

http://docs.python.org/dev/library/concurrent.futures.html#processpoolexecutor-example

import concurrent.futures 
import urllib.request 

URLS = ['http://www.foxnews.com/', 
     'http://www.cnn.com/', 
     'http://europe.wsj.com/', 
     'http://www.bbc.co.uk/', 
     'http://some-made-up-domain.com/'] 

# Retrieve a single page and report the url and contents 
def load_url(url, timeout): 
    conn = urllib.request.urlopen(url, timeout=timeout) 
    return conn.readall() 

# We can use a with statement to ensure threads are cleaned up promptly 
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: 
    # Start the load operations and mark each future with its URL 
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} 
    for future in concurrent.futures.as_completed(future_to_url): 
     url = future_to_url[future] 
     try: 
      data = future.result() 
     except Exception as exc: 
      print('%r generated an exception: %s' % (url, exc)) 
     else: 
      print('%r page is %d bytes' % (url, len(data))) 
16

는 약 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

(이 스레드는 서버 측 파이썬에 대해 있지만이 문제는 다시 잠시 질문을 받았다 때문에 다른 사람들이 찾고있는 곳에서 우연히 발견 할 수도 있습니다..

클라이언트 측 솔루션의 경우 Async.js 라이브러리, 특히 "Control-Flow"섹션을 살펴볼 수 있습니다. 원하는 결과를 얻을 수있는 "폭포"당신과 함께 "병렬"를 결합하여

https://github.com/caolan/async#control-flow

. https://github.com/caolan/async#autotasks-callback 여기서 "쓰기 : - 당신이 제어 - 흐름 아래의 예를 살펴보면

은 -

폭포 (> PostParallelTask ​​병렬 (TaskA, TaskB, TaskC))"자동 "그들은 당신에게 위의 예를 제공 -file "은"get_data "및"make_folder "및"email_link "에 따라 달라집니다.

이 모든 작업은 클라이언트 측에서 발생합니다 (노드를 수행하지 않는 한).JS가 - 서버 측 파이썬 서버 측)

에 pyCurl 이하 실시 예를 조합함으로써 https://github.com/pycurl/pycurl/blob/master/examples/basicfirst.py

@ PyCURL보고에는 비 차단 멀티 스레딩 기능을 달성 할 수있다.

희망이 도움이됩니다. 행운을 빕니다.

Venkatt @http://MyThinkpond.com