【问题标题】:How can I GET a simple HTML form in R?如何在 R 中获取简单的 HTML 表单?
【发布时间】:2016-04-01 11:24:18
【问题描述】:

我有一个类似的问题。我正在尝试从美国人口普查地理编码器链接中获取地址的坐标(纬度和经度)。我遵循了here 提到的方法;但是,我没有得到所需的结果。让我记下我在 3 次尝试中遵循的步骤:

尝试 #1(使用 RCurl):

url_geo <- "http://geocoding.geo.census.gov/geocoder/locations/address?form"
td.html <- getForm(url_geo,
submit = "Find",
street  = "3211 Providence Dr",
city = "Anchorage",
state   = "AK",
zip = "99508",
benchmark = "Public_AR_Current",
.opts = curlOptions(ssl.verifypeer = FALSE))

当我看到td.html 的输出时,它与您执行上述网页的“查看页面源代码”时得到的结果相同。实际上,td.html 应该包含在上述网页中提交表单后出现的结果页面的详细信息。

尝试 #2(使用 httr):

url_geo <- "http://geocoding.geo.census.gov/geocoder/locations/address?form"
fd1 <- list(
submit = "Find",
street  = "3211 Providence Dr",
city = "Anchorage",
state   = "AK",
zip = "99508",
benchmark = "Public_AR_Current"
)
resp1<-GET(url_geo, body=fd1, encode="form")
content(resp1)

resp1 的内容与预期的大不相同。

尝试#3(使用rvest):

url_geo <- "http://geocoding.geo.census.gov/geocoder/locations/address?form"
s <- html_session(url_geo)
f0 <- html_form(s)

在这里,我得到一个错误:

错误:当前页面似乎不是 html。

请帮助我理解我做错了什么。如果您需要我的任何澄清,请告诉我。

