当前位置: 首页 > ds >正文

Python网络爬虫(三) - 爬取动态网页数据

文章目录

  • 一、动态网页及技术介绍
    • 1. 动态网页介绍
    • 2. Selenium 介绍
  • 二、安装 Selenium
    • 1. 安装 Selenium 库
    • 2. 安装浏览器 WebDriver
      • 2.1 Chrome 浏览器
      • 2.2 Edge 浏览器
  • 三、Selenium WebDriver
    • 1. Selenium WebDriver 简介
    • 2. Selenium WebDriver 基本操作
      • 2.1 启动浏览器
      • 2.2 关闭浏览器
      • 2.3 打开网页
      • 2.4 关闭当前网页
      • 2.5 最大化窗口
      • 2.6 最小化窗口
      • 2.7 全屏模式
      • 2.8 页面前进和后退
      • 2.9 页面刷新
      • 2.10 获取页面标题
      • 2.11 获取当前页面URL
      • 2.12 保存网页源码
      • 2.13 截图
        • 2.13.1 截取整个页面
        • 2.13.2 截取特定元素
      • 2.14 示例:Selenium WebDriver 基本操作
    • 3. 元素查找
      • 3.1 查找单个元素
      • 3.2 查找多个元素
      • 3.3 示例:查找元素
    • 4. 元素操作
      • 4.1 基础交互操作
      • 4.2 输入框操作
      • 4.3 键盘操作(结合 `Keys` 类)
      • 4.4 下拉菜单操作(针对 `<select>` 标签)
      • 4.5 表单操作(针对 `<form>` 标签)
      • 4.6 示例:模仿百度搜索
      • 4.7 滚动到元素位置
      • 4.8 鼠标操作
      • 4.9 等待机制
        • 4.9.1 隐式等待 (Implicit Wait)
        • 4.9.2 显式等待 (Explicit Wait)
        • 4.9.3 手动等待 (Thread Sleep)
      • 4.10 无头浏览器模式
        • 4.10.1 配置Chrome为无头模式
        • 4.10.2 配置Edge为无头模式
  • 四、实战:爬取BOSS直聘java职位数据


一、动态网页及技术介绍

1. 动态网页介绍

动态网页是指页面内容可以根据用户交互、时间变化或数据更新而实时改变的网页。与静态网页(内容固定,由服务器一次性返回完整HTML)不同,动态网页的核心内容通常不是在初始HTML中完全呈现,而是通过客户端技术动态生成或加载。

2. Selenium 介绍

Selenium是一个自动化测试工具,最初用于Web应用程序的自动化测试,现在也被广泛应用于动态网页爬虫领域。它能够模拟真实用户在浏览器中的操作,如点击、输入、滚动等,并可以获取JavaScript渲染后的完整页面内容。


二、安装 Selenium

安装 Selenium 主要包括两个步骤:安装 Selenium 库和安装对应浏览器的 WebDriver 驱动程序。以下是详细的安装流程:

1. 安装 Selenium 库

Selenium 库可以通过 Python 的包管理工具 pip 快速安装,安装命令如下:

pip install selenium==4.15.2 -i https://mirrors.aliyun.com/pypi/simple/

安装完成后,可通过以下代码验证是否安装成功:

import selenium
print("Selenium 版本:", selenium.__version__)  # 输出版本号即表示安装成功

2. 安装浏览器 WebDriver

Selenium 需要通过 WebDriver 驱动程序与浏览器进行通信,不同浏览器需要对应版本的 WebDriver。以下是主流浏览器的 WebDriver 安装方法:

