Scrapping de links em conversas no Telegram utilizando Python

Antes de tudo, queria agradecer às pessoas INCRÍVEIS que fazem parte da comunidade Data Science Brazil, que sempre nos motivam a resolver desafios e acima de tudo, a sempre adquirir conhecimento nessa área tão promissora.

O projeto surgiu pela necessidade de concentrar os mais variados links que os integrantes da comunidade DataScienceBrazil postam nas nossas redes sociais (WhatsappTelegram, Slack…) em um único repositório. Nesse projeto, iremos coletar os links que são postados no Telegram.

Então, Let’s Go Baby!

Chave Token de Bot no Telegram

Primeiro, iremos gerar um token de bot do Telegram para utilizarmos no decorrer do projeto.

Para isso, procure e adicione o @BotFather no Telegram:

Tela após adicionar o @BotFather no Telegram

Após isso, crie um bot utilizando o comando /newbot. No exemplo, chamei o bot de “BotTeste”

Tudo bem, um novo bot. Como vamos chamar isso? Por favor, escolha um nome para o seu bot.

Agora, você precisa criar um username para o seu bot para que seja possível procurar ele no Telegram como um usuário. No nosso exemplo, chamei o username de “ProjetoScrapping_bot”

Boa. Agora vamos escolher um nome de usuário para o seu bot. Deve terminar no `bot`. Assim, por exemplo: TetrisBot ou tetris_bot.

Após tudo isso, o Telegram irá gerar a chave token do nosso bot:

Chave gerada com sucesso!!!

Tendo a chave em mãos, agora é hora de instalarmos as bibliotecas que precisaremos no projeto.

Instalação dos Pré-Requisitos

Nesse projeto, foi utilizado o Python 3.7 que vem junto com a versão mais nova do Anaconda (Versão 5.3) além da API pyTelegramBotApi:

https://github.com/eternnoir/pyTelegramBotAPI

Para instalar a API, a própria documentação explica:

  • Usando o pip:
$ pip install pyTelegramBotAPI
  • Usando o git:
$ git clone https://github.com/eternnoir/pyTelegramBotAPI.git
$ cd pyTelegramBotAPI
$ python setup.py install

Feito isso, vamos ao código.

Hora da Mão na Massa!!!

Utilize sua IDE preferida, no projeto utilizei o PyCharm Community.

Crie o projeto com o nome que desejar, e depois crie o arquivo bot.py dentro do projeto:

Projeto “zerado”

Vamos então importar a API que instalamos (pyTelegramBotApi) com o comando abaixo:

import telebot

Após isso, criaremos a variável bot chamando ela pelo token que geramos no começo do projeto com a função ‘Telebot’:

bot = telebot.TeleBot("TOKEN")

