DrissionPage使用

学习目标:

  1. 掌握 DrissionPage基本使用
  2. 掌握 动态数据筛选
  3. 掌握 元素定位与交互方法

DrissionPage是自动化工具,DrissionPage不需要安装驱动,他是直接作用于浏览器,也同样的可以对浏览器操作,还可以直接监听动态接口可以直接获取动态接口.

一. 准备工作

pip install DrissionPage

DrissionPage访问模式有 3 种,它们通常是程序的入口:

  • ChromiumPage:单纯用于操作浏览器的页面对象
  • WebPage:整合浏览器控制和收发数据包于一体的页面对象(不做重点学习)
  • SessionPage:单纯用于收发数据包的页面对象(类似于requests发请求)

二. ChromiumPage

ChromiumPage对象和WebPage对象的 driver 模式,可操控浏览器。

1. 打开浏览器

# 导入 ChromiumOptions
from DrissionPage import ChromiumPage, ChromiumOptions

# 创建浏览器配置对象,指定浏览器路径(目前可以用edg和Chrome浏览器)
co = ChromiumOptions().set_browser_path(r'C:\Program Files\Google\Chrome\Application\chrome.exe')
# 用该配置创建页面对象
page = ChromiumPage(addr_or_opts=co)

2. 访问页面

from DrissionPage import ChromiumPage

page = ChromiumPage()
page.get('https://www.baidu.com', retry=1, interval=1, timeout=1.5)
print(page.html)  # html页面
print(page.user_agent)
print(page.browser_version)

3. 初始化配置

from DrissionPage import ChromiumOptions, ChromiumPage

co = ChromiumOptions()

# 设置启动时最大化
co.set_argument('--start-maximized')
# 设置初始窗口大小
co.set_argument('--window-size', '800,600')
# 设置代理
co.set_proxy('http://localhost:1080')
# 设置不加载图片、静音
co.no_imgs(True).mute(True)
# 是否网址静音
co.mute(True)
# co.headless()  # 无头模式
page = ChromiumPage(co)
# dict格式 请求头设置
h = {'User-Agent':"4355",'connection': 'keep-alive', 'accept-charset': 'GB2312,utf-8;q=0.7,*;q=0.7', 'abc':'123324'}
page.set.headers(headers=h)
page.get('https://www.baidu.com')

page.set.window.mini()  # 小化窗口
page.set.window.max()
page.set.window.size(500, 500) # 设置窗口大小
# 此方法用于隐藏浏览器窗口。 与 headless 模式不一样,这个方法是直接隐藏浏览器进程。在任务栏上也会消失。只支持 Windows 系统,并且必需已安装 pypiwin32 库才可使用。
page.set.window.hide()
# 显示窗口
page.set.window.show()

# 此方法用于隐藏浏览器窗口。 与 headless 模式不一样,这个方法是直接隐藏浏览器进程。在任务栏上也会消失。只支持 Windows 系统,并且必需已安装 pypiwin32 库才可使用。
page.set.window.hide()
# 显示窗口
page.set.window.show()

4. 元素定位

  • 页面对象和元素对象都拥有ele()eles()方法,用于获取其内部指定子元素。
  • ele(): 用于定位单个的页面元素。
  • eles():用于定位一组页面元素,获取到的是一组列表。
  • DrissionPage 有自己单独的一套匹配规则,学习成本较高,可以直接把Selenium的匹配方法平移过来使用,可以节省学习成本
from DrissionPage import ChromiumPage
from DrissionPage.common import By

page = ChromiumPage()
page.get('https://www.baidu.com')
page.set.window.max()
page.ele((By.NAME, 'wd')).input('你好')
page.ele((By.ID, 'su')).click()
  • 多节点匹配
from DrissionPage import ChromiumPage
from DrissionPage.common import By

