Web Scraping Notes01
Web Scraping Notes01
Utilidade
• Muitas vezes os dados não são exportáveis nos sites (i.e., não há
opção de download).
• O web scraping nada mais é do que a extração dos dados diretamente
das páginas da web.
• Por meio do scraping, toda a internet torna-se uma base de dados em
potencial.
• Por exemplo, em alguns sites de instituições federais e estaduais nem
por meio de requisição pela Lei de Acesso de Informação é
disponibilizado dados públicos para download, mesmo estando
disponíveis para consulta. Exemplos:
– Procedimentos do MP-SP.
– Medicamentos registrados na ANVISA.
• Logo, o web scraping nada mais é do que a coleta dessas informações
na página.
# Criando o "driver"
# Firefox:
driver<-rsDriver(browser = "firefox", port = 4448L) # Muitas vezes
basta estes dois parâmetros
# Chrome:
#driver<-rsDriver(browser = "chrome", port = 4440L, chromever = "7
8.0.3904.105")
# Abrir URL:
remDr$navigate("https://consultas.anvisa.gov.br/#/medicamentos/q/?
periodoPublicacaoInicial=1900-01-01&periodoPublicacaoFinal=1975-12
-31")
• OBS.: o navegador fecha ao não ser acionado por muito tempo. Caso
isto ocorra, executar o seguinte comando:
remDr$open()
library("beepr")
beep(2)
2. Repetição.
• For: loop alterando o valor de um elemento i de acordo com uma
sequência pré-estabelecida.
– Utilidade: paginação.
for(i in 1:5){
print(paste0("i igual a: ",i))
}
3. Manipular o tempo
• Sys.sleep: R não executa o próximo comando por n segundos
for(i in 1:5){
print(paste0("esperando ",i," segundos"))
Sys.sleep(i)
}
Sys.sleep(i)
t01<-Sys.time()
print(paste0(s))
}
4. Condicionais
• If: se uma dada relação é verdadeira, executa o(s) comando(s).
• Else: se a dada relação do if for falsa, executa o(s) comando(s).
for(x in 1:5){
if((x%%2)==0){ # %% é operador para o resto da divisão
print(paste0(x," é par"))
}else{
print(paste0(x," é ímpar"))
}
}
## [1] "1 é ímpar"
## [1] "2 é par"
## [1] "3 é ímpar"
## [1] "4 é par"
## [1] "5 é ímpar"
• while: repete o(s) comando(s) até que a relação não seja mais
verdadeira
x<-1
while(x<5){
print(x)
x<-x+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
print(x)
5. Selecionar elemento
• remDr$findElements: seleciona o elemento(s) com base em um
determinado padrão (parâmetro = “using”) e um caminho ()
#remDr$open() #Abrir novamento o navegador
#remDr$navigate("https://consultas.anvisa.gov.br/#/medicamentos/q/
?periodoPublicacaoInicial=1900-01-01&periodoPublicacaoFinal=1975-1
2-31")
remDr$navigate("https://consultas.anvisa.gov.br/#/medicamentos/q/?
periodoPublicacaoInicial=1900-01-01&periodoPublicacaoFinal=1975-12
-31")
while(length(webElems)==0){
print("Esperando página carregar")
Sys.sleep(2)
length(webElems)
## [1] 3
6. Clicar em um elemento
• webElems$clickElement(): clica no elemento webElems
## Criando novo objeto apenas para o terceiro botão (50 itens):
webElems2<-webElems[[3]]
## Clicando no webElems2
webElems2$clickElement()
## Apagando elementos
rm(webElems2,webElems)
for(x in 1:5){
df0<-data.frame(numeros=numeric())
df0<-data.frame(numeros=x)
print(df)
## numeros
## 1 1
## numeros
## 1 1
## 2 2
## numeros
## 1 1
## 2 2
## 3 3
## numeros
## 1 1
## 2 2
## 3 3
## 4 4
## numeros
## 1 1
## 2 2
## 3 3
## 4 4
## 5 5
8. Extrair informações
• Tabelas:
– htmlParse: do pacote XML, comando lê o código fonte da
página
– readHTMLTable: se a página for essencialmente uma tabela,
transforma a página em tabela
#install.packages("XML")
library("XML")
## Lendo a página
doc <- htmlParse(remDr$getPageSource()[[1]])
## Lendo a tabela
table<-readHTMLTable(doc)[[1]]
# Não é perfeito
table
## Limpando a tabela:
# Excluindo primeira coluna e linha
table<-table[-1,-1]
# Renomeando variáveis
colnames(table)<-c("nome","api","registro","processo","empresa","s
ituacao","deferimento","vencimento")
table
• Textos:
– webElems$getElementText(): retorno o texto aparente de um
elemento
remDr$close()
remDr$open()
## remDr$navigate("https://consultas.anvisa.gov.br/#/medicamentos/
2599200340370/?periodoPublicacaoInicial=1900-01-01&periodoPublicac
aoFinal=1975-12-31")
Sys.sleep(4)
### Objetivo: pegar a classe trapêutica:
## Selecionar elemento
webElems <- NULL
while(length(webElems)==0){
print("Esperando página carregar")
Sys.sleep(0.5)
length(webElems)
## [1] 9
webElems[[1]]$getElementText()
## [[1]]
## [1] "MEDICAMENTOS ATIVOS NA SECRECAO GORDUROSA"
(rm(webElems))
## NULL
## [[1]]
## [1] "MEDICAMENTOS ATIVOS NA SECRECAO GORDUROSA"
library("rvest")
##
## Attaching package: 'rvest'
9. Download
• Extrair o link
-webElems$getElementAttribute: retorna o valor do atributo de um
determinada classe
## Exemplo: banco de dados do perfil do aluno da UFABC
remDr$navigate("http://propladi.ufabc.edu.br/informacoes/perfil")
## Selecionando elemento:
webElems <- NULL
while(length(webElems)==0){
print("Esperando página carregar")
Sys.sleep(0.5)
## [1] 7
## Extraindo atributo:
webElems[[1]]$getElementAttribute("href") #Só funciona com element
o único
## [[1]]
## [1] "http://propladi.ufabc.edu.br/images/perfil_graduacao/perfi
l_discente_2018.pdf"
webElems[[2]]$getElementAttribute("href")
## [[1]]
## [1] "http://propladi.ufabc.edu.br/images/perfil_graduacao/micro
dados_perfil_discente_2018.csv"
links
## [1] "/images/perfil_graduacao/perfil_discente_2018.pdf"
## [2] "/images/perfil_graduacao/microdados_perfil_discente_2018.c
sv"
## [3] "/images/perfil_graduacao/microdados_perfil_discente_2016.c
sv"
## [4] "/images/perfil_graduacao/microdados_perfil_discente_2015.x
ls"
## [5] "/images/perfil_graduacao/microdados_perfil_discente_2014.x
ls"
## [6] "/images/perfil_graduacao/microdados_perfil_discente_2013.x
ls"
## [7] "/images/perfil_graduacao/microdados_perfil_discente_2012.x
ls"
• Download
– download.file: com base em um link, realiza o download. No
caso, este comando não funcionária em sites dinâmicos.
## Completando o link:
links<-paste("http://propladi.ufabc.edu.br",trimws(links,"both"),s
ep = "")
## download
# Local:
setwd("C:\\Users\\oOluc\\Dropbox\\web_scraping")
#Download
for(i in 1:length(links)){
## Objeto com o nome do arquivo
file<-substring(links[i],54,nchar(links[i])) # Pega o string ent
re os caracteres indicados
# Download
download.file(links[i],file, mode="wb")
}
## Limpando o R
rm(list=ls())
#Diretório
setwd("C:\\Users\\oOluc\\Dropbox\\web_scraping")
#Pacotes:
packages<-c("XML","RSelenium","rvest","beepr"); lapply(packages, r
equire, character.only=T)
# Objetivo:
df<-data.frame(
nome = character(),
api = character(),
registro = character(),
processo = character(),
empresa = character(),
situacao = character(),
deferimento = character(),
vencimento = character()
)
# Abrir navegador
driver<-rsDriver(browser = "firefox", port = 4441L) #Os argumentos
podem variar.
remDr <- driver[["client"]]
#remDr$open()
## Acessando site
remDr$navigate("https://consultas.anvisa.gov.br/#/medicamentos/q/?
periodoPublicacaoInicial=1900-01-01&periodoPublicacaoFinal=1975-12
-31")
## Clicando em 50 itens
webElems<-NULL
while(is.null(webElems) | length(webElems)==0){
webElems <- tryCatch({remDr$findElements(using = 'css selector',
"button.ng-scope")},
error = function(e){NULL})
#LOOP ATÉ A PAGINA CARREGAR
page<- read_html(remDr$getPageSource()[[1]])
webElems <-page %>% html_nodes("table.table.table-hover.table-st
riped.ng-scope.ng-table tbody tr.ng-scope")
}
rm(page,webElems)
### Loop de paginação
# Como a quantidade total de páginas não está disponível, é melhor
usar o comando while
# Necessário achar alguma característica particular na última pági
na
# No caso, o botão de "próximo" fica bloqueado, mudando o código f
onte
# Este botão é o único com o seguinte código: "ul.pagination.ng-
table-pagination.ng-scope li.ng-scope.disabled a.ng-scope"
## Loop
# Marcando a página
k<-1
while(is.null(elems_ultima_pg) | length(elems_ultima_pg)==0){
# Marcando tempo
t00<-Sys.time() #Tempo inicial
# Reportando
print(paste0("Página ",k))
# Extraindo tabela
doc <- htmlParse(remDr$getPageSource()[[1]]) # Lendo página
# Renomeando variáveis
colnames(table)<-c("nome","api","registro","processo","empresa",
"situacao","deferimento","vencimento")
# Adicionando ao df
df<-rbind(df,table)
## Próxima página
webElem2$clickElement()
while(isTRUE(all.equal(table,table0))){
print("Esperando nova página carregar")
Sys.sleep(1.5)
## Tempo final
t01<-Sys.time()
s<-difftime(t01,t00,units = "secs")
#Reportando
print(paste0("Tempo gasto: ",s))
beep(2)
}#paginacao
## Última página:
# Reportando
print(paste0("Página ",k," (última página)"))
# Extraindo tabela
doc <- htmlParse(remDr$getPageSource()[[1]]) # Lendo página
# Renomeando variáveis
colnames(table)<-c("nome","api","registro","processo","empresa","s
ituacao","deferimento","vencimento")
# Adicionando ao df
df<-rbind(df,table)
# Salvando
write.csv(df,"df_etapa1.csv")
beep(4)
#Diretório
setwd("C:\\Users\\oOluc\\Dropbox\\web_scraping")
# Pacotes:
packages<-c("XML","RSelenium","rvest","beepr"); lapply(packages, r
equire, character.only=T)
# Objetivo:
df<-data.frame(
nome = character(),
api = character(),
registro = character(),
processo = character(),
empresa = character(),
situacao = character(),
deferimento = character(),
vencimento = character(),
n_processo = character(),
date_reg = character(),
classe = character()
)
# Criandonova variável
df0$n_processo<-gsub("[^0-9]","",df0$processo)
# Abrir navegador
driver<-rsDriver(browser = "firefox", port = 4442L) #Os argumentos
podem variar.
remDr <- driver[["client"]]
## Reportando
print(paste0("Extraindo dados do registro ",x))
## Criando URL do registro x
n_proc<-df0$n_processo[x] #pegando o número do processo do regis
tro X
# Colocando no link:
url<-paste0("https://consultas.anvisa.gov.br/#/medicamentos/",n_
proc,"/?periodoPublicacaoInicial=1900-01-01&periodoPublicacaoFinal
=1975-12-31")
## Acessando Url
remDr$navigate(url)
## Extraindo informações
df1<-data.frame(
nome = df0$nome[x],
api = df0$api[x],
registro = df0$registro[x],
processo = df0$processo[x],
empresa = df0$empresa[x],
situacao = df0$situacao[x],
deferimento = df0$deferimento[x],
vencimento = df0$deferimento[x],
n_processo = df0$n_processo[x],
date_reg = as.character(tryCatch({(remDr$findElements(using =
'css selector', "div.ng-scope form.ng-pristine.ng-valid.ng-scope d
iv.panel.panel-default div.table-responsive table.table.table-bord
ered.table-static tbody tr td.ng-binding")[[6]])$getElementText()}
,
error = function(e){NA})[[1]]),
classe = as.character(tryCatch({(remDr$findElements(using = 'c
ss selector', "form.ng-pristine.ng-valid.ng-scope div.panel.panel-
default div.table-responsive table.table.table-bordered.table-stat
ic tbody tr td")[[12]])$getElementText()},
error = function(e){NA})[[1]])
)
# Unindo com data frame:
df<-rbind(df,df1)
## Salvando a cada 50
if((x%%50)==0){
Sys.sleep(1)
save.image(paste0("df_etapa2_1a",x,".RData"))
beep(2)
}
## Tempo
t01<-Sys.time() #tempo final
s<-difftime(t01,t00,units = "secs")
t<-rbind(t,
data.frame(
time=as.numeric(s)
))
print(paste0("Processo ",x," em (s) ",s))
tempo<-((length(df0$n_processo)-(x+1))*(mean(t$time))/60)
print(paste0("Minutos até o fim: ",tempo))
beep(1)
}
write.csv(df,"df_etapa2.csv")
beep(4)