01-selenium

本文我们来一起学习一下selenium自动化,先讲解一下selenium在爬虫中的运用场景,当目标网站因 JS 动态渲染、交互依赖、反爬限制等特性,导致静态爬虫(如 requests)无法直接获取数据时,可以使用Selenium

模拟人使用浏览器的操作来获取数据,了解了这些,下面就开始学习如何使用吧,先配置一下这个环境:

下载第三方库

python 复制代码
# 推荐下载4.9.1
pip install selenium==4.9.1

下载浏览器驱动

我以Edge浏览器为例:

  • 步骤一, 查浏览器版本:
    • 打开 Edge → 右上角三点 → 帮助和反馈 → 关于 Microsoft Edge
  • 步骤二,找对应版本的驱动并下载:
  • 步骤三,写入Path或者手动指定:
    • 可以写入系统路径然后每次程序运行自动搜索,但是每次更新都要升级,或者重新下载
    • 或者运行程序时通过代码指定驱动路径:
python 复制代码
from selenium import webdriver
from selenium.webdriver.edge.service import Service  # 导入Service类

# 1. 指定EdgeDriver的本地路径(换成你实际放的路径)
edge_driver_path = r"D:\drivers\msedgedriver.exe"  # r前缀避免转义问题
service = Service(executable_path=edge_driver_path)

# 2. 初始化Edge选项(保持你原来的options)
options = webdriver.EdgeOptions()

# 3. 启动驱动时传入service
driver = webdriver.Edge(service=service, options=options)

# 后面写正常代码...(打开浏览器等)

做完以上两点基本就算配置好了,本人不经常用,而且配置不算难,再者就是DP个人觉得完全可以替代selenium,所以写的稍显粗浅,本文重点主要是了解一下语法方便后续学习DP(下一文就是)

Selenium常用语法

首先就是打开浏览器了:

python 复制代码
# 导入自动化模块
from selenium import webdriver

# 加载驱动
driver = webdriver.Edge()  # 自动从 PATH 中查找驱动
# 窗口最大化
driver.maximize_window()
# 打开网页
driver.get(r'https://kuwo.cn/rankList')  # 没有post

讲一下流程:首先是导包,然后加载驱动(Chrome也支持),再然后就是窗口最大化,这个尽量都做一下此操作,因为有些网页不最大化窗口数据加载不完全,而且有些网页是懒加载,全屏后能加载更多的内容,还有个比较重要的点是当最大化窗口后,滚动多少距离比较好计算和设置,最大化之后就开始打开网页(get,不是post),然后可以进行元素定位,支持XPATH语法定位和CSS定位(主要是ID,Class)代码如下:

python 复制代码
# 导入定位元素所需模块
from selenium.webdriver.common.by import By

# 元素定位(所见即可得,url不需要分析,反扒无需考虑,缺点是速度慢)
# 利用xpath(这里的url地址是:https://kuwo.cn/rankList)
li = driver.find_elements(By.XPATH, '//ul[@class="rank_list"]/li')
# print(len(li))
# print(li)  # 返回的是对象
# 通过属性名定位(注意value)
class_ = driver.find_element(By.CLASS_NAME, 'page')
name = driver.find_element(By.NAME, 'description')  # value是属性值
print(f'class属性定位结果:\n{class_.text}\nname属性定位结果:\n{name.text}')
# 通过标签名定位(注意value)
div = driver.find_element(By.TAG_NAME, 'div')  # value为标签名
print(f'标签名div内的内容为:\n{div.text}')

除了定位元素功能外还能触发点击事件和控制键盘:

python 复制代码
# 控制键盘的模块
from selenium.webdriver.common.keys import Keys

# 完成搜索
driver.get('http://www.baidu.com/')  # 打开网页
input_value = driver.find_element(By.ID, 'kw')  # 定位输入框
input_value.send_keys('索隆高清图片')  # 搜索框内输入内容
input_value.send_keys(Keys.ENTER)  # 敲下键盘回车键

# 点击事件
# su = driver.find_element(By.ID, 'su')  # 定位搜索框
# su.click()  # 点击搜索框

除此之外还可以模拟登录获取cookie:

