Scraping em Gráficos Interativos com Python

Caminhando pelo gráfico com selenium

Otávio Simões Silveira
Data Hackers
5 min readJun 15, 2020

--

Photo by Markus Winkler on Unsplash

Um exemplo do dia a dia: o Gráfico do Dolar

Digamos que você queira sabe como o real está variando em relação ao dólar hoje. Uma rápida pesquisa no Google resolveria o problema, basta digitar: “dólar real”. Você verá um gráfico interativo como este:

Para ver os valores para todo o período do gráfico, você precisaria mover o cursor ao longo da linha, enquanto o campo que contém o valor e a data continua sendo atualizado constantemente.

Agora, suponha que você queira coletar todos os dados deste gráfico para criar um banco de dados. Como fazer o scraping dos dados da linha inteira se os valores mudam o tempo todo?

Se você fizesse isso manualmente, o que você faria é mover o cursor ao longo da linha enquanto digitava cada valor em uma planilha de Excel ou quem sabe até escrevesse à mão em um caderno. Bem, neste post, veremos como fazer com que o selenium faça exatamente a mesma coisa. Vamos fazê-lo agir como um ser humano, passando o cursor por toda a linha e registrando os valores.

Embora estejamos trabalhando com o gráfico do Google, a lógica implementada aqui pode ser adaptada a qualquer gráfico semelhante.

Como implementar o Scraper

Para implementar esse scraper, vamos usar apenas o selenium, o pandas e o módulo datetime. Depois de importar tudo o que usaremos, vamos direto abrir a conexão e buscar a página. É importante usar o Google em inglês para ficar mais fácil trabalhar com datas.

Em seguida, instanciamos o objeto action, que usaremos para mover o cursor na tela, e os objetos search_bar e search_button que vamos usar para executar a busca. Com isso feito, basta usar o método send_keys para escrever no campo de busca e o método click para clicar no botão pesquisar. Usaremos o WebDriverWait para que o selenium aguarde que o elemento seja completamente carregado na página:

Agora vamos encontrar o elemento da página referente ao gráfico e exibir seu tamanho e localização. Isso é importante para que possamos saber para onde mover o cursor. Também usaremos o WebDriverWait para isso.

Execute tudo o que fizemos até agora para ver o seguinte output:

{'x': 514, 'y': 262} 
{'height': 134, 'width': 301}

Agora que temos essas informações, podemos usá-las para mover o cursor para o canto direito do objeto, usando o método move_to_element_with_offset . Este método move o mouse para uma posição relativa ao canto superior esquerdo do objeto especificado, portanto, precisamos passar como o xoffset todo o comprimento do objeto. Como não há necessidade de mover o cursor no eixo y, o yoffset pode ser definido como zero:

Se tivéssemos usado move_to_element, o que também é uma opção, o cursor se moveria para o centro do elemento.

E agora nosso cursor está aqui:

Observe o cursor na no canto direito do gráfico.

Em seguida, obtemos o primeiro par de valor e data:

Agora só precisamos que o nosso cursor continue se movendo para a esquerda. Para isso, precisamos configurar:

  • O ritmo em que o cursor se moverá (variável pace);
  • A data limite até a qual o cursor irá (variável limit).

Usaremos o método move_by_offset do objeto action para mover o cursor de sua última posição conhecida para a próxima. Um loop infinito fará o cursor se mover até a data limite que configuramos. Quando a data ultrapassar a data limite, usamos o break .

E este é o comportamento que esperamos:

Legal né?! Cada vez que o cursor se move para a esquerda, ele copia um novo valor e uma nova data. Assim como um ser humano movendo o mouse e anotando!

No entanto, se você estiver fazendo isso em um gráfico do Google e alterar o intervalo de tempo do gráfico, digamos, para anos, algumas datas poderão ser ignoradas. Essas datas não são acessíveis nem mesmo manualmente. Talvez isso aconteça porque o eixo x se torne muito grande para um gráfico tão pequeno.

Além disso, é importante deixar claro que o ritmo com o que o cursor se movimenta é definido por tentativa e erro. Se o ritmo for muito pequeno, o cursor levará um longo tempo para passar para a próxima data no gráfico. Se for muito grande, pode pular datas.

Limpando os dados

No entanto, é inevitável que, às vezes, o cursor ainda esteja na mesma data mesmo que tenha acabado de se mover. Por isso, recomendo armazenar os dados em um dicionário e usá-lo para descartar os dados duplicados. Quando terminarmos o scraping, é só converter esse dicionário em um DataFrame. O código completo fica assim:

E estes são os dados que acabamos de extrair:

Último aviso: se você estiver vendo o cursor se mover pela linha, notará que ele volta ao início do gráfico em cada loop. Isso acontece mesmo que o selenium mantenha a última posição conhecida, mas você também pode observar que o cursor continua indo mais à esquerda em cada novo loop no ritmo que estabelecemos. Então, tudo está de acordo com o planejado.

Bem, é isso. Espero que tenha gostado e que isso possa ser útil de alguma forma. Se você tiver alguma dúvida, sugestão ou apenas quiser entrar em contato, deixo meus perfis no Twitter , GitHub e Linkedin .

--

--