异步发送请求的几种方式

时间:2023-02-11 21:12:20
asyncio:
# import    asyncio
# def  fun1():
#     print('start')
#     yield   from   asyncio.sleep(1)
#     print('end')
#
# tasks=[
# fun1(),fun1()
# ]
# loop=asyncio.get_event_loop()
# loop.run_until_complete(asyncio.gather(*tasks))
# loop.close()

 

asyncio的另一种方式:
import    asyncio

@asyncio.coroutine
def   task(host,url='/'):
    print('start',host)
    reader,writer=yield   from  asyncio.open_connection(host,80)###建立连接,和当前的www.baidu.com建立连接,会将这个域名解析成相对应的ip,进行连接

    # request_header_content='''GET  %s HTTP/1.0\r\nHost: %s\r\n\r\n'''%(url,host,)###在这里配置请求头
    request_header_content='''GET / HTTP/1.0\r\nHost:%s\r\n\r\n'''%(host,)###在这里配置请求头
    request_header_content=bytes(request_header_content,encoding='utf-8')

    writer.write(request_header_content)
    yield   from   writer.drain()
    text=yield   from   reader.read()
    print('end',host,url,text)
    writer.close()

tasks=[
task('www.baidu.com'),task('www.baidu.com')
]

loop=asyncio.get_event_loop()
results=loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
 

gevent:开启协程池

# ##协程池
#
# import   gevent
# import  requests
# def  task(method,url,req_kwargs):
#     print(method,url)
#     response=requests.request(method=method,url=url)
#     print('结果',response,response.content)
# from  gevent.pool import   Pool
# pool=Pool(4)
# gevent.joinall([
#     pool.spawn(task, method='get', url='http://www.baidu.com',req_kwargs={}),
#     pool.spawn(task, method='get', url='http://www.baidu.com',req_kwargs={}),
#     pool.spawn(task, method='get', url='http://www.baidu.com',req_kwargs={}),
#     pool.spawn(task, method='get', url='http://www.baidu.com',req_kwargs={})
# ]
# )

 

greenlet:是对gevent进一步的封装,详情请查看源码
# import   greenlet,grequests
# request_list=[
#     grequests.get('http://www.baidu.com'),
#     grequests.get('http://www.baidu.com'),
#     grequests.get('http://www.baidu.com'),
#     grequests.get('http://www.baidu.com'),
# ]
#
# ###执行并获取响应列表
# response_list=grequests.map(request_list,size=10)###后面是可以开启的协程池,后面可以加参数,详细请查看map方法
# print(response_list)

 

AsyncHTTPClient
from   tornado.httpclient import   AsyncHTTPClient
from    tornado.httpclient import  HTTPRequest
from   tornado  import  ioloop

count=0##设置计数器,当count为0的时候,就会终止这个死循环

'''咋这里进行处理这个请求,当请求处理完成之后,就会终止这个循环'''
def  handler_response(response):
    global   count
    count-=1###当计数器为0的时候,就会自动终止

    if  response.error:
        print('error')
    else:
        print(response.body)
    ###在下面进行判断,当是count为0,就进行终止这个循环,不在执行下去
    if  count==0:
        ioloop.IOLoop.current().stop()

'''在这里开启这个循环,循环遍历所有的eurl,进行事件循环的的遍历'''
def  fun():
    url_listy=[
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
    ]
    for   url   in  url_listy:
        global  count###开启计数器
        count=len(url_listy)
        print(url)
        htt_client=AsyncHTTPClient()##3创建这个对象
        htt_client.fetch(HTTPRequest(url),handler_response)#####当执行完之前的url之后,就自动执行后面的回调函数的部分
        ##fetch是查询的意思,创建了httpreqeust里面,后面是回调函数

ioloop.IOLoop.current().add_callback(fun)###将全部的url加全部的事件循环里面
ioloop.IOLoop.current().start()