python 复制代码
# 模拟登录
driver.get('https://qzone.qq.com/')
driver.switch_to.frame('login_frame')  # 切换iframe标签,登陆的时候定位正确却找不到输入框可能就需要切换到iframe标签
# 切换到iframe标签后继续按原方法定位输入框
img_tag = driver.find_element(By.ID, f'img_out_{time.time()}')
time.sleep(2)  # 等待cookie加载完成
# 获取cookie
cookie = driver.get_cookies()  # 获取出来的是列表嵌套字典[{}, {}]
lst = []
# 循环列表
for dic in cookie:
    # 只取name和value
    name = dic['name']
    value = dic['value']
    lst.append(f'{name} = {value}')
# 真正的cookie是以分号+一个空格分隔
real_cookie = '; '.join(lst)
print(real_cookie)

在使用Selenium时由于需要等待JS渲染完成,经常需要我们手动添加time.sleep()等待,不仅麻烦还影响效率,其实有一个方法能解决一半问题,能提升点儿效率(但是还是比较麻烦):

python 复制代码
# selenium 等待问题
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 创建无界面对象
options = webdriver.EdgeOptions()
# 设置无界面(减少占用提升效率)
options.add_argument('--headless')

# 加载驱动并传入无界面参数
driver = webdriver.Edge(options=options)
# 打开百度
driver.get('https://www.baidu.com/')

# 显式等待:针对的是某个单独的元素,提升效率
el_single = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'kw'))  # 定位输入框
)
el_single.send_keys('hello')

还有就是打开多窗口,可以爬取不同的网站:

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Edge()
driver.get("https://某网站.com")  # 主窗口

# 点击链接,被动打开新窗口(比如"详情页"在新窗口打开)
driver.find_element(By.LINK_TEXT, "打开详情页").click()
time.sleep(2)  # 等待新窗口加载

# 获取所有句柄,遍历判断哪个是目标窗口
all_handles = driver.window_handles
target_handle = None
for handle in all_handles:
    driver.switch_to.window(handle)  # 切换到当前句柄
    # 判断URL或标题是否匹配目标
    if "详情页" in driver.title or "detail" in driver.current_url:
        target_handle = handle
        break

# 切换到目标句柄,爬取数据
driver.switch_to.window(target_handle)
print("目标页面标题:", driver.title)
# 爬取数据逻辑...

首先解释一下句柄是什么,其实就是某个窗口的id,id是唯一的,我们可能一次性要爬取几个网站或者是点击某网站首页某个链接后被迫打开了新的窗口,这时候我们就要获取所有网页的句柄,然后通过遍历取句柄,然后判断每个窗口的title值或者网页url来确定句柄是否正确,正确就开爬,其他还有些操作可以参考Selenium文档:Selenium官方文档

需要注意的地方

1.在selenium中,使用Xpath提取数据时,语法稍微有些不同,比如拿链接时在a标签中的href中,需要用webdiver中的专属方法get_attribute('href(属性名,其他属性值提取亦如此)')来获取,文本需要webdriver.text来获取

2.selenium可以运行js代码实现一些交互,使用此代码:driver.execute_script("JS代码", 元素/参数)

3.需定位元素,用send_keys()传入文件路径(无需模拟点击):

python 复制代码
upload_elem = driver.find_element(By.XPATH, '//input[@type="file"]')
upload_elem.send_keys("D:/test.jpg")  # 直接传文件路径

小结

本文浅浅讲了一下Selenium,个人还是比较喜欢DrissionPage的,比较简单,下一文将会讲解DP,如果本文有什么问题请及时提出,一起进步,加油加油

相关推荐
m0_661279181 小时前
学习笔记-安装并启动 Jupyter Noteboo
开发语言·python
xwill*1 小时前
3D-GENERALIST: Vision-Language-Action Models for Crafting 3D Worlds
人工智能·pytorch·python·深度学习
serve the people1 小时前
tensorflow tf.Module 的检查点Checkpoint机制
人工智能·python·tensorflow
gCode Teacher 格码致知1 小时前
Python 3.8.8环境下离线安装python-docx的完整方案-由Deepseek产生
python
哈里谢顿1 小时前
Python 开发中最常见的错误大全(含 JSON 专项解析)
python
LUU_791 小时前
Day26 评价问题介绍
人工智能·python
虚幻如影1 小时前
PyCharm 中离开项目卡住在退出界面
ide·python·pycharm
人工小情绪1 小时前
PyTorch 转 ONNX 实用教程
人工智能·pytorch·python
阿蔹1 小时前
Selenium---控制窗口、manage()方法
java·selenium·测试工具·面试