值得一看
双11 12
广告
广告

R语言进阶网页抓取:处理JavaScript动态加载的数据

R语言进阶网页抓取:处理JavaScript动态加载的数据

本文旨在教授如何使用R语言处理通过JavaScript动态加载的网页数据。针对传统网页抓取工具(如XML或rvest)无法直接获取此类数据的挑战,文章将详细介绍如何利用V8包模拟JavaScript执行环境,直接从JavaScript文件中提取所需数据。通过一个具体的案例,我们将演示如何识别数据源、获取JavaScript内容、在R环境中运行JavaScript代码,并对提取的数据进行清洗和整理,从而高效、准确地获取动态生成的网页信息。

1. 动态网页数据抓取的挑战

在网页数据抓取(web scraping)中,我们经常会遇到数据并非直接嵌入在html结构中,而是通过javascript动态生成的情况。传统的r包,如xml或rvest,主要依赖于解析静态html内容。当目标数据通过javascript异步请求(ajax)或直接内嵌在javascript变量中时,这些工具往往无法直接获取到所需信息。

以从https://www.fatf-gafi.org/countries/网站抓取国家列表为例,初步尝试使用XML::htmlParse可能无法获取到预期的国家数据,因为这些数据并非以标准HTML表格(

)的形式存在,而是嵌套在

元素中,且由JavaScript动态填充。在这种情况下,我们需要一种能够执行JavaScript代码并访问其内部变量的解决方案。

2. 解决方案:利用V8包执行JavaScript

R语言的V8包提供了一个嵌入式JavaScript和WebAssembly引擎,允许我们在R环境中执行JavaScript代码,并与JavaScript运行时环境进行交互。这意味着我们可以加载网页中使用的JavaScript文件,执行其中的代码,然后提取在JavaScript中定义的变量值。

核心思路:

  1. 识别JavaScript数据源: 通过浏览器开发者工具(Network/网络标签页)检查网页加载过程中请求的资源,特别是.js文件,寻找可能包含目标数据的JavaScript文件。
  2. 获取JavaScript内容: 使用httr包下载该JavaScript文件的内容。
  3. 初始化V8引擎: 创建一个V8上下文。
  4. 执行JavaScript代码: 将下载的JavaScript内容在V8上下文中执行。
  5. 提取变量: 从V8上下文中获取JavaScript变量的值。
  6. 数据清洗: 对提取到的数据进行必要的格式转换和清洗。

3. 实战案例:抓取FATF网站的国家数据

我们将以FATF(金融行动特别工作组)网站为例,演示如何抓取其国家列表。

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

3.1 识别数据源

通过访问https://www.fatf-gafi.org/countries/并打开浏览器开发者工具,在“网络”或“Network”标签页中,我们可以观察到页面加载过程中会请求一个名为country-data-multi-lang.js的JavaScript文件。经验证,这个文件包含了我们所需的所有国家数据,以一个名为countries的JavaScript数组变量形式存在。

该JavaScript文件的完整URL通常是:https://www.fatf-gafi.org/media/fatf/fatfv20/js/country-data-multi-lang.js。

3.2 实施步骤与代码示例

首先,确保你已经安装了所需的R包:httr、V8、dplyr和tidyr。

# 载入所需库
library(httr)    # 用于发送HTTP请求
library(V8)      # 用于执行JavaScript
library(dplyr)   # 用于数据操作
library(tidyr)   # 用于数据整理,特别是unnest函数
# 1. 定义JavaScript数据文件的URL
js_url <- 'https://www.fatf-gafi.org/media/fatf/fatfv20/js/country-data-multi-lang.js'
# 2. 使用httr包获取JavaScript文件的内容
# content(GET(js_url), 'text') 将GET请求的响应内容解析为文本
js_content <- content(GET(js_url), 'text')
# 3. 初始化V8上下文
# ct <- v8() 创建一个新的V8引擎上下文
ct <- v8()
# 4. 在V8上下文中执行JavaScript代码
# ct$eval(js_content) 会执行js_content中的所有JavaScript代码
# 这将使得js_content中定义的变量(例如'countries')在V8上下文中可用
ct$eval(js_content)
# 5. 从V8上下文中提取'countries'变量的值
# ct$get("countries") 将JavaScript中的'countries'变量转换为R的数据结构
# 经验证,'countries'是一个嵌套的数据结构,其中'groups'列是列表形式
country_data_raw <- ct$get("countries")
# 6. 数据清洗与整理
# 使用tidyr::unnest() 将嵌套的'groups'列展开
# select() 选择我们感兴趣的列。这里的列索引是根据实际数据结构确定的,
# 建议在实际操作中先查看数据框的列名和结构,再进行选择。
# filter(!is.na(name)) 过滤掉name列为NA的行,通常这些是无效或填充行。
final_country_data <- country_data_raw %>%
unnest(cols = c(groups)) %>% # 展开嵌套的 'groups' 列
select(c(1:2, 4:14, 16)) %>% # 选择特定列,这些列包含了国家名称、代码及相关组织信息
filter(!is.na(name))        # 过滤掉国家名称为空的行
# 查看最终的数据结构和前几行
print(final_country_data)
# str(final_country_data) # 查看数据结构