page = ChromiumPage()
page.get('https://www.baidu.com')
# 检测元素是否加载
aa = page.wait.eles_loaded('#su', timeout=2)
print(aa)
a_list = page.eles((By.XPATH, '//a'))

for a in a_list:
    print(a.text, a.attr('href'))

5.IFrame切换

from DrissionPage import ChromiumPage
from DrissionPage.common import By

page = ChromiumPage()
page.get('https://www.douban.com/')
print(page.ele((By.CLASS_NAME, 'account-form-label')).text)


6. 数据监听


from DrissionPage import ChromiumPage
from DrissionPage.common import By

page = ChromiumPage()
page.get('https://www.ccgp-anhui.gov.cn/site/category?parentId=smNINUwLp%2F04p2g1rUM89Q%3D%3D&childrenCode=anhuiCategory102&utm=site.site-PC-4721.564-pc-websitegroup-nav-front.4.1fff03802d4e11ef96d08f4b994d45f1')
page.listen.start('/portal/category')
page.set.window.max()
# 检测元素是否加载
# aa = page.wait.eles_loaded('.list', timeout=2)
# print(page.listen.steps())
# count 需捕获的数据包总数,为None表示无限
# listen.steps获取的是迭代器
for packet in page.listen.steps(count=4):
    print(packet.response.body)
    page.ele((By.CSS_SELECTOR, '.btn-next i')).click()

7.动作链


from DrissionPage import ChromiumPage
from DrissionPage.common import By


page = ChromiumPage()
page.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
source = page.ele((By.CLASS_NAME, 'ui-draggable'))
target = page.ele((By.CLASS_NAME, 'ui-droppable'))
page.actions.hold(source).release(target)

  • 验证码拖动
from DrissionPage import ChromiumPage
from DrissionPage.common import By

page = ChromiumPage()
page.get('https://www.ynjzjgcx.com/dataPub/enterprise')

# 左键按住元素
page.actions.hold(page.ele((By.CLASS_NAME, 'slide-verify-slider-mask-item')))
# 向右移动鼠标300像素
page.actions.right(300)
# 释放左键
page.actions.release()

三. SessionPage

  • 单纯用于收发数据包的页面对象(类似于requests发请求)

1. post请求

from DrissionPage import SessionPage

page = SessionPage()
data = {
    "recruitType": "SOCIAL",
    "pageSize": "10",
    "keyWord": "python",
    "curPage": "2",
    "projectType": ""
}
page.post('https://talent.baidu.com/httservice/getPostListNew', data=data)

print(page.response.json())

四. WebPage

WebPage对象整合了SessionPageChromiumPage,实现了两者之间的互通。 (不做重点学习)

五. 案例


from DrissionPage import ChromiumPage
import pymongo
from DrissionPage.common import By


class DouDing():
    def __init__(self):
        self.url = 'https://kaoyan.docin.com/pdfreader/web/#/docin/documents?type=1&keyword=%E5%A4%8D%E8%AF%95%E4%BB%BF%E7%9C%9F%E6%A8%A1%E6%8B%9F'
        self.page = ChromiumPage()
        self.page.listen.start('api/web/document/list')
        self.cli = pymongo.MongoClient(host='127.0.0.1')
        self.cll = self.cli['spiders16']['yibao']

    def get_data(self):
        self.page.get(self.url)
        for i in self.page.listen.steps(count=10):
            self.parse_data(i.response.body)
            self.page.ele((By.CLASS_NAME, 'btn-next')).click()

    def parse_data(self, data):
        for i in data['Data']['DocumentInfos']:
            item = {}
            item['DocumentGuid'] = i['DocumentGuid']
            item['DocumentName'] = i['DocumentName']
            item['DocumentPrice'] = i['DocumentPrice']
            self.save_data(item)

    def save_data(self, item):
        print(item)
        self.cll.insert_one(item)

    def main(self):
        self.get_data()


if __name__ == '__main__':
    dd = DouDing()
    dd.main()