zoukankan      html  css  js  c++  java
  • 高性能相关----爬虫

    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()
  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/onda/p/7715030.html
Copyright © 2011-2022 走看看