爬虫_05_线程池多任务异步协程selenium

news/2024/7/19 9:26:13 标签: python, 爬虫, selenium

selenium_0">线程池&多任务异步协程&selenium

异步爬虫

特点:应付面试

  • 基于线程池
  • 基于单线程+多任务的异步爬虫

线程池

python">import requests
import time
#****************************************
#线程池库
form multiprocessing.dumpy import Pool
#****************************************

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

#同步代码
if __name__ == "__main__":
    start = time.time()
    urls = {
        'http://127.0.0.1:5000/bobo',
        'http://127.0.0.1:5000/jay',
        'http://127.0.0.1:5000/tom'
    }
    for url in urls:
        res = get_request(url)
        print(res)
    print('总耗时:',time.time-start)
    #2*3 = 6秒多一点
    
#异步代码
if __name__ == "__main__":
    start = time.time()
    #****************************************
    pool = Pool(3) #3表示开启线程的数量
    #func是回调函数,alist是可迭代类型对象(列表)。这里表示基于线程池的3个线程,需要回调依次对列表中的每一个列表元素进行异步操作,假设列表有3个列表元素,那么回调就会调3次,对3个列表元素,基于3个线程,进行异步操作
    #pool.map(func,alist)
    #使用get_request作为回调函数,需要基于异步的形式对urls列表中的每一个列表元素进行操作
    #保证回调函数必须要有1个参数和有返回值
    result_list = pool.map(get_request,urls)
    #****************************************
    print(result_list)
    print('总耗时:',time.time-start)
    #2秒多一点

单线程+多任务异步协程

基本概念2️⃣3️⃣

pip install asyncio

  • 特殊的函数
    • 如果一个函数的定义被async修饰后,则该函数就变成了一个特殊的函数
    • 特殊之处:
      1. 该特殊的函数调用后,函数内部的实现语句不会被立即执行
      2. 该特殊函数被调用后会返回一个协程对象
  • 协程对象
    • 对象。通过特殊函数的调用返回一个协程对象。
    • 协程 == 特殊函数 == 一组指定的操作
    • 协程 == 一组指定的操作
python">async def get_request(url):
    xxx
#c就是一个协程对象
c = get_request('www.1.com')
  • 任务对象

    • 任务对象就是一个高级的协程对象(任务对象就是对协程对象的进一步封装)

    • 任务对象 == 协程对象 == 特殊函数 == 一组指定操作

    • 任务对象 == 一组指定操作

    • 创建任务对象:

      python">#任务对象就是对协程对象的进一步封装
      task = asyncio.ensure_future(c)
      
    • 任务对象的高级之处

      • 可以给任务对象绑定回调:

        python">async def get_request(url):
            xxx
            return 'bobo'
        
        #回调函数的封装
        #参数t:就是该回调函数的调用者(任务对象)
        def task_callback(t):
            print('i am task callback(),参数t:',t)
            #result返回的就是特殊函数的返回值
            print('t.result()返回的是:',t.result())
        
        #给task绑定一个回调函数
            task.add_done_callback(task_callback)
        
        • 回调函数的调用时机:

          任务被执行完结束后,才可以调用回调函数

        • 回调函数的参数只可以有一个:表示的就是该回调函数的调用者(任务对象)

    • 使用回调函数的参数调用result()返回的就是任务对象表示的特殊函数return的结果

  • 事件循环对象

    • 作用:

      • 可以将多个任务对象注册/装载到事件循环对象中
      • 如果开启了事件循环后,则其内部注册/装载的任务对象表示的指定操作就会被基于异步的被执行
    • 创建方式,注册且启动方式

      python">#创建事件循环对象
      loop = asyncio.get_event_loop()
      #将任务对象注册到事件循环中且开启事件循环
      loop.run_until_complete(task) #无法使用
      
