R Web从不同的URL抓取

时间:2018-01-16 15:09:20

标签: r dataframe web-scraping

我正在网页上抓一页

http://catalog.ihsn.org/index.php/catalog#_r=&collection=&country=&dtype=&from=1890&page=1&ps=100&sid=&sk=&sort_by=nation&sort_order=&to=2017&topic=&view=s&vk=

通过以下代码,我从这个网址构建了一个数据框:

dflist <- map(.x = 1:417, .f = function(x) {
 Sys.sleep(5)
 url <- ("http://catalog.ihsn.org/index.php/catalog#_r=&collection=&country=&dtype=&from=1890&page=1&ps=100&sid=&sk=&sort_by=nation&sort_order=&to=2017&topic=&view=s&vk=")
read_html(url) %>%
html_nodes(".title a") %>%
html_text() %>%
as.data.frame()
}) %>% do.call(rbind, .)

为了得到我感兴趣的所有数据,我重复了相同的代码,它似乎工作得很好,但由于Sys.sleep()的缘故,当然有点慢。

一旦我试图抓住应该包含在数据框中的单个项目描述,我的问题就出现了。

例如,第一个项目描述位于

http://catalog.ihsn.org/index.php/catalog/7118/study-description

第二个项目描述位于

http://catalog.ihsn.org/index.php/catalog/6606/study-description

等等。

我的问题是我无法找到一种动态的方式来抓取所有项目的页面并将它们插入到数据框中,即URL中的数字不是渐进的,也不是链接的末尾。

为了使事情更清楚,这是我正在抓取的网站的结构:

1.http://catalog.ihsn.org/index.php/catalog#_r=&collection=&country=&dtype=&from=1890&page=1&ps=100&sid=&sk=&sort_by=nation&sort_order=&to=2017&topic=&view=s&vk=
   1.1.   http://catalog.ihsn.org/index.php/catalog/7118
        1.1.a http://catalog.ihsn.org/index.php/catalog/7118/related_materials
        1.1.b http://catalog.ihsn.org/index.php/catalog/7118/study-description
        1.1.c. http://catalog.ihsn.org/index.php/catalog/7118/data_dictionary

我已经成功地抓住了1级但不能达到1.1.b. (学习 - 描述),我感兴趣的,因为URL的动态元素(在这种情况下:7118)在该级别的6000页以上的网站中不一致。

1 个答案:

答案 0 :(得分:0)

您必须从.title a中提取更深层的网址,然后将其删除。以下是使用rvesttidyverse

进行操作的小例子
library(tidyverse)
library(rvest)

scraper <- function(x) {

  Sys.sleep(5)
  url <- sprintf("http://catalog.ihsn.org/index.php/catalog#_r=&collection=&country=&dtype=&from=1890&page=%s&ps=100&sid=&sk=&sort_by=nation&sort_order=&to=2017&topic=&view=s&vk=", x)

  html <- read_html(url)

  tibble(title = html_nodes(html, ".title a") %>% html_text(trim = TRUE),
         project_url = html_nodes(html, ".title a") %>% html_attr("href")) 
}

result <- map_df(1:2, scraper) %>% 
  mutate(study_description = map(project_url, ~read_html(sprintf("%s/study-description", .x)) %>% html_node(".xsl-block") %>% html_text()))

对于您想要做的所有事情,这是不完整的,但应该向您展示一种方法。