使用协程实现多个网址同时请求,并异步处理接收到的数据

实现目的:

对百度同时发起100个请求,并异步处理请求的结果

关键技术:

使用队列存储请求的结果

代码如下

# author: luojun
# date: 2020/1/6 16:43

from gevent import monkey
import gevent
import requests
from queue import Queue
import time

import logging

logging.basicConfig(level=logging.INFO)

monkey.patch_all()

q_res = Queue(maxsize=1000)
for i in range(100):
    q_res.put(i, timeout=1)

i = 0


def download(url):
    '''
    网络请求部分
    :param url: 
    :return: 
    '''
    print('start request:{}'.format(url))
    res = requests.get(url=url)
    q_res.put(res.content)
    print(len(res.content), url)


def get_content_queue():
    '''
    数据处理部分
    :return: 
    '''
    while 1:
        # if q_res.empty():
        #     break
        try:
            queue_get = q_res.get(timeout=10)
            logging.info(queue_get)
        except Exception as e:
            break


def add(num):
    global i
    i += num
    time.sleep(1)


def main():
    global i

    url_baidu = 'http://www.baidu.com/'
    list_url = [gevent.spawn(download, url_baidu) for i in range(100)]

    # list_coroutine = [gevent.spawn(add, 1) for i in range(10000)]
    content_deal = gevent.spawn(get_content_queue)

    gevent.joinall(list_url)
    content_deal.join()
    # print(q_res.qsize())
    # gevent.joinall(list_coroutine)
    # print(i)


def main2():
    '''
    对于不断新增的请求可以使用队列的方式,制作异步请求,然后放到队列中,
    获取到一个新的要请求的地址,制作异步请求,放到队列中
    使用循环从队列中取出,然后join

    情况2:已经确定的url地址,放在一个列表中,需要全部请求,不会再次增加,那还是直接做一个异步列表,然后使用joinall 方便,
        对于请求的结果,还是需要使用队列来存储,同时需要创建另一个进程来消耗该队列中的数据,不是很确定能不能实现.
        3,单次请求量如果太大的话还是要考虑使用IP代理,防止被封ip.
    :return:
    '''
    # 现在假设有这么多的地址需要请求,使用协程来实现


    # 对于那种url一直累加的请求,可以使用队列的方式实现.

    pass


#

if __name__ == '__main__':
    main()
    pass

原文地址:https://www.cnblogs.com/qianxunman/p/12171513.html