2.1 Chrome 浏览器

  1. 查看 Chrome 版本

    • 打开 Chrome 浏览器 → 点击右上角三个点 → 帮助 → 关于 Google Chrome
    • 记录版本号(如 130.0.6723.117
  2. 下载对应版本的 ChromeDriver

    • 官方下载地址:Chrome for Testing
    • 镜像地址(国内推荐):CNPM Binaries Mirror
    • 选择与 Chrome 版本匹配的驱动(只需主版本号一致,如 Chrome 130.x 对应 ChromeDriver 130.x)
  3. 配置驱动

    • 将下载的 chromedriver-win64.zip 解压到指定路径
    • 代码中配置示例
      from selenium import webdriver
      from selenium.webdriver.chrome.service import Servicedriver_path = r'D:\ProjectCode\untitled\chromedriver-win32\chromedriver-win32\chromedriver.exe'# 创建一个 Service 对象
      service = Service(executable_path=driver_path)# 初始化 Chrome 浏览器
      driver = webdriver.Chrome(service=service)
      

2.2 Edge 浏览器

  1. 查看Edge浏览器版本:打开Edge浏览器,在地址栏输入“edge://version/”,按下回车键,即可查看当前Edge浏览器的版本号。
  2. 下载对应版本的Edge WebDriver:访问Microsoft官方的开发者网站https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/,在页面上找到并点击“Download WebDriver”按钮,在弹出的对话框中,选择适用于你的操作系统和Edge浏览器版本的WebDriver下载链接。
  3. 配置驱动
    将下载的 edgedriver_win64.zip 解压到指定路径,代码中配置示例:
    from selenium import webdriver
    from selenium.webdriver.edge.service import Serviceedge_driver_path = r"D:\ProjectCode\untitled\edgedriver_win64\msedgedriver.exe"
    service = Service(executable_path=edge_driver_path)
    driver = webdriver.Edge(service=service)
    

三、Selenium WebDriver

1. Selenium WebDriver 简介

Selenium WebDriver 是 Selenium 生态的核心组件,它提供了一套跨浏览器的编程接口,允许开发者通过代码控制浏览器的行为。与传统的 Selenium RC(Remote Control)相比,WebDriver 采用了更贴近浏览器原生支持的方式工作,直接与浏览器内核交互,执行效率更高,支持的浏览器功能更全面。

WebDriver 是动态网页爬虫的重要工具,通过模拟真实用户的浏览器行为,能够解决传统爬虫无法处理的 JavaScript 渲染、动态加载等问题。

2. Selenium WebDriver 基本操作

2.1 启动浏览器

启动浏览器是使用 WebDriver 的第一步,不同浏览器对应不同的 WebDriver 类,通过初始化这些类可以启动相应的浏览器实例。

基本语法:

from selenium import webdriver# 启动Chrome浏览器
driver = webdriver.Chrome(executable_path, options, service, keep_alive)# 启动Edge浏览器
driver = webdriver.Edge(executable_path, options, service, keep_alive)

参数说明:

参数名类型作用描述示例值
executable_path字符串指定 WebDriver 驱动程序的路径(若已添加到系统 PATH 可省略)。"C:/drivers/chromedriver.exe"
options浏览器选项对象配置浏览器启动参数(如无头模式、窗口大小、用户配置等)。options=webdriver.ChromeOptions()
service服务对象配置驱动服务的参数(如日志级别、端口号等)。service=webdriver.ChromeService(log_path="driver.log")
keep_alive布尔值是否保持驱动程序与浏览器的长连接(默认 True,关闭可解决部分连接问题)。keep_alive=False

2.2 关闭浏览器

关闭浏览器是结束WebDriver会话的操作,会终止浏览器进程和驱动程序,释放资源。

方法driver.quit()

2.3 打开网页

通过URL导航到目标网页,是WebDriver的基础操作。

方法driver.get(url)

参数

  • url(字符串):目标网页的URL(需包含协议,如https://)。

2.4 关闭当前网页

关闭当前聚焦的标签页,不影响其他标签页(若为最后一个标签页,浏览器可能自动关闭)。

方法driver.close()

2.5 最大化窗口

将浏览器窗口最大化,模拟用户全屏操作,确保元素在可视区域内。

方法driver.maximize_window()

2.6 最小化窗口

将浏览器窗口最小化到任务栏。

方法driver.minimize_window()

2.7 全屏模式

使浏览器进入全屏模式(类似按F11,无地址栏和工具栏)。

方法driver.fullscreen_window()

2.8 页面前进和后退

模拟浏览器的“前进”和“后退”按钮,在浏览历史中导航。

  • 后退driver.back()
  • 前进driver.forward()

2.9 页面刷新

重新加载当前网页,用于刷新动态内容或恢复页面状态。

方法driver.refresh()

2.10 获取页面标题

获取当前网页的标题(对应HTML中的<title>标签内容)。

属性driver.title

2.11 获取当前页面URL

获取浏览器地址栏中显示的当前网页URL。

属性driver.current_url

2.12 保存网页源码

获取当前页面渲染完成后的完整HTML源码并保存到本地文件,适用于动态网页的JavaScript渲染结果。

属性driver.page_source

2.13 截图

2.13.1 截取整个页面

对当前浏览器窗口进行截图,用于保存页面状态、验证操作结果或捕获验证码等场景。

方法driver.save_screenshot(file_path)

参数

  • file_path(字符串):截图保存路径(需包含文件名和扩展名,如 screenshot.png)。
2.13.2 截取特定元素

对指定元素进行截图。

方法element.screenshot(file_path)

参数

  • file_path(字符串):截图保存路径(需包含文件名和扩展名,如 screenshot.png)。

2.14 示例:Selenium WebDriver 基本操作

import timefrom selenium import webdriver
from selenium.webdriver.edge.service import Service# 启动浏览器
edge_driver_path = r"D:\ProjectCode\untitled\edgedriver_win64\msedgedriver.exe"
service = Service(executable_path=edge_driver_path)
driver = webdriver.Edge(service=service)
# 打开百度
driver.get("https://www.baidu.com")
# 打开boss直聘
driver.get("https://www.zhipin.com")
time.sleep(2)
# 后退到百度
driver.back()
time.sleep(2)
# 前进到boss直聘
driver.forward()
time.sleep(2)
# 刷新网页
driver.refresh()
time.sleep(2)
# 获取当前页面的URL
current_url = driver.current_url
print("当前页面的URL:", current_url)
# 获取当前页面的标题
current_title = driver.title
print("当前页面的标题:", current_title)
# 获取当前页面的HTML
current_html = driver.page_source
print("当前页面的HTML:", current_html)
# 最大化窗口
driver.maximize_window()
time.sleep(2)
# 截取整个页面
driver.save_screenshot("screenshot.png")
# 关闭当前页面
driver.close()
time.sleep(2)
# 关闭浏览器
driver.quit()

3. 元素查找

在 Selenium 中,元素查找是与网页交互的基础,通过定位标签(元素)可以实现点击、输入、提取文本等操作。WebDriver 提供了 find_element()(查找单个元素)和 find_elements()(查找多个元素)两种核心方法,支持多种定位策略。

3.1 查找单个元素

find_element() 方法用于在页面中查找第一个符合条件的元素,返回一个元素对象(若未找到则抛出 NoSuchElementException 异常)。

基本语法:

element = driver.find_element(by=定位策略, value=定位值)

参数说明:

参数名类型作用描述示例值
by字符串/枚举指定元素定位策略,推荐使用 By 类的枚举常量(如 By.IDBy.CSS_SELECTOR)。By.IDBy.CLASS_NAMEBy.XPATH
value字符串定位值,与定位策略对应(如ID值、类名、XPath表达式等)。"kw"(ID值)、"s_ipt"(类名)、"//input"(XPath)

常用定位策略(by的取值):

定位策略说明示例代码(查找百度搜索框)
By.ID通过元素的 id 属性定位(ID通常唯一,定位效率最高)。driver.find_element(By.ID, "kw")
By.NAME通过元素的 name 属性定位。driver.find_element(By.NAME, "wd")
By.CLASS_NAME通过元素的 class 属性定位(class可能重复,需注意唯一性)。driver.find_element(By.CLASS_NAME, "s_ipt")
By.TAG_NAME通过HTML标签名定位(如 inputdiv,适合批量元素的首个)。driver.find_element(By.TAG_NAME, "input")
By.LINK_TEXT通过链接的完整文本定位(精确匹配 <a> 标签的文本内容)。driver.find_element(By.LINK_TEXT, "新闻")
By.PARTIAL_LINK_TEXT通过链接的部分文本定位(模糊匹配 <a> 标签的文本)。driver.find_element(By.PARTIAL_LINK_TEXT, "新")
By.CSS_SELECTOR通过CSS选择器定位(支持类、ID、属性、层级等复杂规则)。driver.find_element(By.CSS_SELECTOR, "#kw")
By.XPATH通过XPath表达式定位(支持复杂层级和条件筛选,兼容性强)。driver.find_element(By.XPATH, "//input[@id='kw']")

3.2 查找多个元素

find_elements() 方法用于在页面中查找所有符合条件的元素,返回一个包含所有元素对象的列表(若未找到则返回空列表)。

基本语法:

elements = driver.find_elements(by=定位策略, value=定位值)

参数说明:
find_element() 完全一致,区别在于返回结果为列表:

参数名类型作用描述示例值
by字符串/枚举find_element(),指定定位策略。By.TAG_NAMEBy.CLASS_NAME
value字符串find_element(),指定定位值。"a"(标签名)、"mnav"(类名)

常用定位策略(by的取值):
find_element() 完全一致。

3.3 示例:查找元素

import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service# 启动浏览器
edge_driver_path = r"D:\ProjectCode\untitled\edgedriver_win64\msedgedriver.exe"
service = Service(executable_path=edge_driver_path)
driver = webdriver.Edge(service=service)# 打开boss直聘
driver.get("https://www.baidu.com/")
time.sleep(2)# 定位“百度一下”按钮
element = driver.find_element(By.ID, 'chat-submit-button')# 定位输入框
element = driver.find_element(By.CLASS_NAME, 'chat-input-textarea')# 通过CSS选择器查找“百度一下”按钮
element = driver.find_element(By.CSS_SELECTOR, '#chat-submit-button')# 关闭浏览器
driver.quit()

4. 元素操作

4.1 基础交互操作

针对各类元素的基础交互,如点击、获取信息等,是最常用的操作类型。

操作目的方法/属性说明适用元素
点击元素element.click()模拟用户单击元素(左键),触发元素默认行为(如提交、跳转)。按钮、链接、复选框、单选框等
获取可见文本element.text返回元素标签内的可见文本(不含HTML标签)。所有包含文本的元素(div、a、span等)
获取属性值element.get_attribute(name)返回元素指定属性的值(如href、src、class等)。所有带属性的元素
判断元素状态element.is_displayed()判断元素是否在页面中可见(布尔值)。所有元素
element.is_enabled()判断元素是否启用(如输入框是否可编辑、按钮是否可点击)。输入框、按钮、下拉框等
element.is_selected()判断复选框/单选框是否被选中(布尔值)。复选框(input[type=“checkbox”])、单选框(input[type=“radio”])

4.2 输入框操作

专门用于文本输入类元素的操作,模拟用户输入、修改内容。

操作目的方法说明
输入文本element.send_keys(*value)向输入框中输入文本,支持字符串或特殊按键(如回车、Tab)。
清空内容element.clear()清除输入框中已有的文本内容,常用于重新输入前重置。
提交输入内容element.submit()提交当前输入框所在的表单(等价于点击表单的提交按钮,仅适用于表单内元素)。

4.3 键盘操作(结合 Keys 类)

模拟键盘按键及组合键,扩展输入操作的灵活性。

操作目的方法示例说明
特殊按键输入send_keys(Keys.ENTER)输入回车键(常用于提交搜索、表单)。
send_keys(Keys.TAB)输入Tab键(切换焦点)。
组合键操作send_keys(Keys.CONTROL, "a")按下Ctrl+A(全选内容)。
send_keys(Keys.SHIFT, "abc")按下Shift+字母(输入大写字母)。
特殊键描述Keys 类常量
回车键(Enter)Keys.RETURNKeys.ENTER
Tab 键Keys.TAB
Esc 键Keys.ESCAPE
空格键Keys.SPACE
向上方向键Keys.ARROW_UPKeys.UP
向下方向键Keys.ARROW_DOWNKeys.DOWN
向左方向键Keys.ARROW_LEFTKeys.LEFT
向右方向键Keys.ARROW_RIGHTKeys.RIGHT
删除键(Delete)Keys.DELETE
退格键(Backspace)Keys.BACK_SPACE
插入键(Insert)Keys.INSERT
Home 键Keys.HOME
End 键Keys.END
Page Up 键Keys.PAGE_UP
Page Down 键Keys.PAGE_DOWN
F1 至 F12 功能键Keys.F1Keys.F12
Ctrl 键Keys.CONTROL
Shift 键Keys.SHIFT
Alt 键Keys.ALT

4.4 下拉菜单操作(针对 <select> 标签)

通过 Select 类简化下拉菜单(单选/多选)的选择操作。

操作目的方法说明
按索引选择select_by_index(index)根据选项索引选择(索引从0开始,适用于固定顺序的下拉框)。
按属性值选择select_by_value(value)根据选项的 value 属性值选择(精准匹配属性值)。
按文本选择select_by_visible_text(text)根据选项的可见文本选择(匹配显示在页面上的文本)。
取消选择(多选)deselect_all()取消所有已选中的选项(仅适用于 multiple="multiple" 的多选下拉框)。
取消单个选择deselect_by_index(index)取消指定索引的选项(多选下拉框专用)。

4.5 表单操作(针对 <form> 标签)

专门用于表单的整体提交或重置。

操作目的方法说明
提交表单form_element.submit()提交整个表单(等价于点击表单内的提交按钮,无需单独定位按钮)。
重置表单form_element.reset()重置表单内所有输入项为默认值(等价于点击重置按钮)。

4.6 示例:模仿百度搜索

import timefrom selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service# 启动浏览器
edge_driver_path = r"D:\ProjectCode\untitled\edgedriver_win64\msedgedriver.exe"
service = Service(executable_path=edge_driver_path)
driver = webdriver.Edge(service=service)# 打开boss直聘
driver.get("https://www.baidu.com/")
time.sleep(2)# 定位输入框
element1 = driver.find_element(By.CLASS_NAME, 'chat-input-textarea')# 通过CSS选择器查找“百度一下”按钮
element2 = driver.find_element(By.CSS_SELECTOR, '#chat-submit-button')# 打印 element1 元素的 'placeholder' 属性值
print(element1.get_attribute('placeholder'))# 打印 element2 元素的可见文本内容(text)
print(element2.text)# 向 element1 输入框中输入文本:“风景图片”
element1.send_keys('风景图片')# 模拟按下“回车键”(Enter),常用于提交搜索或表单
element1.send_keys(Keys.ENTER)# 点击 element2 元素
# element2.click()# 清空 element1 输入框中的所有已输入内容
element1.clear()# 关闭浏览器
driver.quit()

4.7 滚动到元素位置

有时需要滚动页面直到某个元素进入视图中,这可以通过JavaScript执行来完成。

driver.execute_script("arguments[0].scrollIntoView(true);", element)

4.8 鼠标操作

在Selenium中,鼠标操作是通过ActionChains类来实现的。这个类提供了一系列的方法来模拟各种鼠标操作,如点击、双击、右击、拖拽等。

以下是一些常见的鼠标操作及其使用方法:

  1. 导入ActionChains
    在执行任何鼠标操作之前,首先需要从selenium.webdriver.common.action_chains模块中导入ActionChains类。

    from selenium.webdriver.common.action_chains import ActionChains
    
  2. 初始化ActionChains对象
    创建一个ActionChains对象,该对象需要传入一个浏览器驱动实例。

    actions = ActionChains(driver)
    
  3. 常用鼠标操作

    • 点击(Click): 点击一个元素。

      element = driver.find_element(By.ID, "element_id")
      actions.click(element).perform()
      
    • 右键点击(Context Click): 在某个元素上执行右键点击。

      element = driver.find_element(By.ID, "element_id")
      actions.context_click(element).perform()
      
    • 双击(Double Click): 双击一个元素。

      element = driver.find_element(By.ID, "element_id")
      actions.double_click(element).perform()
      
    • 悬停(Move to Element): 将鼠标移动到某个元素上。

      element = driver.find_element(By.ID, "element_id")
      actions.move_to_element(element).perform()
      
    • 拖放(Drag and Drop): 从一个位置拖动元素并释放到另一个位置。

      source_element = driver.find_element(By.ID, "source_id")
      target_element = driver.find_element(By.ID, "target_id")
      actions.drag_and_drop(source_element, target_element).perform()
      
  4. 执行动作
    所有的动作链都需要通过调用.perform()方法来执行。这意味着你可以先定义一系列的动作,然后一次性执行它们。

  5. 链式调用
    ActionChains支持链式调用,即可以连续调用多个方法,最后通过.perform()来执行所有动作。

    actions.move_to_element(element).click().double_click().context_click().perform()
    

4.9 等待机制

在使用Selenium进行Web自动化测试时,等待机制是确保脚本稳定性和可靠性的关键因素之一。由于页面加载和元素渲染的时间可能不同,直接操作未完全加载的元素会导致错误。Selenium提供了两种主要的等待机制:隐式等待和显式等待。

4.9.1 隐式等待 (Implicit Wait)

隐式等待是对整个WebDriver会话设置的一个全局等待时间。如果在指定时间内网页没有加载完成或特定元素尚未出现,WebDriver将继续轮询DOM,直到元素变得可用或超时。

  • 如何使用:

    from selenium import webdriverdriver = webdriver.Chrome()  # 或其他WebDriver实例
    # 设置隐式等待时间为10秒
    driver.implicitly_wait(10)  # 参数为等待的秒数
    
  • 优点: 简单易用,只需设置一次即可应用于所有查找元素的操作。

  • 缺点: 如果页面上的某些元素比设定的时间更早出现,仍需等待至设定的最大时间,可能导致不必要的延迟。

4.9.2 显式等待 (Explicit Wait)

显式等待允许针对特定条件进行等待,只有当该条件满足时才会继续执行后续代码,或者在超过最大等待时间后抛出异常。这种方式更加灵活且高效。

  • 常用方法:

    • WebDriverWait: 结合ExpectedConditions用于检查特定条件是否成立。
  • 示例代码:

    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 ECdriver = webdriver.Chrome()  # 或其他WebDriver实例driver.get("http://example.com")
    try:# 使用WebDriverWait等待最多10秒,直到找到ID为'element_id'的元素element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "element_id")))
    finally:driver.quit()
    

ExpectedConditions

在Selenium中,EC(expected_conditions,预期条件)模块封装了网页自动化测试中常用的方法,用于判断页面元素或页面状态是否满足特定条件,以下是一些常用方法介绍:

  1. 标题判断类
    • title_is:用于判断当前页面的title是否完全等于预期字符串,返回布尔值。例如判断当前页面标题是否为“百度一下,你就知道”。
    • title_contains:判断当前页面的title是否包含预期字符串,返回布尔值。
  2. 元素存在判断类
    • presence_of_element_located:判断某个元素是否被加到了DOM树里,不代表该元素一定可见。使用时需传入元素定位元组,如(By.ID, ‘element_id’)。
    • presence_of_all_elements_located:判断是否至少有1个元素存在于DOM树中。例如判断页面上class为’column-md-3’的元素是否至少有一个存在。
  3. 元素可见性判断类
    • visibility_of_element_located:判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不等于0 ,需传入元素定位元组。
    • visibility_of:与visibility_of_element_located功能相同,只是直接传入定位到的element对象。
    • invisibility_of_element_located:判断某个元素是否不存在于DOM树或不可见。
  4. 元素文本判断类
    • text_to_be_present_in_element:判断某个元素中的text是否包含了预期的字符串。
    • text_to_be_present_in_element_value:判断某个元素中的value属性是否包含了预期的字符串。
  5. frame操作类
    • frame_to_be_available_and_switch_to_it:判断该frame是否可以切换进去,如果可以,返回True并且切换进去,否则返回False。
  6. 元素可操作判断类
    • element_to_be_clickable:判断某个元素是否可见并且是enabled的,即可点击状态。
    • staleness_of:等待某个元素从DOM树中移除,返回True或False。
  7. 元素选中状态判断类
    • element_to_be_selected:判断某个元素是否被选中,一般用于下拉列表等。
    • element_selection_state_to_be:判断某个元素的选中状态是否符合预期,需传入定位到的element对象。
    • element_located_to_be_selected:判断特定元素是否存在于DOM树并被选中,传入元素定位元组。
    • element_located_selection_state_to_be:与element_selection_state_to_be作用相同,只是传入元素定位元组。
  8. 弹窗判断类
    • alert_is_present:判断页面上是否存在alert弹窗。
4.9.3 手动等待 (Thread Sleep)

虽然可以使用Python的time.sleep()方法来实现简单的线程休眠作为等待手段,但这通常不是最佳实践,因为它会造成固定的等待时间,无论实际需要与否,可能会增加不必要的测试运行时间。

  • 不推荐的方式:

    import timetime.sleep(5)  # 强制等待5秒
    

4.10 无头浏览器模式

无头浏览器模式允许你在没有图形用户界面(GUI)的情况下运行浏览器。这对于在服务器环境中执行自动化测试、持续集成(CI)管道中使用Selenium非常有用,因为它不需要显示输出,可以节省资源并提高性能。以下是如何配置不同浏览器以无头模式运行的方法。

4.10.1 配置Chrome为无头模式

对于Chrome浏览器,通过设置--headless选项来启用无头模式。

from selenium import webdriver
from selenium.webdriver.chrome.options import Options# 初始化Chrome选项
chrome_options = Options()# 添加无头模式参数
chrome_options.add_argument("--headless")# 如果需要,还可以添加其他常用参数
chrome_options.add_argument("--disable-gpu")  # 适用于Windows系统的额外参数
chrome_options.add_argument("window-size=1920,1080")  # 设置窗口大小# 使用配置好的选项启动Chrome WebDriver
driver = webdriver.Chrome(options=chrome_options)# 打开网页
driver.get('http://www.example.com')# 输出页面标题,验证是否正确加载
print(driver.title)# 关闭WebDriver
driver.quit()
4.10.2 配置Edge为无头模式

对于新版基于Chromium的Microsoft Edge浏览器,可以通过设置--headless选项来启用无头模式。需要注意的是,由于Edge也是基于Chromium内核,因此它的配置方式与Chrome非常相似。

from selenium import webdriver
from selenium.webdriver.edge.options import Options# 初始化Edge选项
edge_options = Options()# 添加无头模式参数
edge_options.add_argument("--headless")# 如果需要,还可以添加其他常用参数
edge_options.add_argument("--disable-gpu")  # 适用于某些系统的额外参数
edge_options.add_argument("window-size=1920,1080")  # 设置窗口大小# 使用配置好的选项启动Edge WebDriver
driver = webdriver.Edge(options=edge_options)# 打开网页
driver.get('http://www.example.com')# 输出页面标题,验证是否正确加载
print(driver.title)# 关闭WebDriver
driver.quit()

四、实战:爬取BOSS直聘java职位数据

代码如下所示:

import time
from pathlib import Pathimport pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait# 配置 Edge 浏览器的启动选项
options = webdriver.EdgeOptions()# 禁用 Blink 渲染引擎的自动化控制特征
# 作用:隐藏“Chrome 正受到自动化测试工具控制”的提示,减少被网站检测的风险
options.add_argument("--disable-blink-features=AutomationControlled")# 禁用所有浏览器扩展(插件)
options.add_argument("--disable-extensions")# 禁用 GPU 硬件加速
# 原因:在无头模式或服务器环境中,GPU 可能不可用,禁用后可提高稳定性
# options.add_argument("--disable-gpu")# 禁用沙盒模式(sandbox)
# 说明:沙盒是浏览器的安全机制,但在某些 Linux 服务器或 Docker 中需要关闭才能运行
# options.add_argument("--no-sandbox")# 开启远程调试端口,端口号为 9222
# 用于调试浏览器行为(如通过 Chrome DevTools 远程查看页面)
# options.add_argument("--remote-debugging-port=9222")# 启用无头模式(headless)
# 浏览器在后台运行,不显示图形界面,适合服务器或自动化任务
# 注意:无头模式更容易被检测,建议配合其他反检测手段使用
# options.add_argument("--headless")# 禁用自动化扩展(如 WebDriver 标志)
# 防止浏览器暴露自动化特征
options.add_experimental_option("useAutomationExtension", False)# 移除“启用自动化”提示栏(即隐藏“Chrome 正在受到自动软件控制”的黄色警告条)
options.add_experimental_option("excludeSwitches", ["enable-automation"])# 指定 Edge 浏览器驱动程序(msedgedriver.exe)的本地路径
edge_driver_path = r"D:\ProjectCode\untitled\edgedriver_win64\msedgedriver.exe"# 创建 Service 对象,用于管理浏览器驱动进程
service = Service(executable_path=edge_driver_path)# 启动 Edge 浏览器实例,传入服务和配置选项
driver = webdriver.Edge(service=service, options=options)# 在每个新页面加载前注入 JavaScript 脚本
# 作用:覆盖 navigator.webdriver 属性,防止网站通过 JS 检测自动化
# 原理:正常用户浏览器中 navigator.webdriver 为 undefined 或 false,而 Selenium 默认为 true
# 这里将其强行定义为始终返回 false,伪装成正常用户
# driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
#     "source": """
#     Object.defineProperty(navigator, 'webdriver', {
#         get: () => false
#     });
#     """
# })time.sleep(2)# 打开目标网页:BOSS直聘 杭州地区 Java 岗位列表,第1页
driver.get("https://www.zhipin.com/web/geek/jobs?query=&city=101290100&position=100101")# 暂停 2 秒,等待页面加载完成(简单等待,实际项目建议使用 WebDriverWait 显式等待)
time.sleep(2)# div_element_list = driver.find_elements(By.CSS_SELECTOR, ".job-list-container > .rec-job-list > .card-area")data = []try:div_element_list = WebDriverWait(driver, 60).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".job-list-container > .rec-job-list > .card-area")))for div_element in div_element_list:a_element = div_element.find_element(By.CSS_SELECTOR, '.job-name')href = a_element.get_attribute("href")name = a_element.textexperience_education = div_element.find_elements(By.CSS_SELECTOR, '.tag-list > li')experience = experience_education[0].texteducation = experience_education[1].textcompany_name = div_element.find_element(By.CSS_SELECTOR, '.boss-name')company_name = company_name.textcompany_location = div_element.find_element(By.CSS_SELECTOR, '.company-location')company_location = company_location.textprint(href, name, experience, education, company_name, company_location)# time.sleep(random.uniform(1, 3))# 保存数据到csv文件data.append({'href': href,'name': name,'experience': experience,'education': education,'company_name': company_name,'company_location': company_location})# 转换为 DataFramedata_df = pd.DataFrame(data)# 创建保存目录(如果不存在)Path('./data').mkdir(parents=True, exist_ok=True)# 保存为 CSV 文件data_df.to_csv('./data/data.csv', index=False, encoding='utf-8-sig')print(f"图书数据已保存到:'./data/data.csv'")finally:print("等待元素出现超时")driver.quit()

保存后的数据如下图所示:

在这里插入图片描述

http://www.xdnf.cn/news/18341.html

相关文章:

  • 18650锂电池自动化生产线:智能集成提升制造效能
  • 【库的操作】
  • 如何使用tar备份整个openEuler系统
  • PortainerCE 跨云管理:cpolar 内网穿透服务实现多环境统一控制
  • 《Dual Prompt Personalized Federated Learning in Foundation Models》——论文阅读
  • 基于prompt的生物信息学:多组学分析的新界面
  • 【自动化运维神器Ansible】Ansible Role创建与使用详解
  • AI 小游戏批量生产工厂(Deepseek深度推理reasoner模型64K tokens)
  • 【C++】C++ 的护身符:解锁 try-catch 异常处理
  • 【HarmonyOS】应用设置全屏和安全区域详解
  • 【机器人-基础知识】ROS2常用命令
  • MongoDB 查询方法与高级查询表(Python版)
  • 计算机网络技术学习-day3《交换机配置》
  • steal tsoding‘s pastebeam code as go server
  • SQL详细语法教程(五)事务和视图
  • ubuntu 下载安装tomcat简单配置(傻瓜式教程)
  • 如何生成和安全保存私钥?
  • 信号上升时间Tr不为0的信号反射情况
  • scikit-learn/sklearn学习|弹性网络ElasticNet解读
  • linux系统查看ip命令
  • 深度学习与线性模型在扰动预测上的比较
  • kafka 冲突解决 kafka安装
  • 如何在VS Code中使用Copilot与MCP服务器增强开发体验
  • 【Linux操作系统】简学深悟启示录:进程状态优先级
  • Android RxBinding 使用指南:响应式UI编程利器
  • 数据转换细节揭秘:ETL如何精准映射复杂业务逻辑
  • 27.Linux 使用yum安装lamp,部署wordpress
  • 【自动化测试】Selenium详解-WebUI自动化测试
  • Linux: RAID(磁盘冗余阵列)配置全指南
  • 作业标准化:制造企业的效率基石与品质保障