python">#必须使用wait方法对tasks进行封装才可
loop.run_until_complete(asyncio.wait(tasks))
  • 依然6秒的解释(手记,详细)

    在这里插入图片描述

    每一个任务对象都表示一组指定的操作

    指定的操作中:可能会存在阻塞操作(比如sleep,get,post)

    事件循环对象(loop)在最开始的时候是基于按照顺序对每一个任务对象进行执行

    当loop在执行某一个任务对象时,遇到了阻塞操作,则loop会跳过阻塞操作执行下一个任务对象。

    当loop在执行到某一个任务对象的时候,前面的一个任务对象的阻塞操作结束了,loop会回头将该阻塞结束后的任务对象阻塞之后的操作进行执行。

    wait(tasks)作用:可以将任务列表中的任务对象进行可挂起操作。(每一个任务对象都是可以被挂起)

    任务对象的挂起:将当前挂起的任务对象交出CPU的使用权。只有当任务对象的CPU的使用权交出后,loop才可以使用CPU去执行下一个任务对象。

  • wait方法的作用(精要)

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

    • 挂起:将当前的任务对象交出CPU的使用权
  • 注意事项【重要】

    在特殊函数内部不可以出现不支持异步模块对应的代码,否则会中断整个异步效果

  • await关键字

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

python">async def get_request(url):
    print('正在请求的url:',url)
    await asyncio.sleep(2) #支持异步模块的代码
    print('请求结束',url)
    return 'bobo'

多任务的异步爬虫4️⃣

aiohttp

  • 是一个支持异步的网络请求模块
  • pip install aiohttp

使用代码

  1. 写出一个大致的架构
  2. 补充细节
    • 在阻塞操作前加上await关键字
    • 在每一个with前加上async关键字
python">async def get_request(url):
    #实例化好了一个请求对象
    async with aiohttp.ClientSession() as sess:
        #调用get发起请求,返回一个响应对象
        #get/post(url,headers,params/data,proxy="http://ip:port")
        async with await sess.get(url=url) as response:
            #text()获取了字符串形式的响应数据
            #read()获取byte类型的响应数据
            page_text = await response.text()
            return page_text

多任务爬虫的数据解析

  • 一定要使用任务对象的回调函数实现数据解析
  • why
    • 多任务的架构中数据的爬取是封装在特殊函数中,我们一定要保证数据请求结束后,再实现数据解析

使用多任务的异步协程爬取数据实现套路

  1. 可以先使用requests模块将待请求数据对应的url封装到一个列表中(同步)
  2. 可以使用aiohttp模式将列表中的url进行异步的请求和数据解析(异步)

selenium_221">selenium

概念

  • 基于浏览器自动化的模块

  • 自动化:可以通过代码指定一系列的行为动作,然后将其作用到浏览器中

  • pip install selenium

selenium_230">selenium爬虫之间的关联

  1. 可以便捷的捕获到任意形式动态加载的数据(可见即可得)
  2. 实现模拟登录

谷歌驱动下载地址:http://chromedriver.storage.googleapis.com/index.html

简单的使用方法1️⃣

如何捕获动态加载的数据2️⃣

  • 药监总局为例
  • 将前三页所有企业名称爬取

弊端

  • 效率低

动作链ActionChains3️⃣

定义:一系列连续的动作(滑动动作)

selenium_252">让selenium规避监测

  • 有的网站会检测请求是否为selenium发起,如果是的话则让该次请求失败
  • ->规避监测的方法:
    • selenium接管chrome浏览器4️⃣(一般用不到)

实现步骤:

  1. 必须将你电脑中安装的谷歌浏览器的驱动程序所在的目录找到。且将目录添加到环境变量中。

  2. 打开cmd,在命令行中输入指令

    chrome.exe --remote-debugging-port=9222 --user-data-dir=“一个空文件夹的目录”

    指令执行结束后,会打开你本机安装好的谷歌浏览器

  3. 执行如下代码:可以使用下属代码接管步骤2打开真实的浏览器

    python">from selenium import webdriver
    from selenium.webdriver.chrome.options import options
    
    chrome_options = Options()
    chrome_options.add_experimental_option("debuggerAddress","127.0.0.1:9222")
    #本机安装好谷歌的驱动程序路径
    chrome_driver = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
    
    driver = webdriver.Chrome(executable_path=chrome_driver,chrome_options=chrome_options)
    print(driver.title)
    

