我正在使用rvest
包来抓取页面http://www.radiolab.org/series/podcasts中的信息。刮完第一页后,我想按照底部的“下一步”链接,抓第二页,移到第三页等。
以下行给出错误:
html_session("http://www.radiolab.org/series/podcasts") %>% follow_link("Next")
## Navigating to
##
## ./2/
## Error in parseURI(u) : cannot parse URI
##
## ./2/
检查HTML显示rvest
显然不喜欢的“.//”周围有一些额外的错误:
html("http://www.radiolab.org/series/podcasts") %>% html_node(".pagefooter-next a")
## <a href=" ./2/ ">Next</a>
.Last.value %>% html_attrs()
## href
## "\n \n ./2/ "
问题1:
如何让rvest::follow_link
像我的浏览器一样正确处理此链接? (我可以手动抓取“下一步”链接并使用正则表达式进行清理,但更喜欢利用rvest
提供的自动化功能。)
在follow_link
代码的末尾,它会调用jump_to
。所以我尝试了以下内容:
html_session("http://www.radiolab.org/series/podcasts") %>% jump_to("./2/")
## <session> http://www.radiolab.org/series/2/
## Status: 404
## Type: text/html; charset=utf-8
## Size: 10744
## Warning message:
## In request_GET(x, url, ...) : client error: (404) Not Found
深入研究代码时,问题似乎是XML::getRelativeURL
,它使用dirname
去除原始路径的最后一部分(“/ podcasts”):
XML::getRelativeURL("./2/", "http://www.radiolab.org/series/podcasts/")
## [1] "http://www.radiolab.org/series/./2"
XML::getRelativeURL("../3/", "http://www.radiolab.org/series/podcasts/2/")
## [1] "http://www.radiolab.org/series/3"
问题2:
如何让rvest::jump_to
和XML::getRelativeURL
正确处理相对路径?
答案 0 :(得分:1)
由于RadioLab.com似乎仍然存在这个问题,因此您最好的解决方案是创建一个自定义函数来处理这种边缘情况。如果你只是担心这个网站 - 以及这个特殊的错误 - 那么你可以这样写:
library(rvest)
follow_next <- function(session, text ="Next", ...) {
link <- html_node(session, xpath = sprintf("//*[text()[contains(.,'%s')]]", text))
url <- html_attr(link, "href")
url = trimws(url)
url = gsub("^\\.{1}/", "", url)
message("Navigating to ", url)
jump_to(session, url, ...)
}
这将允许您编写如下代码:
html_session("http://www.radiolab.org/series/podcasts") %>%
follow_next()
#> Navigating to 2/
#> <session> http://www.radiolab.org/series/podcasts/2/
#> Status: 200
#> Type: text/html; charset=utf-8
#> Size: 61261
这本身并不是一个错误 - RadioLab上的URL格式错误,而且无法解析格式错误的URL也不是错误。如果你想在处理问题时要自由,你需要手动解决它。
请注意,您还可以使用RSelenium
启动实际浏览器(例如Chrome),并为您执行网址解析。