
本教程探讨了在爬取网页时,当目标内容由javascript动态生成且无明显xhr请求时的数据提取策略。我们将揭示数据可能已内嵌于初始html或js代码中,并演示如何通过检查页面源代码、识别关键标识符来定位并提取这些隐藏的json格式数据,从而实现高效的网页内容抓取。
在进行网页数据抓取时,我们经常会遇到内容由JavaScript动态生成的情况。传统的爬虫通常通过解析服务器返回的原始HTML来提取数据,例如使用XPath或CSS选择器。然而,当页面内容在浏览器端通过JavaScript执行后才呈现,且在网络请求中观察不到明显的XHR(XMLHttpRequest)或Fetch API请求来获取这些数据时,传统的静态解析方法便会失效。这给爬虫开发者带来了挑战,因为这意味着数据并非通过异步请求独立加载,而是以某种方式“隐藏”在初始页面加载中。
例如,对于以下HTML结构,如果其内容 Darkmoon Faire 是由JavaScript动态填充的:
<section class="tiw-line-name " id="EU-group-holiday-line-0" data-side="both"> <a href="/event=479/darkmoon-faire"><img src="https://wow.zamimg.com/images/wow/icons/tiny/calendar_darkmoonfaireelwynnstart.gif">Darkmoon Faire</a> </section>
直接使用XPath查询如 //*[contains(@id, "EU-group-holiday-line")] 可能无法获取到完整或最新的内容,因为在爬虫获取原始HTML时,JavaScript尚未执行。
当网站使用JavaScript生成内容但没有发起额外的XHR请求时,一个关键的推断是:所需数据很可能已经包含在最初加载的HTML文档或内联/外部JavaScript文件中。这意味着数据在页面加载时就已经存在于代码中,只是在DOM构建完成并执行JavaScript后才被“激活”或渲染到用户界面上。
立即学习“Java免费学习笔记(深入)”;
要提取这类数据,我们需要改变思路,不再仅仅关注渲染后的DOM结构,而是深入检查页面的原始源代码。
查看页面源代码: 使用浏览器(如Chrome、Firefox)打开目标网页,然后通过“查看页面源代码”(通常是 Ctrl+U 或右键菜单)来获取未经JavaScript处理的原始HTML内容。
利用特征字符串搜索: 在原始源代码中,搜索那些在渲染页面上可见的、具有唯一性的关键词或模式。例如,如果渲染后的链接中包含 event=479 或 event=643 这样的标识符,那么在源代码中搜索这些字符串,很可能会定位到包含这些数据的JavaScript变量、JSON字符串或HTML注释。
示例分析: 以 https://www.wowhead.com/today-in-wow 为例,如果我们要提取类似 event=479/darkmoon-faire 的事件信息,在原始页面源代码中搜索 event=643 (一个类似的事件ID),我们可能会发现以下JSON格式的子字符串:
{
"icon": "calendar_weekendmistsofpandariastart",
"name": "Timewalking Dungeon Event",
"side": "both",
"url": "/event=643/timewalking-dungeon-event"
},这个发现证实了我们的推断:所需数据以JSON格式直接嵌入在页面的初始加载内容中。
一旦定位到内嵌的数据,我们可以采用以下方法进行提取:
正则表达式与JSON解析: 对于像上面示例中发现的JSON格式数据,我们可以使用正则表达式从原始HTML字符串中匹配并提取出完整的JSON字符串。
Python 示例:
import requests
import re
import json
url = "https://www.wowhead.com/today-in-wow"
response = requests.get(url)
html_content = response.text
# 使用正则表达式匹配包含事件数据的JSON结构
# 这里的正则表达式需要根据实际情况调整,以精确匹配目标JSON块
# 假设我们知道数据在一个特定的JavaScript变量赋值或特定模式中
# 这是一个简化示例,实际可能需要更复杂的匹配逻辑
match = re.search(r'\[\s*\{[^}]*"url":\s*"/event=643/[^}]*\}\s*(?:,\s*\{[^}]*\})*\s*\]', html_content)
if match:
json_str = match.group(0)
try:
# 有时匹配到的可能不是一个完整的JSON数组,而是一个对象列表的一部分
# 需要根据实际情况判断是否需要手动补齐或调整匹配
# 假设我们匹配到的是一个完整的JSON数组或其一部分
data = json.loads(json_str)
for item in data:
if item.get("url") == "/event=643/timewalking-dungeon-event":
print("找到目标事件:")
print(f"名称: {item.get('name')}")
print(f"URL: {item.get('url')}")
print(f"图标: {item.get('icon')}")
except json.JSONDecodeError as e:
print(f"JSON解析错误: {e}")
print(f"匹配到的字符串: {json_str[:200]}...") # 打印部分字符串帮助调试
else:
print("未找到匹配的JSON数据。")
注意: 上述正则表达式是一个示意,实际应用中需要根据目标网站的HTML结构和JavaScript代码,编写更精确和鲁棒的正则表达式来捕获完整的JSON字符串或包含数据的JavaScript变量赋值。
无头浏览器(备选方案): 如果数据确实是在JavaScript执行后才完全构建到DOM中,并且无法在原始源代码中找到易于解析的JSON或变量,那么使用无头浏览器(如Selenium或Puppeteer)仍然是一个选择。无头浏览器可以模拟真实浏览器环境,执行JavaScript并等待页面完全渲染,然后通过其提供的API(如 page.evaluate() 或 driver.find_element_by_xpath())来提取数据。然而,对于本教程探讨的场景(数据已内嵌但无XHR),直接解析源代码通常更高效、资源消耗更低。
通过理解“无XHR请求时JavaScript生成内容”的本质,即数据很可能已内嵌于初始加载中,我们可以通过检查源代码和运用字符串匹配、JSON解析等技术,有效地提取这些看似难以获取的数据。这种方法提供了一种在传统爬虫和无头浏览器之间,更高效、更轻量级的解决方案。
以上就是无XHR请求时提取JavaScript动态生成内容的教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号