爬虫自动化工具:DrissionPage

发布于:2025-04-06 ⋅ 阅读:(30) ⋅ 点赞:(0)

1. DrissionPage初始

官网地址:🛰️ 概述 | DrissionPage官网

        在当今互联网高速发展的时代,网页数据的获取和处理变得愈发重要。传统的自动化工具如 Selenium 在某些方面逐渐显露出一些局限性,而 DrissionPage 正是在这样的背景下崭露头角。

        DrissionPage 的发展历程充满了创新与突破。它最初的设计理念是将浏览器自动化和数据包操控相结合,以解决传统工具在面对复杂网页交互和反爬机制时的不足。从早期的版本开始,DrissionPage 就致力于为开发者提供一种更高效、更便捷的网页自动化解决方案。

        在发展过程中,DrissionPage 不断优化和改进自身的功能。它摆脱了对 Selenium 的依赖,从 3.0 版本开始,作者另起炉灶,用 chromium 协议自行实现了类似 Selenium 的全部功能,并且在此基础上增加了许多独特的特性。例如,无 webdriver 特征使得它更难被网站识别,减少了被阻止或限制访问的风险。 随着技术的不断进步,DrissionPage 的功能也在不断拓展。它不仅可以用于自动化测试,还在爬虫开发等领域展现出强大的潜力。无论是处理复杂的表单交互,还是绕过前端的一些限制,DrissionPage 都能发挥出重要作用。 总之,DrissionPage 以其独特的设计理念和不断创新的精神,在自动化爬虫领域逐渐崛起,为开发者带来了全新的体验和更多的可能性。

        为什么叫DrissionPag?Selenium框架用于操作浏览器的对象叫 Driver,requests 用于管理请求连接的对象叫 Session,因此Drission 就是它们两者的合体。在旧版本中,是通过对 selenium 和 requests 的重新封装实现的。因此 Drission 读作 “拽神”。但从 3.0 版开始,作者另起炉灶,用 chromium 协议自行实现了 selenium 全部功能,从而摆脱了对 selenium 的依赖,功能更多更强,运行效率更高,开发更灵活。

本库采用全自研的内核,内置了 N 多实用功能,对常用功能作了整合和优化,对比 selenium,有以下优点:

  • 无 webdriver 特征

  • 无需为不同版本的浏览器下载不同的驱动

  • 运行速度更快

  • 可以跨 iframe 查找元素,无需切入切出

  • 把 iframe 看作普通元素,获取后可直接在其中查找元素,逻辑更清晰

  • 可以同时操作浏览器中的多个标签页,即使标签页为非激活状态,无需切换

  • 可以直接读取浏览器缓存来保存图片,无需用 GUI 点击另存

  • 可以对整个网页截图,包括视口外的部分(90以上版本浏览器支持)

  • 可处理非open状态的 shadow-root

除了以上优点,本库还内置了无数人性化设计。

  • 极简的语法规则,集成大量常用功能,代码更优雅;

  • 定位元素更加容易,功能更强大稳定;

  • 无处不在的等待和自动重试功能。使不稳定的网络变得易于控制,程序更稳定,编写更省心;

  • 提供强大的下载工具。操作浏览器时也能享受快捷可靠的下载功能;

  • 允许反复使用已经打开的浏览器。无需每次运行从头启动浏览器,调试超方便;

  • 使用 ini 文件保存常用配置,自动调用,提供便捷的设置,远离繁杂的配置项;

  • 内置 lxml 作为解析引擎,解析速度成几个数量级提升;

  • 使用 POM 模式封装,可直接用于测试,便于扩展;

首先,你需要安装 drissionpage。可以通过以下命令进行安装:

pip install drissionpage
# 安装以及导入
pip install DrissionPage -i https://pypi.org/simple

from DrissionPage impor ChromiumPage
from DrissionPage import SessionPage as Session
from DrissionPage import WebPage


# 工具讲解
- ChromiumPage 
    - 类似于selenium的driver.Chrome(...)会打开一个浏览器窗口
    - 只能运行get请求

- SessionPage
    - 使用起来类似 requests模块的session,但比session更强大
    - get/post 都可以满足以及代理

- webpage
    - 集成了 ChromiumPage 和 SessionPage,还可以在两者之间自由切换,非常强大

 2. 重点语法

【1】 get方法

 【2】元素查找

