使用rvest跟随"相对路径"的"下一步"链接

dnl*_*rky 7 html r web-scraping rvest

我正在使用该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/  
Run Code Online (Sandbox Code Playgroud)

检查HTML显示"./ /"周围有一些额外的错误,rvest显然不喜欢:

html("http://www.radiolab.org/series/podcasts") %>% html_node(".pagefooter-next a")
## <a href="&#10;    &#10;      ./2/  ">Next</a> 

.Last.value %>% html_attrs()
##                   href 
## "\n    \n      ./2/  "
Run Code Online (Sandbox Code Playgroud)

问题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
Run Code Online (Sandbox Code Playgroud)

深入研究代码,看起来就是问题所在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"
Run Code Online (Sandbox Code Playgroud)

问题2: 如何获得rvest::jump_toXML::getRelativeURL正确处理相对路径?

Mic*_*ths 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, ...)
}
Run Code Online (Sandbox Code Playgroud)

这将允许您编写如下代码:

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
Run Code Online (Sandbox Code Playgroud)

这本身并不是一个错误 - RadioLab 上的 URL 格式错误,并且无法解析格式错误的 URL 不是错误。如果您想自由地处理问题,则需要手动解决它。

请注意,您还可以使用RSelenium启动实际的浏览器(例如 Chrome)并让它为您执行 URL 解析。