python requests-futures 慢 - 未正确使用线程?
你好,我用 requests-futures 库写了一个多线程的请求和响应处理程序。
但是,它似乎运行得很慢,并且没有我想象中的那样异步。输出的结果很慢,而且是按顺序输出的,而不是我期待的那样交错输出,感觉像是没有正确使用线程。
我想知道为什么我的代码这么慢,以及我该怎么做才能加快速度?如果能给个例子就更好了。
这是我的代码:
#!/usr/bin/python
import requests
import time
from concurrent.futures import ThreadPoolExecutor
from requests_futures.sessions import FuturesSession
session = FuturesSession(executor=ThreadPoolExecutor(max_workers=12))
def responseCallback( sess, resp ):
response = resp.text
if not "things are invalid" in response in response:
resp.data = "SUCCESS %s" % resp.headers['content-length']
else:
resp.data = "FAIL %s" % resp.headers['content-length']
proxies = {
"http":"http://localhost:8080",
"https":"https://localhost:8080"
}
url = 'https://www.examplehere.com/blah/etc/'
headers= {
'Host':'www.examplehere.com',
'Connection':'close',
'Cache-Control':'max-age=0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Origin':'https://www.examplehere.com',
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/533.32 (KHTML, like Gecko) Ubuntu Chromium/34.0.1847.123 Chrome/34.0.1847.123 Safari/337.12',
'Content-Type':'application/x-www-form-urlencoded',
'Referer':'https://www.exampleblah.etc/',
'Accept-Encoding':'gzip,deflate,sdch',
'Accept-Language':'en-US,en;q=0.8,de;q=0.6',
'Cookie':'blah=123; etc=456;',
}
for n in range( 0, 9999 ):
#wibble = n.zfill( 4 )
wibble = "%04d" % n
payload = {
'name':'test',
'genNum':wibble,
'Button1':'Push+Now'
}
#print payload
#r = requests.post( url, data=payload, headers=headers, proxies=proxies, verify=False )
future = session.post( url, data=payload, headers=headers, verify=False, background_callback=responseCallback )
response = future.result()
print( "%s : %s" % ( wibble, response.data ) )
理想情况下,我希望能在不改变我已经使用的库的情况下修复我的代码,但如果这个库有什么问题,我也乐意听取建议……
补充说明:我现在使用的是 Python2,并且使用了 concurrent.futures 的回溯版本。
补充说明:慢 - 大约每秒一个请求,而且不是并发的,而是一个接一个的,也就是说请求1,响应1,请求2,响应2 - 我本来希望它们能交错进行,多个线程同时发送和接收请求。
1 个回答
11
下面的代码是另一种提交多个请求的方法,它可以同时处理几个请求,然后打印出结果。结果会在准备好后立即打印出来,不一定是按照提交的顺序。
这个代码还使用了大量的日志记录,帮助调试问题。它会记录发送的数据。多线程的代码比较复杂,所以多记录一些日志会更好!
源代码
import logging, sys
import concurrent.futures as cf
from requests_futures.sessions import FuturesSession
URL = 'http://localhost'
NUM = 3
logging.basicConfig(
stream=sys.stderr, level=logging.INFO,
format='%(relativeCreated)s %(message)s',
)
session = FuturesSession()
futures = {}
logging.info('start')
for n in range(NUM):
wibble = "%04d" % n
payload = {
'name':'test',
'genNum':wibble,
'Button1':'Push+Now'
}
future = session.get( URL, data=payload )
futures[future] = payload
logging.info('requests done, waiting for responses')
for future in cf.as_completed(futures, timeout=5):
res = future.result()
logging.info(
"wibble=%s, %s, %s bytes",
futures[future]['genNum'],
res,
len(res.text),
)
logging.info('done!')
输出结果
69.3101882935 start
77.9430866241 Starting new HTTP connection (1): localhost
78.3731937408 requests done, waiting for responses
79.4050693512 Starting new HTTP connection (2): localhost
84.498167038 wibble=0000, <Response [200]>, 612 bytes
85.0481987 wibble=0001, <Response [200]>, 612 bytes
85.1981639862 wibble=0002, <Response [200]>, 612 bytes
85.2642059326 done!