# 根据属性查找,@ 后面可跟任意属性
page.ele('@id:ele_id', timeout=2)  # 查找 id 为 ele_id 的元素,设置等待时间2秒  
page.eles('@class')  # 查找所有拥有 class 属性的元素
page.eles('@class:class_name')  # 查找所有 class 含有 ele_class 的元素 
page.eles('@class=class_name')  # 查找所有 class 等于 ele_class 的元素


# 根据 class 或 id 查找
page.ele('#ele_id')  # 等价于 page.ele('@id=ele_id')
page.ele('#:ele_id')  # 等价于 page.ele('@id:ele_id')
page.ele('.ele_class')  # 等价于 page.ele('@class=ele_class')
page.ele('.:ele_class')  # 等价于 page.ele('@class:ele_class')


# 根据 tag name 查找
page.ele('tag:li')  # 查找第一个 li 元素  
page.eles('tag:li')  # 查找所有 li 元素  


# 根据 tag name 及属性查找
page.ele('tag:div@class=div_class')  # 查找 class 为 div_class 的 div 元素
page.ele('tag:div@class:ele_class') # 查找 class 含有 ele_class 的 div 元素
page.ele('tag:div@class=ele_class') # 查找 class 等于 ele_class 的 div 元素
page.ele('tag:div@text():search_text') # 查找文本含有 search_text 的 div 元素
page.ele('tag:div@text()=search_text') # 查找文本等于 search_text 的 div 元素


# 根据文本内容查找
page.ele('search text')  # 查找包含传入文本的元素  
page.eles('text:search text')  # 如文本以 @、tag:、css:、xpath:、text: 开头,则应在前加上 text: 避免冲突  
page.eles('text=search text')  # 文本等于 search_text 的元素
 
# 根据 xpath 或 css selector 查找
page.eles('xpath://div[@class="ele_class"]')  
page.eles('css:div.ele_class') 


# 查找下级元素
element = page.ele('@id:ele_id')
element.ele('@class:class_name')  # 在 element 下级查找第一个 class 为 ele_class 的元素
element.eles('tag:li')  # 在 ele_id 下级查找所有li元素
 
# 根据位置查找
element.parent  # 父元素  
element.next  # 下一个兄弟元素  
element.prev  # 上一个兄弟元素  
 
# 获取 shadow-root,把它作为元素对待。只支持 open 的 shadow-root
ele1 = element.shadow_root.ele('tag:div')
 
# 串连查找
page.ele('@id:ele_id').ele('tag:div').next.ele('some text').eles('tag:a')
 
# 简化写法
eles = page('@id:ele_id')('tag:div').next('some text').eles('tag:a')
ele2 = ele1('tag:li').next('some text')

 简化写法对应列表

 【3】元素操作

element.click(by_js)  # 点击元素,可选择是否用 js 方式点击
element.input(value)  # 输入文本
element.run_script(js)  # 对元素运行 JavaScript 脚本
element.submit()  # 提交
element.clear()  # 清空元素
element.screenshot(path, filename)  # 对元素截图
element.select(text)  # 根据文本选择下拉列表
element.set_attr(attr, value)  # 设置元素属性值
element.remove_attr(attr)  # 删除属性
element.drag(x, y, speed, shake)  # 拖动元素相对距离,可设置速度和是否随机抖动
element.drag_to(ele_or_loc, speed, shake)  # 拖动元素到另一个元素或某个坐标,可设置速度和是否随机抖动
element.hover()  # 在元素上悬停鼠标

【4】元素属性和方法

element.html  # 返回元素 outerHTML
element.inner_html  # 返回元素 innerHTML
element.tag  # 返回元素 tag name
element.text  # 返回元素 innerText 值
element.comments  # 返回元素内注释列表
element.link  # 返回元素 href 或 src 绝对 url
element.texts()  # 返回元素内所有直接子节点的文本,包括元素和文本节点,可指定只返回文本节点
element.attrs  # 返回元素所有属性的字典
element.attr(attr)  # 返回元素指定属性的值
element.css_path  # 返回元素绝对 css 路径
element.xpath  # 返回元素绝对 xpath 路径
element.parent  # 返回元素父元素
element.next  # 返回元素后一个兄弟元素
element.prev  # 返回元素前一个兄弟元素
element.parent()  # 返回第 1 级父元素
element.parents(num)  # 返回第 num 级父元素
element.nexts(num, mode)  # 返回后面第几个元素或节点
element.prevs(num, mode)  # 返回前面第几个元素或节点
element.ele(loc_or_str, timeout)  # 返回当前元素下级第一个符合条件的子元素、属性或节点文本
element.eles(loc_or_str, timeout)  # 返回当前元素下级所有符合条件的子元素、属性或节点文本