Web scraping com RSelenium - Investing.com
Raspando e salvando dados de preço de ações utilizando o R
Para quem depende de base de dados 0800, é sempre um desafio conseguir as informações desejadas. Quando se trata do site Investing.com, há duas formas de pegar dados históricos:
Forma fácil: criar um cadastro no site e baixar os dados;
Forma difícil: criar um 'robozinho' para fazer isso no seu lugar, sem criar cadastro. A vantagem é que se for 100 ações, por exemplo, o algoritmo faz todo o trabalho pesado.
Primeiro, vamos instalar e carregar os pacotes necessários:
packages = c("RSelenium","tidyverse","XML","xts")
new.packages = packages[!(packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
suppressMessages(library(RSelenium))
suppressMessages(library(tidyverse))
suppressMessages(library(XML))
suppressMessages(library(xts))
No próximo passo, vamos definir o navegador e a função que vai fazer todo o trabalho:
driver = rsDriver(browser = "firefox")
remote_driver = driver[["client"]]
robot = function(ticker,indate,findate,fqc){
# Investing
remote_driver$navigate(paste0("https://www.investing.com/search/?q=",ticker))
button_element = remote_driver$findElement(using = 'xpath', "//*[@id='fullColumn']/div/div[2]/div[2]/div[1]/a[1]/span[2]")
button_element$clickElement()
Sys.sleep(5)
webElem <- remote_driver$findElement("css", "body")
i=1
while(i<4){
webElem$sendKeysToElement(list(key = "down_arrow"))
i=i+1
}
# Historical
url = remote_driver$getCurrentUrl()
remote_driver$navigate(paste0(url,"-historical-data"))
Sys.sleep(5)
webElem <- remote_driver$findElement("css", "body")
i=1
while(i<9){
webElem$sendKeysToElement(list(key = "down_arrow"))
i=i+1
}
Sys.sleep(7)
if(fqc=="daily"){
fq = remote_driver$findElement(using = 'xpath', "//*[@id='data_interval']/option[1]")
fq$clickElement()
}else{
if(fqc=="weekly"){
fq = remote_driver$findElement(using = 'xpath', "//*[@id='data_interval']/option[2]")
fq$clickElement()
}else{
if(fqc=="monthly"){
fq = remote_driver$findElement(using = 'xpath', "//*[@id='data_interval']/option[3]")
fq$clickElement()
}
}
}
fq = remote_driver$findElement(using = 'xpath', "//*[@id='data_interval']/option[1]")
fq$clickElement()
element = remote_driver$findElement(using = 'id', "widgetFieldDateRange")
element$clickElement()
startDate = remote_driver$findElement(using = 'id', "startDate")
startDate$clearElement()
startDate$sendKeysToElement(list(indate))
endDate = remote_driver$findElement(using = 'id', "endDate")
endDate$clearElement()
endDate$sendKeysToElement(list(findate))
remote_driver$findElement(using = 'xpath', "//*[@id='applyBtn']")$clickElement()
Sys.sleep(7)
# Table
tab = htmlParse(remote_driver$getPageSource()[[1]])
tab = readHTMLTable(tab)$curr_table
date = gsub(" ","/",tab[,1])
date = gsub(",","",date)
date = readr::parse_date(date,"%b/%d/%Y",locale=locale("en"))
tab[,6] = gsub("M","",tab[,6])
tab[,7] = gsub("%","",tab[,7])
tab = apply(tab[2:7],2,as.numeric)
tab = xts::xts(tab,order.by=date)
write.zoo(tab,file=paste0(ticker,".csv"),sep=",")
}
A configuração do navegador pode levar alguns instantes, se der certo, vai abrir o navegador Firefox. Não precisa usar necessariamente esse navegador, mas foi que tive mais sucesso.
Basicamente, a função acima abre o site Investing, busca pelo ticker desejado, seleciona o link dos dados históricos, define o intervalo temporal, faz a busca, raspa os dados da tabela e por fim faz o download no diretório que devemos definir.
A seguir, veremos dois exemplos:
setwd("...") # Defina o diretório aqui, pois os dados serão salvos neste local.
# Exemplo 1
indate = "01/01/2017" # mm/dd/yyyy
findate = "04/21/2021" # mm/dd/yyyy
fqc = "daily" # disponíveis: "daily", "weekly", "monthly"
robot(ticker = "PETR4", indate = "01/01/2017", findate = "04/21/2021", fqc = "daily")
# Exemplo 2
tick = read.csv("ticker.csv")
for(i in 1:length(paste0(unlist(tick)))){
robot(ticker=paste0(unlist(tick)[i]),indate="01/01/2017",findate="04/21/2021",fqc="daily")
pb = txtProgressBar(min = (1/length(paste0(unlist(tick)))), max = length(paste0(unlist(tick))), style = 3)
setTxtProgressBar(pb,i)
}
# Finalizar sessão
remote_driver$close()
system("taskkill /im java.exe /f", intern=FALSE, ignore.stdout=FALSE)
Se tudo der certo, o robozinho vai trabalhar conforme exemplo abaixo:
O arquivo "ticker.csv" está disponível no meu Github.
Até a próxima!