理论上,您可以从<script> 标记中提取数据,然后使用V8 处理它,但使用splashr 或seleniumPipes 也很容易做到这一点。我写了splashr,所以我会证明:
library(splashr)
library(rvest)
start_splash()
pg <- render_html(url="https://swishanalytics.com/optimus/nba/daily-fantasy-salary-changes?date=2017-11-25")
html_node(pg, "table#stat-table") %>%
html_table() %>%
tibble::as_tibble()
## # A tibble: 256 x 7
## Position Player Salary Change `Proj Fantasy Pts` `Avg Fantasy Pts` Diff
## <chr> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 PF Thon Maker $3,900 +$600 (18.2%) 12.88 13.24 -0.36
## 2 PG DeAndre Liggins $3,500 +$500 (16.7%) 9.68 7.80 +1.88
## 3 PG Elfrid Payton $6,400 +$700 (12.3%) 32.77 28.63 +4.14
## 4 C Jahlil Okafor $3,000 -$400 (-11.8%) 1.71 12.63 -10.92
## 5 PF John Collins $5,200 +$400 (8.3%) 29.65 24.03 +5.63
## 6 SG Buddy Hield $4,600 -$400 (-8.0%) 17.96 21.84 -3.88
## 7 SF Aaron Gordon $7,000 +$500 (7.7%) 32.49 36.91 -4.42
## 8 PG Kemba Walker $7,600 -$600 (-7.3%) 36.27 38.29 -2.02
## 9 PG Lou Williams $6,600 -$500 (-7.0%) 34.28 30.09 +4.19
## 10 PG Raul Neto $3,200 +$200 (6.7%) 6.81 10.57 -3.76
## # ... with 246 more rows
killall_splash()
BeautifulSoup 也不会读取此数据。好吧,你可以定位 <script> 以 JS 形式包含它的标签,并在 Python 上使用类似的 V8 引擎,但它不会比 rvest 更容易做到这一点。
对^^的进一步扩展:
大多数抓取指南告诉您执行“检查元素”以最终找到要定位的 XPath 或 CSS 选择器。检查该表的随机行显示:
对于“普通”网站,这通常有效。
带有 JS 渲染的 XHR 请求(或页面上的 JS+数据)的站点看起来像 ^^ 但您的定位不起作用 b/c read_html()(以及 BeautifulSoup 等效项)无法在页面上呈现 JavaScript没有一些渲染引擎的帮助。您可以尝试通过查看源代码和元素检查来判断这是否正在发生。这是该站点的查看源代码,裁剪为非常长的数据行 + JS + HTML,最终形成表格:
我已经发布了许多关于如何定位<script> 标签和使用V8 的答案。使用 splashr 或 decapitated 会更容易(如果它们已安装并正常工作)。
如果您不想使用 Docker 并使用最新版本的 Chrome,您也可以按照指导 here 进行无头工作并执行以下操作:
res <- system2("chrome", c("--headless", "--dump-dom", "https://swishanalytics.com/optimus/nba/daily-fantasy-salary-changes?date=2017-11-25"), stdout=TRUE)
res 然后变成纯 HTML,您可以使用 rvest 阅读并刮掉。
一个正在开发的包——decapitated——让^^不那么难看:
install_github("hrbrmstr/decapitated")
library(decapitated)
library(rvest)
chrome_version()
## Google Chrome 63.0.3239.59 beta
pg <- chrome_read_html("https://swishanalytics.com/optimus/nba/daily-fantasy-salary-changes?date=2017-11-25")
html_node(pg, "table#stat-table") %>%
html_table() %>%
tibble::as_tibble()
## # A tibble: 256 x 7
## Position Player Salary Change `Proj Fantasy Pts` `Avg Fantasy Pts` Diff
## <chr> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 PF Thon Maker $3,900 +$600 (18.2%) 12.88 13.24 -0.36
## 2 PG DeAndre Liggins $3,500 +$500 (16.7%) 9.68 7.80 +1.88
## 3 PG Elfrid Payton $6,400 +$700 (12.3%) 32.77 28.63 +4.14
## 4 C Jahlil Okafor $3,000 -$400 (-11.8%) 1.71 12.63 -10.92
## 5 PF John Collins $5,200 +$400 (8.3%) 29.65 24.03 +5.63
## 6 SG Buddy Hield $4,600 -$400 (-8.0%) 17.96 21.84 -3.88
## 7 SF Aaron Gordon $7,000 +$500 (7.7%) 32.49 36.91 -4.42
## 8 PG Kemba Walker $7,600 -$600 (-7.3%) 36.27 38.29 -2.02
## 9 PG Lou Williams $6,600 -$500 (-7.0%) 34.28 30.09 +4.19
## 10 PG Raul Neto $3,200 +$200 (6.7%) 6.81 10.57 -3.76
## # ... with 246 more rows
注意:由于新权限和沙盒,Headless Chrome 在 High Sierra 上存在问题。它适用于较旧的 macOS 系统和 Windows/Linux。您只需要正确的版本和正确的环境变量集。