无头浏览器(无可视化界面的浏览器)

除了不显示界面,和可视化的selenium没有任何区别

  • 谷歌无头浏览器(推荐)

    python">from selenuim import webdriver
    from selenuim.webdriver.chrome.options import Options
    import time
    
    #创建一个参数对象,用来控制chrome以无界面模式打开
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
    #驱动路径,自己改
    path = './chromedriver.exe'
    #创建浏览器对象
    browser = webdriver.Chrome(executable_path=path,chrome_options=chrome_options)
    #上网
    url = 'http://www.baidu.com/'
    browser.get(url)
    time.sleep(3)
    #截图
    browser.save_screenshot('baidu.png')
    print(browser.page_source)
    browser.quit()
    
  • phantomJs


http://www.niftyadmin.cn/n/1363925.html

相关文章

爬虫_07_12306模拟登录

07_12306模拟登录 网站地址:https://kyfw.12306.cn/otn/resources/login.html/init 使用selenium打开登录页面对当前selenium打开的这张页面进行截图对当前图片局部区域(验证码图片)进行裁剪 好处:将验证码图片和模拟登录进行一…

OOzie 入门 【转】

http://blackproof.iteye.com/blog/1928122 oozie概述: oozie是基于hadoop的调度器,以xml的形式写调度流程,可以调度mr,pig,hive,shell,jar等等。 主要的功能有 Workflow: 顺序执行流…

爬虫_06_余票检测js解加密

06_余票检测&js解加密&12306模拟登录 余票检测1️⃣ JS解密混淆破解 博客地址:https://www.cnblogs.com/bobo-zhang/p/11243138.html爬取的网站:https://www.aqistudy.cn/html/city_detail.html 分析 修改查询条件(城市的名称时间…

asp.net 中使用JQuery Ajax 上传文件

首先创建一个网页&#xff0c;网页中添加如下代码。 <h3>Upload File using Jquery AJAX in Asp.net</h3> <table> <tr> <td>File:</td> <td> <asp:FileUpload ID"fupload" runat"server" οnchangepr…

爬虫_08_scrapy持久化存储管道操作手动请求发送

08_scrapy&持久化存储&管道操作&手动请求发送 scrapy框架 简介 简介&#xff1a;所谓的框架其实就是一个被集成了很多功能且具有很强通用性的一个项目模板。 学习&#xff1a;学习是学好框架中集成好的各种功能、特性 进阶&#xff1a;逐步的探索框架的底层 …

[python]python学习笔记(四)

14&#xff0c;python如何创建进程并在父子进程通信示例代码如下&#xff1a; [cpp] view plaincopyimport os, sys print "Im going to fork now - the child will write something to a pipe, and the parent will read it back" r, w os.pipe() # r,…

爬虫_09_请求传参中间件大文件下载CrawlSpider

09_请求传参&中间件&大文件下载&CrawlSpider 五大核心组件 目的 大概了解scrapy的运行机制为分布式铺垫 请求传参实现的深度爬取 深度爬取&#xff1a;爬取的数据没有在同一张页面中&#xff08;例如首页数据详情页数据&#xff09; 在scrapy中如果没有请求传…

Hibernate(五)一对一单向关联映射

上次的博文中 Hibernate从入门到精通&#xff08;四&#xff09;基本映射我们已经讲解了一下基本映射和相关概念&#xff0c;接下来 我们会讲稍微复杂点的映射——关系映射。 关系映射分类 关系映射即在基本映射的基础上处理 多个相关对象和多个相关表之间联系的映射。关系映射…