背景:本人不爱看java八股文,也不喜欢深入研究源码,技术栈三年未更新,简历一言难尽,且java业务快写吐了,最近迷上python语言,此时公司需要使用爬虫获取一些数据,因此开始使用python编写爬虫脚本,因公司合规要求:爬取数据需模拟浏览器点击方式,因此使用selenium开源工具,python环境的安装配置这里就不一一叙述,python基础语法目前是看B站业余时间学习(进度-看了不到一周),最后deepseek很好用。
一、Selenium是什么?
Selenium 是一个用于 自动化 Web 浏览器操作 的开源工具套件,主要用于 Web 应用的自动化测试,但也常用于网络爬虫、数据抓取和重复性网页操作自动化等领域。它支持多种编程语言(如 Python、Java、C#、JavaScript 等)和主流浏览器(Chrome、Firefox、Edge、Safari 等),是 Web 自动化领域的标杆工具。
二、Selenium核心组件
1.Selenium IDE(需要翻墙,这个插件好像被禁用啦)
浏览器插件形式的录制回放工具
适合快速生成测试用例
支持导出为Python/Java等代码
2.Selenium WebDriver
主流编程语言(Python/Java/C#/JavaScript等)的API
直接控制浏览器底层驱动
支持Chrome、Firefox、Edge等主流浏览器
3.Selenium Grid
分布式测试执行框架
支持并行运行测试用例
跨平台、跨浏览器测试
三、工作原理
开发者编写自动化脚本 →
WebDriver将指令转换为HTTP请求 →
浏览器驱动(如ChromeDriver)接收指令 →
真实浏览器执行操作 →
返回执行结果
四、关键技术点
1.元素定位策略
推荐使用:xpath
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
2.等待机制
显式等待(推荐)
from selenium.webdriver.support.ui import WebDriverWait
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamicElement"))
)
隐式等待
implicitly_wait是Selenium WebDriver提供的一种全局等待策略,用于设置查找页面元素时的最大等待时间。当尝试定位元素时,若元素未立即出现,WebDriver会在指定时间范围内持续轮询DOM,直到找到元素或超时。
driver.implicitly_wait(5) # 隐式等待,全局有效
线程等待 python
time.sleep()
3高级功能.
执行JavaScript:driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
文件上传/下载处理
浏览器窗口/标签页管理
五.优势与局限
优点:
完全免费开源,社区活跃。
支持多语言、多浏览器
支持复杂交互(如拖拽、弹出框处理)。
可结合代理、无头模式(Headless)适应不同需求。
缺点:
只支持PC端,无法处理桌面应用
动态内容加载需额外等待,执行速度较慢(相比直接 HTTP 请求)。
需安装浏览器和对应驱动,环境配置稍复杂。
动态内容可能导致元素定位不稳定(需配合显式等待等机制)。
验证码等安全机制需绕道处理
环境配置 python + chrome + chrome_driver
python
版本:3.13.2
lvchunfeng@lvchunfengs-MacBook-Pro python-project % python3
Python 3.13.2 (v3.13.2:4f8bb3947cf, Feb 4 2025, 11:51:10) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
chrome浏览器:
本机已经升级最新的版本版本 134.0.6998.45(正式版本) (x86_64)
chrome_driver
需要根据chrome浏览器下载对应版本的驱动 下载参考博客:blog.csdn.net/Sheri996/ar…
webDriver 初始化
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 屏蔽调试的浏览器
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
简单的demo
import time
from lxml.etree import XPath
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from bs4 import BeautifulSoup
import platform
import logging
import pandas as pd
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 屏蔽调试的浏览器
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
driver = webdriver.Chrome(options=options)
driver.get("https://fanyi.youdao.com")
driver.implicitly_wait(20) #
print(driver.current_url)
print(driver.title)
try:
close = driver.find_element(By.XPATH, "/html/body/div[8]/div/img[2]")
close.click()
driver.implicitly_wait(3)
except Exception as ec:
print("关闭错误")
translate = driver.find_element(By.XPATH,
"//*[@id=\"app\"]/div[1]/div/div[2]/div[2]/div[2]/div/div/div[1]/div[1]/div[1]")
translate.click()
driver.implicitly_wait(5)
input = driver.find_element(By.XPATH, "//*[@id=\"js_fanyi_input\"]")
input.send_keys("学习")
time.sleep(10)
driver.implicitly_wait(10)
input = driver.find_element(By.XPATH, "//*[@id=\"js_fanyi_output\"]")
print(input.text)
driver.implicitly_wait(60)
遇到的难点:
1.文件下载拦截:
下载文件时,遇到文件下载一直被拦截,查询很多解决方案,最后时修改配置参数,信任域名。
webDriver初始化时,信任域名
options.add_argument(
"--unsafely-treat-insecure-origin-as-secure=XXXXXXXX(域名)")
2.frame页面切换:
刚开始不知道需要切换frame 使用Xpath路径定位元素一直定位失败。
3.Xpatch 路径动态ID
需要专门学习Xpath路径语法,可以将完整的Xpath路径发给deepseek,它会给你一个模糊匹配的Xpath路径
iframe_xpath = "//iframe[contains(@src, 'dispatchOrderManagement')]"
4.滑动验证码识别
登录时出现滑动验证码验证。 主要使用python的cv2图片识别,找到移动的位置,识别精度度不是很高,增加重试机制。
def _get_pos(image_path):
"""检测图像中符合特定条件的轮廓位置"""
image = cv2.imread(image_path)
if image is None:
print("错误:无法读取图像文件")
return 0
# 增加灰度转换和二值化处理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
# 预处理流程
blurred = cv2.bilateralFilter(gray, 9, 75, 75)
# 动态计算Canny阈值
median = np.median(blurred)
sigma = 0.33
lower = int(max(0, (1.0 - sigma) * median))
upper = int(min(255, (1.0 + sigma) * median))
edges = cv2.Canny(blurred, lower, upper)
# 轮廓检测(仅检测外部轮廓)
contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
max_area = 500 # 最小有效面积阈值
target_x = 0
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
area = cv2.contourArea(contour)
# 强化筛选条件 and (area > max_area) and (cv2.isContourConvex(contour))
if (0.8 < w / h < 1.2) and (2000 > area > max_area):
max_area = area
target_x = x
# 绘制检测结果
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
if target_x:
cv2.imwrite('./111.png', image)
return target_x
return 0
自定义下拉多选:
multi_select = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//input[@name="fromCode"][@placeholder="请选择"]'))
)
ActionChains(driver).click(multi_select).perform()
wait = WebDriverWait(driver, 10)
for item in step["select_item"]:
# 清空输入框
multi_select.clear()
# 输入关键词
multi_select.send_keys(item)
# 使用正确的XPath引号
option_xpath = f'//li[contains(@title, "{item}")]'
try:
# 显式等待选项出现
option = wait.until(EC.element_to_be_clickable((By.XPATH, option_xpath)))
option.click()
except Exception as e:
print(f"未查询到: {item}")
# 使用更安全的关闭方式(如按ESC键)
ActionChains(driver).send_keys(Keys.ESCAPE).perform()
time.sleep(10)
获取Xpath路径
现在用的都是使用浏览器copy Xpath路径,路径比较死
准备使用 TestCase Studio - Selenium IDE 1.8.3 浏览器插件 (需要翻墙)
目前还在摸索阶段
最后: 已成功爬取三个网站数据,但是脚本代码写的比较乱,且脚本写的不够健壮,在思考整理代码,将操作节点做成可配置的。