无法使用rvest抓取所有行

时间:2019-07-08 16:54:55

标签: css r web-scraping css-selectors rvest

我的目标是从bluenile.com抓取所有这些钻石数据。我有一些似乎正在执行此操作的代码,但它仅捕获前61行。

顺便说一句,我正在使用“ SelectorGadget” chrome插件来获取CSS选择器。如果我向下滚动一点,突出显示将停止。与网站有关吗?

library('rvest')

le_url <- "https://www.bluenile.com/diamonds/round-cut?track=DiaSearchRDmodrn"
webpage <- read_html(le_url)

shape_data_html <- html_nodes(webpage,'.shape')
price_data_html <- html_nodes(webpage,'.price')
carat_data_html <- html_nodes(webpage,'.carat')
cut_data_html <- html_nodes(webpage,'.cut')
color_data_html <- html_nodes(webpage,'.color')
clarity_data_html <- html_nodes(webpage,'.clarity')

#Converting data to text
shape_data <- html_text(shape_data_html)
price_data <- html_text(price_data_html)
carat_data <- html_text(carat_data_html)
cut_data <- html_text(cut_data_html)
color_data <- html_text(color_data_html)
clarity_data <- html_text(clarity_data_html)

# make a data.frame
le_mat <- cbind(shape_data, price_data, carat_data, cut_data, color_data, clarity_data)
le_df <- le_mat[-1,]
colnames(le_df) <- le_mat[1,]

1 个答案:

答案 0 :(得分:2)

当您向下滚动页面时,将通过API调用动态添加数据。 API调用具有一个查询字符串,可让您指定startIndex(开始行)和每页结果数(pageSize)。每页的最大结果似乎是1000。返回的是json,您可以从中提取所有想要的信息,包括总行数;通过countRaw键访问。因此,您可以请求初始的1000,解析出总行数countRaw,然后执行循环,调整行startIndex参数,直到获得所有结果为止。

您可以使用json解析器,例如jsonlite处理json响应。

前1000个结果的示例API端点调用:

https://www.bluenile.com/api/public/diamond-search-grid/v2?startIndex=0&pageSize=1000&_=1562612289615&sortDirection=asc&sortColumn=default&shape=RD&hasVisualization=true&isFiltersExpanded=false&astorFilterActive=false&country=USA&language=en-us&currency=USD&productSet=BN&skus=

library(jsonlite)

url <- 'https://www.bluenile.com/api/public/diamond-search-grid/v2?startIndex=0&pageSize=1000&_=1562612289615&sortDirection=asc&sortColumn=default&shape=RD&hasVisualization=true&isFiltersExpanded=false&astorFilterActive=false&country=USA&language=en-us&currency=USD&productSet=BN&skus='
r <-  jsonlite::fromJSON(url)
print(r$countRaw)

您从每个调用中获得8个元素的列表。 r$results是一个包含主要关注信息的数据框。

部分回复:

enter image description here


考虑到我期望的指示结果计数,我可以做类似的事情(考虑到我有限的R经验):

total <- r$countRaw
url2 <- 'https://www.bluenile.com/api/public/diamond-search-grid/v2?startIndex=placeholder&pageSize=1000&_=1562612289615&sortDirection=asc&sortColumn=default&shape=RD&hasVisualization=true&isFiltersExpanded=false&astorFilterActive=false&country=USA&language=en-us&currency=USD&productSet=BN&skus='
if(total > 1000){
  for(i in seq(1000, total + 1, by = 1000)){
    newUrl <- gsub("placeholder", i , url2)
    newdf <- jsonlite::fromJSON(newUrl)$results
    # do something with df e.g. merge
  }
}

但是,似乎只有两个呼叫结果,即上面显示的df中的初始r$results,然后是:

url2 <- 'https://www.bluenile.com/api/public/diamond-search-grid/v2?startIndex=1000&pageSize=1000&_=1562612289615&sortDirection=asc&sortColumn=default&shape=RD&hasVisualization=true&isFiltersExpanded=false&astorFilterActive=false&country=USA&language=en-us&currency=USD&productSet=BN&skus='
r <-  jsonlite::fromJSON(url2)
df2 <- r$results

使用css选择器.row搜索页面将产生1002个结果,相对于指示的总“钻石总数”;因此,我认为围绕过滤器需要做一些探索。