【问题标题】:RSelenium; Looping and downloading csv filesRS硒;循环和下载 csv 文件
【发布时间】:2020-02-14 18:39:12
【问题描述】:

我正在尝试使用 RSelenium(带有 docker)从该网站提取数据:https://nominatransparente.rhnet.gob.mx

#-- Load package
library(RSelenium)
library(rvest)
library(xml2)
library(tidyverse)

#-- Remote driver
remDr <- remoteDriver(remoteServerAddr = "192.168.99.100", port = 4445L, browserName = "chrome")
remDr$open()

#-- navigate to the website 
remDr$navigate("https://nominatransparente.rhnet.gob.mx/")

#-- confirm the website
remDr$getTitle()

#-- screenshot 
remDr$screenshot(display = TRUE)

#-- Loading website's extra information
Sys.sleep(15)

#-- selecting filters: manipulate 
webElement <- remDr$findElement("class name", "switch")
webElement$clickElement()

webElement <- remDr$findElement("class name", "ng-input")
webElement$clickElement()

直到这里,我可以选择并单击下拉菜单,但无法从下拉菜单中选择每个项目(我无法找到正确的 xpath 或 id)。我想浏览这些项目中的每一个,也想从第二个下拉菜单中浏览,然后下载它们各自的 CSV 文件。

我想使用 RSelenium 执行所有操作。我看到了一个类似的问题here,但使用了 rvest。有没有一种有效的方法来提取所有的 CSV 文件?

【问题讨论】:

    标签: r loops web-scraping rvest rselenium


    【解决方案1】:

    我的西班牙语有点生疏,但如果我没记错的话,您会尝试先切换los filtros de búsqueda por Sector e Institución,然后再切换sectorxinstitución 组合。

    如果您单击其中一种组合,例如Aportaciones de Seguridad SocialxFondo de la Vivienda del ISSSTE,您可以观察到以下网络请求:

    method GET
    url "https://dgti-ejz-mspadronserpub.200.34.175.120.nip.io/ms/InfoPadron/servidoresPublicosSector/19/HC6/1/100?query=nombres,primerApellido,segundoApellido,dependencia,tipoEntidad,nombrePuesto,sueldoBase,compensacionGarantizada"
    Headers:
    Host: dgti-ejz-mspadronserpub.200.34.175.120.nip.io
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101                 
    Firefox/71.0
    Accept: application/json
    Accept-Language: de,en-US;q=0.7,en;q=0.3
    Accept-Encoding: gzip, deflate, br
    Referer: https://nominatransparente.rhnet.gob.mx/
    Origin: https://nominatransparente.rhnet.gob.mx
    Connection: keep-alive
    TE: Trailers
    

    此响应是包含相关数据的JSON,我们可以使用httrR 内发出完全相同的请求:

    # Make the request
    headers <- c(
        "Host" = "dgti-ejz-mspadronserpub.200.34.175.120.nip.io",
        "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv=71.0) Gecko/20100101 Firefox/71.0",
        "Accept" = "application/json",
        "Referer" = "https://nominatransparente.rhnet.gob.mx",
        "Origin" = "https://nominatransparente.rhnet.gob.mx",
        "Connection" = "keep-alive",
        "TE" = "Trailers"
    )
    url <- "https://dgti-ejz-mspadronserpub.200.34.175.120.nip.io/ms/InfoPadron/servidoresPublicosSector/19/HC6/1/100?query=nombres,primerApellido,segundoApellido,dependencia,tipoEntidad,nombrePuesto,sueldoBase,compensacionGarantizada"
    
    response <- httr::GET(url, httr::add_headers(headers))
    # Extract the data
    data <- httr::content(response)
    # Example, the first entry
    data$listDtoServidorPublico[[1]]
    # $nombres
    # [1] "JOSE OSCAR"
    # 
    # $primerApellido
    # [1] "ABURTO"
    # 
    # $segundoApellido
    # [1] "LOPEZ"
    # 
    # $dependencia
    # [1] "FONDO DE LA VIVIENDA DEL ISSSTE"
    # 
    # $tipoEntidad
    # [1] "ORGANISMO DESCENTRALIZADO"
    # 
    # $nombrePuesto
    # [1] "JEFE DE AREA PROF B EN PROC HIPOTEC FOVISSSTE"
    # 
    # $sueldoBase
    # [1] 9432
    # 
    # $compensacionGarantizada
    # [1] 2096
    

    如你所见,这个版本比使用Selenium+Docker这种重炮要简单得多。

    此外,您还可以迭代 sectorxinstitución 组合。关键可能是更改 URL 参数以接收不同的组合(即 URL 的 ?query=... 部分。我自己没有对此进行调查,但是通过在请求其他组合时检查 DOM 和网络,您应该能够弄清楚这一点。

    编辑 1:检查网络

    在您的浏览器中,切换开发者工具并在里面点击标签网络。当您执行 Buscar 时,应该会出现一个新请求,即与上述请求类似的请求(取决于选择的组合)。

    我已经为另一个组合做了这个,并观察到请求 url 是

    https://dgti-ejz-mspadronserpub.200.34.175.120.nip.io/ms/InfoPadron/servidoresPublicosSector/25/C00/1/100?query=nombres,primerApellido,segundoApellido,dependencia,tipoEntidad,nombrePuesto,sueldoBase,compensacionGarantizada
    

    因此,我对您必须调整网址的哪一部分是错误的:如果您比较这两个链接,那么它们的区别是什么

     url_1 = x + 19/HC6 + y
     url_2 = x + 25/C00 + y
     # where
     x = https://dgti-ejz-mspadronserpub.200.34.175.120.nip.io/ms/InfoPadron/servidoresPublicosSector/
     y = /100?query=nombres,primerApellido,segundoApellido,dependencia,tipoEntidad,nombrePuesto,sueldoBase,compensacionGarantizada
    

    所以看起来每个sectorxinstitución 都被编码为VW/XYZ。如果您检索所有这些,则可以迭代组合。

    最后,如果您进一步检查网络,您会发现一些包含这些编码映射的请求。

    编辑 2

    正如怀疑的那样,在检查网络时,我使用以下请求 url https://nominatransparente.rhnet.gob.mx/assets/sectores.json 遇到了标记为 sectores.json 的请求。这至少包含我所指的sector 部分的映射。进一步观察可能会为instutución 产生类似的结果。

    您可能必须切换并单击给定的sector,然后才能查看给定sector 的所有institucón 选项。然后在 DOM 中你会看到一个类似的映射。我建议:

    1. Get the sector mapping
    2. Find out inside the network how the list of instituciónes is given back. Probably something like:
    -> Request containing sector-ID in the URL -> return a JSON with all instituciónes
    3. Once you figure out the logic behind it, use httr::GET to create a list of all sector x institución
    4. Once you have this list, iterate over all combinations to get JSON data as above.
    

    【讨论】:

    • 嗨@niko。感谢您的回答。这似乎是一个不错的方法。我想知道,这只检索迭代的第一页 - 大约 100 个注册表(例如,first sectorfirst institution)。请问,您是如何从url 获取所有信息的 - 即代码中的第 11 行?
    • 嘿@niko。我浏览了您的编辑,它非常清晰且很有帮助。目前,我所做的只是手动获取每个部门和机构,并检索数据。这比我试图用 RSelenium 做的更直观。另外,如果我可能会问,由于它检索 JSON 列表,将其转换为数据框的正确方法是什么?我想将所有检索到的数据继续放到一个数据框中。
    • @MaximilianoRodriguez do.call(rbind, data$listDtoServidorPublico) 应该在上面的例子中这样做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 2019-04-11
    • 2019-08-04
    • 1970-01-01
    • 2018-01-12
    相关资源
    最近更新 更多