R语言:从HTML页面高效提取并解析内嵌JSON数据

碧海醫心
发布: 2025-10-02 13:34:01
原创
415人浏览过

R语言:从HTML页面高效提取并解析内嵌JSON数据

本教程详细介绍了在R语言中如何从包含JSON数据的HTML网页中提取并解析所需信息。针对rvest无法直接解析内嵌JSON的问题,我们将展示如何利用html_text()获取网页的原始文本内容,再结合jsonlite::parse_json()将其转换为R数据结构,并进一步处理以提取特定嵌套字段,最终获得结构化的数据。

1. 引言:识别网页中的JSON数据挑战

在进行网页数据抓取(web scraping)时,我们通常会使用r中的rvest包来解析html文档的dom(document object model)结构。然而,现代网页的内容来源多样,有时重要的结构化数据并非以标准的html标签形式存在,而是以json(javascript object notation)字符串的形式内嵌在html文档的某个部分。当遇到这种情况时,直接使用rvest的html_nodes()或html_elements()等函数来定位和提取数据会遇到困难,因为它们主要针对html标签和属性进行匹配。

例如,一个网页的源代码可能包含如下结构:

<body>
  <p>
    [
      {
        "title1" : "abc 123",
        "title2" : "bca 321",
        "title3" : "cba 213",
        "title4" : {"title5": "title6", "title7": [ -17662.3456, 987621.7654]}
      },
      ...
    ]
  </p>
</body>
登录后复制

我们的目标是从这种内嵌的JSON结构中,例如,提取所有"title7"字段的数值数据,并将其整理成一个结构化的数据框。

2. 初步尝试与局限性

首先,我们可以使用rvest包加载网页内容:

# 加载必要的库
library(rvest)
library(httr) # 尽管本例中未直接使用,但httr常用于更复杂的HTTP请求

# 假设的网页URL
url <- "https://mywebsite.com" 

# 读取网页内容
# 注意:read_html函数会尝试将内容解析为HTML文档
page <- read_html(url)

# 查看page对象的基本信息
print(page)
str(page)
登录后复制

此时,page对象是一个html_document类型,包含了网页的DOM结构。如果尝试直接使用html_nodes()来查找JSON中的键(例如"title4"),会发现无法获取任何结果,因为"title4"并非HTML标签:

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

library(dplyr) # 用于管道操作符 %>%

# 尝试通过HTML节点选择器提取"title4"
page %>% html_nodes("title4")

# 结果将是:
# {xml_nodeset (0)}
# 这表明没有找到匹配的HTML节点
登录后复制

这证实了我们的假设:JSON数据是作为纯文本嵌入在HTML中的,而不是作为可被HTML解析器识别的结构。

3. 核心解决方案:提取原始文本与JSON解析

解决这个问题的关键在于两个步骤:首先,从HTML文档中提取包含JSON的原始文本字符串;其次,使用专门的JSON解析库将该字符串转换为R的数据结构。

3.1 步骤一:获取HTML的纯文本内容

rvest包提供了一个非常有用的函数html_text(),它可以提取HTML节点或整个文档的纯文本内容。对于本例,由于JSON数据是直接作为<body>或某个<p>标签的文本内容存在的,我们可以直接对整个page对象或包含JSON的特定节点使用html_text()。

# 提取整个HTML文档的纯文本内容
# 如果JSON数据是body内唯一的文本内容,直接对page使用是可行的。
# 更稳健的做法是先定位到包含JSON的特定HTML节点(如本例中的<p>),再提取其文本。
# 假设JSON字符串是body内唯一的或主要的文本内容
json_raw_text <- page %>% html_text()

# 打印部分文本内容以验证
cat(substr(json_raw_text, 1, 500)) # 打印前500个字符
登录后复制

执行上述代码后,json_raw_text变量将包含一个长字符串,其中就包括了我们想要的JSON数据。

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online30
查看详情 Find JSON Path Online

3.2 步骤二:使用jsonlite解析JSON字符串

R语言中处理JSON数据的标准库是jsonlite。它提供了parse_json()(或更常用的fromJSON())函数,可以将JSON字符串解析为R的列表、数据框等数据结构。一个非常重要的参数是simplifyDataFrame = TRUE,它会尝试将JSON数组自动转换为数据框,大大简化了后续的数据处理。

