【Python爬虫实战】深入 Selenium:从节点信息提取到检测绕过的全攻略

  ????个人主页:易辰君-****博客
???? 系列专栏:https://blog.****.net/2401_86688088/category_12797772.html

前言

在使用 Selenium 进行网页自动化时,不仅需要掌握基本的节点信息提取和选项卡管理,还需要考虑到如何高效等待加载,以及如何绕过网站对自动化工具的检测。这篇文章将详细介绍如何使用 Selenium 获取节点信息、处理延时等待、管理多选项卡,并分享多种绕过检测的方法,帮助开发者应对各种自动化测试中的挑战。


一、获取节点信息

在 Selenium 中,获取节点信息主要通过定位元素和提取属性或文本内容来实现。以下是一些常用的获取节点信息的方式:

(一)获取元素的文本

使用 .text 属性可以获取元素的文本内容。例如:

element = driver.find_element(By.ID, "example-id")
print(element.text)

(二)获取元素的属性

使用 .get_attribute() 方法可以获取元素的属性值,如 hrefclass 等。例如:

element = driver.find_element(By.ID, "example-id")
href_value = element.get_attribute("href")
print(href_value)

(三)获取元素的 CSS 属性

使用 .value_of_css_property() 方法可以获取 CSS 样式属性的值。例如:

element = driver.find_element(By.ID, "example-id")
color = element.value_of_css_property("color")
print(color)

(四)获取元素的尺寸和位置

使用 .size.location 属性可以获取元素的尺寸(宽度和高度)以及位置(x 和 y 坐标)。例如:

element = driver.find_element(By.ID, "example-id")
size = element.size
location = element.location
print(size, location)

(五)检查元素是否可见和启用

使用 .is_displayed().is_enabled() 可以检查元素是否可见或可用。例如:

element = driver.find_element(By.ID, "example-id")
is_displayed = element.is_displayed()
is_enabled = element.is_enabled()
print(is_displayed, is_enabled)

二、延时等待

在 Selenium 中,延时等待是为了确保页面加载完成或元素可见后再进行操作,避免由于加载延迟而导致找不到元素的错误。Selenium 提供了几种常用的等待方式:

(一)隐式等待

隐式等待是全局的,设置后 Selenium 会在查找元素时等待指定的时间,直到元素出现在页面上。如果超过等待时间还未找到元素,则会抛出异常。

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)  # 设置隐式等待时间为10秒
driver.get("https://example.com")

隐式等待的优点是适用于整个 WebDriver 生命周期,缺点是无法针对特定元素灵活控制等待时间。

(二)显式等待

显式等待可以针对特定条件进行等待,直到满足条件或超过最大等待时间。需要用到 WebDriverWaitexpected_conditions 模块。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("https://example.com")

# 等待某个元素可见,最多等待10秒
element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "example-id"))
)

常用条件

  • presence_of_element_located:元素在页面中出现(但不一定可见)。

  • visibility_of_element_located:元素可见(尺寸和位置均非零)。

  • element_to_be_clickable:元素可点击(可见并启用)。

  • text_to_be_present_in_element:指定元素中包含特定文本。

显式等待更灵活,适合特定元素和条件。

(三)强制等待

time.sleep() 是 Python 内置的强制等待方法,代码会暂停指定的秒数。一般不推荐使用,但在调试时可以短暂使用。

import time

driver = webdriver.Chrome()
driver.get("https://example.com")
time.sleep(5)  # 等待5秒

一般优先使用隐式和显式等待,减少页面加载延迟对代码执行的影响,同时避免使用 sleep,以提高效率和稳定性。


三、选项卡管理

在 Selenium 中,选项卡管理涉及到在不同的浏览器选项卡之间切换、关闭和获取选项卡的句柄。以下是一些常用的操作:

(一)打开新选项卡

在 Selenium 中,可以通过执行 JavaScript 打开新选项卡,然后用 Selenium 切换到新选项卡。例如:

driver.execute_script("window.open('https://example.com');")

(二)获取所有选项卡句柄

每个选项卡在 Selenium 中都有一个唯一的句柄,可以用来识别和操作特定的选项卡。使用 .window_handles 可以获取所有选项卡的句柄,返回一个列表:

