R- rvest Web内容刮擦问题 /汽车交易网站



问题

我想查看网站的特定部分(汽车销售平台(。

CSS坦率地使我感到困惑,无法弄清楚我的问题。

#### scraping the website www.otomoto.pl with used cars #####
baseURL_otomoto = "https://www.otomoto.pl/osobowe/?page="
i <- 1
for ( i in 1:7000 )
{
  link = paste0(baseURL_otomoto,i)
  out = read_html(link)
  print(i)
  print(link)
  ### building year 
  build_year  = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[1]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()
  mileage  = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[2]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()
  volume  = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[3]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()
  fuel_type  = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[4]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()

  price = html_nodes(out, xpath = '//div[@class="offer-item__price"]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()
  link = html_nodes(out, xpath = '//div[@class="offer-item__title"]') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()
  offer_details = html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()

任何猜测这种行为的原因可能是什么?

PS#1。

如何从分析网站上可用的报价作为数据。使用类(xpath ='//div [@class = ...(在我的情况下不起作用

PS#2。

我想使用F.I。

来查看实际优惠的细节
gear_type = html_nodes(out, xpath = '//*[@id="parameters"]/ul[1]/li[10]/div') %>%
    html_text() %>%
    str_replace_all("n","") %>%
    str_replace_all("r","") %>%
    str_trim()

参数

  • 在ul [a]中用于a(1:2(&amp;
  • 在li [b]中适用于(1:12(

不幸的是,尽管由于结果数据框为空,但该概念失败了。有什么猜测为什么?

首先,了解CSS选择器和XPATH。您的选择器非常长,非常脆弱(其中一些对我来说根本不起作用,仅两个星期后(。例如,而不是:

html_nodes(out, xpath = '//*[@id="body-container"]/div[2]/div[1]/div/div[6]/div[2]/article[1]/div[2]/div[3]/ul/li[1]') %>%
    html_text()

您可以写:

html_nodes(out, css="[data-code=year]") %>% html_text()

第二,阅读您使用的库文档。str_replace_all模式可能是正则表达式,可以为您节省一个呼叫(使用str_replace_all("[nr]", "")而不是str_replace_all("n","") %>% str_replace_all("r","")(。html_text可以为您进行文本修剪,这意味着根本不需要str_trim()

第三,如果您复制一些代码,请退后一步,思考功能是否不是更好的解决方案;通常会。就您个人而言,就您个人而言,我可能会跳过str_replace_all调用直到数据清洁步骤,何时我会在数据上拨打数据。


要从数据创建data.frame,请调用带有列名和内容的data.frame()功能,例如:

data.frame(build_year = build_year,
    mileage = mileage,
    volume = volume,
    fuel_type = fuel_type,
    price = price,
    link = link,
    offer_details = offer_details)

或者您只能使用一列初始化data.frame,然后将更多向量添加为列:

output_df <- data.frame(build_year = html_nodes(out, css="[data-code=year]") %>% html_text(TRUE))
output_df$volume <- html_nodes(out, css="[data-code=engine_capacity]") %>%
  html_text(TRUE)

最后,您应该注意,data.frame列必须的长度都相同,而您废纸的某些数据是可选的。在编写此答案的那一刻,我几乎没有发动机容量,也没有报价描述。您必须连续使用两个html_nodes调用(因为单个CSS选择器将不匹配不存在的内容(。但是即使那样,html_nodes仍会默默丢弃丢失的数据。这可以通过将html_nodes输出输出到html_node调用来解决:

current_df$volume  = out %>% html_nodes("ul.offer-item__params") %>% 
    html_node("[data-code=engine_capacity]") %>% 
    html_text(TRUE)

我的循环内部循环方法的最终版本在下面。只需确保您在调用它之前初始化空数据。框架并将当前迭代的输出与最终数据框架(例如rbind(合并,否则每次迭代都会覆盖上一个的结果。或者,您可以使用do.call(rbind, lapply()),这是该任务的惯用性R。

作为旁注,在刮擦大量快速更改数据时,请考虑将数据下载和数据处理步骤解耦。想象一下,您尚未考虑某些角案,这会导致R终止。如果这种情况出现在迭代的中间,您将如何进行?您待在一页上的时间越长,您引入的重复物越多(随着报价越多,现有的报价越多地在其他页面上推下来(,您错过了更多的报价(因为销售是结束的,报价永远消失了(。

>

current_df <- data.frame(build_year = html_nodes(out, css="[data-code=year]") %>% html_text(TRUE))
current_df$mileage  = html_nodes(out, css="[data-code=mileage]") %>%
  html_text(TRUE)
current_df$volume  = out %>% html_nodes("ul.offer-item__params") %>% 
    html_node("[data-code=engine_capacity]") %>% 
    html_text(TRUE)
current_df$fuel_type  = html_nodes(out, css="[data-code=fuel_type]") %>%
  html_text(TRUE)
current_df$price = out %>% html_nodes(xpath="//div[@class='offer-price']//span[contains(@class, 'number')]") %>% 
  html_text(TRUE)
current_df$link = out %>% html_nodes(css = "div.offer-item__title h2 > a") %>% 
  html_text(TRUE) %>% 
  str_replace_all("[nr]", "")
current_df$offer_details = out %>% html_nodes("div.offer-item__title") %>% 
    html_node("h3") %>% 
    html_text(TRUE)