使用 RVEST 开始抓取电子商务网站有什么技巧吗?

Any tip for start scraping an e-commerce site with RVEST?

我正在尝试使用 rvest 从电子商务网站抓取一些数据。我还没有找到任何好的例子来指导我。有什么想法吗?

让我们举例说明我是如何开始的:

library(rvest)
library(purrr)

#Specifying the url
url_base <- 'https://telefonia.mercadolibre.com.uy/accesorios-celulares/'
#Reading the HTML code from the website
webpage <- read_html(url)

#Using CSS selectors to scrap the titles section
title_html <- html_nodes(webpage,'.main-title')
#Converting the title data to text
title <- html_text(title_html)
head(title)

#Using CSS selectors to scrap the price section
price <- html_nodes(webpage,'.item__price')
price <- html_text(price)
price

所以,我想做两件基本的事情:

  1. 进入每个产品并从中获取一些数据。
  2. 所有页面的分页

有什么帮助吗?

谢谢。

抓取该信息并不难,并且可以用 rvest 实现。
您需要做的是获取所有 href 并在其上循环。为此,您需要使用 html_attr()

以下代码应该可以完成工作:

library(tidyverse)
library(rvest)

#Specifying the url
url_base <- 'https://telefonia.mercadolibre.com.uy/accesorios-celulares/'
#You need to get href and loop on hrefs
all_pages <- url_base %>% read_html() %>% html_nodes(".pagination__page > a") %>% html_attr("href")
all_pages[1] <- url_base
#create an empty table to store results
result_table <- tibble() 
for(page in all_pages){
    page_source <- read_html(page)
    title <- html_nodes(page_source,'.item__info-title') %>% html_text()
    price <- html_nodes(page_source,'.item__price') %>% html_text()
    item_link <- html_nodes(page_source,'.item__info-title') %>% html_attr("href")
    temp_table <- tibble(title = title, price = price, item_link = item_link)
    result_table <- bind_rows(result_table,temp_table)
}

在每个项目获得 link 后,您可以在项目 link 上循环。

查看更多页面

如你所见,后缀中有一个模式;您只需每次将数字加 50 即可浏览更多页面。

> all_pages
[1] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/"          
[2] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_51" 
[3] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_101"
[4] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_151"
[5] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_201"
[6] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_251"
[7] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_301"
[8] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_351"
[9] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_401"
[10] "https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_451"

所以我们可以这样做:

str_c("https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_",seq.int(from = 51,by = 50,length.out = 40))

抓取每一页

我们以这个页面为例:https://articulo.mercadolibre.com.uy/MLU-449598178-protector-funda-clear-cover-samsung-galaxy-note-8-_JM

pagesource <- read_html("https://articulo.mercadolibre.com.uy/MLU-449598178-protector-funda-clear-cover-samsung-galaxy-note-8-_JM")
n_vendor <- pagesource %>% html_node(".item-conditions") %>% html_text() %>% remove_nt()
product_description <- pagesource %>% html_node(".item-title__primary") %>% html_text() %>% remove_nt()
n_opinion <- pagesource %>% html_node(".average-legend span:nth-child(1)") %>% html_text()
product_price <- pagesource %>% html_nodes(".price-tag-fraction") %>% html_text()
current_table <- tibble(product_description = product_description, 
       product_price = product_price,
       n_vendor = n_vendor,
       n_opinion = n_opinion)
print(current_table)
# A tibble: 1 x 4
product_description                               product_price n_vendor   n_opinion
<chr>                                             <chr>         <chr>      <chr>    
    1 Protector Funda Clear Cover Samsung Galaxy Note 8 14            14vendidos 2   

您可以循环上面的代码块并获取所有信息。

让我们把它们结合起来

以下代码应该可以工作,您可以取消 5 页限制以抓取所有产品信息。

library(tidyverse)
library(rvest)

#Specifying the url
url_base <- 'https://telefonia.mercadolibre.com.uy/accesorios-celulares/'
#You need to get href and loop on hrefs
all_pages <- url_base %>% read_html() %>% html_nodes(".pagination__page > a") %>% html_attr("href")
all_pages <- c(url_base,
               str_c("https://telefonia.mercadolibre.com.uy/accesorios-celulares/_Desde_",
                     seq.int(from = 51,by = 50,length.out = 40)))
#create an empty table to store results
result_table <- tibble() 
for(page in all_pages[1:5]){ #as an example, only scrape the first 5 pages
    page_source <- read_html(page)
    title <- html_nodes(page_source,'.item__info-title') %>% html_text()
    price <- html_nodes(page_source,'.item__price') %>% html_text()
    item_link <- html_nodes(page_source,'.item__info-title') %>% html_attr("href")
    temp_table <- tibble(title = title, price = price, item_link = item_link)
    result_table <- bind_rows(result_table,temp_table)
}

#loop on result table(item_link):
product_table <- tibble()
for(i in 1:nrow(result_table)){
    pagesource <- read_html(result_table[[i,"item_link"]])
    n_vendor <- pagesource %>% html_node(".item-conditions") %>% html_text() %>% remove_nt()
    product_description <- pagesource %>% html_node(".item-title__primary") %>% html_text() %>% remove_nt()
    currency_symbol <- pagesource %>% html_node(".price-tag-symbol") %>% html_text()
    n_opinion <- pagesource %>% html_node(".average-legend span:nth-child(1)") %>% html_text()
    product_price <- pagesource %>% html_nodes(".price-tag-fraction") %>% html_text()
    current_table <- tibble(product_description = product_description, 
                            currency_symbol = currency_symbol,
                            product_price = product_price,
                            n_vendor = n_vendor,
                            n_opinion = n_opinion,
                            item_link = result_table[[i,"item_link"]])
    product_table <- bind_rows(product_table,current_table)
}

结果:

一些问题

代码中还有一些bug,例如:
在此页面上,有两个项目与 css 选择器匹配,这可能会破坏代码。不过有一些解决方案:

  1. 将结果存储在列表中而不是 table
  2. 使用更准确的 CSS 选择器
  3. 只要有多个结果就连接字符串,并且 等等

您可以选择任何符合您要求的方法。

另外,如果你想抓取数量,你可能想使用 tryCatch 来防止任何错误破坏你的循环。

关于 apis

Api与web scraping完全不同,如果你想使用它,你可能需要阅读更多关于api的教程。