Na documentação da API (https://github.com/eternnoir/pyTelegramBotAPI), podemos ver os métodos que ela dispõe. O que iremos sobrescrever é o método @bot.message_handler que é o método que “escuta” as mensagens que chegam no nosso bot:

@bot.message_handler(func=lambda m: True)
def echo_all(message):
	print(message.text)
bot.polling()

O parâmetro func=lambda m: true é para escutar qualquer mensagem que chegar no bot (iremos ver outros parâmetros que podemos passar para o método no decorrer do projeto)

A função echo_all é responsável pelas mensagens que o método @bot.message_handle ‘escutou’.

print(message.text) “printa” o texto da mensagem recebida.

O comando bot.polling() Inicia o bot.

Nesse exemplo, estou “escutando” todas as mensagem que chegam no nosso bot e dando um “print” para ver se tá tudo funcionando.

Vamos testar no nosso projeto então!!!

Execute o código na sua IDE e deixa o console do Python aberto.

Abra o seu Telegram, e inicie um conversa com o bot que você criou. As mensagens que você escrever irão aparecer no console do Python:

Uhuhuhuh. TÁ FUNCIONANDO!!!!! Glória a deuuuuuuuuuxxxxxxxxxxxxx

Uma parte do projeto está feita. Estamos conseguindo coletar as mensagens que chegam no nosso bot. Mas qual é o nosso objetivo? Filtrar somente as mensagens que são links. Então vamos lá.

Lembra que eu falei que podemos passar outros parâmetros para o método @bot.message_handler??? Então, para o filtro de mensagens que forem links, iremos passar o parâmetro regexp que implementa a biblioteca re do Python de expressões regulares para o método @bot.message_handler.

Pra quem não sabe bem o que são expressões regulares, sugiro pesquisar sobre elas e a biblioteca re do Python.

Voltando para o projeto, procurei no Google a expressão regular para links http ou https e acrescentei no parâmetro do método @bot.message_handler:

@bot.message_handler(regexp='((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)')
def echo_all(message):
	print(message.text)
bot.polling()

Agora vamos ver como estamos:

Testando as mensagens com o parâmetro regexp

Como usamos o parâmetro de expressões regulares da biblioteca pyTelegramBotApi (regexp), ele agora só detecta as mensagens que tiverem links.

Como podemos perceber, ele “pega” a mensagem toda com o link incluso. Mas o que interessa é somente o link. Temos então que fazer um outro filtro na mensagem que ele detectou, e após, extrair dessa mensagem o link que desejamos.

Iremos, então, ter que usar a biblioteca re para extrair da mensagem detectada somente o link que desejamos.

A função re.search() da biblioteca re recebe como parâmetro uma expressão regular e uma string. Nisso, ela vai procurar por ocorrências dessa expressão regular na string que foi passado no parâmetro. O resultado dessa função é um objeto do tipo re.Match que contém a string correspondente à expressão regular que passamos.

No nosso caso, passamos a expressão regular de links http e https e o texto da mensagem que contém um link. O resultado será então somente o link que estava na mensagem.

Criamos então uma variável chamada link que recebe o retorno da função re.search():

link = re.search('((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)', message.text)

Pra recuperarmos o link, utilizamos o group(0):

print(link.group(0))

Vamos testar então!

Código da extração de links da mensagem

Como podemos ver, ele está funcionando. Fiz dois prints pra mostrar o o algoritmo fez. No primeiro print(message.text), ele coletou toda a mensagem que continha o link. No segundo print (link.group(0)) ele extraiu somente o link que continha na mensagem.

Agora que coletamos os links podemos fazer o que quisermos com eles como: guardar em um arquivo txt, em um repositório, deixar salvo na nuvem, e etc.

Vamos guardar nossos links em um repositório no dontpad.com?

Let’s Go!

Acesse o www.dontpad.com, crie um nome para o seu repositório e clique em “go!”

Tela do www.dontpad.com

Vamos escrever um teste de texto no repositório:

O nosso repositório

Pronto. Com o repositório criado vamos seguir…

Iremos utilizar uma API não oficial para o dontpad: https://github.com/GuilhermeFreire/dontpad

Essa API implementa o urllib do python para fazer as requisições para o site do Dontpad. Entre no site acima, baixe o arquivo dontpad.py e acrescente ao seu projeto

Agora vamos ao import:

import dontpad

Usaremos primeiramente a função dontpad.read() da API acima para fazer a requisição de leitura do nosso repositório Dontpad. A função dontpad.read()requer como parâmetro o nome do repositório.

dont = dontpad.read("projetoscrapping_bot")

Após fazer a requisição, o resultado é guardado na variável dont que criamos agora. O resultado do print dessa variável é:

Print da variável ‘dont’

Como podemos ver, ele retornou um JSON com as informações da página do repositório. Mas o que nos interessa é o texto que escrevemos, no caso, ele está na chave “body” do JSON criado. Vamos dar um print somente na chave ‘body’ para ver o que ele retorna

import dontpad
dont = dontpad.read("projetoscrapping_bot")
print(dont['body'])

O resultado é esse:

Print da chave ‘body’

Uhuhuhu, estamos conseguindo ler o texto que está no repositório.

Agora vamos adicionar o links que coletamos no nosso bot do Telegram no repositório Dontpad que criamos. Para isso usaremos a função dontpad.write() que escreve no repositório o texto que passaremos como parâmetro.

Porém, para escrevermos o texto no repositório temos que primeiro ler o que já temos e guardar na variável ‘dont’. Depois vamos atualizar o texto que temos na chave ‘body’ e após isso, acrescentamos nessa chave o texto do link que coletamos no nosso bot.

Depois, escrevemos no repositório o texto atualizado. O código usado é:

dont = dontpad.read("projetoscrapping_bot")
dont['body'] = dont['body'] + "\n" + link.group(0)
dontpad.write("projetoscrapping_bot", dont['body'])

Como podemos ver, concatenei a String ‘\n’ para que ele pule uma linha quando for escrever no repositório.

O código completo do projeto está a seguir:

import telebot
import re
import dontpad
bot = telebot.TeleBot("720417634:AAHqs_6mp1bSPKLhencCR_RzJVNzHaYVPYM")
@bot.message_handler(regexp='((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)')
def echo_all(message):
    link = re.search('((https?):((//)|(\\\\))+([\w\d:#@%/;$()~_?\+-=\\\.&](#!)?)*)', message.text)
    print("MENSAGEM COMPLETA: " + message.text)
    print("SOMENTE O LINK DA MENSAGEM: " + link.group(0))
    dont = dontpad.read("projetoscrapping_bot")
    dont['body'] = dont['body'] + "\n" + link.group(0)
    dontpad.write("projetoscrapping_bot", dont['body'])
bot.polling()

Vamos testar!

Testando a primeira vez, tudo funcionando!

Enviando outro link:

Testando a segunda vez. Ele acrescentou o link detectado com sucesso. Emoção é grande aqui rsrsr

Funcionando com sucesso!

Agora, vem a parte mais difícil…

Com faremos para ele ler mensagens de um grupo do Telegram???

Simples! é só adicionar ele no grupo que desejares. Como ele é um usuário do Telegram (você atribuiu um username para ele no começo do projeto), ele pode ser adicionar em grupos. A partir do momento que você adiciona o bot, ele vai consegui ler as mensagens que forem enviadas. Isso é claro, você executando o código.

E assim finalizamos esse ótimo projeto.

Até a próxima….

Segue meus contatos:

Email: yr.soares@hotmail.com / yansoares@datasciencebrazil.org
Linkedin: 
https://www.linkedin.com/in/yan-soares-931932a3/