• 高性能相关----爬虫


    2. 高性能相关 

    基本原理:
    IO多路复用:select,用于检测socket对象是否发生变化(是否连接成功,是否有数据到来)
    Socket:socket客户端

    import socket
    import select

    class Request(object):
    def __init__(self,sock,func,url):
    self.sock = sock
    self.func = func
    self.url = url

    def fileno(self):
    return self.sock.fileno()

    def async_request(url_list):

    input_list = []
    conn_list = []

    for url in url_list:
    client = socket.socket()
    client.setblocking(False)
    # 创建连接,不阻塞
    try:
    client.connect((url[0],80,)) # 100个向百度发送的请求
    except BlockingIOError as e:
    pass

    obj = Request(client,url[1],url[0])

    input_list.append(obj)
    conn_list.append(obj)

    while True:
    # 监听socket是否已经发生变化 [request_obj,request_obj....request_obj]
    # 如果有请求连接成功:wlist = [request_obj,request_obj]
    # 如果有响应的数据: rlist = [request_obj,request_obj....client100]
    rlist,wlist,elist = select.select(input_list,conn_list,[],0.05)
    for request_obj in wlist:
    # print('连接成功')
    # # # # 发送Http请求
    # print('发送请求')
    request_obj.sock.sendall("GET / HTTP/1.0 host:{0} ".format(request_obj.url).encode('utf-8'))
    conn_list.remove(request_obj)

    for request_obj in rlist:
    data = request_obj.sock.recv(8096)
    request_obj.func(data)
    request_obj.sock.close()
    input_list.remove(request_obj)

    if not input_list:
    break

    使用一个线程完成并发操作,如何并发?
    当第一个任务到来时,先发送连接请求,此时会发生IO等待,但是我不等待,我继续发送第二个任务的连接请求....

    IO多路复用监听socket变化
    先连接成功:
    发送请求信息: GET / http/1.0 host....
    遇到IO等待,不等待,继续检测是否有人连接成功:
    发送请求信息: GET / http/1.0 host....
    遇到IO等待,不等待,继续检测是否有人连接成功:
    发送请求信息: GET / http/1.0 host....

    有结果返回:
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数
    读取返回内容,执行回调函数



    问题:什么是协程?
    单纯的执行一端代码后,调到另外一端代码执行,再继续跳...

    异步IO:
    - 【基于协程】可以用 协程+非阻塞socket+select实现,gevent
    - 【基于事件循环】完全通用socket+select实现,Twsited

    1. 如何提高爬虫并发?
    利用异步IO模块,如:asyncio,twisted,gevent
    本质:
    - 【基于协程】可以用 协程+非阻塞socket+select实现,gevent
    - 【基于事件循环】完全通用socket+select实现,Twsited,tornado

    2. 异步非阻塞
    异步:回调 select
    非阻塞:不等待 setblocking(False)

    3. 什么是协程?
    pip3 install gevent

    from greenlet import greenlet

    def test1():
    print(12)
    gr2.switch()
    print(34)
    gr2.switch()


    def test2():
    print(56)
    gr1.switch()
    print(78)

    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    gr1.switch()
  • 相关阅读:
    混合背包
    二维背包
    0/1背包问题(DP)
    冒泡排序
    快速排序
    最长上升子序列
    二分查找
    n后问题
    crontab 定时任务
    删除以某字符串开头的表
  • 原文地址:https://www.cnblogs.com/onda/p/7715030.html
Copyright © 2020-2023  润新知