【问题标题】:Download files from dataframe with multiple elements and rows that contains URLs从包含 URL 的多个元素和行的数据框中下载文件
【发布时间】:2019-03-30 17:58:52
【问题描述】:

我从多个网站抓取了一些 URL,并将它们放在一个包含 145 个元素的大列表中(对于每个被抓取的网站)。每个元素在称为 X[[i]] 的列中有 90-300 行。接下来我想在列表中的 URL 中搜索“议程”一词并使用这些 URL 下载文档,但我无法执行此操作。

我目前的代码是:

## scrape urls  
  url_base <- "https://amsterdam.raadsinformatie.nl/sitemap/meetings/201%d"
    map_df(7:8, function(i){
    page <- read_html(sprintf(url_base, i))
    data_frame(urls = html_nodes(page, "a") %>% html_attr("href") )
    }) -> urls
    rcverg17_18 <- data.frame(urls[grep("raadscomm", urls$urls), ])

## clean data
  rcverg17_18v2 <- sub(" .*", "", rcverg17_18$urls)

## scrape urls from websites
  list <- map(rcverg17_18v2, function(url) {
    url <-  glue("https://amsterdam.raadsinformatie.nl{url}")
    read_html(url) %>%
    html_nodes("a") %>%
    html_attr("href")
    })
list2 <- lapply(list, as.data.frame)

这给出了一个看起来像这样的大列表:

list2

list2 list[145]                     List of length 145
[[1]] list[239 x 1] (S3: dataframe) A data.frame with 239 rows and 1 column
[[2]] list[139 x 1] (S3: dataframe) A data.frame with 139 rows and 1 column
[[3]] list[185 x 1] (S3: dataframe) A data.frame with 186 rows and 1 column
[[4]] list[170 x 1] (S3: dataframe) A data.frame with 170 rows and 1 column
[[.]] ...
[[.]] ...
[[.]] ...

一个元素包含不同的信息,例如:

list2[[1]] 

X[[i]]
1 #zoeken                                                                                            
2 #agenda_container                                                                                                                                                                 
3 #media_wrapper
4 ...

还有包含空格的 URL,例如:

104            https://amsterdam.raadsinformatie.nl/document/4851596/1/ID_17-01-11_Termijnagenda_Verkeer_en_Vervoer

我想要的是搜索其 URL 名称中包含“议程”的 URL,并使用这些 URL 下载文件。我知道我必须使用 download.file() 函数来下载文件,但我不知道具体如何。另外我不知道如何在这种类型的数据框(带有元素)中搜索 URL。谁能帮我完成代码?

请注意,仍然必须删除单元格中的空格才能下载文件。

【问题讨论】:

    标签: r url web-scraping element screen-scraping


    【解决方案1】:

    我们可以用下面的代码来实现

    # Run this code after you create list but before you create list2
    
    data.frame2 = function(x){
      data.frame(x, stringsAsFactors = F)
    }
    
    # New code for list 2  
    list2 <- lapply(list, data.frame2)
    
    # Convert list to data frame
    df = do.call(rbind.data.frame, list2)
    
    # obtain a vector of URL's which contain the work agenda
    url.vec = df[df$x %like% "agenda", ]
    
    # Remove elements of the vector which are the string "#agenda_container" (These are not URL's)
    url.vec = url.vec[url.vec != "#agenda_container"]
    
    # Obtain all URL's which contain the string "document". These URL's allow us to fetch documents. The URL's which don't contain "document" are webpages and and can not be fetched,
    url.vec = url.vec[url.vec %like% "document"]
    
    # Set the working directory
    # setwd("~/PATH WHERE YOU WOULD LIKE TO SAVE THE FILES")
    
    # Download files in a loop
    # we have to add the extension ".pdf"
    # temp.name will name your files with the last part of the URL, after the last backslash ("/")
    
    for(i in url.vec){
      temp.name = tail(unlist(strsplit(i, "\\/")), 1)
      download.file(i, destfile = paste(temp.name,".pdf") )
    }
    

    检查您的文件夹,您的所有文件都应该已下载。这是我将您的文件下载到的临时文件夹:

    【讨论】:

    • 非常感谢您提供的附加代码!看起来它可以工作,但我还没有机会测试最后一部分(您实际下载文件的部分)。我有一些问题要让 %like% 工作。不知何故,所需的软件包出错了,但我设法修复了它。如果我也能完成最后一步,我会告诉你的。
    • @RobinvdMaat :请让我知道代码是否有效,或者您是否仍有问题。 :)
    • hmm...代码为我提供了 url.vec 的空向量。这已经发生在url.vec = df[df$x %like% "agenda", ] 之后。我通过使用agenda17_18 &lt;- data.frame(df[grep("agenda", df$x), ]) agenda17_18 &lt;- data.frame(agenda17_18[agenda17_18 != "#agenda_container"]) agenda17_18 &lt;- sub(" .*", "", agenda17_18$agenda17_18.agenda17_18......agenda_container..) 解决了这个问题。这使我能够下载文件的数据框。唯一的问题是它在包含损坏的 url 时停止。如何让最后一个函数跳过损坏的 url?
    猜你喜欢
    • 2021-07-02
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多