3.3 代码解释

  • httr::GET() 和 content(): 用于发起HTTP GET请求并获取响应内容。’text’参数确保内容被解析为字符串。
  • v8(): 创建一个V8引擎实例,它提供了一个独立的JavaScript运行环境。
  • ct$eval(js_content): 这是核心步骤。它将从网站下载的JavaScript代码在V8引擎中执行。执行后,该JavaScript代码中定义的任何全局变量(例如本例中的countries)都可以在R中访问。
  • ct$get(“countries”): 从V8引擎中提取名为countries的JavaScript变量的值。V8包会自动将其转换为R中对应的数据结构(通常是列表或数据框)。
  • unnest(cols = c(groups)): 观察到ct$get(“countries”)返回的数据框中,有一列名为groups,其内部是一个嵌套的列表或数据框。unnest()函数(来自tidyr包)用于将这些嵌套结构展开为扁平的列,使得数据更易于分析。
  • select(c(1:2, 4:14, 16)): 经过unnest操作后,数据框可能包含多余的列或者需要重新排列的列。这里通过列索引选择最终需要的列。在实际应用中,建议先打印names(final_country_data)或使用glimpse()来查看所有列名,然后按名称选择,以提高代码的可读性和健壮性。
  • filter(!is.na(name)): 过滤掉name列为NA(缺失值)的行。在某些数据源中,末尾可能会有填充的空行,通过这种方式可以清除。

4. 注意事项与总结

  • JavaScript源定位: 找到正确的JavaScript文件是关键。熟练使用浏览器开发者工具(尤其Network/网络和Sources/源标签页)是必备技能。
  • 数据结构探索: 从V8中获取的数据可能是一个复杂的嵌套列表。使用str()、names()、glimpse()等函数来探索其结构,以便正确地使用unnest()、select()等函数进行数据清洗。
  • 动态内容复杂性: 并非所有动态内容都能通过V8直接提取。如果数据是通过复杂的DOM操作、用户交互或加密方式加载,可能需要更高级的工具,如selenium配合无头浏览器进行模拟。但对于数据直接存在于某个JavaScript变量中的情况,V8是一个轻量且高效的选择。
  • 网站政策: 在进行任何网页抓取活动前,请务必查阅网站的robots.txt文件和使用条款,确保你的行为符合网站的规定。

通过本文的学习,你应该能够掌握使用R语言V8包处理JavaScript动态加载数据的基本方法。这种技术极大地扩展了R在网页数据抓取方面的能力,使其能够应对更复杂的现代网页结构。

温馨提示: 本文最后更新于2025-08-08 22:39:13,某些文章具有时效性,若有错误或已失效,请在下方留言或联系易赚网
文章版权声明 1 本网站名称: 创客网
2 本站永久网址:https://new.ie310.com
1 本文采用非商业性使用-相同方式共享 4.0 国际许可协议[CC BY-NC-SA]进行授权
2 本站所有内容仅供参考,分享出来是为了可以给大家提供新的思路。
3 互联网转载资源会有一些其他联系方式,请大家不要盲目相信,被骗本站概不负责!
4 本网站只做项目揭秘,无法一对一教学指导,每篇文章内都含项目全套的教程讲解,请仔细阅读。
5 本站分享的所有平台仅供展示,本站不对平台真实性负责,站长建议大家自己根据项目关键词自己选择平台。
6 因为文章发布时间和您阅读文章时间存在时间差,所以有些项目红利期可能已经过了,能不能赚钱需要自己判断。
7 本网站仅做资源分享,不做任何收益保障,创业公司上收费几百上千的项目我免费分享出来的,希望大家可以认真学习。
8 本站所有资料均来自互联网公开分享,并不代表本站立场,如不慎侵犯到您的版权利益,请联系79283999@qq.com删除。

本站资料仅供学习交流使用请勿商业运营,严禁从事违法,侵权等任何非法活动,否则后果自负!
THE END
喜欢就支持一下吧
点赞14赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容