zoukankan      html  css  js  c++  java
  • 异步爬虫

    <!doctype html>

    异步爬虫

    异步爬虫

    基于线程池

    搭建模拟网站,基于Flask框架

    templates设置如下图,Flask框架只能使用jinja2进行渲染

    第二步:

    在templates中创建test.html

    下面是python搭建Flask框架

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    

    from flask import Flask,render_template
    from time import sleep

    实例化一个app

    app = Flask(name)

    创建视图函数&路由地址

    @app.route('/bobo')
    def index_1():
    sleep(2)
    return render_template('test.html')

    @app.route('/jay')
    def index_2():
    sleep(2)
    return render_template('test.html')

    @app.route('/tom')
    def index_3():
    sleep(2)
    return render_template('test.html')

    if name == "main":
    #debug=True表示开启调试模式:服务器端代码被修改后按下保存键会自动重启服务
    app.run(debug=True)

    线程池,异步爬取网站

    import requests
    

    import time
    from multiprocessing.dummy import Pool

    urls = [
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom',
    ]

    def get_request(url):
    page_text = requests.get(url=url).text
    return len(page_text)

    异步代码

    if name == "main":
    start = time.time()
    pool = Pool(3) #开启线程的数量
    #使用get_requests作为回调函数,需要基于异步的形式对urls列表元素进行操作
    result_list = pool.map(get_request, urls)
    pool.map(parse, result_list) #对返回的三张源码数据进行解析
    print('总耗时:',time.time()-start)

    单线程+多任务异步协程:

    特殊函数

    async是asyncio模块特有的关键字,如果不导入,没有这个关键字

    如果一个函数在定义的时候被async修饰后,则该函数就变成了一个特殊的函数

    特殊之处:

    该特殊函数被调用后,函数内部实现语句不会立即执行

    该特殊函数被调用后会立即返回一个协程对象

    协程对象

    对象。通过特殊函数的调用返回一个协程对象

    协程 == 特殊函数 == 实现内容

    协程 == 实现内容

    任务对象

    任务对象就是通过协程对象的封装

    任务 == 实现内容

    任务对象的高级之处:

    • 可以给任务对象绑定回调,绑定方式task.add_done_callback(task_callback)
    • 绑定的回调函数是在任务执行之后才执行回调函数的,并且回调函数的参数是任务对象
    • 回调函数的参数只可以有一个
    • 使用回电函数的参数调用result返回的就是任务对象表示的特殊函数的返回值

    事件循环对象

    他也是一个对象

    作用:

    • 可以将多个任务对象注册/装载到事件循环对象中
    • 如果开启了事件循环后,则其内部注册/装载的任务对象便是的制定操作就会被基于异步的被执行

    创建方式:

    loop = asyncio.ensure_future(c)

    将任务对象注册到事件循环中且开启事件循环

    loop.run_until_complete(task)

    import requests
    import asyncio
    async def get_requests(url):
        print('正在请求url', url)
        time.sleep(2)
        print('请求结束', url)
        return 'bbbb'
    

    def task_callback(t):
    print('我是回掉函数,参数t', t)
    print('t.result返回的是:', t.result()) #返回的是协程对象的返回值,也就是任务对象的返回值
    if name == "main":
    #c就是一个协程对象
    c = get_request('www.1.com')

    #任务对象就是对携程对象的进一步封装
    task = asyncio.get_event_loop()
    
    #任务对象绑定一个回调函数,回掉函数是在任务执行之后才执行
    task.add_done_callback(task_callback)
    
    #将任务对象注册到事件循环中且开启事件循环
    loop.run_until_complete(task)
    

    多任务

    import asyncio
    import requests
    

    async def get_request(url):
    print('正在请求url', url)
    await asynico.sleep(2) #await保证我们的阻塞不被跳过
    print('请求结束', url)
    return 'bbbb'
    urls = [
    'www.1.com',
    'www.2.com',
    'www.3.com',
    ]
    if name == "main":
    tasks = [] #多任务列表
    #1.创建协程对象
    for url in urls:
    c = get_requet(url)
    task =asyncio.ensure_future(c)
    tasks.append(task)

    #3创建事件循环对象
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    #wait作用是可以将任务列表中的任务对象进行挂起操作。(每一个对象都可以被挂起)
    

    wait方法作用:

    将任务对象列表中的任务对象赋予可被挂起的权限。只有任务对象赋予了可被挂起权限后任务对象才可以被挂起

    挂起:将当前的任务对象交出cpu的使用权

    如果异步之中出现不支持异步模块,程序会被终止

    request,time模块不支持异步

    await关键字作用

    在特殊函数内部,凡是阻塞操作执行前都必须使用await进行修饰。await保证我们的阻塞在异步执行过程中不被跳过

    
    import requests
    import asyncio
    import aiohttp   #支持异步的网络请求模块
    

    async def get_request(url):
    async with aiohttp.ClientSession() as sess:
    #调用get发起请求,返回一个响应对象
    #get/post(url, headers,params/data,proxy="字符串")
    async with await sess.get(url) as response:
    #获取了字符串形式的响应数据
    page_text = await response.text()
    return page _text
    urls = [
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom'
    ]
    if name == "main":
    start = time.time()
    tasks = [] #多任务列表
    #1.创建协程对象
    for url in urls:
    c = get_request(url)
    #2.创建任务对象
    task = asyncio.ensure_future(c)
    tasks.append(task)

    #3.创建事件循环对象
    loop = asyncio.get_event_loop()
    # loop.run_until_complete(tasks)
    #必须使用wait方法对tasks进行封装才可
    loop.run_until_complete(asyncio.wait(tasks))
    print(&#39;总耗时:&#39;, time.time()-start)
    

  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/g15009428458/p/12568902.html
Copyright © 2011-2022 走看看