|
|
发表于 2017-9-17 10:25:15
|
显示全部楼层
本帖最后由 wei_Y 于 2017-9-17 10:29 编辑
建议用线程池或异步方式改进。
线程池可简单使用concurrent库里面的ThreadPoolExecutor。
- with ThreadPoolExecutor(max_work=30) as t:
- t.submit(requests.get, 'http://www.fishc.com')
复制代码
异步方式第三方可使用aiohttp,gevent等异步库实现。
如果是py3.5以上也可以自己封装一个异步http请求类。
异步例:
- import asyncio
- import requests
- class Requests(object):
- def __init__(self):
- self.headers = headers.copy()
- @requestsExceptionFilter
- def get(self, url, **kwargs):
- if not kwargs.get('headers'):
- kwargs['headers'] = self.headers
- return requests.get(url, **kwargs)
-
- @requestsExceptionFilter
- def post(self, url, **kwargs):
- if not kwargs.get('headers'):
- kwargs['headers'] = self.headers
- return requests.post(url, **kwargs)
- class ARequests(Requests):
- """
- 一个异步请求类,
- """
- def __init__(self, callback):
- super().__init__()
- self.callback = callback
- def __enter__(self):
- return self
- def __exit__(self, except_type, value, tb):
-
- return True
- def _httpRequest(self, method, url, kwargs):
- method = method.upper()
- if method == 'GET':
- data = super().get(url, **kwargs)
- elif method == 'POST':
- data = super().post(url, **kwargs)
- return data
- @asyncio.coroutine
- def _get(self, url, **kwargs):
- eventLoop = asyncio.get_event_loop()
- future = eventLoop.run_in_executor(None, self._httpRequest, 'GET', url, kwargs)
- data = yield from future
- return data
- @asyncio.coroutine
- def _post(self, url, **kwargs):
- eventLoop = asyncio.get_event_loop()
- future = eventLoop.run_in_executor(None, self._httpRequest, 'POST', url, kwargs)
- data = yield from future
- return data
- def get(self, url, **kwargs):
- eventLoop = asyncio.get_event_loop()
- future = eventLoop.create_task(self._get(url, **kwargs))
- future.add_done_callback(self.callback)
- def post(self, url, **kwargs):
- eventLoop = asyncio.get_event_loop()
- future = eventLoop.create_task(self._post(url, **kwargs))
- future.add_done_callback(self.callback)
- if __name__ == '__main__':
- import sys
- eventLoop = asyncio.get_event_loop()
-
- urls = ['http://www.fishc.com']*5
- def printData(future):
- print(future.result())
- # 回调函数,下面用的是run_forever,这里需要退出。
- urls.pop()
- if not urls:
- sys.exit()
- http = ARequests(printData)
-
- for i in range(5):
- http.get(urls[i])
- eventLoop.run_forever()
复制代码
- <Response [200]>
- <Response [200]>
- <Response [200]>
- <Response [200]>
- <Response [200]>
- [Finished in 0.6s]
复制代码
Request可以自己用urllib封装下。
异步原理:
http://python.jobbole.com/88291/
装饰器:
http://bbs.fishc.com/thread-77552-1-1.html
多线程:
http://bbs.fishc.com/thread-77760-1-1.html
|
|