XHR Scrape - URL запроса не меняется - PullRequest
0 голосов
/ 29 августа 2018

У меня есть база данных адресов, и я пытаюсь очистить +4 цифры почтового индекса из веб-приложения USPS: https://tools.usps.com/zip-code-lookup.htm?byaddress

Я использую Chrome, а сайт использует XHR. Когда я ввожу адрес, я легко могу найти параметры моего запроса в инспекторе ...

Request parameters

... а также данные из ответа:

Data from response
(выделенные желтым цветом данные - это то, что я пытаюсь очистить)

В каждом учебном пособии, которое я прочитал по этой теме, говорится, что я должен теперь просто "взять URL-адрес запроса и вставить его в браузер, чтобы получить данные JSON", и отображается URL-адрес, который включает в себя все параметры. К сожалению, в этом случае URL-адрес запроса в инспекторе практически идентичен URL-адресу браузера, причем ни один из параметров поиска не включен. Не знаю, как поступить, учитывая это.

Request URL as shown in inspector

Может кто-нибудь посоветовать, как я могу получить эту таблицу JSON? Если это имеет значение, я работаю в R, хотя мне не обязательно помогать с этой частью этой проблемы.

Заранее спасибо. Кроме того, новый пользователь SO здесь, поэтому, пожалуйста, будьте добры, указывая на любые случайные нарушения этикета в этом посте.

Заранее спасибо:)

1 Ответ

0 голосов
/ 13 октября 2018

Закачал на robots.txt и условия и часто задаваемые вопросы и не может найти ничего, что запрещает чистку. Если кто-нибудь ответит, оставьте комментарий, и я с удовольствием удалю ответ.

Иногда вы не можете просто захватить URL-адрес, особенно если есть запрос POST (который здесь имеет место). Вот тут и приходит curlconverter. Щелкните правой кнопкой мыши запись таблицы в представлении «Инструменты разработчика», выберите «Копировать как cURL» и больше ничего не помещайте в буфер обмена. Затем выполните:

library(curlconverter)

st <- straighten() 
req <- make_req(st)

st содержит структуру списка с разложенными компонентами запроса, а req[[1]]() является функцией httr с возможностью вызова. Однако , если вы - немедленно - после запуска этой строки make_req() переместитесь на новую строку и используете функцию paste вашего буфера обмена, вы получите отформатированный источник указанной функции. В данном случае это:

httr::VERB(
  verb = "POST", url = "https://tools.usps.com/tools/app/ziplookup/zipByAddress",
  httr::add_headers(
    `User-Agent` = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0",
    Accept = "application/json, text/javascript, */*; q=0.01",
    `Accept-Language` = "en-US,en;q=0.7,fr-BE;q=0.3",
    Referer = "https://tools.usps.com/zip-code-lookup.htm?byaddress",
    `X-Requested-With` = "XMLHttpRequest",
    DNT = "1", Connection = "keep-alive"
  ),
  httr::set_cookies(
    nsc_usps_com = "MTc0LjYyLjE2Ny45Nw==",
    `NSC_uppmt-xbt8-mc` = "ffffffff3b22378c45525d5f4f58455e445a4a4212d3"
  ),
  body = list(
    companyName = "",
    address1 = "1+Main+Street",
    address2 = "", city = "Cambridge",
    state = "MA", zip = ""
  ),
  encode = "form"
)

Мы можем сказать из этой автоматически созданной функции, что необходимо сохранить файлы cookie, принять JSON и, возможно, некоторую другую переменную заголовка HTTP вместе с POST данными тела.

Следующий шаг - сортировка абсолютно необходимого. Я не даю подсказок о том, как я пришел к тому, что ниже, так как вы должны сделать некоторую работу. Чтобы сохранить состояние файлов cookie, мы делаем начальный GET вызов исходной страницы, чтобы получить файлы cookie, которые будут оставаться неизменными до тех пор, пока активен сеанс R. Затем мы передаем параметры и возвращаем преобразованный JSON:

lookup_zip <- function(address_1, address_2 = "", city = "", 
                       state = "", zip = "", company_name = "") {

  suppressPackageStartupMessages({
    require("httr", quietly = TRUE, warn.conflicts = FALSE)
    require("jsonlite", quietly = TRUE, warn.conflicts = FALSE)
  })

  # prime cookies
  httr::GET(
    url = "https://tools.usps.com/zip-code-lookup.htm",
    httr::user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0")
  ) -> res
  httr::stop_for_status(res)

  httr::POST(
    url = "https://tools.usps.com/tools/app/ziplookup/zipByAddress",
    httr::accept_json(),
    httr::user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0"),
    httr::add_headers(
      Referer = "https://tools.usps.com/zip-code-lookup.htm?byaddress",
      `X-Requested-With` = "XMLHttpRequest"
    ),
    body = list(
      companyName = company_name,
      address1 = address_1,
      address2 = address_2, 
      city = city,
      state = state, 
      zip = zip
    ),
    encode = "form"
  ) -> res

  httr::stop_for_status(res)

  out <- httr::content(res, as = "text", encoding = "UTF-8")

  out <- jsonlite::fromJSON(out)

  out

}

Итак, когда мы запустим:

lookup_zip("1 Main Street", city = "Cambridge", state = "MA")