# 加载jsonlite库
library(jsonlite)

# 使用parse_json解析原始JSON文本
# simplifyDataFrame = TRUE 会尝试将JSON数组解析为数据框
parsed_data <- parse_json(json_raw_text, simplifyDataFrame = TRUE)

# 查看解析后的数据结构
str(parsed_data)
登录后复制

str(parsed_data)的输出将显示一个结构化的R对象,很可能是一个数据框(如果顶层JSON是一个数组),其中嵌套的JSON对象和数组会被转换为列表或嵌套的数据框。例如,它可能会显示:

# 'data.frame':   n obs. of  4 variables:
#  $ title1: chr  "abc 123" "aec 183" ...
#  $ title2: chr  "bca 321" "bga 351" ...
#  $ title3: chr  "cba 213" "cha 293" ...
#  $ title4:'data.frame':   n obs. of  2 variables:
#   ..$ title5: chr  "title6" "title6" ...
#   ..$ title7:List of n
#   .. ..$ : num  -17662 987622
#   .. ..$ : num  -1.62e+09 6.52e+08
登录后复制

这表明JSON数据已经被成功解析为一个包含嵌套数据框和列表的R数据框。

4. 数据提取与重塑

现在数据已经解析为R对象,我们可以轻松地访问和提取所需的信息。根据原始需求,我们需要提取"title7"中的两个数值。parsed_data$title4$title7会返回一个列表,其中每个元素都是一个包含两个数值的向量。

# 访问嵌套的"title7"数据
title7_list <- parsed_data$title4$title7

# 将列表中的向量绑定成一个矩阵
# do.call(rbind, ...) 是将列表中的每个元素作为行绑定起来的常用方法
final_result_matrix <- do.call(rbind, title7_list)

# 查看最终结果
print(final_result_matrix)
登录后复制

最终输出将是一个矩阵,其结构符合我们的预期:

#               [,1]        [,2]
# [1,] -1.766235e+04    987621.8
# [2,] -1.621626e+09 652238322.1
# ...
登录后复制

如果需要将其转换为带有列名的数据框,可以进一步操作:

final_result_df <- as.data.frame(final_result_matrix)
colnames(final_result_df) <- c("title7_1", "title7_2")
final_result_df$id <- 1:nrow(final_result_df) # 添加一个ID列
print(final_result_df)
登录后复制

5. 注意事项与最佳实践

  • JSON字符串的准确性: 确保从html_text()提取的字符串是有效的JSON格式。如果字符串中包含额外的HTML标签或不相关的文本,parse_json()可能会报错。在实际应用中,可能需要使用正则表达式(grep/gsub)来精确地从原始文本中提取出JSON字符串。
  • simplifyDataFrame参数: jsonlite::parse_json()的simplifyDataFrame = TRUE参数非常强大,但对于极其复杂的嵌套JSON结构,它可能无法完全按预期简化。在这种情况下,可能需要手动遍历列表结构或分步解析。
  • 错误处理: 在生产环境中,建议使用tryCatch来捕获可能发生的解析错误,例如网络问题导致页面加载失败,或者JSON格式不正确。
  • 性能考量: 对于非常大的网页或包含巨型JSON字符串的网页,html_text()和parse_json()的性能通常是可接受的,但仍需注意内存消耗。
  • 直接API调用: 如果网页中的JSON数据实际上是通过某个API请求获取的,并且该API的URL是已知的,那么最直接和高效的方法是使用httr::GET()直接请求API,然后使用jsonlite::fromJSON()解析响应内容,而不是通过rvest解析HTML。本教程的方法适用于JSON数据直接嵌入HTML文档的情况。

6. 总结

本教程展示了在R语言中处理网页中内嵌JSON数据的一种高效且健壮的方法。通过结合rvest包的read_html()和html_text()函数来获取原始的JSON字符串,再利用jsonlite包的parse_json()函数进行解析,我们可以成功地从复杂的网页结构中提取出所需的结构化数据。理解网页内容的实际编码方式(HTML DOM vs. 内嵌JSON)是选择正确解析工具和策略的关键。掌握这种方法将极大地扩展R语言在网页数据抓取方面的能力。

以上就是R语言:从HTML页面高效提取并解析内嵌JSON数据的详细内容,更多请关注php中文网其它相关文章!

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

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