Webscraping tabela Tesouro Direto

Olá pessoal, no link
https://www.tesourodireto.com.br/titulos/calculadora.htm
há duas tabelas atualizadas, uma com os títulos disponíveis para investir e outra com os títulos somente para resgate.

Tabela Investir

Tabela Resgatar

Estou precisando de um código para puxa-las para o rstudio, se alguém puder auxiliar fico grato.

1 curtida

Olá @pedro, tudo bem?

Por sorte, os seus dados são alimentados por uma API!

Olhando no Network (Apertando F12, entrando em Network e recarregando a página) da página, eu notei que tinha uma requisição para o arquivo json abaixo.

# primeira forma, via API ----

library(magrittr)
u <- "https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json"
r <- httr::GET(u, httr::config(ssl_verifypeer = FALSE))

da_tesouro <- httr::content(r, simplifyDataFrame = TRUE) %>%
  purrr::pluck("response", 3, 1) %>% 
  tibble::as_tibble() %>% 
  janitor::clean_names()

da_tesouro
#> # A tibble: 29 x 17
#>       cd nm    featrs mtrty_dt min_invstmt_amt untr_invstmt_val invstmt_stbl
#>    <int> <chr> <chr>  <chr>              <dbl>            <dbl> <chr>       
#>  1   153 Teso… "Títu… 2021-03…             0                 0  "Esse inves…
#>  2   159 Teso… "Títu… 2023-03…             0                 0  "Esse inves…
#>  3   171 Teso… "Títu… 2024-09…           107.            10727. "Como não p…
#>  4   164 Teso… "Títu… 2025-03…             0                 0  "Como não p…
#>  5   172 Teso… "Títu… 2027-03…           106.            10574. "Como não p…
#>  6   163 Teso… "Títu… 2022-01…             0                 0  "É mais int…
#>  7   155 Teso… "Títu… 2023-01…             0                 0  "É mais int…
#>  8   146 Teso… "Títu… 2023-01…             0                 0  "É mais int…
#>  9   173 Teso… "Títu… 2024-07…            31.9             798. "É mais int…
#> 10   161 Teso… "Títu… 2025-01…             0                 0  "É mais int…
#> # … with 19 more rows, and 11 more variables: semi_anul_intrst_ind <lgl>,
#> #   rcvg_incm <chr>, anul_invstmt_rate <dbl>, anul_red_rate <dbl>,
#> #   min_red_qty <dbl>, untr_red_val <dbl>, min_red_val <dbl>, isin_cd <chr>,
#> #   fin_indxs$cd <int>, $nm <chr>, wdwl_dt <chr>

Note que o formato da tabela não é exatamente igual o da tabela que aparece no site, mas provavelmente todos seus dados estão aí.

Também tentei obter os dados diretamente das tabelas que estão na página, mas infelizmente isso não é possível (pelo menos não sem selenium) pois o conteúdo é gerado dinamicamente.

# segunda forma, via parse do html ----

# nao da certo, pois a pagina é alimentada dinamicamente

u <- "https://www.tesourodireto.com.br/titulos/calculadora.htm"
r <- httr::GET(u, httr::config(ssl_verifypeer = FALSE))
html <- xml2::read_html(r)
html %>% 
  rvest::html_node("#tabelaResgate")
#> {xml_missing}
#> <NA>

Created on 2021-02-22 by the reprex package (v1.0.0)

Excelente exemplo para nosso curso de web scraping! Obrigado :slight_smile:

2 curtidas

Muito agradecido, deu certo aqui, aproveitei para fazer uns filtros e dar uma alinhada no código para deixar pronto para fazer análises, vou postar abaixo.
Só uma observação, quando você fez a importação e deu o comando tibble::as_tibble(), ele comeu as casas decimais do valor unitário do título, troquei este comando por data.table::data.table()

library(tidyverse)
u <- “https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json
r <- httr::GET(u, httr::config(ssl_verifypeer = FALSE))

da_tesouro <- httr::content(r, simplifyDataFrame = TRUE) %>%
purrr::pluck(“response”, 3, 1) %>%
data.table::data.table() %>%
janitor::clean_names()

x2 <- da_tesouro %>% select(fin_indxs_nm, mtrty_dt, min_invstmt_amt, untr_invstmt_val, untr_red_val, semi_anul_intrst_ind, anul_invstmt_rate, anul_red_rate, wdwl_dt)

x2$mtrty_dt <- substr(x2$mtrty_dt, start=1, stop=10) %>% as.Date()
x2$wdwl_dt <- substr(x2$wdwl_dt, start=1, stop=10) %>% as.Date()

x2 <- x2 %>% rename(“indice” = “fin_indxs_nm”,
“vcto” = “mtrty_dt”,
“inv_min” = “min_invstmt_amt”,
“vlr_un_comp” = “untr_invstmt_val”,
“vlr_un_venda” = “untr_red_val” ,
“cupom” = “semi_anul_intrst_ind”,
“ret_inv” = “anul_invstmt_rate”,
“ret_resgate” = “anul_red_rate”,
“data_emissao” = “wdwl_dt” ) %>%
select(“indice”, “vcto”, “cupom”, “inv_min”, “vlr_un_comp”, “vlr_un_venda”, “ret_inv”, “ret_resgate”, “data_emissao”)

x2
x2_compra <- x2 %>% filter(inv_min>0) %>% select(-c(data_emissao, ret_resgate, vlr_un_venda))
x2_venda <- x2 %>% select(-c(inv_min,data_emissao, vlr_un_comp, ret_inv))