mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
docs
This commit is contained in:
parent
6ccc21b1f6
commit
39d904fe14
0
docs/.nojekyll
Normal file
0
docs/.nojekyll
Normal file
72
docs/README.md
Normal file
72
docs/README.md
Normal file
@ -0,0 +1,72 @@
|
||||
# 简洁!易用 !方便!
|
||||
|
||||
# 简介
|
||||
|
||||
DrissionPage,即 driver 和 session 组合而成的 page。
|
||||
是个基于 python 的 Web 自动化操作集成工具。
|
||||
它用 POM 模式封装了页面和元素常用的方法,
|
||||
自带一套简洁直观优雅的元素定位语法,
|
||||
实现了 selenium 和 requests 之间的无缝切换,
|
||||
可兼顾 selenium 的便利性和 requests 的高效率,
|
||||
更棒的是,它的使用方式非常简洁和人性化,代码量少,对新手友好。
|
||||
|
||||
**交流QQ群:** 897838127 **联系邮箱:** g1879@qq.com
|
||||
|
||||
## 背景
|
||||
|
||||
requests 爬虫面对要登录的网站时,要分析数据包、JS 源码,构造复杂的请求,往往还要应付验证码、JS 混淆、签名参数等反爬手段,门槛较高。若数据是由 JS 计算生成的,还须重现计算过程,体验不好,开发效率不高。
|
||||
使用 selenium,可以很大程度上绕过这些坑,但 selenium 效率不高。因此,这个库将 selenium 和 requests 合而为一,不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
|
||||
除了合并两者,本库还以网页为单位封装了常用功能,简化了 selenium 的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。
|
||||
一切从简,尽量提供简单直接的使用方法,对新手更友好。
|
||||
|
||||
# 特性和亮点
|
||||
|
||||
作者有多年自动化和爬虫经验,踩过无数坑,总结出的经验全写到这个库里了。内置了N多实用功能,对常用功能作了整合和优化。
|
||||
|
||||
## 特性
|
||||
|
||||
- 代码高度集成,以简洁的代码为第一追求。
|
||||
- 页面对象可在 selenium 和 requests 模式间任意切换,保留登录状态。
|
||||
- 极简单但强大的元素定位语法,支持链式操作,代码极其简洁。
|
||||
- 两种模式提供一致的 API,使用体验一致。
|
||||
- 人性化设计,集成众多实用功能,大大降低开发工作量。
|
||||
|
||||
## 亮点功能
|
||||
|
||||
- 每次运行程序可以反复使用已经打开的浏览器。如手动设置网页到某个状态,再用程序接管,或手动处理登录,再用程序爬内容。无须每次运行从头启动浏览器,超级方便。
|
||||
- 使用 ini 文件保存常用配置,自动调用,也提供便捷的设置api,远离繁杂的配置项。
|
||||
- 极致简明的定位语法,支持直接按文本定位元素,支持直接获取前后兄弟元素和父元素等。
|
||||
- 强大的下载工具,操作浏览器时也能享受快捷可靠的下载功能。
|
||||
- 下载工具支持多种方式处理文件名冲突、自动创建目标路径、断链重试等。
|
||||
- 访问网址带自动重试功能,可设置间隔和超时时间。
|
||||
- 访问网页能自动识别编码,无须手动设置。
|
||||
- 链接参数默认自动生成 Host 和 Referer 属性。
|
||||
- 可随时直接隐藏或显示浏览器进程窗口,非 headless 或最小化。
|
||||
- 可自动下载合适版本的 chromedriver,免去麻烦的配置。
|
||||
- d 模式查找元素内置等待,可任意设置全局等待时间或单次查找等待时间。
|
||||
- 点击元素集成 js 点击方式,一个参数即可切换点击方式。
|
||||
- 点击支持失败重试,可用于保证点击成功、判读网页遮罩层是否消失等。
|
||||
- 输入文本能自动判断是否成功并重试,避免某些情况下输入或清空失效的情况。
|
||||
- d 模式下支持全功能的 xpath,可直接获取元素的某个属性,selenium 原生无此功能。
|
||||
- 支持直接获取 shadow-root,和普通元素一样操作其下的元素。
|
||||
- 支持直接获取 after 和 before 伪元素的内容。
|
||||
- 可以在元素下直接使用 > 以 css selector 方式获取当前元素直接子元素。原生不支持这种写法。
|
||||
- 可简单地使用 lxml 来解析 d 模式的页面或元素,爬取复杂页面数据时速度大幅提高。
|
||||
- 输出的数据均已转码及处理基本排版,减少重复劳动。
|
||||
- 可方便地与 selenium 或 requests 原生代码对接,便于项目迁移。
|
||||
- 使用 POM 模式封装,可直接用于测试,便于扩展。
|
||||
- d 模式配置可同时兼容 debugger 和其它参数,原生不能兼容。
|
||||
- 还有很多这里不一一列举…………
|
||||
|
||||
# 免责声明
|
||||
|
||||
请勿将 DrissionPage 应用到任何可能会违反法律规定和道德约束的工作中,请友善使用 DrissionPage,遵守蜘蛛协议,不要将 DrissionPage 用于任何非法用途。如您选择使用 DrissionPage
|
||||
即代表您遵守此协议,作者不承担任何由于您违反此协议带来任何的法律风险和损失,一切后果由您承担。
|
||||
|
||||
# 请我喝咖啡
|
||||
|
||||
如果本项目对您有所帮助,不妨请作者我喝杯咖啡 :)
|
||||
|
||||
|  |  |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
|
26
docs/Tips大集合.md
Normal file
26
docs/Tips大集合.md
Normal file
@ -0,0 +1,26 @@
|
||||
## 全局
|
||||
|
||||
- 切换模式时会自动复制 cookies 到目标模式,并在目标模式下重新访问当前网址,可在参数中禁止自动访问。
|
||||
- 访问网址时如遇到异常,会自动重试3次,也可在对象属性或连接参数里设置重试次数和间隔时间。d 模式这个功能要重载了 check_page() 方法才有效。
|
||||
- 获取到的文本会自动替换 & nbsp; 为空格。
|
||||
- 可以在元素下直接使用 > 以 css selector 方式获取当前元素直接子元素。如 ele1.ele('css:>div')。原生不支持这种写法。
|
||||
- 用 xpath 获取元素的子元素时,可省略前面的 .。如 ele1.ele('div') 和 ele1.ele('.//div') 是一致的。
|
||||
- 保存空的配置对象时,如没有指定路径,会保存到默认 ini 文件。
|
||||
- download() 方法会自动创建 goal_path 参数的文件夹,因此可直接传入不存在的文件夹路径。
|
||||
- set_cookies()可以接收RequestsCookieJar, list, tuple, str, dict,只要格式对扔进去它会自动调整。其中 list 和 tuple 的内容可为 Cookie对象、dict、str。
|
||||
|
||||
## s 模式
|
||||
|
||||
- 在创建 MixPage 对象时传入的 Session 配置是全局有效的,一般无须每次连接传入。
|
||||
- ini 文件里设置了默认 s 模式的 headers,一般情况可直接使用,也可手动设置。
|
||||
- s 模式访问网页时会自动纠正编码,具体为先从 headers 获取,再从页面 meta 标签获取,都找不到就执行 r.apparent_encoding。因此无须手动设置。
|
||||
- 如果没有传入 referer 和 host 值,s 模式在连接时会自动根据当前域名自动填写 Host 和 Referer 属性。
|
||||
|
||||
## d 模式
|
||||
|
||||
- d 模式查找元素默认设置等待超时10秒,10秒内找到立即返回元素,超时返回 None。也可指定超时时间。
|
||||
- cilck() 方法用 selenium 点击失败时会用 js 方式重试,也可在参数里指定直接用 js 或不用 js 重试。
|
||||
- click() 方法可设置 timeout 参数,在时间内会不断重试点击目标,click(by_js=False) 可用于等待覆盖在元素上的遮罩层消失。
|
||||
- 可以用 xpath 直接获取元素属性或文本节点内容,如ele1.ele('xpath://div/@class')或ele1.ele('xpath://div/text()[2]')。原生不支持这种用法。
|
||||
- 在 MixPage 对象设置 timeout 后,该页面下所有元素的查找都会遵循该设置,该值默认为 10。也可以每次查找元素时单独设置,单独设置不影响页面对象的 timeout 属性。
|
||||
- 若设置了 debugger_address,创建 driver 时程序会自动检测该端口,如为空,则自动在该端口启动一个浏览器进程并接入。程序完毕该浏览器不自动关闭,以便后续使用。
|
13
docs/_coverpage.md
Normal file
13
docs/_coverpage.md
Normal file
@ -0,0 +1,13 @@
|
||||
## DrissionPage
|
||||
|
||||
以页面为单位整合 selenium 和 requests,封装了常用操作。
|
||||
极大地简化了代码,易于使用,并可实现两种模式的无缝切换。
|
||||
可兼顾 selenium 的易用性和 requests 的高性能。
|
||||
|
||||
如果本库对你有所帮助,请给予支持!持续维护中。
|
||||
|
||||

|
||||

