使用 rvest 在 R 中抓取网页:问题查找标签

时间:2021-01-19 11:40:45

标签: css r

我正在尝试使用 rvest 库来注释 url 的一些数据。 这个过程在以前的 url 和数据上运行良好,但这次我在为我想要提取的数据找到相关的 CSS“标签”时遇到了困难。

网址是: https://gnomad.broadinstitute.org/variant/8-52733231-G-A?dataset=gnomad_r2_1 我对欧洲等位基因频率的价值特别感兴趣(见图):

enter image description here

我试图通过在源代码中搜索来找到与此号码相关的 CSS 标记。我还尝试了一些 chrome 扩展来显示标签(SelectorGadget)......但我所有的尝试都失败了。结果总是一样的:{xml_nodeset(0)}

我的代码是:

url <-'https://gnomad.broadinstitute.org/variant/8-52733231-G-A?dataset=gnomad_r2_1'
webpage <- read_html(url)
europ.freq<- html_nodes(webpage,'CSS_tag')
europ.freq

谁能帮我解决这个问题??

非常感谢提前!!!!!!!!!

2 个答案:

答案 0 :(得分:0)

这将是一个很长的答案。但是当我开始抓取这些网站时,我很挣扎。所以我只想给你一个关于正在发生的事情的背景。

为什么会这样?

结果中出现空列表的原因很简单:因为节点不存在!

您可以通过打印 read_html(url) 函数在这种情况下返回的原始 html 源代码自行查看

> webpage %>% as.character()
[1] "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>gnomAD</title>\n<meta charset=\"utf-8\">\n<meta name=\"description\" content=\"The Genome Aggregation Database (gnomAD) is a resource developed by an international coalition of investigators, with the goal of aggregating and harmonizing both exome and genome sequencing data from a wide variety of large-scale sequencing projects, and making summary data available for the wider scientific community.\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css\">\n<link rel=\"search\" href=\"/opensearch.xml\" type=\"application/opensearchdescription+xml\" title=\"gnomAD\">\n<style>body,html{height:100%;width:100%;background-color:#fafafa;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell,\"Helvetica Neue\",sans-serif;font-size:14px}@media print{body,html{background:0 0}}</style>\n</head>\n<body>\n<div id=\"root\"></div>\n<script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-85987017-1\"></script><script>function gtag(){dataLayer.push(arguments)}window.gaTrackingId=\"UA-85987017-1\",window.dataLayer=window.dataLayer||[],gtag(\"js\",new Date),gtag(\"config\",\"UA-85987017-1\",{send_page_view:!1}),window.gtag=gtag</script><script src=\"/js/bundle-8c98b722b9c7c14b5bbc.js\"></script>\n</body>\n</html>\n"

如您所见,html 代码非常小。那里不多。这是因为您对 R 中的 url 发出的此请求仅返回网页的空模板。在您的 Web 浏览器中,此网页是动态构建的。您的第一个请求会启动一系列后续请求,这些请求会执行 JS 脚本、下载图像、下载数据……所有这些后续请求都会更新您网页的内容,以便您获得在浏览器中看到的最终结果。

如果您查看 chrome 的开发者工具(下图),您可以看到所有这些请求链

enter image description here

顶部的请求是您使用 read_html 发出的请求。然后它返回的网页会被所有这些后续请求更新。

通常,这些类型的仪表板应用程序会在中间发出一个特定请求,该请求返回一个包含所有数据的 json 字符串以填充网站。在 chrome 中,您可以通过单击屏幕顶部的“XHR”按钮来过滤 json 响应。在这个特定案例中,我用红色箭头标记了该请求。

因此,一种解决方案是查看 json 响应并找到包含您想要的数据的响应。然后在 R 中重复此请求(在本例中为 POST 请求)并使用 json 解析函数(如 jsonlite::fromJSON())解析响应。

但我的经验是,有时有效,有时无效。我并不总是确定如何向服务器发出特定请求。有时会出现格式问题。有时您的浏览器会设置一些状态变量,您必须弄清楚如何去做...

一个可能更好的解决方案是使用 RSelenium(我最近才开始尝试使用)

RSelenium 的解决方案

关于 RSelenium 的几个不错的教程:

https://cran.r-project.org/web/packages/RSelenium/vignettes/basics.html http://joshuamccrain.com/tutorials/web_scraping_R_selenium.html

使用 RSelenium,您实际上是在运行网络浏览器。因此,所有这些后续调用也在发生。网页是动态构建的,您拥有正在寻找的节点(和数据)。

我运行的是 Mac,我无法让 RSelenium 与 Google Chrome 一起使用。使用火狐它完美地工作。也许它对你有用。我还在学习RSelenium的细节。因此,也许您可​​以在 rsDriver 中更改其中一些参数。

library(rvest)
library(RSelenium)

rD <- rsDriver(browser = c("firefox"), port = 4568L,
               chromever = NULL,
               iedrver = NULL, 
               phantomver = NULL,
               version="3.141.59")
remDr <- rD[["client"]]

remDr$navigate('https://gnomad.broadinstitute.org/variant/8-52733231-G-A?dataset=gnomad_r2_1')

# remDr$getPageSource() returns a list with the html code as string
# use read_html to convert it into something that rvest can parse
webpage <- remDr$getPageSource()[[1]] %>% read_html()

# html_table() returns all tables in the webpage as data frames
# the one you want is the second one
df.table <- webpage %>% html_table() %>% .[[2]]

# close browser and stop server
rD$client$close()
rD$server$stop()

print(df.table)

(请注意,我没有通过 css 标签进行搜索,因为在您的示例中,获取整个表格更容易。但如果您愿意,也可以通过 css 标签获取特定节点)

结果是:

                 Population               Population Allele Count Allele Number Number of Homozygotes Allele Frequency
1    European (non-Finnish)   European (non-Finnish)        13779         65426                     0           0.2106
2  African/African-American African/African-American         2264         14050                     0           0.1611
3               South Asian              South Asian         2193         13982                     0           0.1568
4   Latino/Admixed American  Latino/Admixed American         2792         18084                     0           0.1544
5                East Asian               East Asian         1869         12272                     0           0.1523
6        European (Finnish)       European (Finnish)         1665         12042                     0           0.1383
7          Ashkenazi Jewish         Ashkenazi Jewish          592          4344                     0           0.1363
8                     Other                    Other          509          3888                     0           0.1309
9                    Female                   Female        11460         66844                     0           0.1714
10                     Male                     Male        14203         77244                     0           0.1839
11                    Total                    Total        25663        144088                     0           0.1781

您想要的数据值在 df.table$`Allele Frequency`[1] 中。

您可以执行更多操作,例如单击网页或提交表单以更新页面中的数据。我建议看看我上面列出的那两个链接。我也在学习它。

答案 1 :(得分:0)

哇,奇科拉斯顿!

非常感谢您的详细解答和善意。我真的很欣赏它!!!!! :D :D :D :D 在定义了 Firefox 的二进制路径的一些问题之后,我终于解决了:

rs <- rsDriver(browser = "firefox", 
               extraCapabilities = list(`mox:firefoxOptions` = list(binary = "C://Program Files (x86)//Mozilla Firefox//firefox.exe")))

它工作得很好!!!! :D

谢谢谢谢谢谢!!