css - 无法使用 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,]
解决方案
向下滚动页面时,通过 API 调用动态添加数据。API 调用有一个查询字符串,允许您指定startIndex
(起始行)和每页的结果数 ( pageSize
)。每页最大结果似乎是 1000。返回是 json,您可以从中提取所需的所有信息,包括总行数;通过 的键访问countRaw
。因此,您可以请求最初的 1000,解析出总行数,countRaw
然后执行循环,调整行startIndex
参数,直到获得所有结果。
您可以使用 json 解析器,例如 jsonlite 来处理 json 响应。
前 1000 个结果的示例 API 端点调用:
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¤cy=USD&productSet=BN&skus='
r <- jsonlite::fromJSON(url)
print(r$countRaw)
您会从每次调用中获得一个包含 8 个元素的列表。r$results
是一个包含主要兴趣信息的数据框。
部分回复:
鉴于指示的结果计数,我期望我可以做类似的事情(记住我有限的 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¤cy=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¤cy=USD&productSet=BN&skus='
r <- jsonlite::fromJSON(url2)
df2 <- r$results
使用 css 选择器 .row 搜索页面会产生 1002 个结果,而不是指示的所有菱形总数;所以,我认为围绕过滤器需要进行一些探索。
推荐阅读
- c# - Gembox 电子表格 - 删除空白页
- mysql - MYSQL 合并两个表中的两列,仍然使用 LEFT JOIN
- c - 如何在 C 中读取文件时防止任何其他进程写入文件?
- google-sheets - 如何查找列中的前一个值?
- html - 使用 abbr 元素通过 CSS 进行响应式文本更改
- php - php正确的json清单
- jenkins - 如何在声明性管道中获取和格式化 git changelog
- database - 使用自动创建的用户运行 dockerized Oracle 数据库
- c# - 检测串口是否断开C#
- java - Java Swagger 不生成端点响应类型为 List 的服务