使用 rvest 或 RSelenium 抓取 Table
Using rvest or RSelenium to Scrape Table
目标: 使用 R 从以下网站抓取 table。
网址: https://evanalytics.com/mlb/models/teams/advanced
我卡住了什么:
我使用 rvest 来自动化我的大部分数据收集过程,但这个特定站点似乎超出了 rvest 的工作范围(或者至少超出了我的经验水平)。不幸的是,它不会在页面打开时立即加载 table。我试图通过 RSelenium 提出一个解决方案,但未能找到 table 的正确路径(RSelenium 对我来说是全新的)。导航到页面并暂停一小段时间以允许 table 加载后,下一步是什么?
我目前有:
library("rvest")
library("RSelenium")
url <- "https://evanalytics.com/mlb/models/teams/advanced"
remDr <- remoteDriver(remoteServerAddr="192.168.99.100", port=4445L)
remDr$open()
remDr$navigate(url)
Sys.sleep(10)
任何帮助或指导将不胜感激。谢谢!
时间紧迫,所以只是指向 html 源代码,您可以从中提取 table with r vest。
remDr$navigate(url)
html <-remDr$getPageSource()
## this will get you html of the page, form here
## just extract the table as you would with rvest
您可以在没有 Selenium 的情况下通过创建一个 html_session 来执行此操作,以便获取所需的 php session id 来传递 cookie。您还需要 user-agent header。在 session 到位后,您可以发出 POST xhr 请求以获取所有数据。您需要一个 json 解析器来处理响应 html.
中的 json 内容
您可以在其中一个脚本标签中看到参数信息:
function executeEnteredQuery() {
var parameterArray = {
mode: 'runTime',
dataTable_id: 77
};
$.post('/admin/model/datatableQuery.php', {
parameter: window.btoa(jQuery.param(parameterArray))
},
function(res) {
processdataTableQueryResults(res);
}, "json");
}
您可以自己为参数编码字符串:
base64_enc('mode=runTime&dataTable_id=77')
R:
require(httr)
require(rvest)
require(magrittr)
require(jsonlite)
headers = c('User-Agent' = 'Mozilla/5.0')
body = list('parameter' = 'bW9kZT1ydW5UaW1lJmRhdGFUYWJsZV9pZD03Nw==') # base64 encoded params for mode=runTime&dataTable_id=77
session <- html_session('https://evanalytics.com/mlb/models/teams/advanced', httr::add_headers(.headers=headers))
p <- session %>% rvest:::request_POST('https://evanalytics.com/admin/model/datatableQuery.php', body = body)%>%
read_html() %>%
html_node('p') %>%
html_text()
data <- jsonlite::fromJSON(p)
df <- data$dataRows$columns
print(df)
Py:
import requests
import pandas as pd
from bs4 import BeautifulSoup as bs
body = {'parameter': 'bW9kZT1ydW5UaW1lJmRhdGFUYWJsZV9pZD03Nw=='} # base64 encoded params for mode=runTime&dataTable_id=77
with requests.Session() as s:
r = s.get('https://evanalytics.com/mlb/models/teams/advanced')
r = s.post('https://evanalytics.com/admin/model/datatableQuery.php')
data = r.json()
cols = [th.text for th in bs(data['headerRow'], 'lxml').select('th')]
rows = [[td.text for td in bs(row['dataRow'], 'lxml').select('td')] for row in data['dataRows']]
df = pd.DataFrame(rows, columns = cols)
print(df)
目标: 使用 R 从以下网站抓取 table。
网址: https://evanalytics.com/mlb/models/teams/advanced
我卡住了什么: 我使用 rvest 来自动化我的大部分数据收集过程,但这个特定站点似乎超出了 rvest 的工作范围(或者至少超出了我的经验水平)。不幸的是,它不会在页面打开时立即加载 table。我试图通过 RSelenium 提出一个解决方案,但未能找到 table 的正确路径(RSelenium 对我来说是全新的)。导航到页面并暂停一小段时间以允许 table 加载后,下一步是什么?
我目前有:
library("rvest")
library("RSelenium")
url <- "https://evanalytics.com/mlb/models/teams/advanced"
remDr <- remoteDriver(remoteServerAddr="192.168.99.100", port=4445L)
remDr$open()
remDr$navigate(url)
Sys.sleep(10)
任何帮助或指导将不胜感激。谢谢!
时间紧迫,所以只是指向 html 源代码,您可以从中提取 table with r vest。
remDr$navigate(url)
html <-remDr$getPageSource()
## this will get you html of the page, form here
## just extract the table as you would with rvest
您可以在没有 Selenium 的情况下通过创建一个 html_session 来执行此操作,以便获取所需的 php session id 来传递 cookie。您还需要 user-agent header。在 session 到位后,您可以发出 POST xhr 请求以获取所有数据。您需要一个 json 解析器来处理响应 html.
中的 json 内容您可以在其中一个脚本标签中看到参数信息:
function executeEnteredQuery() {
var parameterArray = {
mode: 'runTime',
dataTable_id: 77
};
$.post('/admin/model/datatableQuery.php', {
parameter: window.btoa(jQuery.param(parameterArray))
},
function(res) {
processdataTableQueryResults(res);
}, "json");
}
您可以自己为参数编码字符串:
base64_enc('mode=runTime&dataTable_id=77')
R:
require(httr)
require(rvest)
require(magrittr)
require(jsonlite)
headers = c('User-Agent' = 'Mozilla/5.0')
body = list('parameter' = 'bW9kZT1ydW5UaW1lJmRhdGFUYWJsZV9pZD03Nw==') # base64 encoded params for mode=runTime&dataTable_id=77
session <- html_session('https://evanalytics.com/mlb/models/teams/advanced', httr::add_headers(.headers=headers))
p <- session %>% rvest:::request_POST('https://evanalytics.com/admin/model/datatableQuery.php', body = body)%>%
read_html() %>%
html_node('p') %>%
html_text()
data <- jsonlite::fromJSON(p)
df <- data$dataRows$columns
print(df)
Py:
import requests
import pandas as pd
from bs4 import BeautifulSoup as bs
body = {'parameter': 'bW9kZT1ydW5UaW1lJmRhdGFUYWJsZV9pZD03Nw=='} # base64 encoded params for mode=runTime&dataTable_id=77
with requests.Session() as s:
r = s.get('https://evanalytics.com/mlb/models/teams/advanced')
r = s.post('https://evanalytics.com/admin/model/datatableQuery.php')
data = r.json()
cols = [th.text for th in bs(data['headerRow'], 'lxml').select('th')]
rows = [[td.text for td in bs(row['dataRow'], 'lxml').select('td')] for row in data['dataRows']]
df = pd.DataFrame(rows, columns = cols)
print(df)