## $resultStatus
## [1] "SUCCESS"
## 
## $addressList
##                     addressLine1      city state  zip5 zip4 carrierRoute countyName deliveryPoint checkDigit cmar elot
## 1                      1 MAIN ST CAMBRIDGE    MA 02142 1531         C033  MIDDLESEX            99          3    N 0033
## 2                      1 MAIN ST CAMBRIDGE    MA 02142 1531         C033  MIDDLESEX            99          3    N <NA>
## 3                      1 MAIN ST CAMBRIDGE    MA 02142 1500         C033  MIDDLESEX            01          4    N <NA>
## 4               1 MAIN ST STE 14 CAMBRIDGE    MA 02142 1503         C033  MIDDLESEX            01          1    N <NA>
## 5               1 MAIN ST STE 10 CAMBRIDGE    MA 02142 1504         C033  MIDDLESEX            01          0    N <NA>
## 6               1 MAIN ST STE 24 CAMBRIDGE    MA 02142 1506         C033  MIDDLESEX            01          8    N <NA>
## 7                1 MAIN ST STE 6 CAMBRIDGE    MA 02142 1517         C033  MIDDLESEX            99          9    N <NA>
## 8                1 MAIN ST STE 1 CAMBRIDGE    MA 02142 1517         C033  MIDDLESEX            99          9    N <NA>
## 9               1 MAIN ST STE 11 CAMBRIDGE    MA 02142 1517         C033  MIDDLESEX            99          9    N <NA>
## 10              1 MAIN ST STE 13 CAMBRIDGE    MA 02142 1517         C033  MIDDLESEX            99          9    N <NA>
## 11              1 MAIN ST STE 15 CAMBRIDGE    MA 02142 1517         C033  MIDDLESEX            99          9    N <NA>
## 12               1 MAIN ST STE 8 CAMBRIDGE    MA 02142 1524         C033  MIDDLESEX            01          8    N <NA>
## 13   1 MAIN ST STE (Range 2 - 5) CAMBRIDGE    MA 02142 1599         C033  MIDDLESEX          <NA>       <NA>    N <NA>
## 14  1 MAIN ST STE (Range 7 - 10) CAMBRIDGE    MA 02142 1599         C033  MIDDLESEX          <NA>       <NA>    N <NA>
## 15 1 MAIN ST STE (Range 16 - 24) CAMBRIDGE    MA 02142 1599         C033  MIDDLESEX          <NA>       <NA>    N <NA>
## 16              1 MAIN ST STE 12 CAMBRIDGE    MA 02142 1599         C033  MIDDLESEX            99          9    N <NA>
## 17              1 MAIN ST STE 14 CAMBRIDGE    MA 02142 1599         C033  MIDDLESEX            99          9    N <NA>
##    elotIndicator recordType dpvConfirmation defaultFlag               companyName
## 1              A          H               D           Y                      <NA>
## 2           <NA>       <NA>            <NA>        <NA>                      <NA>
## 3           <NA>       <NA>            <NA>        <NA>                      <NA>
## 4           <NA>       <NA>            <NA>        <NA>     BENCHMARKING PARTNERS
## 5           <NA>       <NA>            <NA>        <NA>              C MARKET INC
## 6           <NA>       <NA>            <NA>        <NA> SIMAT HELLIESEN & EICHNER
## 7           <NA>       <NA>            <NA>        <NA>                      <NA>
## 8           <NA>       <NA>            <NA>        <NA>                      <NA>
## 9           <NA>       <NA>            <NA>        <NA>                      <NA>
## 10          <NA>       <NA>            <NA>        <NA>                      <NA>
## 11          <NA>       <NA>            <NA>        <NA>                      <NA>
## 12          <NA>       <NA>            <NA>        <NA>       NEW ENGLAND PENSION
## 13          <NA>       <NA>            <NA>        <NA>                      <NA>
## 14          <NA>       <NA>            <NA>        <NA>                      <NA>
## 15          <NA>       <NA>            <NA>        <NA>                      <NA>
## 16          <NA>       <NA>            <NA>        <NA>                      CEME
## 17          <NA>       <NA>            <NA>        <NA>                      <NA>

То, что вы не должны делать с вышесказанным:

  • Не будьте придурком # 1: Если вы собираетесь совершать повторные звонки, установите задержку в (т. Е. Sys.sleep(5). Вы получаете эту информацию бесплатно, и мои налоги поддерживают сайт. не особенный.
  • Не будьте придурком # 2: результаты кэширования, возможно, даже на диске. Перепишите функцию, чтобы использовать пакет memoise.
  • Не будь придурком # 3: Не продавай создаваемую базу данных. Я узнаю, если ты это сделаешь (см. № 4)
  • Не будьте придурком # 4: Несмотря на то, что SO заявляет, что в противном случае не отвечает, но вышеприведенный код имеет лицензию AGPL, поэтому вы обязаны опубликовать исходный текст любой коммерческой вещи, которую вы пишете на его основе ( если это ваше конечное намерение). У меня есть системы масштабирования Интернет-архива, которые ежедневно сканируют Интернет. Я буду знать.

Вполне возможно, что это невинная академическая потребность, но SO полон (ежедневных) чистящих вопросов, которые задают неэтичные воры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...