0

0

Python网络爬虫:应对动态CSS类名选择的策略

聖光之護

聖光之護

发布时间:2025-09-23 11:32:40

|

939人浏览过

|

来源于php中文网

原创

python网络爬虫:应对动态css类名选择的策略

在Python网络爬虫中,面对现代网站动态生成的随机CSS类名(如media-story-card__body__3tRWy)是常见挑战。本文将详细介绍如何利用CSS属性选择器,特别是“以...开头”的选择器([attribute^="value"]),来有效定位这些元素。通过实例代码,您将学会如何编写更健壮的爬虫,成功提取数据,即使面对变化的网页结构。

动态CSS类名:爬虫的挑战

现代网站为了优化性能、实现组件化或防止简单爬虫,常常会采用前端框架(如React、Vue、Angular)来动态生成CSS类名。这些类名通常包含随机字符或哈希值,例如media-story-card__body__3tRWy,与传统的稳定类名(如search-result-content)形成鲜明对比。当类名频繁变化时,依赖固定类名进行元素选择的爬虫会很快失效,导致数据抓取失败。

对于网络爬虫开发者而言,这意味着不能简单地复制浏览器开发者工具中看到的完整类名来定位元素。我们需要一种更灵活、更具韧性的选择策略。

解决方案:CSS属性选择器

CSS属性选择器提供了一种强大的方式,允许我们根据元素的属性及其值来选择元素,而不仅仅是ID或完整的类名。当类名具有可预测的前缀但后缀随机时,属性选择器显得尤为有效。

1. 以特定前缀开头的属性选择器 ([attribute^="value"])

这是解决动态类名问题的核心方法。它允许我们选择那些指定属性值以特定字符串开头的元素。

立即学习Python免费学习笔记(深入)”;

语法: [attribute^="prefix_value"]

示例: 如果一个元素的类名是media-story-card__body__3tRWy,我们可以观察到media-story-card__body__这部分是相对稳定的前缀。因此,我们可以使用div[class^="media-story-card__body__"]来选择所有类名以media-story-card__body__开头的div元素。

2. 其他常用属性选择器

除了“以...开头”的选择器,还有其他几种属性选择器在不同场景下也很有用:

Sora
Sora

Sora是OpenAI发布的一种文生视频AI大模型,可以根据文本指令创建现实和富有想象力的场景。

下载
  • *`[attribute="value"]:包含特定子串** 选择属性值中包含指定子串的元素。例如,div[class*="story-card"]可以选择类名中包含story-card的所有div`元素。
  • [attribute$="value"]:以特定后缀结尾 选择属性值以指定字符串结尾的元素。这在某些特定场景下也可能有用,但对于随机后缀的类名则不适用。
  • [attribute="value"]:属性值完全匹配 选择属性值完全等于指定字符串的元素。这适用于稳定的属性值。

实战演练:使用BeautifulSoup与属性选择器

下面我们将通过一个具体的Python爬虫示例来展示如何应用CSS属性选择器。

原始问题代码(可能失效):

from bs4 import BeautifulSoup
import requests
from rich.pretty import pprint

text = "hello"
url = f"https://www.reuters.com/site-search/?query={text}"

response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml")

# 尝试直接选择完整的动态类名,这很容易失效
results = soup.select("div.media-story-card__body__3tRWy") 

for result in results:
    pprint(result)
    pprint("###############")

在上述代码中,div.media-story-card__body__3tRWy这种选择器依赖于完整的动态类名,一旦3tRWy部分发生变化,代码就会失效,无法抓取到任何结果。

优化后的代码(使用属性选择器):

from bs4 import BeautifulSoup
import requests
from rich.pretty import pprint

text = "hello"
url = f"https://www.reuters.com/site-search/?query={text}"

response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
soup = BeautifulSoup(response.text, "lxml")

# 使用CSS属性选择器:选择所有类名以"media-story-card__body__"开头的div元素
# 这样即使类名后缀随机变化,只要前缀稳定,也能准确选中
results = soup.select('div[class^="media-story-card__body__"]') 

if not results:
    print(f"未找到匹配 '{text}' 的结果,请检查选择器或网页结构。")

for i, result in enumerate(results):
    print(f"--- 结果 {i+1} ---")
    # 这里可以进一步解析每个result,例如提取标题、链接等
    # 假设标题在一个a标签内,且其类名也可能部分动态
    title_tag = result.select_one('a[class^="media-story-card__heading__"]')
    if title_tag:
        pprint(f"标题: {title_tag.get_text(strip=True)}")
        pprint(f"链接: {title_tag['href']}")
    else:
        pprint("未找到标题或链接。")
    print("###############")

代码解析:

  1. soup.select('div[class^="media-story-card__body__"]'):这是关键的改进。它不再依赖完整的类名,而是寻找所有div元素,其class属性值以media-story-card__body__开头。这样,无论后面的随机字符如何变化,只要这个前缀保持不变,我们就能成功选中目标元素。
  2. response.raise_for_status():这是一个良好的实践,用于检查HTTP请求是否成功,如果状态码不是200,会抛出异常,避免后续解析错误。
  3. 对结果进行迭代和进一步解析:在找到主要容器元素后,我们通常还需要从这些容器中提取更具体的数据,如标题、链接、摘要等。这里也示范了如何对子元素使用类似的属性选择器。

注意事项与最佳实践

  1. 选择稳定的前缀: 在使用^=选择器时,选择一个尽可能长且稳定的前缀至关重要。过短的前缀可能导致选中不相关的元素,而过长的前缀则可能因微小变化而失效。通过观察多个页面和刷新页面来确定最稳定的前缀。
  2. 结合其他选择器: 如果仅靠属性前缀选择器仍然不够精确,可以将其与其他CSS选择器结合使用,例如:div[class^="some-prefix"] > h2.title-class(子元素选择器)、div[class^="some-prefix"] + p(相邻兄弟选择器)等。
  3. 利用浏览器开发者工具: 熟练使用浏览器的开发者工具(F12)是发现稳定选择器的关键。
    • 检查元素: 右键点击目标元素,选择“检查”,观察其HTML结构和属性。
    • 观察类名变化: 刷新页面多次,看哪些部分是动态变化的,哪些是稳定的。
    • 尝试CSS选择器: 在开发者工具的控制台(Console)中,可以使用$$('css-selector')来测试你的CSS选择器是否能准确选中目标元素。
  4. 考虑API接口: 对于高度动态或反爬机制严格的网站,直接爬取HTML可能非常困难。有时,网站会提供公开或隐藏的API接口来获取数据。通过监控网络请求(Network tab in DevTools),你可能会发现这些API,直接调用API通常比解析HTML更高效和稳定。
  5. 处理JavaScript渲染: 如果页面内容是通过JavaScript动态加载的,requests库可能无法获取到完整内容。在这种情况下,你需要使用Selenium或Playwright等工具来模拟浏览器行为,等待JavaScript执行完毕后再进行解析。

总结

面对现代网站中常见的动态CSS类名,直接使用完整的类名进行选择是不可靠的。通过掌握CSS属性选择器,特别是“以...开头”的选择器([attribute^="value"]),我们可以编写出更具鲁棒性的网络爬虫。结合浏览器开发者工具进行细致的分析,选择最稳定的属性前缀,并灵活运用其他选择器,将大大提高爬虫的成功率和维护性。在遇到极端情况时,也应考虑探索API接口或使用无头浏览器等高级策略。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1204

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

192

2025.07.29

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号