【问题标题】:Web scraping PDF files from a map网络从地图中抓取 PDF 文件
【发布时间】:2019-02-02 10:15:17
【问题描述】:

我一直在尝试按照此代码下载嵌入在地图中的 pdf(可以在 here 找到原始文件)。每个 pdf 都涉及巴西的一个自治市(5,570 个文件)。

library(XML)
library(RCurl)
url <- "http://simec.mec.gov.br/sase/sase_mapas.php?uf=RJ&tipoinfo=1"
page   <- getURL(url)
parsed <- htmlParse(page)
links  <- xpathSApply(parsed, path="//a", xmlGetAttr, "href")
inds   <- grep("*.pdf", links)
links  <- links[inds]
regex_match <- regexpr("[^/]+$", links, perl=TRUE)
destination <- regmatches(links, regex_match)
for(i in seq_along(links)){
  download.file(links[i], destfile=destination[i])
  Sys.sleep(runif(1, 1, 5))
}

我已经在其他项目中使用过该代码几次,并且成功了。对于这种特定情况,它没有。事实上,我已经尝试了很多方法来抓取这些文件,但对我来说似乎是不可能的。最近,我得到了以下链接。然后可以结合 uf(状态)和 muncod(市政代码)来下载文件,但我不知道如何将其包含到代码中。

http://simec.mec.gov.br/sase/sase_mapas.php?uf=MT&muncod=5100102&acao=download

提前致谢!

【问题讨论】:

  • 你知道可能的状态的值是什么(即,引用每个状态的两个字符代码是什么)?你有一个是 RJ...其他的是什么?
  • 没关系,我找到了他们

标签: r google-maps pdf web-scraping


【解决方案1】:
devtools::install_github("ropensci/RSelenium")

library(rvest)
library(httr)
library(RSelenium)

# connect to selenium server from within r (REPLACE SERVER ADDRESS)
rem_dr <- remoteDriver(
  remoteServerAddr = "192.168.50.25", port = 4445L, browserName = "firefox"
)

rem_dr$open()

# get the two-digit state codes for brazil by scraping the below webpage
tables <- "https://en.wikipedia.org/wiki/States_of_Brazil" %>%
  read_html() %>%
  html_table(fill = T)
states <- tables[[4]]$Abbreviation

# for each state, we are going to go navigate to the map of that state using
# selenium, then scrape the list of possible municipality codes from the drop
# down menu present in the map
get_munip_codes <- function(state) {
  url <- paste0("http://simec.mec.gov.br/sase/sase_mapas.php?uf=", state)
  rem_dr$navigate(url)
  # have to wait until the drop down menu loads. 8 seconds will be enough time
  # for each state
  Sys.sleep(8)
  src <- rem_dr$getPageSource()

  out <- read_html(src[[1]]) %>%
    html_nodes(xpath = "//select[@id='muncod']/option[boolean(@value)]") %>%
    xml_attrs("value") %>%
    unlist(use.names = F)

  print(state)
  out
}

state_munip <- sapply(
  states, get_munip_codes, USE.NAMES = TRUE, simplify = FALSE
)

# now you can download each pdf. first create a directory for each state, where
# the pdfs for that state will go:
lapply(names(state_munip), function(x) dir.create(file.path("brazil-pdfs", x)))

# ...then loop over each state/municipality code and download the pdf
lapply(
  names(state_munip), function(state) {
    lapply(state_munip[[state]], function(munip) {
      url <- sprintf(
        "http://simec.mec.gov.br/sase/sase_mapas.php?uf=%s&muncod=%s&acao=download",
        state, munip
      )
      file <- file.path("brazil-pdfs", state, paste0(munip, ".pdf"))
      this_one <- paste0("state ", state, ", munip ", munip)
      tryCatch({
        GET(url, write_disk(file, overwrite = TRUE))
        print(paste0(this_one, " downloaded"))
      },
      error = function(e) {
        print(paste0("couldn't download ", this_one))
        try(unlink(file, force = TRUE))
      }
      )
    })
  }
)

步骤:

  1. 获取你的windows机器的IP地址(见https://www.digitalcitizen.life/find-ip-address-windows

  2. 通过运行以下命令启动 selenium 服务器 docker 容器: docker run -d -p 4445:4444 selenium/standalone-firefox:2.53.1

  3. 通过运行以下命令启动 rocker/tidyverse docker 容器: docker run -v `pwd`/brazil-pdfs:/home/rstudio/brazil-pdfs -dp 8787:8787 rocker/tidyverse

  4. 进入您的首选浏览器并输入此地址:http://localhost:8787 ...这将带您进入 rstudio 服务器的登录屏幕。使用用户名“rstudio”和密码“rstudio”登录

  5. 将上面显示的代码复制/粘贴到新的 Rstudio .R 文档中。将 remoteServerAddr 的值替换为您在第 1 步中找到的 IP 地址。

  6. 运行代码...这应该将 pdf 文件写入一个目录“brazil-pdfs”,该目录位于容器内并映射到您的 Windows 机器(换句话说,pdf 文件将显示在巴西-pdfs 本地计算机上的目录)。注意,运行代码需要一段时间 b/c 有很多 pdf。

【讨论】:

  • 嗨,克里斯,非常感谢您的帮助!我只是无法测试代码,因为似乎 RSelenium 有问题 (github.com/ropensci/RSelenium/issues/172)。我会尽快回复您。
  • RSelenium 不在 CRAN 上...您可以使用 devtools 包安装它:devtools::install_github("ropensci/RSelenium")
  • 我做到了,然后我收到以下消息:“安装失败:命令失败 (1)”。根据ropensci github上的讨论,似乎RSelenium已被删除,因为它依赖于binmanwdman,两者都会有检查问题。
  • 用户建议安装以下序列,但 RSelenium 不起作用。 library(devtools)install_version("binman", version = "0.1.0", repos = "https://cran.uni-muenster.de/")install_version("wdman", version = "0.2.2", repos = "https://cran.uni-muenster.de/")install_version("RSelenium", version = "1.7.1", repos = "https://cran.uni-muenster.de/")
  • 效果很好。整个过程花了 36 小时 [由于文件繁重],但非常顺利!
猜你喜欢
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多