|
||||
|
||||
[Gitee](https://gitee.com/g1879/DrissionPage)
|
||||
[开始阅读](README.md)
|
3
docs/_navbar.md
Normal file
3
docs/_navbar.md
Normal file
@ -0,0 +1,3 @@
|
||||
* [DataRecorder](https://gitee.com/g1879/DataRecorder)
|
||||
* [ListPage](https://gitee.com/g1879/ListPage)
|
||||
* [Demos](https://gitee.com/g1879/DrissionPage-demos)
|
36
docs/_sidebar.md
Normal file
36
docs/_sidebar.md
Normal file
@ -0,0 +1,36 @@
|
||||
* [简介](简介.md)
|
||||
|
||||
* 入门指南
|
||||
* [基本概念](入门指南\基本概念.md)
|
||||
* [快速上手](入门指南\快速上手.md)
|
||||
* 特性演示
|
||||
* [与 requests 对比](入门指南\特性演示\与requests代码对比.md)
|
||||
* [与 selenium 对比](入门指南\特性演示\与selenium代码对比.md)
|
||||
* [模式切换](入门指南\特性演示\模式切换.md)
|
||||
* [获取并打印元素属性](入门指南\特性演示\获取并打印元素属性.md)
|
||||
* [下载文件](入门指南\特性演示\下载文件.md)
|
||||
|
||||
* 使用方法
|
||||
* [创建页面对象](使用方法\创建页面对象.md)
|
||||
* [访问网页](使用方法\访问网页.md)
|
||||
* [获取页面元素](使用方法\获取页面元素.md)
|
||||
* [获取元素信息](使用方法\获取元素信息.md)
|
||||
* [操作页面元素](使用方法\操作页面元素.md)
|
||||
* [获取网页信息](使用方法\获取网页信息.md)
|
||||
* [页面操作](使用方法\页面操作.md)
|
||||
* 启动配置
|
||||
* [概述](使用方法\启动配置\概述.md)
|
||||
* [Chrome 启动配置]('使用方法\启动配置\Chrome启动配置.md')
|
||||
* [Session 启动配置](使用方法\启动配置\Session启动配置.md)
|
||||
* [使用配置文件](使用方法\启动配置\使用配置文件.md)
|
||||
* [下载文件](使用方法\下载文件.md)
|
||||
* [cookies 的使用](使用方法\cookies的使用.md)
|
||||
* [Drission 对象](使用方法\Drission对象.md)
|
||||
* [对接 selenium 及 requests 代码](使用方法\对接selenium及requests代码.md)
|
||||
* [使用其它浏览器](使用方法\使用其它浏览器.md)
|
||||
* [DriverPage 和 SessionPage](使用方法\DriverPage和SessionPage.md)
|
||||
* [打包程序](使用方法\打包程序.md)
|
||||
|
||||
* [Tips大集合](Tips大集合.md)
|
||||
* [版本历史](版本历史.md)
|
||||
* [鸣谢](鸣谢.md)
|
91
docs/index.html
Normal file
91
docs/index.html
Normal file
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="code-wXFsIBcC45" name="baidu-site-verification"/>
|
||||
<title>DrissionPage</title>
|
||||
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
|
||||
<meta content="Description" name="description">
|
||||
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0" name="viewport">
|
||||
<link href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css" rel="stylesheet">
|
||||
<link href="//unpkg.com/gitalk/dist/gitalk.css" rel="stylesheet">
|
||||
<!-- <link rel="stylesheet" href="./ignore/font.css"> -->
|
||||
<style>
|
||||
/* body {font-family: PingFang; } */
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
count: {
|
||||
countable: true,
|
||||
fontsize: '0.9em',
|
||||
color: 'rgb(90,90,90)',
|
||||
language: 'chinese'
|
||||
}, // 字数+分钟
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}', // 时间 格式 {}
|
||||
notFoundPage: '错误页面/_404.md',
|
||||
// logo: 'https://www.easyicon.net/api/resizeApi.php?id=1214577&size=24',
|
||||
search: {
|
||||
noData: {
|
||||
'/': '😞 没有结果'
|
||||
},
|
||||
paths: 'auto',
|
||||
placeholder: {
|
||||
'/': '🔍 搜索'
|
||||
}
|
||||
},
|
||||
name: 'DrissionPage',
|
||||
repo: 'g1879', // github 主页
|
||||
sidebarDisplayLevel: 1, // 折叠层级
|
||||
autoHeader: true, // 自动增加标题
|
||||
mergeNavbar: true, //小屏设备下合并导航栏到侧边栏
|
||||
loadSidebar: true,
|
||||
loadNavbar: true,
|
||||
coverpage: true,
|
||||
subMaxLevel: 2,
|
||||
pagination: {
|
||||
previousText: 'PREVIOUS',
|
||||
nextText: 'NEXT',
|
||||
crossChapter: true
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<!-- v4 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
|
||||
|
||||
<!-- 折叠侧边栏 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-sidebar-collapse/dist/docsify-sidebar-collapse.min.js"></script>
|
||||
|
||||
<!--全文搜索,直接用官方提供的无法生效-->
|
||||
<script src="https://cdn.bootcss.com/docsify/4.5.9/plugins/search.min.js"></script>
|
||||
|
||||
<!-- 表情插件 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/emoji.min.js"></script>
|
||||
|
||||
<!-- code高亮 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-python.min.js"></script>
|
||||
|
||||
<!-- 复制代码到剪贴板 -->
|
||||
<script src="//unpkg.com/docsify-copy-code"></script>
|
||||
|
||||
|
||||
<!-- 图片缩放 -->
|
||||
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.js"></script>
|
||||
<!-- 字数统计 -->
|
||||
<script src="//unpkg.com/docsify-count/dist/countable.js"></script>
|
||||
|
||||
<script src="//unpkg.com/docsify-pagination/dist/docsify-pagination.min.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
151
docs/使用方法/Drission对象.md
Normal file
151
docs/使用方法/Drission对象.md
Normal file
@ -0,0 +1,151 @@
|
||||
Drission 对象用于管理 driver 和 session 对象。在多个页面协同工作时,Drission 对象用于传递驱动器,使多个页面类可控制同一个浏览器或 Session 对象。
|
||||
可直接读取 ini 文件配置信息创建,也可以在初始化时传入配置信息。
|
||||
在“使用方法->创建页面对象”章节已经涉及过 Drission 的用法,这里介绍属性和方法。
|
||||
|
||||
# Drission 类
|
||||
|
||||
初始化参数:
|
||||
|
||||
- driver_or_options:driver 对象或 DriverOptions、Options 类,传入 False 则创建空配置对象
|
||||
- session_or_options:Session 对象或设置字典,传入 False 则创建空配置对象
|
||||
- ini_path:ini 文件路径
|
||||
- proxy:代理设置,dict 类型。格式:{'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
|
||||
|
||||
前两个参数可直接接收 WebDriver 和 Session 对象,这时后面两个参数无效。
|
||||
若接收配置对象,则按照配置创建 WebDriver 和 Session 对象。
|
||||
|
||||
用 ini 文件信息创建:
|
||||
|
||||
```python
|
||||
# 由默认 ini 文件创建
|
||||
drission = Drission()
|
||||
|
||||
# 由其它 ini 文件创建
|
||||
drission = Drission(ini_path='D:\\settings.ini')
|
||||
```
|
||||
|
||||
传入配置创建:
|
||||
|
||||
```python
|
||||
from DrissionPage.config import DriverOptions
|
||||
|
||||
# 创建 driver 配置对象
|
||||
do = DriverOptions()
|
||||
# 传入配置,driver_options 和 session_options 都是可选的,须要使用对应模式才须要传入
|
||||
drission = Drission(driver_options=do)
|
||||
```
|
||||
|
||||
## session
|
||||
|
||||
此属性返回该对象管理的 Session 对象。
|
||||
|
||||
## driver
|
||||
|
||||
此属性返回该对象管理的 WebDriver 对象。
|
||||
|
||||
## driver_options
|
||||
|
||||
此属性返回用于创建 WebDriver 对象的 DriverOptions 对象。
|
||||
|
||||
## session_options
|
||||
|
||||
此属性以 dict 形式返回用于创建 Session 对象的配置参数。可传入 dict 或 SessionOptions 赋值。
|
||||
|
||||
## proxy
|
||||
|
||||
此属性返回代理信息,dict 形式。可传入 dict 赋值。格式:{'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
|
||||
|
||||
## debugger_progress
|
||||
|
||||
此属性返回浏览器进程(如有)。
|
||||
|
||||
## kill_browser()
|
||||
|
||||
此方法用于关闭浏览器进程。
|
||||
|
||||
参数:无
|
||||
|
||||
返回: None
|
||||
|
||||
## get_browser_progress_id()
|
||||
|
||||
此方法用于获取浏览器进程id。
|
||||
|
||||
参数:无
|
||||
|
||||
返回: None
|
||||
|
||||
## hide_browser()
|
||||
|
||||
此方法用于隐藏浏览器进程窗口。
|
||||
|
||||
参数:无
|
||||
|
||||
返回: None
|
||||
|
||||
## show_browser()
|
||||
|
||||
此方法用于显示浏览器进程窗口。
|
||||
|
||||
参数:无
|
||||
|
||||
返回: None
|
||||
|
||||
## set_cookies()
|
||||
|
||||
此方法用于设置cookies。可选择对某个对象设置。
|
||||
|
||||
参数:
|
||||
|
||||
- cookies:cookies信息,可为 CookieJar, list, tuple, str, dict
|
||||
- set_session:是否设置 Session 对象的 cookies
|
||||
- set_driver:是否设置浏览器的 cookies
|
||||
|
||||
返回:None
|
||||
|
||||
## cookies_to_session()
|
||||
|
||||
此方法用于把 WebDriver 对象的 cookies 复制到 Session 对象。
|
||||
|
||||
参数:
|
||||
|
||||
- copy_user_agent:是否复制 user agent 信息
|
||||
|
||||
返回:None
|
||||
|
||||
## cookies_to_driver()
|
||||
|
||||
此方法用于把 Session 对象的 cookies 复制到 WebDriver 对象。
|
||||
复制 cookies 到浏览器必须指定域名。
|
||||
|
||||
参数:
|
||||
|
||||
- url:作用域
|
||||
|
||||
返回:None
|
||||
|
||||
## close_driver()
|
||||
|
||||
此方法用于关闭 WebDriver 对象,可选择是否关闭浏览器进程。
|
||||
|
||||
参数:
|
||||
|
||||
- kill:是否关闭浏览器进程
|
||||
|
||||
返回:None
|
||||
|
||||
## close_session()
|
||||
|
||||
此方法用于关闭 Session 对象。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## close()
|
||||
|
||||
此方法用于关闭 Session 和 WebDriver 对象。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
37
docs/使用方法/DriverPage和SessionPage.md
Normal file
37
docs/使用方法/DriverPage和SessionPage.md
Normal file
@ -0,0 +1,37 @@
|
||||
如果无须切换模式,可根据需要只使用 DriverPage 或 SessionPage。
|
||||
分别对应 d 和 s 模式,用法和 MixPage 相似。
|
||||
|
||||
# SessionPage
|
||||
|
||||
```python
|
||||
from DrissionPage.session_page import SessionPage
|
||||
from DrissionPage import Drission
|
||||
|
||||
# 用配置文件信息创建 Drission,获取其中 Session 对象
|
||||
session = Drission().session
|
||||
# 传入 Session 对象创建页面对象
|
||||
page = SessionPage(session)
|
||||
|
||||
# 使用页面对象
|
||||
page.get('http://www.baidu.com')
|
||||
# 输出:百度一下
|
||||
print(page.ele('#su').text)
|
||||
```
|
||||
|
||||
# DriverPage
|
||||
|
||||
```python
|
||||
from DrissionPage.driver_page import DriverPage
|
||||
from DrissionPage import Drission
|
||||
|
||||
# 用配置文件信息创建 Drission,获取其中 WebDriver 对象
|
||||
driver = Drission().driver
|
||||
# 传入 WebDriver 对象创建页面对象
|
||||
page = DriverPage(driver)
|
||||
|
||||
# 使用页面对象
|
||||
page.get('http://www.baidu.com')
|
||||
# 输出:百度一下
|
||||
print(page.ele('#su').text)
|
||||
```
|
||||
|
21
docs/使用方法/cookies的使用.md
Normal file
21
docs/使用方法/cookies的使用.md
Normal file
@ -0,0 +1,21 @@
|
||||
MixPage 支持获取和设置 cookies,具体使用方法如下:
|
||||
|
||||
```python
|
||||
# 以字典形式返回 cookies,只会返回当前域名可用的 cookies
|
||||
page.cookies
|
||||
|
||||
# 以列表形式返回当前域名可用 cookies,每个 cookie 包含所有详细信息
|
||||
page.get_cookies(as_dict=False)
|
||||
|
||||
# 以列表形式返回所有 cookies,只有 s 模式有效
|
||||
page.get_cookies(all_domains=True)
|
||||
|
||||
# 设置 cookies,可传入 RequestsCookieJar, list, tuple, str, dict
|
||||
page.set_cookies(cookies)
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
|
||||
- d 模式设置 cookies 后要刷新页面才能看到效果。
|
||||
- s 模式可在 ini 文件、SessionOptions、配置字典中设置 cookies,在 MixPage 初始化时即可传入,d 模式只能用 set_cookies() 函数设置。
|
||||
|
59
docs/使用方法/下载文件.md
Normal file
59
docs/使用方法/下载文件.md
Normal file
@ -0,0 +1,59 @@
|
||||
selenium 缺乏对浏览器下载文件的有效管理,难以进行检测下载状态、重命名、失败管理。
|
||||
使用 requests 下载文件能较好实现以上功能,但代码较为繁琐。
|
||||
因此 DrissionPage 封装了 download 方法,整合了两者优点,可从 selenium 获取登录信息,用 requests 进行下载。弥补了 selenium 的不足,使下载简洁高效。
|
||||
|
||||
## 功能
|
||||
|
||||
- 支持 d 模式下用 requests 下载文件
|
||||
- 可指定下载路径,若路径不存在会自动创建文件夹
|
||||
- 重命名文件,可不填写扩展名,程序自动补充
|
||||
- 存在同名文件时,可选择重命名、覆盖、跳过等处理方式
|
||||
- 显示下载进度
|
||||
- 支持 post 方式
|
||||
- 支持自定义连接参数
|
||||
|
||||
## download() 方法
|
||||
|
||||
参数:
|
||||
|
||||
- file_ur:文件 url
|
||||
- goal_path:存放路径,填写到文件夹,不填写文件名
|
||||
- rename:重命名文件,可不写扩展名,不输入则用网络文件原名
|
||||
- file_exists:若存在同名文件,可选择 'rename', 'overwrite', 'skip' 方式处理,若选择重命名,会在文件名后面添加序号
|
||||
- post_data:post 方式的数据,这个参数不为 None 时自动转成 post 方式
|
||||
- show_msg:是否显示下载信息和进度
|
||||
- show_errmsg:出现异常时是否显示和抛出
|
||||
- retry:重试次数,与页面对象的设置一致,默认 3 次
|
||||
- interval:重试间隔时间,与页面对象的设置一致,默认 2 秒
|
||||
- **kwargs;连接参数,s 模式专用,与 requests 的一致
|
||||
|
||||
返回:下载是否成功(bool)和状态信息(成功时信息为文件路径)的元组,跳过时第一位返回 None
|
||||
|
||||
## 示例
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage()
|
||||
# 文件 url
|
||||
url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
|
||||
# 存放路径
|
||||
save_path = r'C:\download'
|
||||
|
||||
# 重命名为img.png,存在重名时自动在文件名末尾加上序号,显示下载进度
|
||||
res = page.download(url, save_path, 'img', 'rename', show_msg=True)
|
||||
# 打印结果
|
||||
print(res)
|
||||
```
|
||||
|
||||
显示:
|
||||
|
||||
```
|
||||
https://www.baidu.com/img/flexible/logo/pc/result.png
|
||||
result.png -> img.png
|
||||
正在下载到:C:\download
|
||||
100% C:\download\img.png
|
||||
|
||||
(True, 'C:\\download\\img.png')
|
||||
```
|
||||
|
16
docs/使用方法/使用其它浏览器.md
Normal file
16
docs/使用方法/使用其它浏览器.md
Normal file
@ -0,0 +1,16 @@
|
||||
目前设置功能只支持 Chrome 浏览器,如要使用其它浏览器,可使用 selenium 原生方法创建 driver,然后用 Drission 对象接收即可。
|
||||
|
||||
**注意:** 本库所有功能暂时只对 Chrome 做了完整测试。
|
||||
|
||||
```python
|
||||
from selenium import webdriver
|
||||
from DrissionPage import Drission, MixPage
|
||||
|
||||
# 用 selenium 原生代码创建 WebDriver 对象
|
||||
driver = webdriver.Firefox()
|
||||
# 把 WebDriver 对象传入 Drission 对象
|
||||
dr = Drission(driver_or_options=driver)
|
||||
|
||||
page = MixPage(drission=dr)
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
158
docs/使用方法/创建页面对象.md
Normal file
158
docs/使用方法/创建页面对象.md
Normal file
@ -0,0 +1,158 @@
|
||||
在入门指南的快速上手一节,我们已经初步了解如何创建页面对象,本节进一步介绍更多功能。
|
||||
页面对象类型为 MixPage,通过 MixPage() 创建。
|
||||
可以通过指定配置信息创建须要的页面对象,如无界面的浏览器、是否加载插件、是否接管已打开的浏览器、设置 headers、设置代理等等。
|
||||
这些配置信息,可以通过几种方式设置。配置的详细用法后文再讲。本节先了解创建页面对象的几种方式。
|
||||
|
||||
# MixPage 类
|
||||
|
||||
MixPage 页面对象封装了常用的网页操作,并实现在两种模式之间的切换。
|
||||
MixPage 须控制一个 Drission 对象并使用其中的 WebDriver 或 Session 对象来实现。对浏览器或网络连接的操作。如没有传入,MixPage 会自己创建一个(使用传入的配置信息或从默认 ini 文件读取)。
|
||||
|
||||
初始化参数:
|
||||
|
||||
- mode:初始化时模式,'d' 或 's',默认为 'd'
|
||||
- drission:Drission 对象,不传入时会自动创建
|
||||
- timeout:超时时间,s 模式时为连接时间,d 模式时为查找元素、处理弹出框、输入文本等超时时间
|
||||
- driver_options:浏览器设置,没传入drission 参数时会用这个设置新建 Drission 对象中的 WebDriver 对象,传入 False 则不创建
|
||||
- session_options:requests 设置,没传入 drission 参数时会用这个设置新建 Drission 对象中的 Session 对象,传入 False 则不创建
|
||||
|
||||
# 直接创建
|
||||
|
||||
这种方式代码最简洁,程序会从配置文件中读取配置,自动生成页面对象。可以保持代码简洁。
|
||||
在基本概念一节我们提到过,本库使用配置文件记录常用配置信息,也可以直接把配置写在代码里。
|
||||
|
||||
```python
|
||||
# 默认以 d 模式创建页面对象
|
||||
page = MixPage('d')
|
||||
|
||||
# 指定以 s 模式创建页面对象
|
||||
page = MixPage('s')
|
||||
```
|
||||
|
||||
# 通过配置信息创建
|
||||
|
||||
本库有两种管理配置信息的对象,分别是 DriverOptions 和 SessionOptions,对应 d 模式和 s 模式的配置。
|
||||
须要时,可以创建相应的配置对象进行设置。
|
||||
|
||||
## DriverOptions 类
|
||||
|
||||
DriverOptions 用于管理创建浏览器时的配置,浏览器创建后再修改这个配置是没有效果的。
|
||||
DriverOptions 对象能实现链式操作。
|
||||
|
||||
初始化参数:
|
||||
|
||||
- read_file:是否从 ini 文件中读取配置信息
|
||||
- ini_path:ini 文件路径,为 None 则读取默认 ini 文件
|
||||
|
||||
```python
|
||||
from Drission import MixPage
|
||||
# 导入 DriverOptions
|
||||
from DrissionPage.config import DriverOptions
|
||||
|
||||
# 创建浏览器配置对象,从文件读取配置,并增加设置浏览器静音和不加载图片
|
||||
do = DriverOptions().set_mute().set_no_imgs()
|
||||
# 用该配置创建页面对象
|
||||
page = MixPage(driver_options=do)
|
||||
```
|
||||
|
||||
## SessionOptions 类
|
||||
|
||||
SessionOptions 用于管理创建浏览器时的配置,浏览器创建后再修改这个配置是没有效果的。
|
||||
SessionOptions 对象能实现链式操作。
|
||||
|
||||
初始化参数:
|
||||
|
||||
- read_file:是否从 ini 文件中读取配置信息
|
||||
- ini_path:ini 文件路径,为 None 则读取默认 ini 文件
|
||||
|
||||
```python
|
||||
from Drission import MixPage
|
||||
# 导入 SessionOptions
|
||||
from DrissionPage.config import SessionOptions
|
||||
|
||||
proxies = {'http': 'http://127.0.0.1:1080',
|
||||
'https': 'https://127.0.0.1:1080'}
|
||||
|
||||
# 创建浏览器配置对象,不从 ini 文件读取,并设置代理信息
|
||||
so = SessionOptions(read_file=False).set_proxies(proxies)
|
||||
# 用该配置创建页面对象(s 模式)
|
||||
page = MixPage(mode='s', session_options=so)
|
||||
```
|
||||
|
||||
d 模式的配置和 s 模式的配置是可以同时使用的,不会互相影响。
|
||||
|
||||
```python
|
||||
page = MixPage(mode='s', session_options=so, driver_options=do)
|
||||
```
|
||||
|
||||
# 传入 Drission 对象创建
|
||||
|
||||
在入门指南的基本概念一节里,我们讲过 Drission 对象相当于驱动器的角色。事实上,上述两种方式,MixPage 都会自动创建一个 Drission 对象用于管理与网站或浏览器的连接,我们当然也可以手动创建并传入 MixPage。
|
||||
Drission 一般是不用手动创建的,要手动创建的时候,一般是用于i以下几种情况:
|
||||
|
||||
- 指定使用某个配置文件
|
||||
- 在不同 MixPage 间传递驱动器
|
||||
- 与 selenium 或 requests 原生代码拼接,用于兼容这两者的代码
|
||||
|
||||
## Drission 类
|
||||
|
||||
初始化参数:
|
||||
|
||||
- driver_or_options:WebDriver 对象、DriverOptions 对象或 Options 对象。传入 False 时自动创建一个空配置对象。
|
||||
- session_or_options:Session 对象、SessionOptions 对象、Options 对象或设置字典。传入 False 时自动创建一个空配置对象。
|
||||
- ini_path:要使用的 ini 文件的路径
|
||||
- proxy:初始化时设置代理
|
||||
|
||||
## 使用其它 ini 文件创建
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage, Drission
|
||||
|
||||
d = Drission(ini_path=r'./config1.ini')
|
||||
page = MixPage(drission=d)
|
||||
```
|
||||
|
||||
## 传递驱动器
|
||||
|
||||
多页面对象间共用驱动器,如多个 MixPage 控制一个浏览器:
|
||||
|
||||
```python
|
||||
from Drission import MixPage
|
||||
|
||||
page1 = MixPage()
|
||||
d = page1.drission
|
||||
page2 = MixPage(drission=d)
|
||||
```
|
||||
|
||||
## 从 selenium 和 requests 代码传入
|
||||
|
||||
DrissionPage 的代码能和 selenium 及 requests 代码兼容,便于不同程序间的对接。
|
||||
只需把 driver 对象或 session 传入 Drission 对象即可。
|
||||
|
||||
```python
|
||||
from selenium import webdriver
|
||||
from requests import Session
|
||||
from DrissionPage import Drission, MixPage
|
||||
|
||||
driver = webdriver.Chrome()
|
||||
session = Session()
|
||||
|
||||
d = Drission(driver_or_options=driver, session_or_options=session)
|
||||
page = MixPage(drission=d)
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
## 用配置信息创建
|
||||
|
||||
因为 MixPage 创建时能直接接收配置信息,所以这个方法基本不需要用到,写出来只是表示有这个功能。
|
||||
|
||||
```python
|
||||
from DrissionPage.config import DriverOptions, SessionOptions
|
||||
from DrissionPage import Drission, MixPage
|
||||
|
||||
do = DriverOptions()
|
||||
so = SessionOptions()
|
||||
d = Drission(driver_or_options=do, session_or_options=so)
|
||||
page = MixPage(drission=d)
|
||||
```
|
||||
|
177
docs/使用方法/启动配置/Chrome启动配置.md
Normal file
177
docs/使用方法/启动配置/Chrome启动配置.md
Normal file
@ -0,0 +1,177 @@
|
||||
为使浏览器设置更便利,本库扩展了 selenium.webdriver.chrome.options 的 Options 对象功能,创建了 DriverOptions 类,专门用于管理浏览器的启动配置。
|
||||
**注意:**
|
||||
|
||||
- DriverOptions 仅用于管理启动配置,浏览器启动后再修改无效。
|
||||
- 若设置了 debugger_address 且浏览器未启动,则只有 arguments、driver_path、chrome_path 参数生效。
|
||||
- 若设置了 debugger_address 且接管已有浏览器,只有 driver_path 参数生效。
|
||||
|
||||
# DriverOptions 类
|
||||
|
||||
DriverOptions 类继承自 Options 类,保留了原来所有功能,原生功能不在这里叙述,只介绍增加的功能。
|
||||
对象创建时,可从配置文件中读取配置来进行初始化,不从文件读取则创建一个空配置对象。
|
||||
该类绝大部分方法都支持链式操作。
|
||||
|
||||
初始化参数:
|
||||
|
||||
- read_file:是否从默认 ini 文件中读取配置信息
|
||||
- ini_path:ini 文件路径,为 None 则读取默认 ini 文件
|
||||
|
||||
## driver_path
|
||||
|
||||
此属性返回 chromedriver 文件路径。
|
||||
|
||||
## chrome_path
|
||||
|
||||
此属性返回 Chrome 浏览器启动文件路径,即 binary_location。
|
||||
为空时程序会根据注册表或系统路径查找。
|
||||
|
||||
## set_paths()
|
||||
|
||||
该方法用于设置浏览器用到的几种路径信息。
|
||||
|
||||
参数:
|
||||
|
||||
- driver_path:chromedriver.exe 路径
|
||||
- chrome_path:chrome.exe 路径
|
||||
- local_port:本地端口号
|
||||
- debugger_address:调试浏览器地址,会覆盖 local_port 设置,例:127.0.0.1:9222
|
||||
- download_path:下载文件路径
|
||||
- user_data_path:用户数据路径
|
||||
- cache_path:缓存路径
|
||||
|
||||
返回:None
|
||||
|
||||
## save()
|
||||
|
||||
此方法用于保存当前配置对象的信息到配置文件。
|
||||
|
||||
参数:
|
||||
|
||||
- path:配置文件的路径,传入 None 保存到当前读取的配置文件,传入 'default' 保存到默认 ini 文件
|
||||
|
||||
返回:配置文件绝对路径
|
||||
|
||||
## remove_argument()
|
||||
|
||||
此方法用于移除一个 argument 项。
|
||||
|
||||
参数:
|
||||
|
||||
- value:设置项名称,带有值的设置项传入设置名称即可
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## remove_experimental_option()
|
||||
|
||||
此方法用于移除一个实验设置,传入key值删除。
|
||||
|
||||
参数:
|
||||
|
||||
- key:实验设置的名称
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## remove_all_extensions()
|
||||
|
||||
此方法用于移除所有插件。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## set_argument()
|
||||
|
||||
此方法用于设置浏览器配置的 argument 属性。
|
||||
|
||||
参数:
|
||||
|
||||
- arg:属性名
|
||||
- value:属性值,有值的属性传入值,没有的传入bool 类型表示开关
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## set_timeouts()
|
||||
|
||||
此方法用于设置三种超时时间,selenium 4 以上版本有效。
|
||||
|
||||
参数:
|
||||
|
||||
- implicit:查找元素超时时间
|
||||
- pageLoad:页面加载超时时间
|
||||
- script:脚本运行超时时间
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## set_headless()
|
||||
|
||||
该方法用于设置是否已无头模式启动浏览器。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
|
||||
返回:None
|
||||
|
||||
## set_no_imgs()
|
||||
|
||||
该方法用于设置是否禁止加载图片。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
|
||||
返回:None
|
||||
|
||||
## set_mute()
|
||||
|
||||
该方法用于设置是否静音。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
|
||||
返回:None
|
||||
|
||||
## set_proxy()
|
||||
|
||||
该方法用于设置代理。
|
||||
|
||||
参数:
|
||||
|
||||
- proxy: 代理网址和端口,如 127.0.0.1:1080
|
||||
|
||||
返回:None
|
||||
|
||||
## set_user_agent()
|
||||
|
||||
该方法用于设置 user agent。
|
||||
|
||||
参数:
|
||||
|
||||
- user_agent:user agent文本
|
||||
|
||||
返回:None
|
||||
|
||||
## as_dict()
|
||||
|
||||
该方法以 dict 方式返回所有配置信息。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:配置信息
|
||||
|
||||
# 简单示例
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
from DrissionPage.config import DriverOptions
|
||||
|
||||
# 创建配置对象(默认从 ini 文件中读取配置)
|
||||
do = DriverOptions()
|
||||
# 设置不加载图片、静音
|
||||
do.set_no_imgs(True).set_mute(True)
|
||||
|
||||
# 以该配置创建页面对象
|
||||
page = MixPage(driver_options=do)
|
||||
```
|
||||
|
155
docs/使用方法/启动配置/Session启动配置.md
Normal file
155
docs/使用方法/启动配置/Session启动配置.md
Normal file
@ -0,0 +1,155 @@
|
||||
SessionOptions 对象用于管理 Session 对象连接配置。
|
||||
其使用逻辑与 DriverOptions 相似。
|
||||
|
||||
**注意:** SessionOptions 仅用于管理启动配置,程序启动后再修改无效。
|
||||
|
||||
# SessionOptions 类
|
||||
|
||||
SessionOptions 对象创建时默认读取默认 ini 文件配置信息,也可手动设置所需信息。
|
||||
该类的方法支持链式操作。
|
||||
|
||||
初始化参数:
|
||||
|
||||
- read_file:是否从默认 ini 文件中读取配置信息
|
||||
- ini_path:ini 文件路径,为 None 则读取默认 ini 文件
|
||||
|
||||
## headers
|
||||
|
||||
该属性返回 headers 设置信息,可传入字典赋值。
|
||||
|
||||
## set_headers()
|
||||
|
||||
该方法与 headers 参数赋值功能一致。
|
||||
|
||||
参数:
|
||||
|
||||
- headers:headers 字典
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## set_a_header()
|
||||
|
||||
该方法用于设置 headers 中的一个项。
|
||||
|
||||
参数:
|
||||
|
||||
- attr:设置项名称
|
||||
- value:设置值
|
||||
|
||||
返回:当前对象
|
||||
|
||||
```python
|
||||
so = SessionOptions()
|
||||
so.set_a_header('accept', 'text/html')
|
||||
so.set_a_header('Accept-Charset', 'GB2312')
|
||||
|
||||
print(so.headers)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'accept': 'text/html', 'accept-charset': 'GB2312'}
|
||||
```
|
||||
|
||||
## remove_a_header()
|
||||
|
||||
此方法用于从 headers 中移除一个设置项。
|
||||
|
||||
参数:
|
||||
|
||||
- attr:要删除的设置名称
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## cookies
|
||||
|
||||
此属性返回 cookies 设置信息,可赋值。
|
||||
可接收 dict、list、tuple、str、RequestsCookieJar 等格式的信息。
|
||||
|
||||
## proxies
|
||||
|
||||
此属性返回代理信息,可赋值。可传入字典类型。
|
||||
格式:{'http': 'http://xx.xx.xx.xx:xxxx', 'https': 'http://xx.xx.xx.xx:xxxx'}
|
||||
|
||||
## set_proxies()
|
||||
|
||||
此方法与 proxies 属性赋值功能一致。
|
||||
|
||||
参数:
|
||||
|
||||
- dict 格式的代理参数
|
||||
|
||||
返回:当前对象
|
||||
|
||||
## auth
|
||||
|
||||
此属性用于返回和设置 auth 参数,接收 tuple 类型参数。
|
||||
|
||||
## hooks
|
||||
|
||||
此属性用于返回和设置 hooks 参数,接收 dict 类型参数。
|
||||
|
||||
## params
|
||||
|
||||
此属性用于返回和设置 params 参数,接收 dict 类型参数。
|
||||
|
||||
## verify
|
||||
|
||||
此属性用于返回和设置 verify 参数,接收 bool 类型参数。
|
||||
|
||||
## cert
|
||||
|
||||
此属性用于返回和设置 cert 参数,接收 str 或 tuple 类型参数。
|
||||
|
||||
## adapters
|
||||
|
||||
此属性用于返回和设置 adapters 参数。
|
||||
|
||||
## stream
|
||||
|
||||
此属性用于返回和设置 stream 参数,接收 bool 类型参数。
|
||||
|
||||
## trust_env
|
||||
|
||||
此属性用于返回和设置 trust_env 参数,接收 bool 类型参数。
|
||||
|
||||
## max_redirects
|
||||
|
||||
此属性用于返回和设置 max_redirects 参数,接收 int 类型参数。
|
||||
|
||||
## save()
|
||||
|
||||
此方法用于保存当前配置对象的信息到配置文件。
|
||||
|
||||
参数:
|
||||
|
||||
- path:配置文件的路径,传入 None 保存到当前读取的配置文件,传入 'default' 保存到默认 ini 文件
|
||||
|
||||
返回:配置文件绝对路径
|
||||
|
||||
## as_dict()
|
||||
|
||||
该方法以 dict 方式返回所有配置信息。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:配置信息
|
||||
|
||||
# 简单示例
|
||||
|
||||
```python
|
||||
from DrissionPage.config import SessionOptions
|
||||
from DrissionPage import MixPage
|
||||
|
||||
# 创建配置对象(默认从 ini 文件中读取配置)
|
||||
so = SessionOptions()
|
||||
# 设置 cookies
|
||||
so.cookies = ['key1=val1; domain=xxxx', 'key2=val2; domain=xxxx']
|
||||
# 设置 headers 一个参数
|
||||
so.set_a_header('Connection', 'keep-alive')
|
||||
|
||||
# 以该配置创建页面对象
|
||||
page = MixPage(mode='s', session_options=so)
|
||||
```
|
||||
|
265
docs/使用方法/启动配置/使用配置文件.md
Normal file
265
docs/使用方法/启动配置/使用配置文件.md
Normal file
@ -0,0 +1,265 @@
|
||||
本库使用 ini 文件记录浏览器或 Session 对象的启动配置。便于配置复用,免于在代码中加入繁琐的配置信息。
|
||||
默认情况下,MixPage 对象启动时自动加载文件中的配置信息。
|
||||
也可以在默认配置基础上用简单的方法再次修改,再保存到 ini 文件。
|
||||
也可以保存多个 ini 文件,按不同项目须要调用。
|
||||
**注意:**
|
||||
|
||||
- ini 文件仅用于管理启动配置,浏览器或 Session 创建后再修改 ini 文件内容是没有效果的。
|
||||
- 如果是接管已打开的浏览器,这些设置也没有用。
|
||||
- 每次升级本库,ini 文件都会被重置,可另存到其它路径以免重置。
|
||||
|
||||
# ini 文件内容
|
||||
|
||||
ini 文件默认拥有三部分配置:paths、chrome_options、session_options,初始内容如下。
|
||||
|
||||
```
|
||||
[paths]
|
||||
; chromedriver.exe路径
|
||||
chromedriver_path =
|
||||
|
||||
; 临时文件夹路径,暂时没有实际作用
|
||||
tmp_path =
|
||||
|
||||
[chrome_options]
|
||||
; 浏览器默认地址和端口,程序会启动或接管这个端口的浏览器进程,设为 '' 则用 selenium 普通方式启动浏览器
|
||||
debugger_address = 127.0.0.1:9222
|
||||
|
||||
; chrome.exe路径
|
||||
binary_location =
|
||||
|
||||
; 配置信息
|
||||
arguments = [
|
||||
; 静音
|
||||
'--mute-audio',
|
||||
; 不使用沙盒
|
||||
'--no-sandbox',
|
||||
; 谷歌文档提到需要加上这个属性来规避bug
|
||||
'--disable-gpu',
|
||||
; 忽略警告
|
||||
'ignore-certificate-errors',
|
||||
; 不显示信息栏
|
||||
'--disable-infobars'
|
||||
]
|
||||
|
||||
; 插件
|
||||
extensions = []
|
||||
|
||||
; 实验性配置
|
||||
experimental_options = {
|
||||
'prefs': {
|
||||
; 下载不弹出窗口
|
||||
'profile.default_content_settings.popups': 0,
|
||||
; 无弹窗
|
||||
'profile.default_content_setting_values': {'notifications': 2},
|
||||
; 禁用PDF插件
|
||||
'plugins.plugins_list': [{"enabled": False, "name": "Chrome PDF Viewer"}]
|
||||
},
|
||||
; 设置为开发者模式,防反爬虫
|
||||
'excludeSwitches': ["enable-automation"],
|
||||
'useAutomationExtension': False
|
||||
}
|
||||
|
||||
[session_options]
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
||||
"Connection": "keep-alive",
|
||||
"Accept-Charset": "utf-8;q=0.7,*;q=0.7"
|
||||
}
|
||||
```
|
||||
|
||||
# 文件位置
|
||||
|
||||
默认配置文件存放在库文件夹下,文件名为 configs.ini。
|
||||
用户可另存其它配置文件,或从另存的文件读取配置,但默认文件的位置和名称不会改变。
|
||||
|
||||
# 使用默认配置文件启动
|
||||
|
||||
## 使用 MixPage 对象自动加载
|
||||
|
||||
这是默认启动方式。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage()
|
||||
```
|
||||
|
||||
## 使用配置对象加载
|
||||
|
||||
这种方式一般用于加载配置后须要进一步修改。
|
||||
|
||||
```python
|
||||
from Drission.config import DriverOptions, SessionOptions
|
||||
|
||||
do = DriverOptions()
|
||||
so = SessionOptions()
|
||||
|
||||
page = MixPaage(driver_options=do, session_option=so)
|
||||
```
|
||||
|
||||
## 使用 Drission 对象加载
|
||||
|
||||
这种方式一般用于加载非默认配置文件,或须在多个页面对象间传递 Drission 对象的情况。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage, Drission
|
||||
|
||||
ds = Drission(ini_path=r'D:\config1.ini')
|
||||
page = MixPage(drission=ds)
|
||||
```
|
||||
|
||||
# 保存/另存 ini 文件
|
||||
|
||||
```python
|
||||
from DrissionPage.config import DriverOptions
|
||||
|
||||
do = DriverOptions()
|
||||
# 设置不加载图片
|
||||
do.set_no_imgs()
|
||||
|
||||
# 保存到默认 ini 文件
|
||||
do.save()
|
||||
|
||||
# 保存到其它位置的配置文件
|
||||
do.save(r'D:\config1.ini')
|
||||
```
|
||||
|
||||
# easy_set 方法
|
||||
|
||||
Chrome 浏览器的配置繁琐且难以记忆,本库提供一些常用功能的快速设置方法,调用即可修改 ini 文件中该部分内容。
|
||||
**注意:**
|
||||
|
||||
- easy_set 方法仅用于设置 ini 文件,浏览器或 Session 创建后再调用没有效果的。
|
||||
- 如果是接管已打开的浏览器,这些设置也没有用。
|
||||
|
||||
## 简单示例
|
||||
|
||||
```python
|
||||
# 导入
|
||||
from DrissionPage.easy_set import set_headless
|
||||
|
||||
# 设置无头模式
|
||||
set_headless(True)
|
||||
```
|
||||
|
||||
## show_settings()
|
||||
|
||||
该方法用于打印 ini 文件内容。
|
||||
|
||||
参数:
|
||||
|
||||
- ini_path:ini 文件路径,默认读取默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_paths()
|
||||
|
||||
该方法用于设置浏览器用到的几种路径信息,设置后可检查 driver 是否和浏览器匹配。
|
||||
|
||||
参数:
|
||||
|
||||
- driver_path:chromedriver.exe 路径
|
||||
- chrome_path:chrome.exe 路径
|
||||
- local_port:本地端口号
|
||||
- debugger_address:调试浏览器地址,会覆盖 local_port 设置,例:127.0.0.1:9222
|
||||
- download_path:下载文件路径
|
||||
- tmp_path:临时文件夹路径,暂时没有作用
|
||||
- user_data_path:用户数据路径
|
||||
- cache_path:缓存路径
|
||||
- ini_path:要修改的 ini 文件路径,默认设置默认 ini 文件
|
||||
- check_version:是否检查 chromedriver 和 Chrome 是否匹配
|
||||
|
||||
返回:None
|
||||
|
||||
## set_headless()
|
||||
|
||||
该方法用于设置是否已无头模式启动浏览器。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
- ini_path: 要修改的ini文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_no_imgs()
|
||||
|
||||
该方法用于设置是否禁止加载图片。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
- ini_path: 要修改的ini文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_mute()
|
||||
|
||||
该方法用于设置是否静音。
|
||||
|
||||
参数:
|
||||
|
||||
- on_off:bool 类型,表示开或关
|
||||
- ini_path: 要修改的ini文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_proxy()
|
||||
|
||||
该方法用于设置代理。
|
||||
|
||||
参数:
|
||||
|
||||
- proxy: 代理网址和端口,如 127.0.0.1:1080
|
||||
- ini_path: 要修改的ini文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_user_agent()
|
||||
|
||||
该方法用于设置 user agent。
|
||||
|
||||
参数:
|
||||
|
||||
- user_agent:user agent文本
|
||||
- ini_path: 要修改的ini文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## set_argument()
|
||||
|
||||
该方法用于设置浏览器配置 argument 属性。
|
||||
|
||||
参数:
|
||||
|
||||
- arg:属性名
|
||||
- value:属性值,有值的属性传入值。没有的传入 bool 表示开或关
|
||||
- ini_path:要修改的 ini 文件路径,默认设置默认 ini 文件
|
||||
|
||||
返回:None
|
||||
|
||||
## check_driver_version()
|
||||
|
||||
该方法用于检查传入的chrome和chromedriver是否匹配。
|
||||
|
||||
参数:
|
||||
|
||||
- driver_path:chromedriver.exe路径
|
||||
- chrome_path:chrome.exe路径
|
||||
|
||||
返回:bool 类型,表示是否匹配
|
||||
|
||||
## get_match_drive()
|
||||
|
||||
该方法用于自动识别 chrome 版本并下载匹配的 driver。
|
||||
|
||||
参数:
|
||||
|
||||
- ini_path:要读取和修改的 ini 文件路径
|
||||
- save_path:chromedriver 保存路径
|
||||
- chrome_path:指定 chrome.exe 位置,不指定会自动依次在 ini 文件、注册表、系统路径中查找
|
||||
- show_msg:是否打印信息
|
||||
- check_version:是否检查版本匹配
|
||||
|
||||
返回:成功返回 driver 路径,失败返回 None
|
7
docs/使用方法/启动配置/概述.md
Normal file
7
docs/使用方法/启动配置/概述.md
Normal file
@ -0,0 +1,7 @@
|
||||
浏览器和连接的配置很复杂,若都写在代码中,会让代码看上去很臃肿。
|
||||
因此,本库提供了一些方法简化其使用。
|
||||
|
||||
- 使用 ini 文件记录常用配置,使配置便于复用,无须在代码中编写繁琐的配置。
|
||||
- 使用 DriverOptions 对象管理浏览器配置,它继承自 selenium 原生的 Options 对象,加入更多便捷的功能。
|
||||
- 增加专门用于管理连接配置的 SessionOptions。
|
||||
- 提供 easy_set 方法,专门用于对 ini 文件中常用配置进行管理,简化配置操作。
|
59
docs/使用方法/对接selenium及requests代码.md
Normal file
59
docs/使用方法/对接selenium及requests代码.md
Normal file
@ -0,0 +1,59 @@
|
||||
DrissionPage 代码可无缝拼接 selenium 及 requests 代码。既可直接使用 selenium 的 WebDriver 对象,也可导出自身的 WebDriver 给 selenium 代码使用。requests 的
|
||||
Session 对象也可直接传递。便于已有项目的迁移。
|
||||
|
||||
# selenium 转 DrissionPage
|
||||
|
||||
```python
|
||||
from selenium import webdriver
|
||||
|
||||
driver = webdriver.Chrome()
|
||||
driver.get('https://www.baidu.com')
|
||||
|
||||
# 把 driver 传递给 Drission,创建 MixPage 对象
|
||||
drission = Drission(driver_or_options=driver)
|
||||
page = MixPage(drission=drission)
|
||||
|
||||
# 打印结果:百度一下,你就知道
|
||||
print(page.title)
|
||||
```
|
||||
|
||||
# DrissionPage 转 selenium
|
||||
|
||||
```python
|
||||
page = MixPage()
|
||||
page.get('https://www.baidu.com')
|
||||
|
||||
# 从 MixPage 对象中获取 WebDriver 对象
|
||||
driver = page.driver
|
||||
# 打印结果:百度一下,你就知道
|
||||
print(driver.title)
|
||||
# 使用 selenium 原生功能
|
||||
element = driver.find_element(By.XPATH, '//div')
|
||||
```
|
||||
|
||||
# requests 转 DrissionPage
|
||||
|
||||
``` python
|
||||
from requests import Session
|
||||
|
||||
session = requets.Session()
|
||||
|
||||
# 把 session 传递给 Drission,创建 MixPage 对象
|
||||
drission = Drission(session_or_options=session)
|
||||
page = MixPage('s', drission=drission)
|
||||
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
# DrissionPage 转 requests
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
|
||||
# 提取 MixPage 中的 Session 对象
|
||||
session = page.session
|
||||
|
||||
response = session.get('https://www.baidu.com')
|
||||
```
|
52
docs/使用方法/打包程序.md
Normal file
52
docs/使用方法/打包程序.md
Normal file
@ -0,0 +1,52 @@
|
||||
# 注意事项
|
||||
|
||||
程序如直接打包为 exe 文件,运行会遇到报错。这是可能因为程序在默认路径找不到 ini 文件引起的。解决的方法有两种:
|
||||
|
||||
1. **把 ini 文件放到打包的程序文件夹**
|
||||
这样程序运行时会根据相对路径查找 ini 文件,避免找不到默认文件的问题
|
||||
|
||||
```python
|
||||
from DrissionPage import Drission, MixPage
|
||||
|
||||
drission = Drission(ini_path=r'.\configs.ini') # ini文件放在程序相同路径下
|
||||
page = MixPage(drission=drission)
|
||||
```
|
||||
|
||||
2. **把配置写到程序中,不使用 ini 文件**
|
||||
|
||||
```python
|
||||
from DrissionPage.config import DriverOptions, SessionOptions
|
||||
from DrissionPage import MixPage
|
||||
|
||||
do = DriverOptions(read_file=False)
|
||||
so = SessionOptions(read_file=False)
|
||||
page = MixPage(driver_options=do, session_options=so)
|
||||
```
|
||||
|
||||
**注意** ,这个时候 Drission 的两个参数都要输入内容,如果其中一个不需要设置可以输入 False,如:
|
||||
|
||||
```python
|
||||
drission = Drission(driver_or_options=do, session_or_options=False)
|
||||
```
|
||||
|
||||
# 实用示例
|
||||
|
||||
通常,我会把一个绿色浏览器和打包后的 exe 文件放在一起,程序中用相对路径指向该浏览器,这样拿到别的电脑也可以正常实用。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
from DrissionPage.config import DriverOptions
|
||||
|
||||
do = DriverOptions(read_file=False).set_paths(local_port='9888',
|
||||
chrome_path=r'.\Chrome\chrome.exe',
|
||||
driver_path=r'.\Chrome\chromedriver.exe',
|
||||
user_data_path=r'.\Chrome\userData')
|
||||
page = MixPage(driver_options=do, session_options=False)
|
||||
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
注意以下两点,程序就会跳过读取 ini 文件:
|
||||
|
||||
- DriverOptions() 里要设置 read_file=False
|
||||
- 如果不传入某个模式的配置(示例中为 s 模式),要在 MixPage() 初始化是设置对应参数为 False
|
451
docs/使用方法/操作页面元素.md
Normal file
451
docs/使用方法/操作页面元素.md
Normal file
@ -0,0 +1,451 @@
|
||||
d 模式下的 DriverElement 对象可以对浏览器相应元素进行控制。
|
||||
|
||||
# 元素操作方法
|
||||
|
||||
## click()
|
||||
|
||||
此方法用于点击元素。可以选择是否用 js 方式点击,可以在点击失败时自动重试。默认情况下,使用 selenium 原生的点击方法,如果重试超过限定时间,自动改用 js 方式点击。可通过 by_js 参数设置点击方式。
|
||||
此设计除了可保证点击成功,还可以用于检测页面上的遮罩层是否消失。遮罩层经常出现在 js 方式翻页的时候,它出现的时候会阻碍 selenium
|
||||
的原生点击,所以可以通过对其下面的元素不断重试点击,来判断遮罩层是否存在。当然,这个方法是否可行要看具体网页设计。
|
||||
而如果直接使用 js 进行点击,则可无视任何遮挡,只要元素在 DOM 内,就能点击得到,这样可以根据须要灵活地对元素进行操作。
|
||||
|
||||
注意:使用 js 方式点击时,是不会进行重试的。
|
||||
|
||||
参数:
|
||||
|
||||
- by_js:是否用 js 方式点击,为 None 时先用 selenium 原生方法点击,重试失败超时后改为用 js 点击;为 True 时直接用 js 点击;为 False 时即使重试超时也不会改用 js。
|
||||
- timeout:点击失败重试超时时间,为 None 时使用父页面 timeout 设置。
|
||||
|
||||
返回:bool,表示是否点击成功。
|
||||
|
||||
```python
|
||||
# 点击一个元素,重试超时根据所在页面元素而定,都失败就改用 js 点击
|
||||
ele.click()
|
||||
|
||||
# 点击一个元素,重试 5 秒,都失败也不改用 js 点击
|
||||
ele.click(by_js=False, timeout=5)
|
||||
|
||||
# 假设遮罩层出现,ele 是遮罩层下方的元素
|
||||
ele.click(timeout = 10) # 不断重试点击,直到遮罩层消失,或到达 10 秒
|
||||
ele.click(by_js=True) # 无视遮罩层,直接用 js 点击下方元素
|
||||
```
|
||||
|
||||
## click_at()
|
||||
|
||||
此方法用于带偏移量点击元素,偏移量相对于元素左上角坐标。不传入 x 或 y 值时点击元素中点。可选择是否用 js 方式点击,但不会进行重试。
|
||||
可用于点击一些奇怪的东西,比如用 before 表示的控件。
|
||||
点击的目标不一定在元素上,可以传入负值,或大于元素大小的值,点击元素附近的区域。向右和向下为正值,向左和向上为负值。
|
||||
|
||||
参数:
|
||||
|
||||
- x:相对元素左上角坐标的x轴偏移量
|
||||
- y:相对元素左上角坐标的y轴偏移量
|
||||
- by_js:是否用js点击
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 点击元素右上方 50*50 的位置
|
||||
ele.click_at(50, -50)
|
||||
|
||||
# 点击元素上中部,x 相对左上角向右偏移50,y 保持在元素中点
|
||||
ele.click_at(x=50)
|
||||
|
||||
# 点击元素中点,和 click() 相似,但没有重试功能
|
||||
ele.click_at()
|
||||
```
|
||||
|
||||
## r_click()
|
||||
|
||||
此方法实现右键单击元素。
|
||||
|
||||
无参数。
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
ele.r_click()
|
||||
```
|
||||
|
||||
## r_click_at()
|
||||
|
||||
此方法用于带偏移量右键点击元素,用法和 click_at() 相似,但没有 by_js 参数。
|
||||
|
||||
参数:
|
||||
|
||||
- x:相对元素左上角坐标的x轴偏移量
|
||||
- y:相对元素左上角坐标的y轴偏移量
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 点击距离元素左上角 50*50 的位置(位于元素内部)
|
||||
ele.r_click_at(50, 50)
|
||||
```
|
||||
|
||||
## input()
|
||||
|
||||
此方法用于向元素输入文本或组合键,也可用于输入文件路径到 input 元素(文件间用\n间隔)。可选择输入前是否清空元素。
|
||||
insure 参数为 True 时可自动确保输入正确。该功能是为了应对 selenium 原生输入在某些i情况下会失效的问题。
|
||||
接收组合键的时候可接收 selenium 的 Keys 对象的值。组合键要放在一个 tuple 中传入。
|
||||
注意:insure 为 True 时不能用于接收组合键。
|
||||
**Tips:** 有些文本框可以接收回车代替点击按钮,可以直接在文本末尾加上 '\n'。
|
||||
|
||||
参数:
|
||||
|
||||
- vals:文本值或按键组合
|
||||
- clear:输入前是否清空文本框
|
||||
- insure:是否确保输入正确,不能用于输入组合键
|
||||
- timeout:尝试输入的超时时间,不指定则使用父页面的超时时间,只在 insure_input 参数为 True 时生效
|
||||
|
||||
返回:bool,表示是否成功输入。insure_input 为 False 时始终返回 True。
|
||||
|
||||
```python
|
||||
# 输入文本
|
||||
ele.input('Hello world!')
|
||||
|
||||
# 输入文本并回车
|
||||
ele.input('Hello world!\n')
|
||||
|
||||
# 输入组合键
|
||||
from selenium.webdriver import Keys
|
||||
ele.input((Keys.CONTROL, 'a'), insure=False)
|
||||
|
||||
# 向上传文本控件输入文本路径(传入多个路径)
|
||||
ele.input('D:\\test1.txt\nD:\\test2.txt')
|
||||
```
|
||||
|
||||
## run_script()
|
||||
|
||||
此方法用于对元素执行 js 代码,代码中用 arguments[0] 表示自己。
|
||||
|
||||
参数:
|
||||
|
||||
- script:js 文本
|
||||
- *args:传入 js 的参数
|
||||
|
||||
返回:js 执行的结果
|
||||
|
||||
```python
|
||||
# 用执行 js 的方式点击元素
|
||||
ele.run_script('arguments[0].click()')
|
||||
```
|
||||
|
||||
## clear()
|
||||
|
||||
此方法用于清空元素文本,可使用确保清空的方式,若元素是不可编辑的,返回 None。
|
||||
|
||||
参数:
|
||||
|
||||
- insure_clear:是否确保清空。为 True 则用 input() 确保值变成 '',为 False 则用 selenium 元素 clear() 方法
|
||||
|
||||
返回:bool,是否清空成功,不能清空的元素返回 None
|
||||
|
||||
```python
|
||||
ele.clear()
|
||||
```
|
||||
|
||||
## screenshot()
|
||||
|
||||
此方法用于对元素进行截图。
|
||||
如果是图片元素,会自动等待加载结束才截图。
|
||||
此方法能自动获取能够使用的文件名,避免重名覆盖原有文件。并返回保存路径。
|
||||
保存格式为 png。
|
||||
|
||||
参数:
|
||||
|
||||
- path:图片保持路径
|
||||
- filename:图片文件名,不传入时以元素 tag 标签命名
|
||||
|
||||
返回:图片的完整路径
|
||||
|
||||
```python
|
||||
path = ele.screenshot(r'D:\tmp', 'img_name')
|
||||
```
|
||||
|
||||
## set_prop()
|
||||
|
||||
此方法用于设置元素 property 属性。
|
||||
|
||||
参数:
|
||||
|
||||
- prop: 属性名
|
||||
- value: 属性值
|
||||
|
||||
返回:bool,是否设置成功
|
||||
|
||||
```python
|
||||
ele.set_prop('value', 'Hello world!')
|
||||
```
|
||||
|
||||
## set_attr()
|
||||
|
||||
此方法用于设置元素 attribute 属性。
|
||||
|
||||
参数:
|
||||
|
||||
- attr:属性名
|
||||
- value:属性值
|
||||
|
||||
返回:bool,是否设置成功
|
||||
|
||||
```python
|
||||
ele.set_attr('href', 'http://www.gitee.com')
|
||||
```
|
||||
|
||||
## remove_attr()
|
||||
|
||||
此方法用于删除元素 attribute 属性。
|
||||
|
||||
参数:
|
||||
|
||||
- attr:属性名
|
||||
|
||||
返回:bool,是否删除成功
|
||||
|
||||
```python
|
||||
ele.remove_attr('href')
|
||||
```
|
||||
|
||||
## submit()
|
||||
|
||||
此方法用于提交表单,若元素不在表单内,返回 None,否则返回 True。
|
||||
|
||||
无参数。
|
||||
|
||||
返回:True 或 None
|
||||
|
||||
```python
|
||||
ele.submit()
|
||||
```
|
||||
|
||||
## drag()
|
||||
|
||||
此方法用于拖拽元素到相对于当前的一个新位置,可以设置速度,可以选择是否随机抖动。
|
||||
|
||||
参数:
|
||||
|
||||
- x:x 变化值
|
||||
- y:y 变化值
|
||||
- speed:拖动的速度,传入 0 即瞬间到达
|
||||
- shake:是否随机抖动
|
||||
|
||||
返回:bool,表示是否拖动成功
|
||||
|
||||
```python
|
||||
# 拖动当前元素到距离 50*50 的位置,速度为 100,不随机抖动
|
||||
ele.drag(50, 50, 100, False)
|
||||
```
|
||||
|
||||
## drag_to()
|
||||
|
||||
此方法用于拖拽元素到另一个元素上或一个坐标上。
|
||||
|
||||
参数:
|
||||
|
||||
- ele_or_loc: 另一个元素或坐标元组,接收元素时坐标是元素中点的坐标。可接收 selenium 的 WebElement 或本库的 DriverElement
|
||||
- speed: 拖动的速度,传入 0 即瞬间到达
|
||||
- shake: 是否随机抖动
|
||||
|
||||
返回:bool,表示是否拖动成功
|
||||
|
||||
```python
|
||||
# 把 ele1 拖拽到 ele2 上
|
||||
ele1 = page.ele('#div1')
|
||||
ele2 = page.ele('#div2')
|
||||
ele1.drag_to(ele2)
|
||||
|
||||
# 把 ele1 拖拽到网页 50, 50 的位置
|
||||
ele1.drag_to((50, 50))
|
||||
```
|
||||
|
||||
## scroll_to()
|
||||
|
||||
此方法用于按参数指示方式滚动元素中的滚动条。默认状态滚动到底端。
|
||||
|
||||
参数:
|
||||
|
||||
- mode:滚动方向,为字符串,可选范围见下文
|
||||
- pixel:滚动的像素
|
||||
|
||||
返回:None
|
||||
|
||||
mode 参数可在以下选项中选择:
|
||||
|
||||
- 'top':元素顶端,选择它时 pixel 参数无效
|
||||
- 'bottom':元素底端,选择它时 pixel 参数无效
|
||||
- 'half':元素中间位置,选择它时 pixel 参数无效
|
||||
- 'rightmost':元素最右边,垂直方向位置不变,选择它时 pixel 参数无效
|
||||
- 'leftmost':元素最左边,垂直方向位置不变,选择它时 pixel 参数无效
|
||||
- 'up':向上
|
||||
- 'down':向下
|
||||
- 'left':向左
|
||||
- 'right':向右
|
||||
|
||||
```python
|
||||
# 元素滚动到底部
|
||||
ele.scroll_to()
|
||||
|
||||
# 元素滚动到最右边
|
||||
ele.scroll_to('rightmost')
|
||||
|
||||
# 元素向下滚动 200 像素
|
||||
ele.scroll_to('down', 200)
|
||||
```
|
||||
|
||||
## hover()
|
||||
|
||||
此方法用于模拟鼠标悬停在元素上,可接受偏移量,偏移量相对于元素左上角坐标。不传入 x 或 y 值时悬停在元素中点。x 和 y 值可接受负值。
|
||||
|
||||
参数:
|
||||
|
||||
- x:相对元素左上角坐标的x轴偏移量
|
||||
- y:相对元素左上角坐标的y轴偏移量
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 悬停在元素右上方 50*50 的位置
|
||||
ele.hover(50, -50)
|
||||
|
||||
# 悬停在元素上中部,x 相对左上角向右偏移50,y 保持在元素中点
|
||||
ele.hover(x=50)
|
||||
|
||||
# 悬停在元素中点
|
||||
ele.hover()
|
||||
```
|
||||
|
||||
# Select 类
|
||||
|
||||
select 元素的操作较为复杂,因此专门做了一个类用于处理它。每个 DriverElement 都有 select 属性,如果是 select 元素,该属性是一个 Select 类,否则该属性为 False。
|
||||
select 元素要操作列表时,实际上是对这个 Select 对象进行操作。
|
||||
|
||||
```python
|
||||
ele.select
|
||||
```
|
||||
|
||||
## 属性
|
||||
|
||||
### is_multi
|
||||
|
||||
该属性表示当前 select 元素是否多选列表。
|
||||
|
||||
```python
|
||||
ele.select.is_multi
|
||||
```
|
||||
|
||||
### options
|
||||
|
||||
该属性以列表形式返回当前 select 元素下所有列表项元素对象,这些对象是 DriverElement。
|
||||
|
||||
```python
|
||||
options = ele.select.options
|
||||
```
|
||||
|
||||
### selected_option
|
||||
|
||||
该属性返回第一个被选中的元素对象。
|
||||
|
||||
```python
|
||||
option_ele = ele.select.selected_option
|
||||
```
|
||||
|
||||
### selected_options
|
||||
|
||||
该属性以列表形式返回第所有被选中的元素对象。如果是单选列表,返回一个列表
|
||||
|
||||
```python
|
||||
options = ele.select.select.selected_options
|
||||
```
|
||||
|
||||
## 方法
|
||||
|
||||
### select()
|
||||
|
||||
该方法用于选定或取消选定下拉列表中子元素。Select 类的 \_\_call\_\_() 方法直接调用这个方法,因此可以直接`ele.select()`来替代这个方法。写法更直观。
|
||||
当元素是多选列表时,可以接受 list 或 tuple,同时选择多个项。
|
||||
|
||||
参数:
|
||||
|
||||
- text_value_index:根据文本、值选或序号择选项,若允许多选,传入list或tuple可多选
|
||||
- para_type:参数类型,可选 'text'、'value'、'index',默认根据文本选择
|
||||
- deselect:是否取消选择
|
||||
|
||||
返回:是否选择成功
|
||||
|
||||
```python
|
||||
# 根据文本选择下拉列表项
|
||||
ele.select('text')
|
||||
|
||||
# 根据 value 选择下拉列表项
|
||||
ele.select(value, 'value')
|
||||
|
||||
# 根据序号选择下拉列表项
|
||||
ele.select(index, 'index')
|
||||
|
||||
# 选择多个文本项
|
||||
ele.select(('text1', 'text2'))
|
||||
|
||||
# 选择多个 value 项
|
||||
ele.select(('value1', 'value2'), 'value')
|
||||
|
||||
# 选择多个序号
|
||||
ele.select(('index1', 'index2'), 'index')
|
||||
```
|
||||
|
||||
### deselect()
|
||||
|
||||
此方法用于取消选定下拉列表中子元素。当元素是多选列表时,可以接受 list 或 tuple,同时取消选择多个项。
|
||||
|
||||
参数:
|
||||
|
||||
- text_value_index:根据文本、值选或序号择选项,若允许多选,传入list或tuple可多选
|
||||
- para_type:参数类型,可选 'text'、'value'、'index'
|
||||
|
||||
返回:是否选择成功
|
||||
|
||||
```python
|
||||
# 根据文本取消选择下拉列表项
|
||||
ele.select.deselect('text')
|
||||
|
||||
# 根据 value 取消选择下拉列表项
|
||||
ele.select.deselect(value, 'value')
|
||||
|
||||
# 根据序号取消选择下拉列表项
|
||||
ele.select.deselect(index, 'index')
|
||||
|
||||
# 取消选择多个文本项
|
||||
ele.select.deselect(('text1', 'text2'))
|
||||
|
||||
# 取消选择多个 value 项
|
||||
ele.select.deselect(('value1', 'value2'), 'value')
|
||||
|
||||
# 取消选择多个序号
|
||||
ele.select.deselect(('index1', 'index2'), 'index')
|
||||
```
|
||||
|
||||
## 多项列表独有功能
|
||||
|
||||
### clear()
|
||||
|
||||
此方法用于清空多选列表选项。
|
||||
|
||||
无参数。
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
ele.select.clear()
|
||||
```
|
||||
|
||||
### invert
|
||||
|
||||
此方法用于反选多选列表选项。
|
||||
|
||||
无参数。
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
ele.select.invert()
|
||||
```
|
366
docs/使用方法/获取元素信息.md
Normal file
366
docs/使用方法/获取元素信息.md
Normal file
@ -0,0 +1,366 @@
|
||||
获取到须要的页面元素后,可以使用元素对象获取元素的信息。
|
||||
|
||||
本库有三种元素对象,分别是 DriverElement、ShadowRootElement、SessionElement,前两者是 d 模式下通过浏览器页面元素生成,后者由静态文本生成。DriverElement 和
|
||||
SessionElement 的基本属性一致。
|
||||
|
||||
ShadowRootElement 由于是 shadow dom 元素,属性比较其余两种少,下文单独介绍。
|
||||
|
||||
# 示例
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取推荐目录下所有 a 元素
|
||||
li_eles = page('tag:ul@@text():全部推荐项目').eles('t:a')
|
||||
|
||||
for i in li_eles: # 遍历列表
|
||||
print(i.tag, i.text, i.attr('href')) # 获取并打印标签名、文本、href 属性
|
||||
|
||||
"""输出:
|
||||
a 全部推荐项目 https://gitee.com/explore/all
|
||||
a 前沿技术 https://gitee.com/explore/new-tech
|
||||
a 智能硬件 https://gitee.com/explore/hardware
|
||||
a IOT/物联网/边缘计算 https://gitee.com/explore/iot
|
||||
a 车载应用 https://gitee.com/explore/vehicle
|
||||
以下省略……
|
||||
"""
|
||||
```
|
||||
|
||||
# 两种模式共有属性
|
||||
|
||||
假设 ele 为以下 div 元素的对象:
|
||||
|
||||
```html
|
||||
<div id="div1">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
```
|
||||
|
||||
## html
|
||||
|
||||
此属性返回元素的 outerHTML 文本。
|
||||
|
||||
```python
|
||||
html = ele.html
|
||||
"""返回:
|
||||
<div id="div1">Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
</div>
|
||||
"""
|
||||
```
|
||||
|
||||
## inner_html
|
||||
|
||||
此属性返回元素的 innerHTML 文本。
|
||||
|
||||
```python
|
||||
inner_html = ele.inner_html
|
||||
"""返回:
|
||||
Hello World!
|
||||
<p>行元素</p>
|
||||
<!--这是注释-->
|
||||
"""
|
||||
```
|
||||
|
||||
## tag
|
||||
|
||||
此属性返回元素的标签名。
|
||||
|
||||
```python
|
||||
tag = ele.tag
|
||||
# 返回:div
|
||||
```
|
||||
|
||||
## text
|
||||
|
||||
此属性返回元素内所有文本组合成的字符串。
|
||||
该字符串已格式化,即已转码,已去除多余换行符,符合人读取习惯,便于直接使用。无须重复写处理代码。
|
||||
|
||||
```python
|
||||
text = ele.text
|
||||
"""返回:
|
||||
Hello World!
|
||||
行元素
|
||||
"""
|
||||
```
|
||||
|
||||
## raw_text
|
||||
|
||||
此属性返回元素内原始文本。
|
||||
|
||||
```python
|
||||
text = ele.raw_text
|
||||
"""返回(注意保留了元素间的空格和换行):
|
||||
Hello World!
|
||||
行元素
|
||||
|
||||
|
||||
"""
|
||||
```
|
||||
|
||||
## texts()
|
||||
|
||||
此方法返回元素内所有直接子节点的文本,包括元素和文本节点。 它有一个参数 text_node_only,为True 时则只获取只返回文本节点。这个方法适用于获取文本节点和元素节点混排的情况。
|
||||
|
||||
参数:
|
||||
|
||||
- text_node_only:是否只返回文本节点
|
||||
|
||||
返回:文本列表
|
||||
|
||||
```python
|
||||
texts = ele.texts()
|
||||
print(e.texts(text_node_only=True))
|
||||
# 输出:['Hello World!', '行元素']
|
||||
|
||||
print(e.texts())
|
||||
# 输出:['Hello World!']
|
||||
```
|
||||
|
||||
## comments
|
||||
|
||||
```python
|
||||
comments = ele.comments
|
||||
# 返回:[<!--这是注释-->]
|
||||
```
|
||||
|
||||
## attrs
|
||||
|
||||
此属性以字典形式返回元素所有属性及值。
|
||||
|
||||
```python
|
||||
attrs = ele.attrs
|
||||
# 返回:{'id': 'div1'}
|
||||
```
|
||||
|
||||
## attr()
|
||||
|
||||
此方法返回元素某个 attribute 属性值。它接收一个字符串参数 attr,返回该属性值文本,无该属性时返回 None。
|
||||
此属性返回的 src、href 属性为已补充完整的路径。text 属性为已格式化文本,innerText 属性为未格式化文本。
|
||||
|
||||
参数:
|
||||
|
||||
- attr:属性名称
|
||||
|
||||
返回:属性值文本
|
||||
|
||||
```python
|
||||
ele_id = ele.attr('id')
|
||||
# 返回:div1
|
||||
```
|
||||
|
||||
## link
|
||||
|
||||
此方法返回元素的 href 属性或 src 属性,没有这两个属性则返回 None。
|
||||
|
||||
```html
|
||||
<a href='http://www.baidu.com'>百度</a>
|
||||
```
|
||||
|
||||
假设 a_ele 为以上元素的对象:
|
||||
|
||||
```python
|
||||
link = a_ele.link
|
||||
# 返回:http://www.baidu.com
|
||||
```
|
||||
|
||||
## page
|
||||
|
||||
此属性返回元素所在的页面对象。
|
||||
|
||||
- 由页面对象生成的元素返回该页面对象,如 MixPage,DriverPage,SessionPage
|
||||
- 由 html 文本直接生成的 SessionElement 的 page 属性为 None。
|
||||
|
||||
```python
|
||||
page = ele.page
|
||||
```
|
||||
|
||||
## inner_ele
|
||||
|
||||
此属性返回被当前元素包装的对应模式原本的元素对象。
|
||||
d 模式包装的是一个 selenium 的 WebElement 对象,s 模式包装的是一个 lxml 的 HtmlElement 对象。
|
||||
获取该对象,可直接使用该对象以该库的原生代码来执行须要的操作,便于不同项目的对接,及使用本库没有封装的功能。
|
||||
|
||||
```python
|
||||
# 获取元素的 WebElement 对象
|
||||
web_ele = ele.inner_ele
|
||||
# 使用 selenium 原生的元素点击方法
|
||||
web_ele.find_element(By.ID, 'ele_id').click()
|
||||
```
|
||||
|
||||
## xpath
|
||||
|
||||
此属性返回当前元素在页面中 xpath 的绝对路径。
|
||||
|
||||
```python
|
||||
xpath = ele.xpath
|
||||
# 返回:/html/body/div
|
||||
```
|
||||
|
||||
## css_path
|
||||
|
||||
此属性返回当前元素在页面中 css selector 的绝对路径。
|
||||
|
||||
```python
|
||||
css = ele.css_path
|
||||
# 返回::nth-child(1)>:nth-child(1)>:nth-child(1)
|
||||
```
|
||||
|
||||
## is_valid()
|
||||
|
||||
此方法返回当前元素是否可用。SessionElement 始终返回 True,DriverElement 视乎元素是否还在 DOM 内返回布尔值。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:布尔值
|
||||
|
||||
```python
|
||||
is_valid = ele.is_valid()
|
||||
```
|
||||
|
||||
# DriverElement 独有属性
|
||||
|
||||
## size
|
||||
|
||||
此属性以字典形式返回元素的大小。
|
||||
|
||||
```python
|
||||
size = ele.size
|
||||
# 返回:{'height': 50, 'width': 50}
|
||||
```
|
||||
|
||||
## location
|
||||
|
||||
此属性以字典形式返回元素坐标。
|
||||
|
||||
```python
|
||||
loc = ele.location
|
||||
# 返回:{'x': 50, 'y': 50}
|
||||
```
|
||||
|
||||
## before
|
||||
|
||||
此属性以文本形式返回当前元素的 ::before 伪元素内容。
|
||||
|
||||
```python
|
||||
before_txt = ele.before
|
||||
```
|
||||
|
||||
## after
|
||||
|
||||
此属性以文本形式返回当前元素的 ::after 伪元素内容。
|
||||
|
||||
```python
|
||||
after_txt = ele.after
|
||||
```
|
||||
|
||||
## style()
|
||||
|
||||
该方法返回元素 css 样式属性值,可获取伪元素的属性。它有两个参数,style 参数输入样式属性名称,pseudo_ele 参数输入伪元素名称,省略则获取普通元素的 css 样式属性。
|
||||
|
||||
参数:
|
||||
|
||||
- style:样式名称
|
||||
- pseudo_ele: 伪元素名称(如有)
|
||||
|
||||
返回:样式属性值
|
||||
|
||||
```python
|
||||
prop = ele.style('color', 'first-letter')
|
||||
```
|
||||
|
||||
## prop()
|
||||
|
||||
此方法返回 property 属性值。它接收一个字符串参数,返回该参数的属性值。
|
||||
|
||||
参数:
|
||||
|
||||
- prop:属性名称
|
||||
|
||||
返回:属性值
|
||||
|
||||
```python
|
||||
prop = ele.peop('value')
|
||||
```
|
||||
|
||||
## select
|
||||
|
||||
此属性返回 select 元素用于处理下拉列表的 Select 类(下一节说明),非下拉列表元素返回 False。
|
||||
|
||||
```python
|
||||
select = ele.select
|
||||
```
|
||||
|
||||
## is_selected()
|
||||
|
||||
此方法以布尔值返回元素是否选中。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:布尔值
|
||||
|
||||
```python
|
||||
selected = ele.is_selected()
|
||||
```
|
||||
|
||||
## is_enabled()
|
||||
|
||||
此方法以布尔值返回元素是否可用。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:布尔值
|
||||
|
||||
```python
|
||||
enable = ele.is_enabled()
|
||||
```
|
||||
|
||||
## is_displayed()
|
||||
|
||||
此方法以布尔值返回元素是否可见。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:布尔值
|
||||
|
||||
```python
|
||||
displayed = ele.is_displayed()
|
||||
```
|
||||
|
||||
# ShadowRootElement 属性
|
||||
|
||||
本库把 shadow dom 的 root 看作一个元素处理,可以获取属性,也可以执行其下级的查找,但其属性比较少。有如下这些:
|
||||
|
||||
## tag
|
||||
|
||||
元素标签名
|
||||
|
||||
## html
|
||||
|
||||
shadow-root 内的 html 文本,与其余两种元素不一样,其余两种的 html 属性获取的是 outerHTML,ShadowRootElement 的 html 属性获取的是内部的。
|
||||
|
||||
## page
|
||||
|
||||
元素所在页面对象。
|
||||
|
||||
## inner_ele
|
||||
|
||||
从 js 中获取到的 shadow-root 元素。
|
||||
|
||||
## parent_ele
|
||||
|
||||
这是 ShadowRootElement 独有的属性,返回它所依附的普通元素对象。
|
||||
|
||||
## is_enabled()
|
||||
|
||||
与 DriverElement 一致。
|
||||
|
||||
## is_valid()
|
||||
|
||||
与 DriverElement 一致。
|
||||
|
178
docs/使用方法/获取网页信息.md
Normal file
178
docs/使用方法/获取网页信息.md
Normal file
@ -0,0 +1,178 @@
|
||||
本节介绍获取页面对象各种信息的属性和方法。
|
||||
|
||||
# 两种模式共有属性
|
||||
|
||||
## url
|
||||
|
||||
此属性返回当前访问的 url。
|
||||
|
||||
## mode
|
||||
|
||||
此属性返回当前页面对象的模式,'s' 或 'd'。
|
||||
|
||||
## drission
|
||||
|
||||
此属性返回当前页面对象使用的 Drission 对象。
|
||||
|
||||
## driver
|
||||
|
||||
此属性返回当前页面对象使用的 WebDriver 对象。访问时会自动切换到 d 模式。
|
||||
|
||||
## session
|
||||
|
||||
此属性返回当前页面对象使用的 Session 对象。访问时不会切换模式。
|
||||
|
||||
## cookies
|
||||
|
||||
此属性以 dict 方式返回当前页面所使用的 cookies。
|
||||
d 模式只返回当前标签页的 cookies,s 模式则只返回当前访问的 url 的cookies。
|
||||
|
||||
## get_cookies()
|
||||
|
||||
此方法获取 cookies 并以 cookie 组成的 list 形式返回。
|
||||
|
||||
参数:
|
||||
|
||||
- as_dict:是否以字典方式返回,为 False 返回 cookie 组成的 list
|
||||
- all_domains:是否返回所有域的 cookies,只有 s 模式下生效
|
||||
|
||||
返回:cookies信息
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
p = MixPage('s')
|
||||
p.get('http://www.baidu.com')
|
||||
p.get('http://gitee.com')
|
||||
|
||||
for i in p.get_cookies(as_dict=False, all_domains=True):
|
||||
print(i)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'domain': '.baidu.com', 'domain_specified': True, ......}
|
||||
......
|
||||
{'domain': 'gitee.com', 'domain_specified': False, ......}
|
||||
......
|
||||
```
|
||||
|
||||
## html
|
||||
|
||||
此属性返回当前页面 html 文本。
|
||||
|
||||
## title
|
||||
|
||||
此属性返回当前页面 title 文本。
|
||||
|
||||
## timeout
|
||||
|
||||
s 模式下,此属性代表网络请求超时时间。
|
||||
d 模式下,此属性为元素查找、点击、处理提示框等操作的超时时间。
|
||||
默认为 10,可对其赋值。
|
||||
|
||||
```python
|
||||
# 创建 MixPage 对象时指定
|
||||
page = MixPage(timeout=5)
|
||||
|
||||
# 修改 timeout
|
||||
page.timeout = 20
|
||||
```
|
||||
|
||||
## retry_times
|
||||
|
||||
此参数为网络连接失败时的重试次数。默认为 3,可对其赋值。
|
||||
|
||||
```python
|
||||
# 修改重试次数
|
||||
page.retry_times = 5
|
||||
```
|
||||
|
||||
## retry_interval
|
||||
|
||||
此参数为网络连接失败时的重试等待间隔秒数。默认为 2,可对其赋值。
|
||||
|
||||
```python
|
||||
# 修改重试等待间隔时间
|
||||
page.retry_interval = 1.5
|
||||
```
|
||||
|
||||
## url_available
|
||||
|
||||
此属性以布尔值返回当前链接是否可用。
|
||||
s 模式下根据 Response 对象的 status_code 判断。
|
||||
d 模式根据 check_page() 方法返回值判断。
|
||||
|
||||
# s 模式独有属性
|
||||
|
||||
## response
|
||||
|
||||
此属性为 s 模式请求网站后生成的 Response 对象,本库没实现的功能可直接获取此属性调用 requests 库的原生功能。
|
||||
|
||||
```python
|
||||
# 打印连接状态
|
||||
r = page.response
|
||||
print(r.status_code)
|
||||
```
|
||||
|
||||
## json
|
||||
|
||||
此属性把请求内容解析成 json。
|
||||
比如请求接口时,返回内容是 json 格式,那就可以用这个属性获取。
|
||||
事实上,用 html 属性获取也是可以的,不过 html 属性没有对文本进行解析。
|
||||
|
||||
# d 模式独有属性
|
||||
|
||||
## timeouts
|
||||
|
||||
此属性以字典方式返回三种超时时间,selenium 4 以上版本可用。
|
||||
'implicit' 用于元素查找、点击重试、输入文本重试、处理弹出框重试等;
|
||||
'pageLoad' 用于等待页面加载;
|
||||
'script' 用于等待脚本执行。
|
||||
|
||||
```python
|
||||
print(page.timeouts)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'implicit': 10, 'pageLoad': 30.0, 'script': 30.0}
|
||||
```
|
||||
|
||||
## tabs_count
|
||||
|
||||
此属性返回当前浏览器标签页数量。
|
||||
|
||||
## tab_handles
|
||||
|
||||
此属性以列表形式返回当前浏览器所有标签页的 handle。
|
||||
|
||||
## current_tab_index
|
||||
|
||||
此属性返回当前标签页的序号。
|
||||
**注意:** 自动化过程中若手动点击标签页,会使被点击标签页的 handle 排到首位,从而导致排序与视觉效果不一致。
|
||||
|
||||
## current_tab_handle
|
||||
|
||||
此属性返回当前标签页的 handle。
|
||||
|
||||
## active_ele
|
||||
|
||||
此属性返回当前页面上焦点所在元素。类型为 DriverElement。
|
||||
|
||||
## wait_obj
|
||||
|
||||
此属性返回当前页面对象用于等待的对象。
|
||||
|
||||
## chrome_downloading()
|
||||
|
||||
此方法返回浏览器下载中的文件列表。
|
||||
|
||||
参数:
|
||||
|
||||
- path: 下载文件夹路径,默认从配置信息读取
|
||||
|
||||
返回:下载中的文件列表
|
||||
|
857
docs/使用方法/获取页面元素.md
Normal file
857
docs/使用方法/获取页面元素.md
Normal file
@ -0,0 +1,857 @@
|
||||
本节介绍如何从页面对象或元素对象中获取需要的元素对象。
|
||||
|
||||
无论是爬虫还是页面自动化,定位元素都是重中之重的的技能,浏览器开发者工具虽然可以直接复制绝对 xpath 或 css 路径,但这样做一来代码繁琐,可读性低,二来难以应付动态变化的页面。
|
||||
本库提供一套简洁易用的语法,用于快速定位元素,并且内置等待功能、支持链式查找,减少了代码的复杂性。
|
||||
|
||||
定位元素大致分为三种方法:
|
||||
|
||||
- 在页面或元素内查找子元素
|
||||
- 根据 DOM 结构相对定位
|
||||
- 根据页面布局位置相对定位
|
||||
|
||||
d 模式的元素还有专门用于处理 shadow dom 的 shadow_root 属性。获取到的元素可继续用这些方法获取后代元素,使用方法和普通元素基本一致。
|
||||
|
||||
# 示例
|
||||
|
||||
## 简单示例
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<div id="one">
|
||||
<p class="p_cls" name="row1">第一行</p>
|
||||
<p class="p_cls" name="row2">第二行</p>
|
||||
<p class="p_cls">第三行</p>
|
||||
</div>
|
||||
<div id="two">
|
||||
第二个div
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
假设 page 为以上页面的 MixPage 对象,我们可以用这些方法获取其中的元素:
|
||||
|
||||
```python
|
||||
# 获取 id 为 one 的元素
|
||||
div1 = page.ele('#one')
|
||||
|
||||
# 获取 div1 元素内所有 p 元素组成的列表
|
||||
p_eles = div1.eles('tag:p')
|
||||
|
||||
# 获取 name 属性为 row1 的元素
|
||||
p1 = page.ele('@name=row1')
|
||||
|
||||
# 获取 name 属性为 row2 且包含“第二”文本的 p 元素
|
||||
p_ele = page.ele('tag:p@@text():第二@@name=row2')
|
||||
|
||||
# 获取包含“第二个div”文本的元素
|
||||
div2 = page.ele('第二个div')
|
||||
|
||||
# 用 xpath 查找
|
||||
div2 = page.ele('xpath://div[@id="tow"]')
|
||||
|
||||
# 从第一行元素用相对定位获取第三行元素
|
||||
p3 = p1.next(2)
|
||||
|
||||
# 获取 p1 元素的父元素
|
||||
parent = p1.parent()
|
||||
|
||||
# 获取 p1 后面的第一个 div 元素
|
||||
div2 = p1.after(1, 'tag:div')
|
||||
```
|
||||
|
||||
## 实际示例
|
||||
|
||||
复制此代码可直接运行查看结果。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
page.get('https://gitee.com/explore')
|
||||
|
||||
# 获取包含“全部推荐项目”文本的 ul 元素
|
||||
ul_ele = page.ele('tag:ul@@text():全部推荐项目')
|
||||
|
||||
# 获取该 ul 元素下所有 a 元素
|
||||
titles = ul_ele.eles('tag:a')
|
||||
|
||||
# 遍历列表,打印每个 a 元素的文本
|
||||
for i in titles:
|
||||
print(i.text)
|
||||
|
||||
"""输出:
|
||||
全部推荐项目
|
||||
前沿技术
|
||||
智能硬件
|
||||
IOT/物联网/边缘计算
|
||||
车载应用
|
||||
以下省略……
|
||||
"""
|
||||
```
|
||||
|
||||
# 查找元素方法
|
||||
|
||||
## ele()
|
||||
|
||||
此方法用于查找并返回第一个匹配的元素,d 模式下返回 DriverElement,s 模式下返回 SessionElement,用 xpath 获取元素属性时,直接返回属性文本。查找不到结果则返回 None。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_str(元素对象拥有):元素的定位信息,可以是loc元组,或查询字符串
|
||||
- loc_or_ele(页面对象拥有):元素的定位信息,可以是元素对象,loc元组,或查询字符串
|
||||
- timeout:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
|
||||
|
||||
返回:s 模式下返回 SessionElement,d 模式下返回 DriverElement,或用 xpath 获取到的属性值
|
||||
|
||||
```python
|
||||
# 在页面内查找元素
|
||||
ele1 = page.ele('search text')
|
||||
|
||||
# 在元素内查找后代元素
|
||||
ele2 = ele1.ele('search text')
|
||||
|
||||
# 使用 xpath 获取后代中第一个 div 元素的 class 属性
|
||||
class = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
## eles()
|
||||
|
||||
此方法与 ele() 相似,但返回的是匹配到的所有元素组成的列表,用 xpath 获取元素属性时,返回属性文本组成的列表。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_str:元素的定位信息,可以是loc元组,或查询字符串
|
||||
- timeout:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
|
||||
|
||||
返回:s 模式下返回 SessionElement 组成的列表,d 模式下返回 DriverElement 组成的列表,或用 xpath 获取到的属性值组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele 元素内的所有 p 元素
|
||||
p_eles = ele.eles('tag:p')
|
||||
# 打印第一个 p 元素
|
||||
print(p_eles[0])
|
||||
```
|
||||
|
||||
## s_ele()
|
||||
|
||||
此方法用于在一个元素下查找后代元素,以 SessionElement 形式返回结果(xpath 获取属性值时依然是返回 str),也可以直接将一个元素或页面转换为 SessionElement 版本。
|
||||
|
||||
这是为了 d 模式处理速度的提升,当爬取复杂页面信息而且不须要和元素进行交互时,生成整个页面或者主要容器元素的 SessionElement ,再在其中获取信息,可以将速度提升几个数量级。
|
||||
|
||||
s 模式下这个方法和 ele() 是一样的。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_str(元素对象拥有):元素的定位信息,可以是loc元组,或查询字符串。为 None 时直接返回当前元素的 SessionElemnet 版本
|
||||
- loc_or_ele(页面对象拥有):元素的定位信息,可以是loc元组,或查询字符串。为 None 时直接返回当前页面的 SessionElemnet 版本
|
||||
|
||||
返回:SessionElement,或用 xpath 获取到的属性值
|
||||
|
||||
```python
|
||||
# 获取元素或页面的的 SessionElement 版本
|
||||
ele2 = ele1.s_ele()
|
||||
ele2 = page.s_ele()
|
||||
|
||||
# 在 ele1 元素下查找元素,并以 SessionElemnet 返回
|
||||
ele2 = ele1.s_ele('search text')
|
||||
|
||||
# 在页面下查找元素,并以 SessionElemnet 返回
|
||||
ele = page.s_ele('search text')
|
||||
```
|
||||
|
||||
## s_eles()
|
||||
|
||||
此方法与 s_ele() 相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_str:元素的定位信息,可以是loc元组,或查询字符串(必填)
|
||||
|
||||
返回:SessionElement 组成的列表,或用 xpath 获取到的属性值组成的列表
|
||||
|
||||
## active_ele
|
||||
|
||||
该属性返回当前页面焦点所在元素。d 模式独有。
|
||||
|
||||
```python
|
||||
ele = page.active_ele
|
||||
```
|
||||
|
||||
## shadow_root
|
||||
|
||||
DriverElement 元素除了以上方法和属性外,还有 shadow_root 属性,用于获取其内部的 shadow_root 元素。
|
||||
该属性返回的是一个 ShadowRootElement,类似于 DriverElement,功能比 DriverElement 少。但也有 ele() 和 eles() 方法,可直接搜索其下的元素,返回 DriverElement 元素。
|
||||
该 DriverElement 和普通的没有区别。
|
||||
|
||||
```python
|
||||
# 获取一个元素下是 shadow root
|
||||
shadow_ele = ele.shadow_root
|
||||
# 获取该 shadow root 下的一个元素
|
||||
ele1 = shadow_ele.ele('search text')
|
||||
# 点击获取到的元素
|
||||
ele1.click()
|
||||
```
|
||||
|
||||
# 查找语法
|
||||
|
||||
我们使用一套简洁高效的语法去定位元素,大大简化了定位元素的代码量,增强了功能,也兼容 css selector、xpath、selenium 原生的 loc 元组(s 模式也能用)。d 模式和 s
|
||||
模式定位元素的语法是完全一样的,便于模式切换时平滑过渡。
|
||||
|
||||
**关键字** 是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
|
||||
|
||||
## =
|
||||
|
||||
表示精确匹配,匹配完全符合的文本或属性。
|
||||
|
||||
## :
|
||||
|
||||
表示模糊匹配,匹配含有某个字符串的文本或属性。
|
||||
|
||||
## \#
|
||||
|
||||
表示 id 属性,只在语句最前面且单独使用时生效,可配合 = 或 :。
|
||||
|
||||
```python
|
||||
# 在页面中查找 id 属性为 ele_id 的元素
|
||||
ele1 = page.ele('#ele_id')
|
||||
|
||||
# 在 ele1 元素内查找 id 属性包含 ele_id 文本的元素
|
||||
ele2 = ele1.ele('#:ele_id')
|
||||
```
|
||||
|
||||
## .
|
||||
|
||||
表示 class 属性,只在语句最前面且单独使用时生效,可配合 = 或 :。
|
||||
|
||||
```python
|
||||
# 查找 class 属性为 ele_class 的元素
|
||||
ele2 = ele1.ele('.ele_class')
|
||||
|
||||
# 查找 class 属性包含 ele_class 文本的元素
|
||||
ele2 = ele1.ele('.:ele_class')
|
||||
```
|
||||
|
||||
## @
|
||||
|
||||
表示某个属性,只匹配一个属性。
|
||||
@ 关键字只有一个简单功能,就是匹配 @ 后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在 @ 或 @@,也作为要匹配的内容对待。
|
||||
|
||||
```python
|
||||
# 查找 name 属性为 ele_name 的元素
|
||||
ele2 = ele1.ele('@name=ele_name')
|
||||
|
||||
# 查找 name 属性包含 ele_name 文本的元素
|
||||
ele2 = ele1.ele('@name:ele_name')
|
||||
|
||||
# 查找有 name 属性的元素
|
||||
ele2 = ele1.ele('@name')
|
||||
|
||||
# 查找没有任何属性的元素
|
||||
ele2 = ele1.ele('@')
|
||||
|
||||
# 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理
|
||||
ele2 = ele1.ele('@email=abc@def.com')
|
||||
```
|
||||
|
||||
## @@
|
||||
|
||||
表示某个属性,多属性匹配时使用,个数不限。还能匹配要忽略的元素,匹配文本时也和 @ 不一样。
|
||||
@@ 后跟 - 时,表示 not。如:
|
||||
|
||||
- `@@-name`表示匹配没有 name 属性的元素
|
||||
|
||||
- `@@-name=ele_name`表示匹配 name 属性不为 ele_name 的元素
|
||||
|
||||
如有以下情况,不能使用此方式,须改用 xpath的方式:
|
||||
|
||||
- 匹配文本或属性中出现 @@
|
||||
|
||||
- 属性名本身以 - 开头
|
||||
|
||||
```python
|
||||
# 查找 name 属性为 name 且 class 属性包含 cls 文本的元素
|
||||
ele2 = ele1.ele('@@name=name@@class:cls')
|
||||
|
||||
# 查找没有 class 属性的元素
|
||||
ele2 = ele1.ele('@@-class')
|
||||
|
||||
# 查找 name 属性不包含 ele_name 的元素
|
||||
ele2 = ele1.ele('@@-name:ele_name')
|
||||
```
|
||||
|
||||
## text
|
||||
|
||||
要匹配的文本,查询字符串如开头没有任何关键字,也表示根据 text 作模糊查找。
|
||||
如果元素内有多个直接的文本节点,精确查找时可匹配所有文本节点拼成的字符串,模糊查找时可匹配每个文本节点。
|
||||
|
||||
```python
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('text=some text')
|
||||
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('text:some text')
|
||||
|
||||
# 与上一行一致
|
||||
ele2 = ele1.ele('some text')
|
||||
```
|
||||
|
||||
Tips:若要查找的文本包含`text:` ,可下面这样写,即第一个`text:` 为关键字,第二个是要查找的内容:
|
||||
|
||||
```python
|
||||
ele2 = page.ele('text:text:')
|
||||
```
|
||||
|
||||
## text()
|
||||
|
||||
作为查找属性时使用的文本关键字,必须与 @ 或 @@ 配合使用。
|
||||
与 @ 配合和与 @@ 配合使用时,text() 的意义是有差别的。
|
||||
|
||||
@text() 表示在元素的直接子文本节点中匹配,且多个节点不能合并匹配。 @@text() 表示在元素内部所有文本中匹配,且会把元素内部所有文本拼成一个总字符串再进行匹配,因此可以模糊匹配元素里面任意文本。
|
||||
|
||||
```python
|
||||
# 查找文本为 some text 的元素
|
||||
ele2 = ele1.ele('@text()=some text')
|
||||
|
||||
# 查找文本包含 some text 的元素
|
||||
ele2 = ele1.ele('@text():some text')
|
||||
|
||||
# 查找文本为 some text 且 class 属性为 cls 的元素
|
||||
ele2 = ele1.ele('@@text()=some text@@class=cls')
|
||||
|
||||
# 查找文本为 some text 且没有任何属性的元素(因第一个 @@ 后为空)
|
||||
ele2 = ele1.ele('@@@@text():some text')
|
||||
|
||||
# 查找直接子文本包含 some text 字符串的元素,和 text 关键字没有区别
|
||||
ele = page.ele('@text():some text')
|
||||
ele = page.ele('text:some text')
|
||||
|
||||
# 查找元素内部包含 some text 字符串的元素
|
||||
ele = page.ele('@@text():some text')
|
||||
```
|
||||
|
||||
## tag
|
||||
|
||||
表示元素的标签,只在语句最前面且单独使用时生效,可与 @ 或 @@ 配合使用。tag: 与 tag= 效果一致。
|
||||
|
||||
```python
|
||||
# 定位 div 元素
|
||||
ele2 = ele1.ele('tag:div')
|
||||
|
||||
# 定位 class 属性为 cls 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@class=cls')
|
||||
|
||||
# 定位文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text()=text')
|
||||
|
||||
# 定位 class 属性为 cls 且文本为 text 的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@class=cls@@text()=text')
|
||||
|
||||
# 查找直接文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@text():text')
|
||||
|
||||
# 查找内部文本节点包含 text 字符串的 div 元素
|
||||
ele2 = ele1.ele('tag:div@@text():text')
|
||||
```
|
||||
|
||||
**Tips:** 注意, `'tag:div@text():text'` 和 `'tag:div@@text():text'` 是有区别的,前者只在 div 的直接文本节点搜索,后者搜索 div 的整个内部。
|
||||
|
||||
## css
|
||||
|
||||
表示用 css selector 方式查找元素。css: 与 css= 效果一致。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('css:.div')
|
||||
|
||||
# 查找 div 子元素元素,这个写法是本库特有,原生不支持
|
||||
ele2 = ele1.ele('css:>div')
|
||||
```
|
||||
|
||||
## xpath
|
||||
|
||||
表示用 xpath 方式查找元素。xpath: 与 xpath= 效果一致。
|
||||
该方法支持完整的 xpath 语法,能使用 xpath 直接获取元素属性,selenium 不支持这种用法。
|
||||
|
||||
```python
|
||||
# 查找 div 元素
|
||||
ele2 = ele1.ele('xpath:.//div')
|
||||
|
||||
# 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
|
||||
ele2 = ele1.ele('xpath://div')
|
||||
|
||||
# 获取 div 元素的 class 属性,返回字符串
|
||||
txt = ele1.ele('xpath://div/@class')
|
||||
```
|
||||
|
||||
**Tips:**
|
||||
查找元素的后代时,selenium 原生代码要求 xpath 前面必须加 . ,否则会变成在全个页面中查找。笔者觉得这个设计是画蛇添足,既然已经通过元素查找了,自然应该只查找这个元素内部的元素。所以,用xpath 在元素下查找时,最前面
|
||||
// 或 / 前面的 . 可以省略。
|
||||
|
||||
## selenium 的 loc 元组
|
||||
|
||||
查找方法能直接接收 selenium 原生定位元组进行查找,s 模式下也支持这种写法。
|
||||
|
||||
```python
|
||||
# 查找 id 为 ele_id 的元素
|
||||
loc1 = By.ID, 'ele_id'
|
||||
ele = page.ele(loc1)
|
||||
|
||||
# 按 xpath 查找
|
||||
loc2 = By.XPATH, '//div[@class="ele_class"]'
|
||||
ele = page.ele(loc2)
|
||||
```
|
||||
|
||||
# 等待
|
||||
|
||||
d 模式下所有查找元素操作都自带等待,默认为跟随元素所在页面 timeout 属性(默认 10 秒),也可以在每次查找时单独设置,单独设置的等待时间不会改变页面原来设置。
|
||||
|
||||
```python
|
||||
# 页面初始化时设置查找元素超时时间为 15 秒
|
||||
page = MixPage(timeout=15)
|
||||
# 设置查找元素超时时间为 5 秒
|
||||
page.timeout = 5
|
||||
|
||||
# 使用页面超时时间来查找元素(5 秒)
|
||||
ele1 = page.ele('some text')
|
||||
# 为这次查找页面独立设置等待时间(1 秒)
|
||||
ele1 = page.ele('some text', timeout=1)
|
||||
# 查找后代元素,使用页面超时时间(5 秒)
|
||||
ele2 = ele1.ele('some text')
|
||||
# 查找后代元素,使用单独设置的超时时间(1 秒)
|
||||
ele2 = ele1.ele('some text', timeout=1)
|
||||
```
|
||||
|
||||
# DOM 内相对定位
|
||||
|
||||
以下方法可以以某元素为基准,在 DOM 中按照条件获取其兄弟元素、祖先元素、文档前后元素。
|
||||
除获取元素外,还能通过 xpath 获取任意节点内容,如文本节点、注释节点。这在处理元素和文本节点混排的时候非常有用。
|
||||
|
||||
## parent()
|
||||
|
||||
此方法获取当前元素某一级父元素,可指定筛选条件或层数。
|
||||
|
||||
参数:
|
||||
|
||||
- level_or_loc:第几级父元素,或定位符
|
||||
|
||||
返回:
|
||||
|
||||
```python
|
||||
# 获取 ele1 的第二层父元素
|
||||
ele2 = ele1.parent(2)
|
||||
|
||||
# 获取 ele1 父元素中 id 为 id1 的元素
|
||||
ele2 = ele1.parent('#id1')
|
||||
```
|
||||
|
||||
## next()
|
||||
|
||||
此方法返回当前元素后面的某一个兄弟元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素后面某个兄弟元素或节点文本
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第一个兄弟元素
|
||||
ele2 = ele1.next()
|
||||
|
||||
# 获取 ele1 后面第 3 个兄弟元素
|
||||
ele2 = ele1.next(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.next(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.next(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
## nexts()
|
||||
|
||||
此方法返回后面全部符合条件的兄弟元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素前面符合条件的兄弟元素或节点文本组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面所有兄弟元素
|
||||
eles = ele1.nexts()
|
||||
|
||||
# 获取 ele1 后面所有 div 兄弟元素
|
||||
divs = ele1.nexts('tag:div')
|
||||
|
||||
# 获取 ele1 后面的所有文本节点
|
||||
txts = ele1.nexts('xpath:text()')
|
||||
```
|
||||
|
||||
## prev()
|
||||
|
||||
此方法返回当前元素前面的某一个兄弟元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素前面某个兄弟元素或节点文本
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第一个兄弟元素
|
||||
ele2 = ele1.prev()
|
||||
|
||||
# 获取 ele1 前面第 3 个兄弟元素
|
||||
ele2 = ele1.prev(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.prev(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.prev(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
## prevs()
|
||||
|
||||
此方法返回前面全部符合条件的兄弟元素或节点组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素前面符合条件的兄弟元素或节点文本组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有兄弟元素
|
||||
eles = ele1.prevs()
|
||||
|
||||
# 获取 ele1 前面所有 div 兄弟元素
|
||||
divs = ele1.prevs('tag:div')
|
||||
```
|
||||
|
||||
## after()
|
||||
|
||||
此方法返回当前元素后面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素后面某个元素或节点
|
||||
|
||||
```python
|
||||
# 获取 ele1 后面第 3 个元素
|
||||
ele2 = ele1.after(3)
|
||||
|
||||
# 获取 ele1 后面第 3 个 div 元素
|
||||
ele2 = ele1.after(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 后面第一个文本节点的文本
|
||||
txt = ele1.after(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
## afters()
|
||||
|
||||
此方法返回后面符合条件的全部元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素后面符合条件的元素或节点组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有兄弟元素
|
||||
eles = ele1.prevs()
|
||||
|
||||
# 获取 ele1 前面所有 div 兄弟元素
|
||||
divs = ele1.prevs('tag:div')
|
||||
```
|
||||
|
||||
## before()
|
||||
|
||||
此方法返回当前元素前面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素前面某个元素或节点
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面第 3 个元素
|
||||
ele2 = ele1.before(3)
|
||||
|
||||
# 获取 ele1 前面第 3 个 div 兄弟元素
|
||||
ele2 = ele1.before(3, 'tag:div')
|
||||
|
||||
# 获取 ele1 前面第一个文本节点的文本
|
||||
txt = ele1.before(1, 'xpath:text()')
|
||||
```
|
||||
|
||||
## befores()
|
||||
|
||||
此方法返回前面全部符合条件的元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
- timeout:查找元素的超时时间
|
||||
|
||||
返回:本元素前面符合条件的元素或节点组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 前面所有兄弟元素
|
||||
eles = ele1.befores()
|
||||
|
||||
# 获取 ele1 前面所有 div 兄弟元素
|
||||
divs = ele1.befores('tag:div')
|
||||
```
|
||||
|
||||
# 页面布局相对定位
|
||||
|
||||
以下方法用于在页面上根据显示位置定位元素。只能有在 d 模式,selenium4 版本,且 driver 版本较新的情况下才能使用。
|
||||
与上面通过 DOM 定位的方法不同,这些方法只能获取元素,不能获取节点。
|
||||
获取多个元素时,元素由近到远排列。
|
||||
|
||||
## left()
|
||||
|
||||
此方法返回当前元素左边的某一个元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素左边的某个元素
|
||||
|
||||
```python
|
||||
# 获取 ele1 左边第 3 个元素
|
||||
ele2 = ele1.left(3)
|
||||
|
||||
# 获取 ele1 左边第 3 个 div 元素
|
||||
ele2 = ele1.left(3, 'tag:div')
|
||||
```
|
||||
|
||||
## lefts()
|
||||
|
||||
此方法返回左边全部符合条件的元素组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素左边符合条件的元素组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 左边所有元素
|
||||
eles = ele1.lefts()
|
||||
|
||||
# 获取 ele1 左边所有 div 元素
|
||||
divs = ele1.lefts('tag:div')
|
||||
```
|
||||
|
||||
## right()
|
||||
|
||||
此方法返回当前元素左边的某一个元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素左边的某个元素
|
||||
|
||||
```python
|
||||
# 获取 ele1 左边第 3 个元素
|
||||
ele2 = ele1.right(3)
|
||||
|
||||
# 获取 ele1 左边第 3 个 div 元素
|
||||
ele2 = ele1.right(3, 'tag:div')
|
||||
```
|
||||
|
||||
## rights()
|
||||
|
||||
此方法返回右边全部符合条件的元素组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素右边符合条件的元素组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 右边所有元素
|
||||
eles = ele1.rights()
|
||||
|
||||
# 获取 ele1 右边所有 div 元素
|
||||
divs = ele1.rights('tag:div')
|
||||
```
|
||||
|
||||
## below()
|
||||
|
||||
此方法返回当前元素下边的某一个元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素下边的某个元素
|
||||
|
||||
```python
|
||||
# 获取 ele1 下边第 3 个元素
|
||||
ele2 = ele1.below(3)
|
||||
|
||||
# 获取 ele1 下边第 3 个 div 元素
|
||||
ele2 = ele1.below(3, 'tag:div')
|
||||
```
|
||||
|
||||
## belows()
|
||||
|
||||
此方法返回下边全部符合条件的元素组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素下边符合条件的元素组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 下边所有元素
|
||||
eles = ele1.belows()
|
||||
|
||||
# 获取 ele1 下边所有 div 元素
|
||||
divs = ele1.belows('tag:div')
|
||||
```
|
||||
|
||||
## above()
|
||||
|
||||
此方法返回当前元素上边的某一个元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素上边的某个元素
|
||||
|
||||
```python
|
||||
# 获取 ele1 上边第 3 个元素
|
||||
ele2 = ele1.above(3)
|
||||
|
||||
# 获取 ele1 上边第 3 个 div 元素
|
||||
ele2 = ele1.above(3, 'tag:div')
|
||||
```
|
||||
|
||||
## aboves()
|
||||
|
||||
此方法返回上边全部符合条件的元素组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素上边符合条件的元素组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 上边所有元素
|
||||
eles = ele1.aboves()
|
||||
|
||||
# 获取 ele1 上边所有 div 元素
|
||||
divs = ele1.aboves('tag:div')
|
||||
```
|
||||
|
||||
## near()
|
||||
|
||||
此方法返回最接近当前元素的某一个元素,可指定筛选条件和第几个。
|
||||
|
||||
参数:
|
||||
|
||||
- index:查询结果中的第几个
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:最接近本元素的某个元素
|
||||
|
||||
```python
|
||||
# 获取最接近 ele1 的第 3 个元素
|
||||
ele2 = ele1.near(3)
|
||||
|
||||
# 获取最接近 ele1 的第 3 个 div 元素
|
||||
ele2 = ele1.near(3, 'tag:div')
|
||||
```
|
||||
|
||||
## nears()
|
||||
|
||||
此方法返回该元素附近全部符合条件的元素组成的列表,可用查询语法筛选。
|
||||
|
||||
参数:
|
||||
|
||||
- filter_loc:用于筛选元素的查询语法
|
||||
|
||||
返回:本元素附近符合条件的元素组成的列表
|
||||
|
||||
```python
|
||||
# 获取 ele1 附近所有元素
|
||||
eles = ele1.nears()
|
||||
|
||||
# 获取 ele1 附近所有 div 元素
|
||||
divs = ele1.nears('tag:div')
|
||||
```
|
||||
|
||||
# 简化写法
|
||||
|
||||
为进一步精简代码,对语法进行了精简
|
||||
|
||||
- 定位语法都有其简化形式。
|
||||
- 页面和元素对象都实现了 \_\_call\_\_() 方法,可直接调用。
|
||||
- 所有查找方法都支持链式操作
|
||||
|
||||
示例:
|
||||
|
||||
```python
|
||||
# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
|
||||
eles = page('#table_id').eles('t:tr')
|
||||
|
||||
# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
|
||||
ele2 = ele1('.cls1')('tx=text')
|
||||
|
||||
# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
|
||||
ele2 = ele1.sr('.cls')
|
||||
|
||||
# 按xpath 查找元素
|
||||
ele2 = ele1('x://div[@class="ele_class"]')
|
||||
```
|
||||
|
||||
简化写法对应列表
|
||||
|
||||
| 原写法 | 简化写法 |
|
||||
| :---------: | :------: |
|
||||
| text | tx |
|
||||
| text() | tx() |
|
||||
| tag | t |
|
||||
| xpath | x |
|
||||
| css | c |
|
||||
| shadow_root | sr |
|
||||
|
||||
# Tips
|
||||
|
||||
- 从一个 DriverElement 元素获取到的 SessionElement 版本,依然能够使用相对定位方法定位祖先或兄弟元素。
|
||||
- SessionElement 和 SessionPage 的 ele() 和 eles() 方法也有 timeout 参数,但它是不生效的,仅用于保持与 d 模式元素书写一致,便于无差别的调用。
|
||||
- 定位语句内容与关键字重复时,请使用 xpath 或 css selector 代替。
|
||||
|
98
docs/使用方法/访问网页.md
Normal file
98
docs/使用方法/访问网页.md
Normal file
@ -0,0 +1,98 @@
|
||||
操作页面前通常要先跳转到目标 url(接管现有浏览器除外),本库访问网页主要支持 get() 和 post() 两种方式,还支持自动重试。
|
||||
|
||||
# get()
|
||||
|
||||
该方法在 d 模式和 s 模式下都可用,用于跳转到一个网址。
|
||||
当连接失败时,程序默认重试 3 次,每次间隔 2 秒,也可以通过参数设置重试次数和间隔。
|
||||
如果目标 url 和当前 url 一致,程序默认不跳转,可通过参数强制跳转。
|
||||
在 s 模式下,可传入连接参数,语法与 requests 的 get() 方法一致。
|
||||
方法返回是否连接成功的布尔值,s 模式下根据 Response 对象的 status_code 参数决定,d 模式下根据浏览器的状态,还可以通过重写 check_page() 方法实现自定义检查方式。
|
||||
|
||||
参数:
|
||||
|
||||
- url:目标 url
|
||||
- go_anyway:若目标 url 与当前 url 一致,是否强制跳转
|
||||
- show_errmsg:是否显示和抛出异常,默认不抛出,连接错误会返回 None
|
||||
- retry:重试次数,与页面对象的设置一致,默认 3 次
|
||||
- interval:重试间隔(秒),与页面对象的设置一致,默认 2 秒
|
||||
- **kwargs:连接参数,s 模式专用,与 requests 的使用方法一致
|
||||
|
||||
返回:是否连接成功
|
||||
|
||||
## d 模式
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('d')
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
## s 模式
|
||||
|
||||
s 模式的 **kwargs 参数与 requests 中该参数使用方法一致,但有一个特点,如果该参数中设置了某一项(如 headers),该项中的每个项会覆盖从配置中读取的同名项,而不会整个覆盖。
|
||||
就是说,如果想继续使用配置中的 headers 信息,而只想修改其中一项,只需要传入该项的值即可。这样可以简化代码逻辑。
|
||||
|
||||
实用功能:
|
||||
|
||||
- 程序会根据要访问的网址自动在 headers 中加入 Host 和 Referer 项。
|
||||
- 程序会自动从返回内容中确定编码,一般情况无须手动设置。
|
||||
- s 模式下页面对象的 timeout 属性是指连接超时时间,不是查找元素超时时间。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
|
||||
headers = {'referer': 'gitee.com'}
|
||||
cookies = {'name': 'value', }
|
||||
proxies = {'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
|
||||
page.get(url, headers=headers, cookies=cookies, proxies=proxies)
|
||||
```
|
||||
|
||||
# post()
|
||||
|
||||
该方法是用 post 方式请求页面。大致用法与 get() 一致,但增加一个 data 参数。
|
||||
只有 s 模式拥有,调用该方法时,页面对象会自动切换到 s 模式。
|
||||
与 requests 不一样的是,post() 只使用一个 data 参数,而不区分 data 和 json,要传入 json 参数的值也是传入 data。
|
||||
是否须要增加 json 参数有待考察,如有须要请与本库作者联系。
|
||||
|
||||
参数:
|
||||
|
||||
- url:目标 url
|
||||
- data:提交的数据,可以是 dict 或 str 类型
|
||||
- go_anyway:若目标 url 与当前 url 一致,是否强制跳转
|
||||
- show_errmsg:是否显示和抛出异常,默认不抛出,连接错误会返回 None
|
||||
- retry:重试次数,与页面对象的设置一致,默认 3 次
|
||||
- interval:重试间隔(秒),与页面对象的设置一致,默认 2 秒
|
||||
- **kwargs:连接参数,s 模式专用
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
|
||||
data = {'username': 'xxxxx', 'pwd': 'xxxxx'}
|
||||
page.post('http://example.com', data=data)
|
||||
```
|
||||
|
||||
# 其它请求方式
|
||||
|
||||
本库只针对常用的 get 和 post 方式作了优化,但也可以通过提取页面对象内的 Session 对象以原生 requests 代码方式执行其它请求方式。当然,它们工作在 s 模式。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage('s')
|
||||
# 获取内置的 Session 对象
|
||||
session = page.session
|
||||
# 以 head 方式发送请求
|
||||
response = session.head('https://www.baidu.com')
|
||||
print(r.headers)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
{'Accept-Ranges': 'bytes', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Length': '277', 'Content-Type': 'text/html', 'Date': 'Tue, 04 Jan 2022 06:49:18 GMT', 'Etag': '"575e1f72-115"', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:26 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18'}
|
||||
```
|
464
docs/使用方法/页面操作.md
Normal file
464
docs/使用方法/页面操作.md
Normal file
@ -0,0 +1,464 @@
|
||||
本节介绍页面对象可以使用的方法,有些方法是两种模式共有的,有些只有某种模式可以使用。当调用独有方法时,会自动切换到该模式。如调用`post()`方法时,会先切换到 s 模式,并同步登录信息。
|
||||
|
||||
# 两种模式共有的方法
|
||||
|
||||
## get()
|
||||
|
||||
此方法用于跳转到一个 url,详细用法见“使用方法 -> 访问网页”章节。
|
||||
|
||||
## ele()、eles()、s_ele()、s_eles()
|
||||
|
||||
这些方法用于在页面中查找元素,详细用法见“使用方法 -> 获取页面元素”章节。
|
||||
|
||||
## change_mode()
|
||||
|
||||
此方法用于转换 MixPage 模式。
|
||||
切换后默认在目标模式重新跳转到原模式所在 url。
|
||||
**注意:** s 模式转 d 模式时,若浏览器当前网址域名和 s 模式不一样,必定会跳转。
|
||||
|
||||
参数:
|
||||
|
||||
- mode:目标模式字符串,'s' 或 'd',默认转换到另一种
|
||||
- go:转换后是否跳转到原模式所在 url
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
from time import sleep
|
||||
|
||||
# 创建页面对象,默认 d 模式
|
||||
page = MixPage()
|
||||
# 访问个人中心页面(未登录,重定向到登录页面)
|
||||
page.get('https://gitee.com/profile')
|
||||
|
||||
# 打印当前模式和登录前的 title
|
||||
print('当前模式:', page.mode)
|
||||
print('登录前title:', page.title, '\n')
|
||||
|
||||
# 使用 d 模式输入账号密码登录
|
||||
page.ele('#user_login').input('your_user_name')
|
||||
page.ele('#user_password').input('your_password\n')
|
||||
sleep(1)
|
||||
|
||||
# 切换到 session 模式
|
||||
page.change_mode()
|
||||
|
||||
# 打印当前模式和登录后的 title()
|
||||
print('当前模式:', page.mode)
|
||||
print('登录后title:', page.title)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
当前模式:d
|
||||
登录前title: 登录 - Gitee.com
|
||||
|
||||
当前模式:s
|
||||
登录后title: 个人资料 - 码云 Gitee.com
|
||||
```
|
||||
|
||||
## set_cookies()
|
||||
|
||||
此方法用于设置 cookies。
|
||||
可以接收 CookieJar、list、tuple、str、dict 格式的 cookies。
|
||||
|
||||
参数:
|
||||
|
||||
- cookies:cookies 信息
|
||||
- refresh:设置cookies后是否刷新页面
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
cookies = {'name': 'abc'}
|
||||
page.set_cookies(cookies)
|
||||
```
|
||||
|
||||
## cookies_to_session()
|
||||
|
||||
此方法用于从 WebDriver 对象复制 cookies 到 Session 对象。
|
||||
|
||||
参数:
|
||||
|
||||
- copy_user_agent:是否同时复制 user agent 信息
|
||||
|
||||
返回:None
|
||||
|
||||
## cookies_to_driver()
|
||||
|
||||
此方法用于从 Session 对象复制 cookies 到 WebDriver 对象。
|
||||
|
||||
参数:
|
||||
|
||||
- url:指定 url,默认用当前 url
|
||||
|
||||
返回:None
|
||||
|
||||
## download()
|
||||
|
||||
此方法用于下载文件,详细用法见“使用方法 -> 下载文件”章节。
|
||||
|
||||
## close_driver()
|
||||
|
||||
此方法用于关闭 WebDriver 对象和浏览器。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## close_session()
|
||||
|
||||
此方法用于关闭 Session 对象。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
# s 模式独有方法
|
||||
|
||||
## post()
|
||||
|
||||
此方法用于以 post 方式访问 url,具体用法见“使用方法 -> 访问网页”章节。
|
||||
|
||||
# d 模式独有方法
|
||||
|
||||
## hide_browser()
|
||||
|
||||
此方法用于隐藏浏览器进程窗口,非最小化,任务栏上也可隐藏。
|
||||
但若操作过程中有新增标签页,浏览器会重新出现。 只支持 Windows 系统,且只有设置了 local 或 debugger_address 时生效。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## show_browser()
|
||||
|
||||
此方法用于显示被隐藏的浏览器进程。
|
||||
只支持 Windows 系统,且只有设置了 local 或 debugger_address 时生效。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## wait_ele()
|
||||
|
||||
此方法用于等待元素到达某种状态,支持显示、隐藏、删除三种。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_ele:元素或定位符,支持 selenium 和本库定位符
|
||||
- mode:等待方式,可选:'del', 'display', 'hidden'
|
||||
- timeout:等待超时时间
|
||||
|
||||
返回:是否等待成功
|
||||
|
||||
```python
|
||||
# 等待 id 为 div1 的元素被隐藏
|
||||
page.wait_ele('#div1', 'hidden', 3)
|
||||
```
|
||||
|
||||
## run_script()
|
||||
|
||||
此方法用于执行 js 脚本。
|
||||
|
||||
参数:
|
||||
|
||||
- script:js 脚本文本
|
||||
- *args:传入的参数
|
||||
|
||||
返回:脚本执行结果
|
||||
|
||||
```python
|
||||
# 执行 js 脚本显示弹出框显示 Hello world!
|
||||
page.run_script('alert(arguments[0]+arguments[1])', 'Hello', ' world!')
|
||||
```
|
||||
|
||||
## run_async_script()
|
||||
|
||||
此方法用于以异步方式执行 js 脚本。
|
||||
|
||||
参数:
|
||||
|
||||
- script:js 脚本文本
|
||||
- *args:传入的参数
|
||||
|
||||
返回:脚本执行结果
|
||||
|
||||
## set_timeouts()
|
||||
|
||||
此方法用于设置三种超时时间,selenium 4 以上版本生效。
|
||||
|
||||
参数:
|
||||
|
||||
- implicit:查找元素超时时间
|
||||
- pageLoad:页面加载超时时间
|
||||
- script:脚本运行超时时间
|
||||
|
||||
返回:None
|
||||
|
||||
## to_frame()
|
||||
|
||||
此方法用于将页面焦点移到某个 frame 或 iframe。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_ele:iframe的定位信息,默认跳到最顶层。
|
||||
|
||||
返回:当前页面对象,可用于链式操作
|
||||
|
||||
loc_or_ele 参数支持以下信息:
|
||||
|
||||
- iframe 元素对象,DriverElement 和 WebElement 都可以
|
||||
- 本库或 selenium 定位符,如 'tag:iframe'、(By.XPATH, '//iframe')
|
||||
- iframe 在页面中的序号,如 0 表示第一个 iframe
|
||||
- iframe 的 id 或 name 值
|
||||
- 'main' 或 'parent' 字符串,分别代表跳转到顶层和父 iframe
|
||||
|
||||
```python
|
||||
# 传入元素
|
||||
iframe = page.ele('tag:iframe')
|
||||
page.to_frame(iframe)
|
||||
|
||||
# 使用定位符
|
||||
page.to_frame('tag:iframe')
|
||||
|
||||
# 使用序号,0 代表第一个
|
||||
page.to_frame(0)
|
||||
|
||||
# 使用 id 或 name 值
|
||||
page.to_frame('iframe_id')
|
||||
|
||||
# 使用 'main' 或 'parent' 字符串
|
||||
page.to_frame('main')
|
||||
page.to_frame('parent')
|
||||
```
|
||||
|
||||
## to_tab()
|
||||
|
||||
此方法把焦点定位到某个标签页。
|
||||
|
||||
参数:
|
||||
|
||||
- num_or_handle:标签页序号或 handle 字符串,序号第一个为 0,最后为 -1
|
||||
|
||||
返回:None
|
||||
|
||||
**注意:** 自动化过程中若手动点击标签页,会使被点击标签页的 handle 排到首位,从而导致排序与视觉效果不一致。
|
||||
|
||||
```python
|
||||
# 跳转到第一个标签页
|
||||
page.to_tab(0)
|
||||
|
||||
# 跳转到 handle 为该字符串的标签页
|
||||
page.to_tab('xxxxxxxxxxxxxxxxxxxx')
|
||||
```
|
||||
|
||||
## create_tab()
|
||||
|
||||
此方法用于新建并定位到一个标签页,该标签页在最后面。可指定跳转到一个 url。
|
||||
|
||||
参数:
|
||||
|
||||
- url:新标签页跳转到的 url
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
page.create_tab('http://www.baidu.com')
|
||||
```
|
||||
|
||||
## close_tabs()
|
||||
|
||||
此方法用于关闭指定的标签页,标签页可以是序号或 handle 值,可关闭多个。默认关闭当前的。
|
||||
**注意:** 当程序使用的是截关的浏览器,获取到的 handle 顺序和视觉效果不一致,不能按序号关闭。
|
||||
|
||||
参数:
|
||||
|
||||
- num_or_handles:要保留的标签页序号或 handle,可传入 list 或 tuple,为None时关闭当前页
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 关闭当前标签页
|
||||
page.close_tabs()
|
||||
|
||||
# 关闭第1、3个标签页
|
||||
page.close_tabs((0, 2))
|
||||
```
|
||||
|
||||
## close_other_tabs()
|
||||
|
||||
此方法用于关闭指定标签页以外的标签页,标签页可以是序号或 handle 值,可保留多个。默认保留当前的。
|
||||
**注意:** 当程序使用的是截关的浏览器,获取到的 handle 顺序和视觉效果不一致,不能按序号关闭。
|
||||
|
||||
参数:
|
||||
|
||||
- num_or_handles:要保留的标签页序号或 handle,可传入 list 或 tuple,为None时关闭当前页
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 关闭除当前标签页外的所有标签页
|
||||
page.close_other_tabs()
|
||||
|
||||
# 关闭除第一个以外的标签页
|
||||
page.close_other_tabs(0)
|
||||
|
||||
# 关闭除 handle 为 aaaaa 和 bbbbb 以外的标签页
|
||||
reserve_list = ('aaaaa', 'bbbbb')
|
||||
page.close_other_tabs(reserve_list)
|
||||
```
|
||||
|
||||
## scroll_to()
|
||||
|
||||
此方法用于按参数指示方式滚动页面。默认状态滚动到底端。
|
||||
|
||||
参数:
|
||||
|
||||
- mode:滚动方向,为字符串,可选范围见下文
|
||||
- pixel:滚动的像素
|
||||
|
||||
返回:None
|
||||
|
||||
mode 参数可在以下选项中选择:
|
||||
|
||||
- 'top':页面顶端,选择它时 pixel 参数无效
|
||||
- 'bottom':页面底端,选择它时 pixel 参数无效
|
||||
- 'half':页面中间位置,选择它时 pixel 参数无效
|
||||
- 'rightmost':页面最右边,垂直方向位置不变,选择它时 pixel 参数无效
|
||||
- 'leftmost':页面最左边,垂直方向位置不变,选择它时 pixel 参数无效
|
||||
- 'up':向上
|
||||
- 'down':向下
|
||||
- 'left':向左
|
||||
- 'right':向右
|
||||
|
||||
```python
|
||||
# 页面滚动到底部
|
||||
page.scroll_to()
|
||||
|
||||
# 页面滚动到最右边
|
||||
page.scroll_to('rightmost')
|
||||
|
||||
# 页面向下滚动 200 像素
|
||||
page.scroll_to('down', 200)
|
||||
```
|
||||
|
||||
## scroll_to_see()
|
||||
|
||||
此方法用于滚动页面直到元素可见。
|
||||
|
||||
参数:
|
||||
|
||||
- loc_or_ele:元素的定位信息,可以是元素、定位符
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 滚动到某个已获取到的元素
|
||||
ele = page.ele('tag:div')
|
||||
page.scroll_to_see(ele)
|
||||
|
||||
# 滚动到按定位符查找到的元素
|
||||
page.scroll_to_see('tag:div')
|
||||
# 也可用 selenium 定位符
|
||||
page.scroll_to_see((By.XPATH, '//div'))
|
||||
```
|
||||
|
||||
## refresh()
|
||||
|
||||
此方法用于刷新当前页面。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## back()
|
||||
|
||||
此方法用于在浏览历史中后退一步。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## forward()
|
||||
|
||||
此方法用于在浏览历史中前进一步。
|
||||
|
||||
参数:无
|
||||
|
||||
返回:None
|
||||
|
||||
## screenshot()
|
||||
|
||||
此方法用于生成页面可见范围截图。图片为 png 格式。
|
||||
此方法能够自动处理文件重命名的情况,给新文件后面增加序号。
|
||||
|
||||
参数:
|
||||
|
||||
- path:图片保存路径
|
||||
- filename:图片文件名,可不写后缀,不传入时以页面 title 命名
|
||||
|
||||
返回:图片完整路径
|
||||
|
||||
```python
|
||||
# 浏览器窗口截图,保存到 D 盘 img 文件夹,文件名为 img1.png
|
||||
page.screenshot(r'D:\img', 'img1')
|
||||
```
|
||||
|
||||
## set_window_size()
|
||||
|
||||
此方法用于设置浏览器窗口大小。
|
||||
默认最大化,任一参数为0最小化。
|
||||
|
||||
参数:
|
||||
|
||||
- height:浏览器窗口高度
|
||||
- width:浏览器窗口宽度
|
||||
|
||||
返回:None
|
||||
|
||||
```python
|
||||
# 窗口最大化
|
||||
page.set_window_size()
|
||||
|
||||
# 窗口最小化
|
||||
page.set_window_size(0)
|
||||
|
||||
# 设置窗口为 800*600
|
||||
page.set_window_size(800, 600)
|
||||
```
|
||||
|
||||
## process_alert()
|
||||
|
||||
此方法 用于处理提示框。
|
||||
它能够设置等待时间,等待提示框出现才进行处理,若超时没等到提示框,返回 None。
|
||||
它可只获取提示框文本而不处理提示框。
|
||||
|
||||
参数:
|
||||
|
||||
- mode:'ok' 或 'cancel',若输入其它值,不会按按钮但依然返回文本值
|
||||
- text:处理 prompt 提示框时可输入文本
|
||||
- timeout:等待提示框出现的超时时间
|
||||
|
||||
返回:提示框内容文本,未等到提示框则返回 None
|
||||
|
||||
```python
|
||||
# 确认提示框并获取提示框文本
|
||||
txt = page.process_alert()
|
||||
|
||||
# 点击取消
|
||||
page.process_alert('cancel')
|
||||
|
||||
# 给 prompt 提示框输入文本并点击确定
|
||||
paeg.process_alert('ok', 'some text')
|
||||
|
||||
# 不处理提示框,只获取提示框文本
|
||||
txt = page.process_alert(None)
|
||||
```
|
||||
|
||||
## check_page()
|
||||
|
||||
此方法用于检查页面是否符合预期,它默认返回 None,须由子类实现其功能。
|
||||
用于 POM 模式时,可派生各种页面子类,从而实现检查页面的功能。
|
149
docs/入门指南/基本概念.md
Normal file
149
docs/入门指南/基本概念.md
Normal file
@ -0,0 +1,149 @@
|
||||
本节讲解 DrissionPage 的一些基本概念。了解它大概的构成和运作原理。
|
||||
默认读者对网络协议、html、selenium、requests 等有基本认识。
|
||||
|
||||
# 网页自动化
|
||||
|
||||
网页自动化的形式通常有两种,它们各有优劣:
|
||||
|
||||
- 直接向服务器发送数据包,获取需要的数据
|
||||
- 控制浏览器跟网页进行交互
|
||||
|
||||
前者轻量级,速度快,便于多线程、分布式部署,如 requests 库。但当数据包机构复杂,甚至加入加密技术时,开发过程烧脑程度直线上升。
|
||||
|
||||
后者使用浏览器模拟人的行为,如 selenium。写起来简单得多,免去复杂的分析过程,但速度非常慢,占用资源巨大。
|
||||
|
||||
鉴于此,DrissionPage 以页面为单位将两者整合,对 selenium 和 requests 进行了重新封装,实现两种模式的互通,并加入常用的页面和元素控制功能,可大幅降低开发难度和代码量。
|
||||
selenium 用于操作浏览器的对象叫 Driver,requests 用于管理连接的对象叫 Session,Drission 就是它们两者的合体。
|
||||
|
||||
# 工作模式
|
||||
|
||||
如上所述,DrissionPage 既可控制浏览器,也可用数据包方式访问网络数据。它有两种工作方式:d 模式和 s 模式。
|
||||
页面对象可以在这两种模式间切换,两种模式拥有一致的使用方法,但任一时间只能处于其中一种模式。
|
||||
|
||||
## d 模式
|
||||
|
||||
d 模式既表示 Driver,还有 Dynamic 的意思。
|
||||
d 模式用于控制浏览器,不仅可以读取浏览器获取到的信息,还能对页面进行操作,如点击、填写、开关标签页、改变元素属性、执行 js 脚本等等。
|
||||
d 模式功能强大,但运行速度受浏览器制约非常缓慢,而且需要占用大量内存。
|
||||
|
||||
## s 模式
|
||||
|
||||
s 模式既表示 Session,还有 speed、silence 的意思。
|
||||
s 模式的运行速度比 d 模式快几个数量级,但只能基于数据包进行读取或发送,不能对页面进行操作,不能运行 js。
|
||||
爬取数据时,如网站数据包较为简单,应首选 s 模式。
|
||||
|
||||
## 模式切换
|
||||
|
||||
页面对象可以在 d 模式和 s 模式之间切换,这通常用于以下情况:
|
||||
|
||||
- 当登录验证很严格,难以解构,如有验证码的时候,用浏览器处理登录,然后转换成 s 模式爬取数据。既避免了处理烧脑的 js,又能享受 s 模式的速度。
|
||||
- 页面数据由 js 产生,且页面结构极其复杂,可以用 d 模式读取页面元素,然后把元素转成 s 模式的元素进行分析。可以极大地提高 d 模式的处理速度。
|
||||
|
||||
上述两种情况,第一种是整个页面对象进行模式转换:
|
||||
|
||||
```python
|
||||
page.change_mode()
|
||||
```
|
||||
|
||||
第二种是在 d 模式时仅对部分元素进行转换,如把表格元素转换为 s 模式的元素,在解析时速度比直接解析 d 模式元素快几个数量级。甚至可以把整个页面转换为 s 模式的元素,也是可以的。
|
||||
|
||||
```python
|
||||
# 获取页面上一个 table 元素
|
||||
ele = page.ele('tag:table')
|
||||
# 把该元素转换成 s 模式的元素
|
||||
ele = ele.s_ele()
|
||||
# 获取所有行元素
|
||||
rows = ele.eles('tag:tr')
|
||||
```
|
||||
|
||||
# 主要对象
|
||||
|
||||
## MixPage
|
||||
|
||||
顾名思义,MixPage 对象是整合了两种模式的页面对象,所有页面的跳转、读取、操作、标签页控制都由该对象进行。
|
||||
|
||||
```python
|
||||
# 创建页面对象
|
||||
page = MixPage('d')
|
||||
# 访问百度
|
||||
page.get('http://www.baidu.com')
|
||||
# 定位输入框并输入关键字
|
||||
page.ele('#kw').input('python')
|
||||
# 点击“百度一下”按钮
|
||||
page.ele('@value=百度一下').click()
|
||||
```
|
||||
|
||||
详细使用方法见“创建页面对象”和“操作页面”章节。
|
||||
|
||||
## DriverElement
|
||||
|
||||
DriverElemnet 对象是 d 模式所产生的页面元素对象,用于可对其进行点击、文本输入、拖拽、运行 js 脚本等操作,也可以基于这个元素查找其下级或周围的元素。
|
||||
|
||||
```python
|
||||
# 点击一个元素
|
||||
ele1.click()
|
||||
# 输入文本
|
||||
ele1.input('some text')
|
||||
# 获取 class 属性
|
||||
attr = ele1.attr('class')
|
||||
# 设置 style 属性
|
||||
ele1.set_attr('style', 'display:none;')
|
||||
# 获取其子元素中所有 a 元素
|
||||
links = ele1.eles('tag:a')
|
||||
```
|
||||
|
||||
详细使用方法见“获取页面元素”、“获取元素信息”和“操作页面元素”章节。
|
||||
|
||||
## SessionElement
|
||||
|
||||
SessionElement 对象是 s 模式所产生的页面元素对象,可以读取元素信息,或基于它进行下级元素查找、相对定位其它元素,但不能执行点击等操作。
|
||||
这种对象解析效率很高,当 d 模式页面太复杂时,可把 d 模式的元素转换为 SessionElement 进行解析,提高速度。转换的同时可以执行下级元素的查找。
|
||||
|
||||
```python
|
||||
# 获取元素 tag 属性
|
||||
tag = ele1.tag
|
||||
# 在元素下查找第一个 name 为 name1 的子元素
|
||||
ele2 = ele1.ele('@name=name1')
|
||||
|
||||
# 假设 d_ele 是一个 DriverElement,使用其 SessionElement 版本进行子元素查找
|
||||
ele2 = d_ele.s_ele('@name=name1')
|
||||
```
|
||||
|
||||
## Drission
|
||||
|
||||
Drission 对象用于管理与网页通讯的 WebDriver 对象和 Session 对象,相当于驱动器的角色。能实现这两个对象间的登录状态传递等。但它提供的功能往往通过 MixPage 调用,所以出场几率并不高。
|
||||
|
||||
```python
|
||||
from DrissionPage import Drission
|
||||
|
||||
# 创建 Drission 对象
|
||||
d = Drission()
|
||||
# 通过创建 MixPage 对象
|
||||
page = MixPage(drission=d)
|
||||
```
|
||||
|
||||
实际上,如果创建时不传入 Drission 对象,MixPage 会自动根据配置信息创建一个。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
# 直接创建 MixPage 对象,隐性创建 Drission 对象
|
||||
page = MixPage()
|
||||
```
|
||||
|
||||
# 结构图
|
||||
|
||||
如图所示,Drission 对象负责链接的创建、共享登录状态等工作,类似 selenium 中 driver 的概念。
|
||||
MixPage 对象负责对获取到的页面进行解析、操作。
|
||||
DriverElement 和 SessionElement 则是从页面对象中获取到的元素对象。负责对元素进行解析和操作。
|
||||
|
||||

|
||||
|
||||
# 配置管理
|
||||
|
||||
无论 requests 还是 selenium,都通常须要一些配置信息才能正常工作,如长长的 user_agent、driver 路径、浏览器配置等。这些代码往往是繁琐而重复的,不利于代码的简洁。
|
||||
因此,DrissionPage 使用配置文件记录常用配置信息,程序会自动读取默认配置文件里的内容。所以,在示例中,通常看不见配置信息的代码。
|
||||
|
||||
这个功能支持用户保存不同的配置文件,按情况调研,也可以支持直接把配置写在代码里面,屏蔽读取配置文件。
|
||||
|
||||
Tips:当须要打包程序时,必须把配置写到代码里,否则会报错。
|
137
docs/入门指南/快速上手.md
Normal file
137
docs/入门指南/快速上手.md
Normal file
@ -0,0 +1,137 @@
|
||||
# 安装
|
||||
|
||||
```
|
||||
pip install DrissionPage
|
||||
```
|
||||
|
||||
# 导入
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
```
|
||||
|
||||
# 初始化
|
||||
|
||||
s 模式是无须初始化的,导入后就可以直接使用。
|
||||
d 模式因为使用浏览器,须要配置浏览器和对应的 driver。
|
||||
|
||||
## 自动配置方式
|
||||
|
||||
身为自动化工具,DrissionPage 拥有自动识别电脑安装的 Chrome 版本并自动下载对应 chromedriver 功能。这时只要直接创建页面对象即可正常使用。
|
||||
第一次运行后,程序会记录 Chrome 和 driver 路径到配置文件,以后直接调用。
|
||||
|
||||
```python
|
||||
page = MixPage()
|
||||
page.get('https://www.baidu.com')
|
||||
```
|
||||
|
||||
## 手动配置方式
|
||||
|
||||
**注意:** 这段代码只用于设置配置文件中的路径信息,**运行一次即可**,勿写到正式程序里 。
|
||||
|
||||
有些版本的 Chrome 程序无法获取正确的 driver,就须要手动配置路径。
|
||||
新建一个**临时文件** ,修改并运行以下代码,可手动指定 Chrome 和 driver 路径,记录到配置文件,以后程序会自动读取其中的配置,无须再写。
|
||||
|
||||
如果想把配置信息写在代码里,请查阅“使用方法”里相关章节。
|
||||
|
||||
```python
|
||||
from DrissionPage.easy_set import set_paths
|
||||
|
||||
# 请将以下路径修改为本机实际路径,chrome_path多数情况下可省略
|
||||
set_paths(driver_path=r"D:\chrome\chromedriver.exe",
|
||||
chrome_path=r"D:\chrome\chrome.exe")
|
||||
```
|
||||
|
||||
当出现以下提示,说明设置成功:
|
||||
|
||||
```
|
||||
正在检测可用性...
|
||||
版本匹配,可正常使用。
|
||||
```
|
||||
|
||||
各版本 driver 下载地址:
|
||||
|
||||
- 国外:https://chromedriver.chromium.org/downloads
|
||||
- 国内:http://npm.taobao.org/mirrors/chromedriver
|
||||
|
||||
# 上手示例
|
||||
|
||||
现在,我们通过一些例子,来直观感受一下 DrissionPage 的工作方式。
|
||||
|
||||
## 爬取新冠排行榜
|
||||
|
||||
网址:https://www.outbreak.my/zh/world
|
||||
此示例爬取全球新冠情况排行榜。该网站是纯 html 页面,特别适合 s 模式爬取和解析。
|
||||
|
||||

|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
# 用 s 模式创建页面对象
|
||||
page = MixPage('s')
|
||||
# 访问数据网页
|
||||
page.get('https://www.outbreak.my/zh/world')
|
||||
|
||||
# 获取表头元素
|
||||
thead = page('tag:thead')
|
||||
# 获取表头列,跳过其中的隐藏的列
|
||||
title = thead.eles('tag:th@@-style:display: none;')
|
||||
data = [th.text for th in title]
|
||||
|
||||
print(data) # 打印表头
|
||||
|
||||
# 获取内容表格元素
|
||||
tbody = page('tag:tbody')
|
||||
# 获取表格所有行
|
||||
rows = tbody.eles('tag:tr')
|
||||
|
||||
for row in rows:
|
||||
# 获取当前行所有列
|
||||
cols = row.eles('tag:td')
|
||||
# 生成当前行数据列表(跳过其中没用的几列)
|
||||
data = [td.text for k, td in enumerate(cols) if k not in (2, 4, 6)]
|
||||
|
||||
print(data) # 打印行数据
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
['总 (205)', '累积确诊', '死亡', '治愈', '现有确诊', '死亡率', '恢复率']
|
||||
['美国', '55252823', '845745', '41467660', '12,939,418', '1.53%', '75.05%']
|
||||
['印度', '34838804', '481080', '34266363', '91,361', '1.38%', '98.36%']
|
||||
['巴西', '22277239', '619024', '21567845', '90,370', '2.78%', '96.82%']
|
||||
['英国', '12748050', '148421', '10271706', '2,327,923', '1.16%', '80.57%']
|
||||
['俄罗斯', '10499982', '308860', '9463919', '727,203', '2.94%', '90.13%']
|
||||
['法国', '9740600', '123552', '8037752', '1,579,296', '1.27%', '82.52%']
|
||||
......
|
||||
```
|
||||
|
||||
## 登录 gitee 网站
|
||||
|
||||
网址:https://gitee.com/login
|
||||
此示例演示使用控制浏览器的方式自动登录 gitee 网站。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
# 用 d 模式创建页面对象(默认模式)
|
||||
page = MixPage()
|
||||
# 跳转到登录页面
|
||||
page.get('https://gitee.com/login')
|
||||
|
||||
# 定位到账号文本框并输入账号
|
||||
page.ele('#user_login').input('你的账号')
|
||||
# 定位到密码文本框并输入密码
|
||||
page.ele('#user_password').input('你的密码')
|
||||
# 点击登录按钮
|
||||
page.ele('@value=登 录').click()
|
||||
```
|
||||
|
||||
# 说明
|
||||
|
||||
无论电脑安装的 Chrome 能否正常使用,我们都建议使用绿色版 Chrome。因为 driver 的更新速度往往跟不上浏览器的更新速度,一旦浏览器自动升级而 driver
|
||||
未出新版,就会出现无法启动的情况。所以建议用关闭升级功能的绿色版浏览器,使程序运行更稳定。
|
||||
|
||||
如果计划程序打包成 exe 文件,就不能使用默认配置文件记录配置,具体方法请查看“使用方法->打包程序”章节。
|
12
docs/入门指南/特性演示/下载文件.md
Normal file
12
docs/入门指南/特性演示/下载文件.md
Normal file
@ -0,0 +1,12 @@
|
||||
DrissionPage 带一个简便易用的下载器,一行即可实现下载功能。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
|
||||
save_path = r'C:\download'
|
||||
|
||||
page = MixPage('s')
|
||||
page.download(url, save_path)
|
||||
```
|
||||
|
39
docs/入门指南/特性演示/与requests代码对比.md
Normal file
39
docs/入门指南/特性演示/与requests代码对比.md
Normal file
@ -0,0 +1,39 @@
|
||||
以下代码实现一模一样的功能,对比两者的代码量:
|
||||
|
||||
## 获取元素内容
|
||||
|
||||
```python
|
||||
url = 'https://baike.baidu.com/item/python'
|
||||
|
||||
# 使用 requests:
|
||||
from lxml import etree
|
||||
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
|
||||
response = requests.get(url, headers = headers)
|
||||
html = etree.HTML(response.text)
|
||||
element = html.xpath('//h1')[0]
|
||||
title = element.text
|
||||
|
||||
# 使用 DrissionPage:
|
||||
page = MixPage('s')
|
||||
page.get(url)
|
||||
title = page('tag:h1').text
|
||||
```
|
||||
|
||||
**Tips:** DrissionPage 自带默认 headers
|
||||
|
||||
## 下载文件
|
||||
|
||||
```python
|
||||
url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
|
||||
save_path = r'C:\download'
|
||||
|
||||
# 使用 requests:
|
||||
r = requests.get(url)
|
||||
with open(f'{save_path}\\img.png', 'wb') as fd:
|
||||
for chunk in r.iter_content():
|
||||
fd.write(chunk)
|
||||
|
||||
# 使用 DrissionPage:
|
||||
page.download(url, save_path, 'img') # 支持重命名,处理文件名冲突
|
||||
```
|
||||
|
98
docs/入门指南/特性演示/与selenium代码对比.md
Normal file
98
docs/入门指南/特性演示/与selenium代码对比.md
Normal file
@ -0,0 +1,98 @@
|
||||
以下代码实现一模一样的功能,对比两者的代码量:
|
||||
|
||||
## 用显性等待方式查找第一个文本包含 some text 的元素。
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
element = WebDriverWait(driver).until(ec.presence_of_element_located((By.XPATH, '//*[contains(text(), "some text")]')))
|
||||
|
||||
# 使用 DrissionPage:
|
||||
element = page('some text')
|
||||
```
|
||||
|
||||
## 跳转到第一个标签页
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
driver.switch_to.window(driver.window_handles[0])
|
||||
|
||||
# 使用 DrissionPage:
|
||||
page.to_tab(0)
|
||||
```
|
||||
|
||||
## 按文本选择下拉列表
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
from selenium.webdriver.support.select import Select
|
||||
select_element = Select(element)
|
||||
select_element.select_by_visible_text('text')
|
||||
|
||||
# 使用 DrissionPage:
|
||||
element.select('text')
|
||||
```
|
||||
|
||||
## 拖拽一个元素
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
ActionChains(driver).drag_and_drop(ele1, ele2).perform()
|
||||
|
||||
# 使用 DrissionPage:
|
||||
ele1.drag_to(ele2)
|
||||
```
|
||||
|
||||
## 滚动窗口到底部(保持水平滚动条不变)
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
driver.execute_script("window.scrollTo(document.documentElement.scrollLeft, document.body.scrollHeight);")
|
||||
|
||||
# 使用 DrissionPage:
|
||||
page.scroll_to('bottom')
|
||||
```
|
||||
|
||||
## 设置 headless 模式
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
options = webdriver.ChromeOptions()
|
||||
options.add_argument("--headless")
|
||||
|
||||
# 使用 DrissionPage:
|
||||
set_headless(True)
|
||||
```
|
||||
|
||||
## 获取伪元素内容
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
text = webdriver.execute_script('return window.getComputedStyle(arguments[0], "::after").getPropertyValue("content");', element)
|
||||
|
||||
# 使用 DrissionPage:
|
||||
text = element.pseudo_after
|
||||
```
|
||||
|
||||
## 获取 shadow-root
|
||||
|
||||
新版 selenium 已可直接获取 shadow-root,但生成的 ShadowRoot 对象功能实在是太少了。
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
shadow_element = webdriver.execute_script('return arguments[0].shadowRoot', element)
|
||||
|
||||
# 使用 DrissionPage:
|
||||
shadow_element = element.shadow_root
|
||||
```
|
||||
|
||||
## 用 xpath 直接获取属性或文本节点(返回文本)
|
||||
|
||||
```python
|
||||
# 使用 selenium:
|
||||
相当复杂
|
||||
|
||||
# 使用 DrissionPage:
|
||||
class_name = element('xpath://div[@id="div_id"]/@class')
|
||||
text = element('xpath://div[@id="div_id"]/text()[2]')
|
||||
```
|
||||
|
27
docs/入门指南/特性演示/模式切换.md
Normal file
27
docs/入门指南/特性演示/模式切换.md
Normal file
@ -0,0 +1,27 @@
|
||||
用 selenium 登录网站,然后切换到 requests 读取网页。两者会共享登录信息。
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
from time import sleep
|
||||
|
||||
# 创建页面对象,默认 d 模式
|
||||
page = MixPage()
|
||||
# 访问个人中心页面(未登录,重定向到登录页面)
|
||||
page.get('https://gitee.com/profile')
|
||||
|
||||
# 使用 selenium 输入账号密码登录
|
||||
page.ele('@id:user_login').input('your_user_name')
|
||||
page.ele('@id:user_password').input('your_password\n')
|
||||
sleep(1)
|
||||
|
||||
# 切换到 s 模式
|
||||
page.change_mode()
|
||||
# 登录后 session 模式的输出
|
||||
print('登录后title:', page.title, '\n')
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
登录后title: 个人资料 - 码云 Gitee.com
|
||||
```
|
22
docs/入门指南/特性演示/获取并打印元素属性.md
Normal file
22
docs/入门指南/特性演示/获取并打印元素属性.md
Normal file
@ -0,0 +1,22 @@
|
||||
```python
|
||||
# 接上段代码
|
||||
foot = page.ele('#footer-left') # 用 id 查找元素
|
||||
first_col = foot.ele('css:>div') # 使用 css selector 在元素的下级中查找元素(第一个)
|
||||
lnk = first_col.ele('text:命令学') # 使用文本内容查找元素
|
||||
text = lnk.text # 获取元素文本
|
||||
href = lnk.attr('href') # 获取元素属性值
|
||||
|
||||
print(text, href, '\n')
|
||||
|
||||
# 简洁模式串联查找
|
||||
text = page('@id:footer-left')('css:>div')('text:命令学').text
|
||||
print(text)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Git 命令学习 https://oschina.gitee.io/learn-git-branching/
|
||||
|
||||
Git 命令学习
|
||||
```
|
243
docs/版本历史.md
Normal file
243
docs/版本历史.md
Normal file
@ -0,0 +1,243 @@
|
||||
# v2.3.0
|
||||
|
||||
- DriverPage 添加 forward() 方法
|
||||
- DriverPage 的 close_current_tab() 改为 close_tabs(),可一次过关闭多个标签页
|
||||
- DriverPage 添加 run_async_script()
|
||||
- DriverPage 添加 timeouts 属性
|
||||
- DriverPage 添加 set_timeouts() 方法
|
||||
- DriverElement 添加 scroll_to() 方法,可在元素内滑动滚动条
|
||||
- DriverOptions 添加 set_page_load_strategy() 方法
|
||||
- ini 文件增加 page_load_strategy、set_window_rect、timeouts 三个属性
|
||||
- 其它优化和问题修复
|
||||
|
||||
# v2.2.1
|
||||
|
||||
- 新增基于页面布局的相对定位方法 left(),right(),below(),above(),near(),lefts(),rights(),belows(),aboves(),nears()
|
||||
- 修改基于 DOM 的相对定位方法:删除 parents()方法,parent 属性改为 parent()方法,next 属性 改为 next() 方法,prev 属性改为 prev() 方法,nexts() 和 prevs()
|
||||
方法改为返回多个对象
|
||||
- 增加 after(),before(),afters(),before() 等基于 DOM 的相对定位方法
|
||||
- 定位语法增加 @@ 和 @@- 语法,用于同时匹配多个条件和排除条件
|
||||
- 改进 ShadowRootElement 功能,现在在 shadow-root 下查找元素可用完全版的定位语法。
|
||||
- DriverElement 的 after 和 before 属性改为 pseudo_after 和 pseudo_before
|
||||
- DriverElement 的 input() 增加 timeout 参数
|
||||
- DriverElement 的 clear() 增加 insure_clear 参数
|
||||
- 优化 DriverElement 的 submit() 方法
|
||||
- DriverPage 增加 active_ele 属性,获取焦点所在元素
|
||||
- DriverPage 的 get_style_property() 改名为 style()
|
||||
- DriverPage 的 hover() 增加偏移量参数
|
||||
- DriverPage 的 current_tab_num 改名为 current_tab_index
|
||||
- DriverPage 的 to_frame() 方法返回页面对象自己,便于链式操作
|
||||
- 优化自动下载 driver 逻辑
|
||||
- set_paths() 增加 local_port 参数
|
||||
- 默认使用 9222 端口启动浏览器
|
||||
- 其它优化和问题修复
|
||||
|
||||
# v2.0.0
|
||||
|
||||
- 支持从 DriverElement 或 html 文本生成 SessionElement,可把 d 模式的页面信息爬取速度提高几个数量级(使用新增的 s_ele() 和 s_eles() 方法)
|
||||
- 支持随时隐藏和显示浏览器进程窗口(只支持 Windows 系统)
|
||||
- s 模式和 d 模式使用相同的提取文本逻辑,d 模式提取文本效率大增
|
||||
- input() 能自动检测以确保输入成功
|
||||
- click() 支持失败后不断重试,可用于确保点击成功及等待页面遮罩层消失
|
||||
- 对 linux 和 mac 系统路径问题做了修复
|
||||
- download() 能更准确地获取文件名
|
||||
- 其它稳定性和效率上的优化
|
||||
|
||||
# v1.11.7
|
||||
|
||||
- SessionOptions 增加 set_headers()
|
||||
- 调整 MixPage 初始化参数
|
||||
- click() 增加 timeout 参数,修改逻辑为在超时时间内不断重试点击。可用于监视遮罩层是否消失
|
||||
- 处理 process_alert() 增加 timeout 参数
|
||||
- 其他优化和问题修复
|
||||
|
||||
# v1.11.0
|
||||
|
||||
- set_property 属性改名为 set_prop
|
||||
- 增加 prop()
|
||||
- clear() 改用 selenium 原生
|
||||
- 增加 r_click() 和 r_click_at()
|
||||
- input() 返回 None
|
||||
- 增加 input_txt()
|
||||
|
||||
# v1.10.0
|
||||
|
||||
- 优化启动浏览器的逻辑
|
||||
- 用 debug 模式启动时可读取启动参数
|
||||
- 完善 select 标签处理功能
|
||||
- MixPage 类的 to_iframe() 改名为 to_frame()
|
||||
- MixPage 类的 scroll_to() 增加 'half' 方式,滚动半页
|
||||
- Drission 类增加 kill_browser() 方法
|
||||
|
||||
# v1.9.0
|
||||
|
||||
- 元素增加 click_at() 方法,支持点击偏移量
|
||||
- download() 支持重试
|
||||
- 元素 input() 允许接收组合键,如 ctrl+a
|
||||
- 其它优化
|
||||
|
||||
# v1.8.0
|
||||
|
||||
- 添加 retry_times 和 retry_interval 属性,可统一指定重连次数
|
||||
- 元素对象增加 raw_text 属性
|
||||
- 元素查找字符串支持极简模式,用 x 表示 xpath、c 表示 css、t 表示 tag、tx 表示 text
|
||||
- s 模式元素 text 尽量与 d 模式保持一致
|
||||
- 其它完善和问题修复
|
||||
|
||||
# v1.7.7
|
||||
|
||||
- 创建 driver 时可自动下载 chromedriver.exe
|
||||
- 修复获取不到 content-type 时会出现的问题
|
||||
|
||||
# v1.7.1
|
||||
|
||||
- d 模式如指定了调试端口,可自动启动浏览器进程并接入
|
||||
- 去除对 cssselect 库依赖
|
||||
- 提高查找元素效率
|
||||
- 调整获取元素 xpath 和 css_path 逻辑
|
||||
|
||||
# v1.7.0
|
||||
|
||||
- 优化 cookies 相关逻辑
|
||||
- MixPage 增加 get_cookies() 和 set_cookies() 方法
|
||||
- 增加 SessionOptions 类
|
||||
- 浏览文件 DriverElement 增加 remove_attr() 方法
|
||||
- 修复 MixPage 初始化时 Session 导入 cookies 时的问题
|
||||
- MixPage 的 close_other_tabs() 方法现在可以接收列表或元组以保留多个 tab
|
||||
- 其它优化
|
||||
|
||||
# v1.6.1
|
||||
|
||||
- 增加 . 和 # 方式用于查找元素,相当于 @Class 和 @id
|
||||
- easy_set 增加识别 chrome 版本并自动下载匹配的 driver 功能
|
||||
- 改进配置功能
|
||||
- 修复 shadow-root 方面的问题
|
||||
|
||||
# v1.5.4
|
||||
|
||||
- 优化获取编码的逻辑
|
||||
- 修复下载不能显示进度的问题
|
||||
|
||||
# v1.5.2
|
||||
|
||||
- 修复获取 html 时会把元素后面的文本节点带上的问题
|
||||
- 修复获取编码可能出现的错误
|
||||
- 优化 download() 和获取编码代码
|
||||
|
||||
# v1.5.1
|
||||
|
||||
- 修复获取编码可能出现的 bug
|
||||
|
||||
# v1.5.0
|
||||
|
||||
- s 模式使用 lxml 库代替 requests_html 库
|
||||
- 可直接调用页面对象和元素对象获取下级元素,element('@id=ele_id') 等价于element.ele('@id=ele_id')
|
||||
- nexts()、prevs() 方法可获取文本节点
|
||||
- 可获取伪元素属性及文本
|
||||
- 元素对象增加 link 和 inner_html 属性
|
||||
- 各种优化
|
||||
|
||||
# v1.4.0
|
||||
|
||||
- d 模式使用 js 通过 evaluate 方法处理 xpath,放弃使用 selenium 原生的方法,以支持用 xpath 直接获取文本节点、元素属性
|
||||
- d 模式增加支持用 xpath 获取元素文本、属性
|
||||
- 优化和修复小问题
|
||||
|
||||
# v1.3.0
|
||||
|
||||
- 可与 selenium 代码无缝对接
|
||||
- 下载功能支持 post 方式
|
||||
- 元素添加 texts 属性,返回元素内每个文本节点内容
|
||||
- s 模式增加支持用 xpath 获取元素文本、属性
|
||||
|
||||
# v1.2.1
|
||||
|
||||
- 优化修复网页编码逻辑
|
||||
- download 函数优化获取文件名逻辑
|
||||
- 优化 download() 获取文件大小逻辑
|
||||
- 优化 MixPage 对象关闭 session 逻辑
|
||||
|
||||
# v1.2.0
|
||||
|
||||
- 增加对 shadow-root 的支持
|
||||
- 增加自动重试连接功能
|
||||
- MixPage 可直接接收配置
|
||||
- 修复一些 bug
|
||||
|
||||
# v1.1.3
|
||||
|
||||
- 连接有关函数增加是否抛出异常参数
|
||||
- session 模式判断编码优化
|
||||
- driver 模式 check_page() 优化
|
||||
- 修复 run_script() 遗漏 args 参数的问题
|
||||
|
||||
# v1.1.1
|
||||
|
||||
- 删除 get_tabs_sum() 和 get_tab_num() 函数,以属性 tabs_count 和 current_tab_num 代替
|
||||
- 增加 current_tab_handle、tab_handles 属性
|
||||
- to_tab() 和 close_other_tabs() 函数可接收 handle 值
|
||||
- create_tab 可接收一个 url 在新标签页打开
|
||||
- 其它优化和 bug 修复
|
||||
|
||||
# v1.1.0
|
||||
|
||||
- 元素对象增加 xpath 和 css path 路径属性
|
||||
- 修复 driver 模式下元素对象用 css 方式不能获取直接子元素的问题(selenium 的锅)
|
||||
- session 模式下现在能通过 xpath 定位上级元素
|
||||
- 优化 driver 模式兄弟元素、父级元素的获取效率
|
||||
- 优化标签页处理功能
|
||||
- 其它小优化和修复
|
||||
|
||||
# V1.0.5
|
||||
|
||||
- 修复切换模式时 url 出错的 bug
|
||||
|
||||
# V1.0.3
|
||||
|
||||
- DriverOptions 支持链式操作
|
||||
- download 函数增加参数处理遇到已存在同名文件的情况,可选跳过、覆盖、自动重命名
|
||||
- download 函数重命名调整为只需输入文件名,不带后缀名,输入带后缀名也可自动识别
|
||||
|
||||
# V1.0.1
|
||||
|
||||
- 增强拖拽功能和 chrome 设置功能
|
||||
|
||||
# V0.14.0
|
||||
|
||||
- Drission 类增加代理设置和修改
|
||||
|
||||
# V0.12.4
|
||||
|
||||
- click() 的 by_js 可接收 False
|
||||
- 修复一些 bug
|
||||
|
||||
# V0.12.0
|
||||
|
||||
- 增加 tag:tagName@arg=val 查找元素方式
|
||||
- MixPage 增加简易方式创建对象方式
|
||||
|
||||
# V0.11.0
|
||||
|
||||
- 完善 easy_set 的函数
|
||||
- 元素增加多级定位函数
|
||||
|
||||
# v0.10.2
|
||||
|
||||
- 完善 attr 及 attrs 功能
|
||||
|
||||
# v0.10.1
|
||||
|
||||
- 增加 set_headless 以及 to_iframe 兼容全部原生参数
|
||||
|
||||
# v0.9.4
|
||||
|
||||
- 修复 bug
|
||||
|
||||
# v0.9.0
|
||||
|
||||
- 增加了元素拖拽和处理提示框功能
|
||||
|
||||
# v0.8.4
|
||||
|
||||
- 基本完成
|
||||
|
64
docs/简介.md
Normal file
64
docs/简介.md
Normal file
@ -0,0 +1,64 @@
|
||||
DrissionPage,即 driver 和 session 组合而成的 page。
|
||||
是个基于 python 的 Web 自动化操作集成工具。
|
||||
它用 POM 模式封装了页面和元素常用的方法,
|
||||
自带一套简洁直观优雅的元素定位语法,
|
||||
实现了 selenium 和 requests 之间的无缝切换,
|
||||
可兼顾 selenium 的便利性和 requests 的高效率,
|
||||
更棒的是,它的使用方式非常简洁和人性化,代码量少,对新手友好。
|
||||
|
||||
**项目地址:**
|
||||
|
||||
- https://github.com/g1879/DrissionPage
|
||||
- https://gitee.com/g1879/DrissionPage
|
||||
|
||||
**联系邮箱:** g1879@qq.com **QQ交流群:** 897838127
|
||||
|
||||
# 背景
|
||||
|
||||
requests 爬虫面对要登录的网站时,要分析数据包、JS 源码,构造复杂的请求,往往还要应付验证码、JS 混淆、签名参数等反爬手段,门槛较高。若数据是由 JS 计算生成的,还须重现计算过程,体验不好,开发效率不高。
|
||||
使用 selenium,可以很大程度上绕过这些坑,但 selenium 效率不高。因此,这个库将 selenium 和 requests 合而为一,不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
|
||||
除了合并两者,本库还以网页为单位封装了常用功能,简化了 selenium 的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。
|
||||
|
||||
# 特性
|
||||
|
||||
- 代码高度集成,以简洁的代码为第一追求。
|
||||
- 页面对象可在 selenium 和 requests 模式间任意切换,保留登录状态。
|
||||
- 极简单但强大的元素定位语法,支持链式操作,代码极其简洁。
|
||||
- 两种模式提供一致的 API,使用体验一致。
|
||||
- 使用 POM 模式封装,便于扩展。
|
||||
- 兼容 selenium 代码,便于项目迁移。
|
||||
- 人性化设计,集成众多实用功能,大大降低开发工作量。
|
||||
|
||||
# 亮点功能
|
||||
|
||||
作者有多年自动化和爬虫经验,踩过无数坑,总结出的经验全写到这个库里。内置了N多实用功能,对常用功能作了整合和优化。使用时可以更专注业务逻辑,减少重复操作。大概罗列一下:
|
||||
|
||||
- 每次运行程序可以反复使用已经打开的浏览器。如手动设置网页到某个状态,再用程序接管,或手动处理登录,再用程序爬内容。无须每次运行从头启动浏览器,超级方便。
|
||||
- 使用 ini 文件保存常用配置,自动调用,也提供便捷的设置api,远离繁杂的配置项。
|
||||
- 极致简明的定位语法,支持直接按文本定位元素,支持极其灵活的相对定位方法。
|
||||
- 强大的下载工具,操作浏览器时也能享受快捷可靠的下载功能。
|
||||
- 下载工具支持多种方式处理文件名冲突、自动创建目标路径、断链重试等。
|
||||
- 访问网址带自动重试功能,可设置间隔和超时时间。
|
||||
- 访问网页能自动识别编码,无须手动设置。
|
||||
- 链接参数默认自动生成 Host 和 Referer 属性。
|
||||
- 可随时直接隐藏或显示浏览器进程窗口,非 headless 或最小化。
|
||||
- 可自动下载合适版本的 chromedriver,免去麻烦的配置。
|
||||
- d 模式查找元素内置等待,可任意设置全局等待时间或单次查找等待时间。
|
||||
- 点击元素集成 js 点击方式,一个参数即可切换点击方式。
|
||||
- 点击支持失败重试,可用于保证点击成功、判读网页遮罩层是否消失等。
|
||||
- 输入文本能自动判断是否成功并重试,避免某些情况下输入或清空失效的情况。
|
||||
- d 模式下支持全功能的 xpath,可直接获取元素的某个属性,selenium 原生无此功能。
|
||||
- 支持直接获取 shadow-root,和普通元素一样操作其下的元素。
|
||||
- 支持直接获取 after 和 before 伪元素的内容。
|
||||
- 可以在元素下直接使用 > 以 css selector 方式获取当前元素直接子元素。原生不支持这种写法。
|
||||
- 可简单地使用 lxml 来解析 d 模式的页面或元素,爬取复杂页面数据时速度大幅提高。
|
||||
- 输出的数据均已转码及处理基本排版,减少重复劳动。
|
||||
- 可方便地与 selenium 或 requests 原生代码对接,便于项目迁移。
|
||||
- 使用 POM 模式封装,可直接用于测试,便于扩展。
|
||||
- d 模式配置可同时兼容 debugger 和其它参数,原生不能兼容。
|
||||
- 还有很多这里不一一列举…………
|
||||
|
||||
# 免责声明
|
||||
|
||||
请勿将 DrissionPage 应用到任何可能会违反法律规定和道德约束的工作中,请友善使用 DrissionPage,遵守蜘蛛协议,不要将 DrissionPage 用于任何非法用途。如您选择使用 DrissionPage
|
||||
即代表您遵守此协议,作者不承担任何由于您违反此协议带来任何的法律风险和损失,一切后果由您承担。
|
4
docs/鸣谢.md
Normal file
4
docs/鸣谢.md
Normal file
@ -0,0 +1,4 @@
|
||||
- 剩爪(感谢建群)
|
||||
- 激石网页设计-小徐(感谢找bug和提建议)
|
||||
- Bumblebee47大怪兽47(感谢测试)
|
||||
- kkjj828(感谢建议)
|
Loading…
x
Reference in New Issue
Block a user