Я очень новичок в R, поэтому изо всех сил пытался найти правильный способ сделать это с purrr
. Я уверен, что есть хороший простой способ, и, возможно, кто-то поможет мне / вам с этим. На данный момент я вернулся к использованию цикла.
Это может показаться немного похожим на дома, но я хотел избежать большей части того, что я подозреваю, является динамическим на странице (например, многие из classNames) и предоставить что-то, чтоможет иметь немного более длительный срок годности.
Ваш код не работает, частично, потому что нет элемента table
, содержащего эти данные. Вместо этого вы можете собрать «строки» желаемой выходной таблицы, используя более стабильно выглядящий атрибут класса fi-row
. Затем в каждой строке можно собрать столбцы, сопоставив элементы с атрибутом title
или data-test='fin-col'
на основе родительского узла строки.
Я использую регулярное выражение для сопоставления по датам (так как они меняются со временем) и объединить их со статическими двумя заголовками, чтобы получить конечные заголовки данных для вывода. Я ограничиваю регулярное выражение одним текстом узла, который, как я знаю, должен содержать совпадения с образцами, которые являются только теми необходимыми датами.
R:
library(rvest)
library(stringr)
library(magrittr)
page <- read_html('https://finance.yahoo.com/quote/AAPL/financials?p=AAPL')
nodes <- page %>%html_nodes(".fi-row")
df = NULL
for(i in nodes){
r <- list(i %>%html_nodes("[title],[data-test='fin-col']")%>%html_text())
df <- rbind(df,as.data.frame(matrix(r[[1]], ncol = length(r[[1]]), byrow = TRUE), stringsAsFactors = FALSE))
}
matches <- str_match_all(page%>%html_node('#Col1-3-Financials-Proxy')%>%html_text(),'\\d{1,2}/\\d{1,2}/\\d{4}')
headers <- c('Breakdown','TTM', matches[[1]][,1])
names(df) <- headers
View(df)
Пример:
Py:
import requests, re
import pandas as pd
import BeautifulSoup as bs
r = requests.get('https://finance.yahoo.com/quote/AAPL/financials?p=AAPL')
soup = bs(r.content, 'lxml')
results = []
for row in soup.select('.fi-row'):
results.append([i.text for i in row.select('[title],[data-test="fin-col"]')])
p = re.compile(r'\d{1,2}/\d{1,2}/\d{4}')
headers = ['Breakdown','TTM']
headers.extend(p.findall(soup.select_one('#Col1-3-Financials-Proxy').text))
df = pd.DataFrame(results, columns = headers)
print(df)