以下脚本允许我访问具有多个具有相似名称的链接的网站。我想只获得其中一个,因为它在网站上以粗体打印,因此可能与其他部分不同。但是,我找不到在列表中选择粗体链接的方法。
有人会对此有所了解吗? 提前谢谢!
library(httr)
library(rvest)
sp="Alnus japonica"
res <- httr::POST(url ="http://apps.kew.org/wcsp/advsearch.do",
body = list(page ="advancedSearch",
AttachmentExist ="",
family ="",
placeOfPub ="",
genus = unlist(strsplit(as.character(sp), split=" "))[1],
yearPublished ="",
species = unlist(strsplit(as.character(sp), split=" "))[2],
author ="",
infraRank ="",
infraEpithet ="",
selectedLevel ="cont"),
encode ="form")
pg <- content(res, as="parsed")
lnks <- html_attr(html_nodes(pg,"a"),"href")
#how get the url of the link wth accepted name (in bold)?
res2 <- try(GET(sprintf("http://apps.kew.org%s", lnks[grep("id=",lnks)] [1])),silent=T)
#this gets a link but often fails to get the bold one
答案 0 :(得分:9)
首先,抓住tidy-html5
(它适用于几乎所有内容)并安装它并确保它位于PATH
。
正如我的评论所说,浏览器会在<b>
之外处理<p>
,因为它们需要防弹。 libxml2
没有。所以,我们需要首先清理它(我现在需要创建一个新的tidyhtml
包)然后处理整理版本:
library(xml2)
library(httr)
library(rvest)
res <- httr::POST(url ="http://apps.kew.org/wcsp/advsearch.do",
body = list(page ="advancedSearch",
AttachmentExist ="",
family ="",
placeOfPub ="",
genus = "Alnus",
yearPublished ="",
species = "japonica",
author ="",
infraRank ="",
infraEpithet ="",
selectedLevel ="cont"),
encode ="form")
tf <- tempfile(fileext=".html")
cat(content(res, as="text"), file=tf)
tidy <- system2("tidy", c("-q", tf), TRUE)
pg <- read_html(paste0(tidy, sep="", collapse=""))
html_nodes(pg, xpath=".//p/b/a[contains(@href, 'name_id')]")
## {xml_nodeset (1)}
## [1] <a href="/wcsp/namedetail.do?name_id=6471" class="onwa ...
如果需要通过XPath选择CSS选择器:
html_nodes(pg, "p > b > a[href*='name_id']")
<强>更新强>
我为libtidy
启动了一个基本的pkg包装器。如果您使用的是OS X并使用Homebrew,您可以执行:brew install tidy-html5
(安装上面的二进制文件和libtidy
库)和devtools::install_github("hrbrmstr/tidyhtml")
来安装pkg。然后,它只是:
library(xml2)
library(httr)
library(rvest)
library(htmltidy)
res <- httr::POST(url ="http://apps.kew.org/wcsp/advsearch.do",
body = list(page ="advancedSearch",
AttachmentExist ="",
family ="",
placeOfPub ="",
genus = "Alnus",
yearPublished ="",
species = "japonica",
author ="",
infraRank ="",
infraEpithet ="",
selectedLevel ="cont"),
encode ="form")
tidy_html <- tidy(content(res, as="text"))
pg <- read_html(tidy_html)
html_nodes(pg, "p > b > a[href*='name_id']")
我应该可以在Windows&amp; linux并使它成为一个真正的包(它是一个薄的包装器,现在没有错误检查)但是这将在TODO上停留一段时间。
答案 1 :(得分:1)
我觉得此处可能存在rvest
/ httr
的错误,因为<b>
似乎在相关链接上围绕<a href...>
,但在解析时没有版本
我用过:
library(rvest)
sp=strsplit("Alnus japonica", " ")[[1]]
session <- html_session("http://apps.kew.org/wcsp/advsearch.do")
form <- html_form(session)[[1]]
filled_form <- set_values(form, genus = sp[1], species = sp[2])
out <- submit_form(session, filled_form)
请看以下内容:
out %>% html_nodes(xpath = "descendant-or-self::*") %>% `[`(81:90)
# {xml_nodeset (10)}
# [1] <p><a href="/wcsp/namedetail.do;jsessionid=F6180417706056852E58C1E290B5087A? ...
# [2] <a href="/wcsp/namedetail.do;jsessionid=F6180417706056852E58C1E290B5087A?nam ...
# [3] <i>Alnus</i>
# [4] <i> japonica</i>
# [5] <b>\n </b>
# [6] <p><a href="/wcsp/namedetail.do;jsessionid=F6180417706056852E58C1E290B5087A? ...
# [7] <a href="/wcsp/namedetail.do;jsessionid=F6180417706056852E58C1E290B5087A?nam ...
# [8] <i>Alnus</i>
# [9] <i> japonica</i>
# [10] <p><a # href="/wcsp/namedetail.do;jsessionid=F6180417706056852E58C1E290B5087A? ...
如您所见,<b>
节点显示为空。但是,当我在Chrome上手动输入搜索并View Source
时,我会看到:
<b>
<p><a href="/wcsp/namedetail.do?name_id=6471" class="onwardnav"><i>Alnus</i><i> japonica</i> (Thunb.) Steud., Nomencl. Bot., ed. 2, 1: 55 (1840).</a>
</p>
</b>
相关的<a>
介于<b>
和</b>
之间,告诉我它应该是<b>
的孩子,但这一点是空白的:
out %>% html_nodes(xpath = "//b/child::*")
我承认不是xpath
专家,所以我可能会把事情弄糟。希望这有助于您顺利前进。