使用 R 进行网页抓取(抓取隐藏号码“单击此处显示号码”)

问题描述 投票:0回答:4

作为数据科学团队的实习生,我的任务是找到一种使用 R 自动收集房地产广告网站上特定数据的方法。

感谢这篇文章中给出的答案(使用 R 对房地产广告进行网页抓取)以及代码中的一些更改,我成功地执行了我想要的任务。但我的问题是我无法抓取电话号码。我尝试了几种方法但没有成功。

我想做与上一篇文章完全相同的事情,但将电话号码作为新变量。

这是广告的详细信息:https://www.leboncoin.fr/ventes_immobilieres/1074663461.htm?ca=13_s我的变量是:价格(“Prix”)、城市(“Ville”)、表面(“表面”)、“GES”、“Classe énergie”、房间数量(“Pièces”)和电话号码,以及广告中显示的图片数量。

我注意到答案中给出的代码不再有效,因为在提出问题时,该网站不安全(http)。今天它包括开头的“https”。这就是我对代码进行一些更改的原因。

我是 R 初学者,任何帮助将不胜感激(抱歉我的英语不好)。

get_ad_links = function(page){
require(rvest)
# construct url to page (!when running the code put the url in 1 line!)
url_base = "https://www.leboncoin.fr/ventes_immobilieres/offres/
languedoc_roussillon/pyrenees_orientales"
url      = paste(url_base, "?o=", page,"&ret=1&ret=2&f=p", sep = "")
page     = read_html(url)

# extract links to ads on page
a="//*/section/section/ul/li["
b="]/a/@href"
t =lapply(1:30, function(i)  paste(a,i,b, sep = ""))
ad_links = sapply(1:30,function(i) { page %>% 
html_node(xpath=as.character(t[i])) %>% html_text()})
return(ad_links)  
}

# Function to Get Ad Details by Ad URL
get_ad_details = function(ad_url){
require(rvest)
# parse ad url to html tree
doc = read_html(paste("https:",ad_url,sep=""))

# extract labels and values using xpath expression
pattern<- "</?\\w+((\\s+\\w+(\\s*m\\s*(?:\".*?
\"|'.*?'[^'\">\\s]+))?)+\\s*|\\s*)/?>"

prix = doc %>% 
html_node(xpath="//section/section/section[2]/div[4]/h2/span[2]") %>% 
html_text()
PRIX = stringr::str_replace_all(prix,pattern,"")
PRIX =stringr::str_wrap(PRIX)
ville = doc %>% 
html_node(xpath="//section/section/section[2]/div[5]/h2/span[2]") %>% 
html_text()
VILLE = stringr::str_replace_all(ville,pattern,"")
VILLE = stringr::str_wrap(VILLE)
surface = doc %>% 
html_node(xpath="//section/section/section[2]/div[8]/h2/span[2]") %>% 
html_text()
SURFACE = stringr::str_replace_all(surface,pattern,"")
SURFACE = stringr::str_wrap(SURFACE)
pieces = doc %>% 
html_node(xpath="//section/section/section[2]/div[7]/h2/span[2]") %>% 
html_text()
PIECES = stringr::str_replace_all(pieces,pattern,"")
PIECES = stringr::str_wrap(PIECES)
type = doc %>% 
html_node(xpath="//section/section/section[2]/div[6]/h2/span[2]") %>% 
html_text()
TYPE_BIEN = stringr::str_replace_all(type,pattern,"")
TYPE_BIEN = stringr::str_wrap(TYPE_BIEN)
ges = doc %>% 
html_node(xpath="//section/section/section[2]/div[9]/h2/span[2]") %>% 
html_text()
GES = stringr::str_replace_all(ges,pattern,"")
GES = stringr::str_wrap(GES)
values  = c(PRIX, VILLE,SURFACE,PIECES,TYPE_BIEN,GES)

# convert to data frame and add labels
mydf  = as.data.frame(t(values))
names(mydf)= c("PRIX", "VILLE","SURFACE","PIECES" ,"TYPE_BIEN","GES")
return(mydf)
}


ad_links = get_ad_links(page = 1)