【问题讨论】:

    标签: html r get rcurl rvest


    【解决方案1】:

    人口普查网站非常好,可以将 JSON 发回给您(这是出乎意料的,并且是通过此电话获得的不错的奖励):

    library(httr)
    library(jsonlite)
    
    URL <- "http://geocoding.geo.census.gov/geocoder/locations/address"
    
    res <- GET(URL,
               query=list(street="3211 Providence Dr",
                          city="Anchorage",
                          state="AK",
                          zip="99508",
                          benchmark=4))
    
    dat <- fromJSON(content(res, as="text"))
    
    str(dat$result$addressMatches)
    ## 'data.frame': 1 obs. of  4 variables:
    ##  $ matchedAddress   : chr "3211 PROVIDENCE DR, ANCHORAGE, AK, 99508"
    ##  $ coordinates      :'data.frame':  1 obs. of  2 variables:
    ##   ..$ x: num -150
    ##   ..$ y: num 61.2
    ##  $ tigerLine        :'data.frame':  1 obs. of  2 variables:
    ##   ..$ tigerLineId: chr "638504877"
    ##   ..$ side       : chr "L"
    ##  $ addressComponents:'data.frame':  1 obs. of  12 variables:
    ##   ..$ fromAddress    : chr "3001"
    ##   ..$ toAddress      : chr "3399"
    ##   ..$ preQualifier   : chr ""
    ##   ..$ preDirection   : chr ""
    ##   ..$ preType        : chr ""
    ##   ..$ streetName     : chr "PROVIDENCE"
    ##   ..$ suffixType     : chr "DR"
    ##   ..$ suffixDirection: chr ""
    ##   ..$ suffixQualifier: chr ""
    ##   ..$ city           : chr "ANCHORAGE"
    ##   ..$ state          : chr "AK"
    ##   ..$ zip            : chr "99508"
    

    您可以使用flatten 参数到fromJSON 来处理数据帧可怕数据结构中的那些数据帧:

    dat <- fromJSON(content(res, as="text"), flatten=TRUE)
    dplyr::glimpse(dat$result$addressMatches)
    
    ## Observations: 1
    ## Variables: 17
    ## $ matchedAddress                    (chr) "3211 PROVIDENCE DR, ANCHORAGE, AK, 99508"
    ## $ coordinates.x                     (dbl) -149.8188
    ## $ coordinates.y                     (dbl) 61.18985
    ## $ tigerLine.tigerLineId             (chr) "638504877"
    ## $ tigerLine.side                    (chr) "L"
    ## $ addressComponents.fromAddress     (chr) "3001"
    ## $ addressComponents.toAddress       (chr) "3399"
    ## $ addressComponents.preQualifier    (chr) ""
    ## $ addressComponents.preDirection    (chr) ""
    ## $ addressComponents.preType         (chr) ""
    ## $ addressComponents.streetName      (chr) "PROVIDENCE"
    ## $ addressComponents.suffixType      (chr) "DR"
    ## $ addressComponents.suffixDirection (chr) ""
    ## $ addressComponents.suffixQualifier (chr) ""
    ## $ addressComponents.city            (chr) "ANCHORAGE"
    ## $ addressComponents.state           (chr) "AK"
    ## $ addressComponents.zip             (chr) "99508"
    

    这会将其包装成一个函数以便于调用:

    #' Geocode address using the Census API
    #'
    #' @param steet Street
    #' @param city City
    #' @param state State
    #' @param zip Zip code
    #' @param benchmark "\code{current}" for this most current information,
    #'        "\code{2014}" for data from the 2014 U.S. ACS survey,
    #'        "\code{2010}" for data from the 2010 U.S. Census. This defaults
    #'        to "\code{current}".
    #' @result \code{list} of query params and response values. If successful,
    #'         the geocoded values will be in \code{var$result$addressMatches}
    census_geocode <- function(street, city, state, zip, benchmark="current") {
    
      URL <- "http://geocoding.geo.census.gov/geocoder/locations/address"
    
      bench <- c(`current`=4, `2014`=8, `2010`=9)[benchmark]
    
      res <- GET(URL,
                 query=list(street=street, city=city, state=state,
                            zip=zip, benchmark=bench))
    
      warn_for_status(res)
    
      fromJSON(content(res, as="text"), flatten=TRUE)
    
    }
    
    census_geocode("3211 Providence Dr", "Anchorage", "AK", "99508")
    

    【讨论】:

    • 嗨 hrbrmstr - 非常感谢您详细回答。我真的很感激。我仍然想了解的一件事如下:如果您看到我的帖子,您会注意到我的 URL 与您的 URL 略有不同,尽管两者都登陆同一个网页。您使用的那个给出了所需的结果,但我使用的那个没有给出所需的结果。你能在这里发表评论吗?祝你圣诞快乐,新年快乐。
    • 嗯,我的作品? :-) 我在示例中使用了它,因为它是我在 Dev Tools & Burp Suite 中看到的,当时我试图确保我拥有所需的所有参数。不知道还能说什么。
    • :-)。再次感谢你。有没有办法使用 httr 来确定要填写的表格,就像我们在 rvest 中的方式(请参阅我的帖子和我从 stackoverflow 遵循的链接)?我觉得如果您在网页中有多个表单,那么这些信息可能会有用。如果您对这方面有一些了解,请提供一些启发。谢谢。
    【解决方案2】:

    构建您的 URL 并直接提交生成的 URL,绕过任何形式!例如,使用您选择的参数,您将获得以下 URL:

    urlgeo<-"http://geocoding.geo.census.gov/geocoder/locations/address?street=3211+Providence+Dr&city=Anchorage&state=AK&zip=99508&benchmark=4"
    

    然后,您可以通过getURL简单地检索内容:

    getURL(urlgeo)
    

    将拥有所有需要的信息。要构建 URL,只需 paste 其参数,将任何空格替换为 +

    【讨论】:

    • 嗨 nicola - 非常感谢您回答我的问题。这真的很有帮助。祝您圣诞快乐,2016 年新年快乐。
    • 其实我在发帖时没有看到你的评论,因为页面没有更新。
    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 2020-10-19
    • 2019-03-04
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多