DrissionPage官网:https://drissionpage.cn/
DrissionPage开源项目: https://github.com/g1879/DrissionPage 、 https://gitee.com/g1879/DrissionPage
# drissionpage
# https://drissionpage.cn/
# https://github.com/g1879/DrissionPage
# https://gitee.com/g1879/DrissionPage
# edge://version/
# 🌏 安装
# ✅️️ 运行环境
# 操作系统:Windows、Linux 或 Mac。
# python 版本:3.6 及以上
# 支持浏览器:Chromium 内核(如 Chrome 和 Edge)
# ✅️️ 安装
# 请使用 pip 安装 DrissionPage:
# pip install DrissionPage
# ✅️️ 升级
# 📌 升级最新稳定版
# pip install DrissionPage --upgrade
# 📌 指定版本升级
# pip install DrissionPage==4.0.0b17
# https://drissionpage.cn/get_start/import
# 🌏 导入
# ✅️ 页面类
# 页面类是最主要的工具,用于控制浏览器或收发数据包。
# DrissionPage 包含三种主要页面类。根据需要在其中选择使用。
# 📌 ChromiumPage
# 如果只要控制浏览器,导入ChromiumPage。
# from DrissionPage import ChromiumPage
# 导入模块
from DrissionPage import ChromiumPage, ChromiumOptions
# 创建ChromiumPage对象,设置浏览器路径
co = ChromiumOptions().set_paths(browser_path=r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
page = ChromiumPage(co)
# 访问网页,设置访问超时时间
page.get('http://g1879.gitee.io/DrissionPageDocs', retry=3, interval=2, timeout=15)
# 案例1
print(f">>>>>>>>\n当前对象控制的页面地址和端口:{page.address}\n浏览器请求头:{page.user_agent}\n是否正在加载状态{page.is_loading}{page.states.ready_state}")
# 获取id="-概述"的元素HTML内容
# overview_xpath_1 = 'x://*[contains(@id, "-概述")]'
# overview_html_1 = page.ele(overview_xpath_1).html
# print(">>>>>>>>>\n当前概述html:", overview_html_1)
# xpath的使用
# overview_xpath_2 = "x://*[contains(@class, 'announcementBar_mb4j')]"
# overview_html_2 = page.ele(overview_xpath_2).html
# print(">>>>>>>>>\n当前页面源代码:", page.html)
print(">>>>>>>>>\n当前版本信息text:", page.ele("x://p[contains(text(), '最新版本')]").text)
print(">>>>>>>>>\ngit链接:", page.ele("x://p[contains(text(), '项目地址')]/a").attr("href"))
page.close()
Xpath使用
使用XPATH有如下几种方法定位元素(相比CSS选择器,方法稍微多一点):
- a、通过绝对路径定位元素(不推荐!)
WebElement ele = driver.findElement(By.xpath("html/body/div/form/input")); - b、通过相对路径定位元素
WebElement ele = driver.findElement(By.xpath("//input")); - c、使用索引定位元素
WebElement ele = driver.findElement(By.xpath("//input[4]")); - d、使用XPATH及属性值定位元素
WebElement ele = driver.findElement(By.xpath("//input[@id='fuck']"));
//其他方法(看字面意思应该能理解吧)
WebElement ele = driver.findElement(By.xpath("//input[@type='submit'][@name='fuck']"));
WebElement ele = driver.findElement(By.xpath("//input[@type='submit' and @name='fuck']"));
WebElement ele = driver.findElement(By.xpath("//input[@type='submit' or @name='fuck']")); - e、使用XPATH及属性名称定位元素
元素属性类型:@id 、@name、@type、@class、@tittle
//查找所有input标签中含有type属性的元素
WebElement ele = driver.findElement(By.xpath("//input[@type]")); - f、部分属性值匹配
WebElement ele = driver.findElement(By.xpath("//input[start-with(@id,'fuck')]"));//匹配id以fuck开头的元素,id='fuckyou'
WebElement ele = driver.findElement(By.xpath("//input[ends-with(@id,'fuck')]"));//匹配id以fuck结尾的元素,id='youfuck'
WebElement ele = driver.findElement(By.xpath("//input[contains(@id,'fuck')]"));//匹配id中含有fuck的元素,id='youfuckyou' - g、使用任意值来匹配属性及元素
WebElement ele = driver.findElement(By.xpath("//input[@*='fuck']"));//匹配所有input元素中含有属性的值为fuck的元素
元素定位总结
三大模式
C模式——操纵浏览器
# 操控浏览器
# 导入模块
from DrissionPage import ChromiumPage, ChromiumOptions
# 创建ChromiumPage对象,设置浏览器路径
co = ChromiumOptions().set_paths(browser_path=r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
page = ChromiumPage(co)
# 页面分析,网址:https://gitee.com/login
# 打开网址,按F12,我们可以看到页面 html,找到用户名\密码\登录按钮的xpath
page.get('https://gitee.com/login')
# 定位到账号文本框,获取文本框元素
ele = page.ele('#user_login')
# 输入对文本框输入账号
ele.input('您的账号')
# 定位到密码文本框并输入密码
page.ele('#user_password').input('您的密码')
# 点击登录按钮
page.ele('@value=登 录').click()
S模式——收发数据包
# 收发数据包
# 导入模块
from DrissionPage import SessionPage
# 创建页面对象
page = SessionPage()
# 爬取3页
for i in range(1, 4):
# 访问某一页的网页
page.get(f'https://gitee.com/explore/all?page={i}')
# 获取所有开源库<a>元素列表
# 从 html 代码中可以看到,所有开源项目的标题都是class属性为'title project-namespace-path'的<a>元素。我们可以遍历这些<a>元素,获取它们的信息。
links = page.eles('.title project-namespace-path')
# 遍历所有<a>元素
for link in links:
# 打印链接信息
print(link.text, link.link)
W模式——模式切换
# 模式切换
# 这个示例演示WebPage如何切换控制浏览器和收发数据包两种模式。
# 通常,切换模式是用来应付登录检查很严格的网站,可以用浏览器处理登录,再转换模式用收发数据包的形式来采集数据。
# 但是这种场景需要有对应的账号,不便于演示。演示使用浏览器在 gitee 搜索,然后转换到收发数据包的模式来读取数据。虽然此示例现实使用意义不大,但可以了解其工作模式。
# 导入模块
from DrissionPage import WebPage, ChromiumOptions, SessionOptions
# 创建WebPage对象,设置浏览器路径
co = ChromiumOptions().set_paths(browser_path=r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
so = SessionOptions()
page = WebPage(chromium_options=co, session_or_options=so)
# 创建页面对象
page = WebPage()
# 访问网址
page.get('https://gitee.com/explore')
# 查找文本框元素并输入关键词
# 输入框<input>元素id属性为'q',搜索按钮<button>元素文本包含'搜索'文本,可用来作条件查找元素
page('#q').input('DrissionPage')
# 点击搜索按钮
page('t:button@tx():搜索').click()
# 等待页面加载
page.wait.load_start()
# 切换到收发数据包模式
page.change_mode()
# 获取所有行元素
# 通过分析 html 代码,我们可以看出,每个结果的标题都存在id为'hits-list'里面,class为'item'的元素中。因此,我们可以获取页面中所有这些元素,再遍历获取其信息。
items = page('#hits-list').eles('.item')
# 遍历获取到的元素
for item in items:
# 打印元素文本
print(item('.title').text)
print(item('.desc').text)
print()
# 关闭页面
page.close()
标签页功能
# 以哔哩哔哩搜索并获取搜索结果的标题为例
# 导入模块
from DrissionPage import WebPage, ChromiumOptions, SessionOptions
import pandas as pd
# 创建ChromiumPage对象,设置浏览器路径
co = ChromiumOptions().set_paths(browser_path=r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
page = ChromiumOptions(co)
so = SessionOptions()
page = WebPage(chromium_options=co, session_or_options=so)
# 页面分析,网址:https://www.bilibili.com/
page.get('https://www.bilibili.com/')
# 定位到搜索文本框,获取文本框元素
search_ele = page.ele("x://input[contains(@class, 'nav-search-input')]")
# 输入对文本框输入搜索信息
search_ele.input("BUCCHIGIRI 杂谈")
# 模拟点击搜索按钮
tab = page.ele('x://div[contains(@class, "nav-search-btn")]').click.for_new_tab()
# 切换到收发数据包模式
tab.change_mode()
# 获取所有标题元素
items_path = "x://h3[contains(@class, 'bili-video-card__info--tit')]"
items = tab.eles(items_path)
links_path = "x://div[contains(@class, 'bili-video-card__info--right')]//a"
links = tab.eles(links_path)
# 定义一个空列表来存放元素文本
text_list = []
# 遍历获取到的元素
for item in items:
# 打印元素文本
print(item.text)
print()
# 将元素文本添加到列表中
text_list.append(item.text)
# 筛选出包含"www"的链接,打印链接文本,并存入列表中
link_list = []
for link in links:
if "www" in link.attr("href"):
link_list.append(link.attr("href"))
# 打印筛选后的链接列表
for www_link in link_list:
print(www_link)
# 创建Pandas DataFrame,这里假设只有一个文本列
df = pd.DataFrame({"Text": text_list},{"link": link_list})
# 保存到CSV文件,文件名为"output.csv",位于当前工作目录下
csv_file_path = "20240416爬虫实践output.csv"
df.to_csv(csv_file_path, index=False)
print(f"Element texts saved to {csv_file_path}")
# 遍历 link_list
for link in link_list:
# 创建对象,设置浏览器路径
page = SessionPage()
# 打开当前链接
page.get(link)
# 获取播放量元素,如果不能获取则填入空数据
views_path = "x://div[contains(@class, 'view-text')]"
view = page.ele(views_path)
if view:
view_list.append(view.text)
else:
view = "error"
view_list.append(view)
# 获取弹幕量元素,如果不能获取则填入空数据
dms_path = "x://div[contains(@class, 'dm-text')]"
dm = page.ele(dms_path)
if dm:
dm_list.append(dm.text)
else:
dm = "error"
dm_list.append(dm)
# 获取时间元素,如果不能获取则填入空数据
times_path = "x://div[contains(@class, 'pubdate-ip-text')]"
times = page.ele(times_path)
if times:
time_list.append(times.text)
else:
times = "error"
time_list.append(times)
# 获取点赞元素,如果不能获取则填入空数据
likes_path = "x://span[contains(@class, 'video-like-info video-toolbar-item-text')]"
like = page.ele(likes_path)
if like:
like_list.append(like.text)
else:
like = "error"
like_list.append(like)
# 获取投币元素,如果不能获取则填入空数据
coins_path = "x://span[contains(@class, 'video-coin-info video-toolbar-item-text')]"
coin = page.ele(coins_path)
if coin:
coin_list.append(coin.text)
else:
coin = "error"
coin_list.append(coin)
# 获取收藏元素,如果不能获取则填入空数据
collects_path = "x://span[contains(@class, 'video-fav-info video-toolbar-item-text')]"
collect = page.ele(collects_path)
if collect:
collect_list.append(collect.text)
else:
collect = "error"
collect_list.append(collect)
# 获取转发元素,如果不能获取则填入空数据
forwards_path = "x://div[contains(@class, 'video-share-info video-toolbar-item-text')]//span"
forward = page.ele(forwards_path)
if forward:
forward_list.append(forward.text)
else:
forward = "error"
forward_list.append(forward)
print('forward error')
# 获取评论元素,如果不能获取则填入空数据
comments_path = "//li[contains(@class, 'nav-title')]//span[2]"
comment = page.ele(comments_path)
if comment:
comment_list.append(comment.text)
else:
comment = "error"
comment_list.append(comment)
print('comment error')
# 延迟1秒
page.wait(1)
print("Loop continues.")
print("Loop finished.")
# 关闭新标签页
tab.close()
# 如果需要,可以继续操作原页面或关闭原页面(此处假设关闭原页面)
page.close()
# # 创建Pandas DataFrame,每个列表作为一列
# df = pd.DataFrame({
# "Title": title_list,
# "Views": view_list,
# "Dm": dm_list,
# "Time": time_list,
# "Likes": like_list,
# "Coins": coin_list,
# "Collects": collect_list,
# "Comments": comment_list,
# "Forwards": forward_list
# })
# # 保存到CSV文件,文件名为"output.csv",位于当前工作目录下
# csv_file_path = "20240416爬虫实践output_202404171915.csv"
# df.to_csv(csv_file_path, index=False)
# print(f"Element texts saved to {csv_file_path}")
# # 从csv文件中读取标题和链接列表
# df = pd.read_csv('bilibili.csv')
# link_list = df['Link'].tolist()
# title_list = df['Title'].tolist()