
本文将围绕以下问题展开:在使用Beautiful Soup抓取网页内容时遇到的NameError问题,并提供更高级的数据提取技巧。我们将深入探讨如何正确解析动态加载的内容,特别是那些存储在
问题分析与解决方案
初学者在使用Beautiful Soup提取网页内容时,经常会遇到NameError,这通常是因为变量的作用域问题或者没有正确找到目标元素。例如,在提供的代码中,text变量可能没有被赋值就直接在print(text)中使用了,这会导致NameError。此外,更重要的是,要认识到有些网页的内容并不是直接以HTML标签的形式呈现,而是通过JavaScript动态加载,存储在
针对这种情况,我们需要采取不同的策略。
从
当目标数据存储在
以下是一个示例,展示了如何从Habr网站提取文章标题和摘要:
import re
import json
import requests
from bs4 import BeautifulSoup
URL = "https://habr.com/ru/hubs/gamedev/articles/" # 目标网址
page = requests.get(URL).text
# 使用正则表达式提取 window.__INITIAL_STATE__ 变量的内容
data = re.search(r"window\.__INITIAL_STATE__=(.*}});", page).group(1)
# 将提取的字符串解析为JSON对象
data = json.loads(data)
# 遍历文章列表,提取标题和摘要
for a in sorted(
data["articlesList"]["articlesList"].values(),
key=lambda k: k["timePublished"],
reverse=True,
):
print(a["titleHtml"])
# 使用Beautiful Soup解析HTML格式的摘要文本
print(BeautifulSoup(a["leadData"]["textHtml"], "html.parser").text)
# 我们只需要第一篇文章的信息
break代码解释:
- 导入必要的库: re用于正则表达式,json用于解析JSON数据,requests用于发送HTTP请求,BeautifulSoup用于解析HTML。
- 发送HTTP请求并获取网页内容: 使用requests.get(URL).text获取网页的文本内容。
- 使用正则表达式提取数据: re.search(r"window\.__INITIAL_STATE__=(.*}});", page).group(1)这行代码使用正则表达式从网页内容中提取window.__INITIAL_STATE__变量的值。这个变量通常包含了网页的初始数据,包括文章标题、摘要等。
- 解析JSON数据: json.loads(data)将提取的字符串转换为JSON对象,方便后续操作。
- 遍历文章列表并提取信息: 代码遍历data["articlesList"]["articlesList"].values(),这是一个包含文章信息的字典列表。
- 提取标题和摘要: a["titleHtml"]提取文章标题,BeautifulSoup(a["leadData"]["textHtml"], "html.parser").text提取文章摘要,并使用Beautiful Soup去除HTML标签。
- 只提取第一篇文章: break语句用于只提取第一篇文章的信息。
注意事项:
- 正则表达式的编写: 正则表达式的编写需要根据具体的网页结构进行调整。要确保正则表达式能够准确地匹配到目标数据。
- JSON数据的结构: JSON数据的结构可能比较复杂,需要仔细分析,找到目标数据所在的路径。
- 动态加载的内容: 有些网页的内容是动态加载的,需要使用Selenium等工具模拟浏览器行为才能获取到完整的数据。
总结
使用Beautiful Soup提取网页内容是一项常见的任务,但需要掌握一些技巧才能应对各种情况。当遇到NameError时,首先要检查变量的作用域和是否正确赋值。当目标数据存储在