handles = driver.window_handles
print(handles)

(三)切换到指定选项卡

使用 .switch_to.window() 方法切换到指定的选项卡,通过传入选项卡的句柄来指定。例如,切换到第二个选项卡:

driver.switch_to.window(handles[1])

通常,handles[0] 是第一个选项卡,handles[1] 是第二个选项卡,以此类推。

(四)获取当前选项卡的句柄

使用 .current_window_handle 可以获取当前选项卡的句柄:

current_handle = driver.current_window_handle
print(current_handle)

(五)关闭特定选项卡

使用 .close() 方法可以关闭当前选项卡。关闭后,如果还想继续操作其他选项卡,需要切换到其他有效句柄。例如:

driver.switch_to.window(handles[1])
driver.close()  # 关闭第二个选项卡
driver.switch_to.window(handles[0])  # 切换回第一个选项卡

(六)切换回默认选项卡

通常,第一个打开的选项卡即为默认选项卡,句柄为 handles[0]。可以使用 .switch_to.window(handles[0]) 切换回默认选项卡。


四、绕过检测

在使用 Selenium 进行网页自动化时,许多网站会检测 Selenium 的使用并阻止或限制访问。以下是一些常用的绕过检测的方法:

(一)修改浏览器指纹

一些网站会检测浏览器指纹(例如 navigator.webdriver 属性),Selenium 默认会暴露这一信息。可以使用 JavaScript 来隐藏这一属性:

driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
})

(二)使用无头模式并调整参数

无头浏览器可以在后台运行 Chrome,但有些网站会检测无头模式。可以在启动时设置一些参数来减少检测概率:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless")  # 无头模式
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--user-agent=your-custom-user-agent")  # 设置用户代理
driver = webdriver.Chrome(options=options)

(三)禁用 WebDriver 扩展

Selenium 的 WebDriver 扩展会在浏览器上显示特定标识,可以在启动时禁用这些扩展:

options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

(四)模拟用户行为

网站可能检测到机械化的鼠标和键盘操作。可以通过 Selenium 模拟用户的自然行为,例如随机延迟和移动鼠标:

from selenium.webdriver.common.action_chains import ActionChains
import time
import random

# 随机延迟
time.sleep(random.uniform(2, 5))

# 模拟鼠标移动
action = ActionChains(driver)
element = driver.find_element(By.ID, "example-id")
action.move_to_element(element).perform()

(五)使用随机 User-Agent

设置不同的 User-Agent 来模拟不同的浏览器和设备,避免被网站识别为自动化工具:

options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")

也可以使用 fake_useragent 库生成随机 User-Agent(需额外安装 fake_useragent 库)。

(六)使用代理 IP

许多网站会根据 IP 进行访问频率检测,使用代理 IP 可以分散访问来源,避免频繁请求被封禁:

options.add_argument("--proxy-server=http://your-proxy-server.com:port")

(七)通过扩展绕过检测

一些检测工具使用插件或扩展来绕过检测。例如,安装一个反检测插件(如 Stealth 插件),这可以帮助避免被检测为自动化工具。

(八)减少显式 Selenium 命令的使用

尽量避免直接显式的 Selenium 命令,而是通过 JavaScript 代码直接执行页面操作。例如,使用 execute_script() 执行滚动、点击等操作。

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

(九)切换浏览器或使用非官方的 WebDriver

一些非官方的 WebDriver,如 undetected-chromedriver,可以有效地绕过检测。


五、总结

在 Selenium 自动化测试中,掌握节点信息获取、延时等待和选项卡管理是实现流畅操作的基础,而面对网站的反自动化检测,绕过检测的方法则是实现稳定自动化的关键。通过综合使用隐式和显式等待、模拟用户行为、随机化 User-Agent、设置代理等技术,开发者可以在提高效率的同时,提升测试的稳定性和隐蔽性。希望本文提供的方法和技巧能够帮助你更顺利地完成自动化任务。

上一篇:新书速览|Java网络爬虫精解与实践


下一篇:解决虚拟机启动报:此主机支持AMD-V,但AMD-V处于禁用状态