Очистка веб-сайта с помощью формы и JS с помощью R

1

Я пытаюсь отказаться от веб-сайта, который имеет форму и который генерирует информацию, которую я хочу от JS (я думаю).

Это веб-сайт: https://www.distancecalculator.net/, он вычисляет расстояние между городами.

Например, я хочу рассчитать расстояние между этими двумя городами:

  • Craíbas - AL, Brasil
  • Масейо - А.Л., Бразилия

Кажется, что, хотя я использую POST для заполнения формы, мой скребок по-прежнему собирает данные, доступные перед тем, как нажать кнопку "Рассчитать". Что я делаю неправильно?

Вот мой код:

library(httr)
library(rvest)

url <- "https://www.distancecalculator.net/"

fd <- list(
  submit = "Calculate Distance",
  "originCity"  = "Craíbas - AL, Brasil",
  "destinationCity" = "Maceió - AL, Brasil"
)

resp<-POST(url, body=fd, encode="form")
conte <- content(resp)
conte

tex <- conte %>% html_nodes(xpath = '//span[@id="driving-distance-km"]/text()') %>% html_text()
tex
  • 1
    Если вы ищете для расчета расстояния между городами. Я предлагаю вам взглянуть на опции R, такие как пакет geosphere, а пакет maps содержит набор данных world.cities. Эти пакеты могут удовлетворить ваши потребности.
  • 0
    Есть ряд других постов, которые могут помочь, если вы ищете что-то вроде «скрести форму» под тегом r - возможно, не точные дубликаты, но некоторые ответы, которые могут помочь. Вы также можете проверить RSelenium, который построен для этого типа задач
Показать ещё 1 комментарий
Теги:
web-scraping
rvest

1 ответ

1
Лучший ответ

Я согласен с комментарием, что RSeleneium был бы лучшим для этого. Вот ваш желаемый результат с помощью RSelenium.

library(RSelenium)

url <- "https://www.distancecalculator.net/"

#Start Selenium
rD <- rsDriver(port = 4444L, browser = "chrome")
remDr <- rD$client 
remDr$navigate(url)

#Type in the information
originCity <- remDr$findElement(using = "css", "#originCity")
originCity$sendKeysToElement(list("Craíbas - AL, Brasil"))
#Click the first item
clickFirst <- remDr$findElements(using = "css", ".pac-item")
clickFirst2 <- unlist(lapply(clickFirst, function(x){
  x$getElementText()
}))
clickFirst2
click <- clickFirst[[which(clickFirst2 == clickFirst2[1])]]
click$clickElement()

destinationCity <- remDr$findElement(using = "css", "#destinationCity")
destinationCity$sendKeysToElement(list("Maceió - AL, Brasil"))
#Click the first item
clickFirst <- remDr$findElements(using = "css", ".pac-item")
clickFirst2 <- unlist(lapply(clickFirst, function(x){
  x$getElementText()
}))
clickFirst2
click <- clickFirst[[which(clickFirst2 == clickFirst2[1])]]
click$clickElement()

#No longer Necessary 
calculate <- remDr$findElements(using = "xpath", '//*[contains(concat( " ", 
@class, " " ), concat( " ", "button", " " ))]')
calculate2 <- unlist(lapply(calculate, function(x){
   x$getElementText()
 }))
calculate2
click <- calculate[[which(calculate2 == calculate2[1])]]
click$clickElement()

#Scrape the result
dist <- remDr$findElements(using = "css", "#driving-distance-km")
dist <- unlist(lapply(dist, function(x){
  x$getElementText()
}))
dist
remDr$close()

И ссылка на информацию пакета RSelenium: https://cran.r-project.org/web/packages/RSelenium/vignettes/RSelenium-basics.html

  • 0
    Эй, действительно интересный код. Я попробовал это на своей машине, и местоположения заполнили коробки, но они не проверяли первое вхождение, которое он запрашивает на веб-сайте. Таким образом, когда он нажимает «вычислить», я получаю «0 км» для городов. Это случилось для вас?
  • 0
    Нет, я не получил это. Однако я обновил код, чтобы он нажимал на первое место в блоке, когда мы его вводим. Обратите внимание, что когда мы делаем это, нам больше не нужно запускать строку, которая нажимает на блок вычисления.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню