【问题标题】:Scraping escaped JSON data within a <script type="text/javascript"> in R在 R 中的 <script type="text/javascript"> 中抓取转义的 JSON 数据
【发布时间】:2020-02-25 14:57:28
【问题描述】:

我目前正在尝试从以下 html 页面上的两个图表中抓取数据(来自那里列出的两个图表的信息:Forsmark 和 Ringhals):https://group.vattenfall.com/se/var-verksamhet/vara-energislag/karnkraft/aktuell-karnkraftsproduktion

数据来源于这样的脚本标签(片段)

<script type="text/javascript">
/*<![CDATA[*/ productionData = JSON.parse("{\"timestamp\":1582642616000,\"powerPlant\":\"Ringhals\", // etc
</script>

我想要两个如下所示的数据框:

F1          F2          F3       
number      number      number 

R1          R2          R3       
number      number      number  

我尝试使用 XML 和 xpath 来解析一个 html 页面,但没有得到任何结果。

你有什么想法吗?

谢谢!

【问题讨论】:

标签: html r json web-scraping


【解决方案1】:

那些图表是 &lt;iframe&gt;s 加载自

所以你应该直接刮掉这两页。

这是一个有趣的挑战。

使用rvestjsonlite 并不太难,如果您还没有安装它们,则必须安装。两者都需要rtools

试试这个:

library('rvest')
library('jsonlite')

# Load the URL (do the same for the other iframe)
url <- 'https://gvp.vattenfall.com/sweden/produced-power/iframe/forsmark'

# Parse it
webpage <- read_html(url)

# Extract the script element. That's a CSS selector for the specific one that holds the json data
# You can find it in your browser's DevTools by finding the script element
# and right-clicking, choosing Copy > CSS Path/Selector
script_element <- html_nodes(webpage, 'body > section:nth-child(2) > script:nth-child(2)')

# Extract its string content
json = html_text(script_element)

# Clean it up
json = gsub("\n        /*<![CDATA[*/\n        productionData = JSON.parse(", "", json, fixed=TRUE)
json = gsub(");\n        /*]]>*/\n    ", "", json, fixed=TRUE)
json = gsub("\"{", "{\"", json, fixed=TRUE)
json = gsub("}\"", "}", json, fixed=TRUE)
json = gsub("{\"\\\"", "{\\\"", json, fixed=TRUE)

# Extract data
data = jsonlite::fromJSON(gsub("\\\"", "\"", json, fixed=TRUE))

警告:我并不是真正的 R 专家,可能有更优雅的方式来执行此操作(尤其是数据清理部分)。但它有效。

为了历史保存,取这个DOM节点(&lt;script&gt;标签的文本内容):

"\n        /*<![CDATA[*/\n        productionData = JSON.parse(\"{\\\"timestamp\\\":1582643336000,\\\"powerPlant\\\":\\\"Forsmark\\\",\\\"blockProductionDataList\\\":[{\\\"name\\\":\\\"F1\\\",\\\"production\\\":998.86194,\\\"percent\\\":99.88619},{\\\"name\\\":\\\"F2\\\",\\\"production\\\":1120.434,\\\"percent\\\":97.8545},{\\\"name\\\":\\\"F3\\\",\\\"production\\\":1189.7126,\\\"percent\\\":99.55754}]}\");\n        /*]]>*/\n    "

会产生这种格式的数据

> data
$timestamp
[1] 1.582647e+12

$powerPlant
[1] "Forsmark"

$blockProductionDataList
  name production  percent
1   F1   997.7902 99.77902
2   F2  1131.6150 98.83100
3   F3  1190.0520 99.58594

【讨论】:

  • 非常感谢您的详细解答和解释!效果很好。
  • @Kat 真棒,我很高兴!完成工作很有趣,这是一个非常不寻常的案例(对我来说),JSON 实际上是在脚本标签中的页面内转义的。
猜你喜欢
  • 2020-10-17
  • 2017-07-25
  • 2019-11-26
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2011-05-13
  • 2016-12-12
  • 2014-01-13
相关资源
最近更新 更多