# grab ad details for first 30 links from page 1
require(plyr)
ad_details = ldply(ad_links[1:30], get_ad_details, .progress = 'text')
r rvest
4个回答
2
投票

这里的问题是电话号码位于按钮后面,必须单击该按钮才能显示该号码。这样做的目的是为了防止网络抓取工具获取这些电话号码。

无法使用

rvest
点击网站。不过,您可以使用
RSelenium
研究另一种方法。此方法使用 webbrowser docker,它的工作方式与普通浏览器一样,但可以通过 R 命令进行控制。


1
投票

最后我设法使用 Rselenium 找到了解决方案,这里是 get_phone_number 函数,它给出了一个数据帧,其中广告链接作为 ID,以及我与之前创建的数据帧匹配的电话号码。

但是我面临一个新问题,实际上当我检索 4 或 5 个电话号码时,我的 IP 地址被阻止了。另外,当我使用不在法国的 VPN 时,点击电话号码后不会出现。

那么,如何在每次点击后动态更改我的 IP 地址(仅限法国)或任何其他想法?

x<- c("RSelenium","rvest","plyr")

lapply(x, require, character.only = TRUE)

wdman::selenium(verbose = FALSE)

remDr <- remoteDriver(port = 4567L, browserName = "phantomjs")
remDr$open() 

# Function to Get the phone number by Ad URL
get_ad_phoneNumber = function(ad_url){

# put the url as ID to match later with the data frame created previously
Id = ad_url

 # go to the url
remDr$navigate(ad_url)
Sys.sleep(5) # wait until the page stop  loading

# find the phone number's button 
webElem <- remDr$findElement(using = 'css selector', value = 'aside > div > 
div.box-grey-light.mbs.align-center > div > button')

Sys.sleep(5)  # wait until the page stop  loading

webElem$clickElement() # click on the the button

Sys.sleep(5)  # wait until the page stop  loading

#find the phone number after the click
webElem <- remDr$findElement(using = 'xpath', value = 
 '//aside/div/div[1]/div/span/a')

 # extract the phone as a string character 
phoneNumber=webElem$getElementText()

values  = c(Id,phoneNumber)

# convert to data frame and add labels
mydf  = as.data.frame(t(values))
names(mydf)= c("ID","PhoneNumber")
return(mydf)
}

0
投票

这就是我在早期编程时想到的。

现在看,我对它的流量和缺乏评论感到畏缩。但它奏效了。 请告诉我是否有效?我是 StackOverflow 的新手。

 Shownumbers <- function(k){
      for (i in k:k){
        url <- paste0("https://www.yellowpages.co.za/search?what=travel&pg=")
          webpage_new <- read_html(url)
          show_html <- html_nodes(webpage_new , ".idShowNumber")
          show <- html_text(show_html)

          show <- as.character(sub(paste("\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t") , "" , 
  show))
          show <- as.character(replace(show , as.character("\\") , ""))

          show_base <- as.data.frame(show)
          show_final <- show_base
        paste0(i)
      }

        paste0(url,k)
      }

      Shownumbers(1)

      for(d in 1:135){

        url <- paste0("https://www.yellowpages.co.za/search?what=travel&pg=")
        if(d ==1){ 
          Shownumbers(d)
          webpage_new <- read_html(url)
          no_html <- html_nodes(webpage_new , ".yext-phone")
          no <- html_text(no_html)

          no <- as.character(sub(paste("\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t") , "" , no))
          no <- as.character(replace(no , as.character("\\") , ""))

          no_base <- as.data.frame(no)
          no_final <- no_base
        } else {
          Shownumbers(d)
          webpage_new <- paste0(url,d)
          no_read <- read_html(webpage_new)
          no_html <- html_nodes(no_read , ".yext-phone")
          no <- html_text(no_html)

          no <- as.character(sub(paste("\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t") , "" , no))
          no <- as.character(replace(no , as.character("\\") , ""))

          no_base <- as.data.frame(no)
          no_final <- rbind(no_final,no_base)


        }
        paste0(d)
      }

      no_final <- unique(no_final)

0
投票

请检查此存储库。 提供有关如何抓取网站中隐藏元素的更多信息 点击这里

© www.soinside.com 2019 - 2024. All rights reserved.