Fazendo login com o Requests

Logando no site do restaurante da universidade

Para interagir com sistemas web, precisamos entender como os mesmos funcionam, o navegador que usamos utiliza o protocolo HTTP para se comunicar, é interessante que sentemos em uma cadeira e estudemos o funcionamento do protocolo, porém…tudo é requisição e resposta nesse tipo de comunicação com alguns tipos de ação/verbos, como GET, DELETE, PUT e POST. Para fazermos o login em um site, precisamos de uma sessão, para isso é gerado um cookie, que nada mais é que uma sequência de caracteres que identifica nossa sessão de forma única e serve para registrar e fazer nossa identificação online. Para gerenciar uma sessão, devemos portanto ter um cookie e o Requests vem com um método incluso para fazer isso, muitas vezes é necessário ter uma sessão em um site mesmo sem usuário e senha.

Segue um exemplo usando requests para fazer o login e extrair as informações de um usuário do site do SRU (Sistema de Restaurante Universitário) da UNESP/IBILCE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import requests
import re
import sys

class SRU:
    def __init__(self, username, password):
        self.__username = username
        self.__password = password
        self.__session = requests.Session()
        self.__data = {}
        self.start()

    def start(self):
        self.login()
        self.get_id()
        self.get_informations()
        _data = self.get_data()
        print(_data)

    def login(self):
        response = self.__session.get("https://sru.ibilce.unesp.br/login")
        csrf = re.findall(r'name="_csrf" value=".*"', response.text)[1].split('"')[3]
        self.__session.post("https://sru.ibilce.unesp.br/login", data={"username": self.__username, "password": self.__password, "_csrf": csrf})
        
    def get_id(self):
        response = self.__session.get("https://sru.ibilce.unesp.br/cliente/buscar-usuario-logado")
        ID = response.json()["idUsuario"]
        self.__data["ID"] = ID

    def get_informations(self):
        response = self.__session.get("https://sru.ibilce.unesp.br/usuario/dados-pessoais")
        self.__data["name"] =  re.findall(r'placeholder="Insira seu nome" required="true" type="text" value=".*"/>', response.text)[0].split('"')[7]
        self.__data["email"] = re.findall(r'placeholder="Insira seu e-mail" type="email" required="true" value=".*"/>', response.text)[0].split('"')[7]
        self.__data["cpf"] = re.findall(r'name="cpf" class="form-control" readonly="readonly" type="text" value=".*"/>', response.text)[0].split('"')[9]

    def get_data(self):
        return self.__data

SRU(sys.argv[1], sys.argv[2])
  • Da linha 1 a 3, estamos importando as bilbiotecas utilizadas no nosso programa
  • Na Linha 5, estamos declarando uma classe, se quiser saber mais sobre, leia um pouco mais sobre [como programar com classe]
  • Da linha 6 a 11, estamos utilizando um método especial do python, o __init__ que é executado quando a classe é instanciada. Nele estamos definindo os atributos de nosso programa, no caso, senha, nome de usuário, nossa sessão web e um dicionário para armazenar os nossos dados
  • Linha 13 a 18 defimos nosso método principal, que fará todas as tarefas que queremos
  • Linha 20 a 23 fazemos o método login, responsável por enviar nossas informações para o site, imitando o comportamento realizado quando utilizamos o navegador. Isso pode ser descoberto verificando as requisições feitas apertando o botão F12 no seu teclado e indo na parte de Rede ao acessar qualquer site. Note que não apenas usuário e senha são enviados para o servidor, mas também uma sequência de caracteres que funciona como validador de uma sessão. Essa sequência sempre aparece ao abrirmos a página em seu código fonte e vários sites utilizam coisas desse gênero
  • Linha 25 a 28 nos comunicamos com o site para extrair o ID de usuário, é o número que muitos utilizam para poder se identificar no restaurante universitário
  • Linha 30 a 34 podemos também extrair todos os dados do nosso usuário
  • Linha 36 e 37 serve para retornar as informações extraídas
  • Linha 39 estancia a classe e faz a passagem de parâmetros via linha de comando

Para executar esse programa, basta fazer python nome_arquivo.py usuário senha, ele te retornará algo como:

{‘ID’: 666, ‘name’: ‘Lucas Villela’, ‘email’: ‘lucasvillela@email.br’, ‘cpf’: ‘6666666666’}

Isso, além de tudo, nos prova que estávamos logados no site e podemos fazer o que bem entender nele ;)

Logando no Quotes to Scrap

O site quotes to scrap é um local com várias frases legais, criado para servir de exemplo para diversos web scraping e também para publicar frases (Óbvio). Quando entramos no Quotes to Scrap temos uma página de login, basta enviar os dados e ser feliz.

Podemos logar facilmente utilizando Requests, depois de investigar um pouco o funcionamento do site:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import requests
import re
import sys

class Quotes:
    def __init__(self, username="lcsvillela", password="lcsvillela"):
        self.__username = username
        self.__password = password
        self.__session = requests.Session()
        self.start()

    def login(self):
        response = self.__session.get("https://quotes.toscrape.com/login")
        csrf = re.findall(r'name="csrf_token" value=".*"/>', response.text)[0].split('"')[3]
        self.__session.post("https://quotes.toscrape.com/login", data={"username": self.__username, "password": self.__password, "csrf_token": csrf})

    def get_info(self):
        response = self.__session.get("https://quotes.toscrape.com")
        re.findall(r'<a href="[^"]*">\(Goodreads page\)</a>',response.text)

    def start(self):
        self.login()
        self.get_info()
        
        
Quotes()

Para provar que nosso programa está logado no site, vamos extrair os links do GoodReads page (só aparecem quando estamos logados), ao executar o programa os links são exibidos.

Fazendo login com scrapy

Já fiz vários textos por aqui falando sobre o Scrapy, como extraí 30000 frases, mas sobre o login, basta fazermos as requisições assim como o Requests faz, porém no Scrapy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from scrapy import Spider
from scrapy.http import FormRequest
from scrapy.utils.response import open_in_browser


class Quotes(Spider):
    name = 'quotes'
    start_urls = ('http://quotes.toscrape.com/login',)

    def parse(self, response):
        token = response.xpath('//*[@name="csrf_token"]/@value').get()
        return FormRequest.from_response(response,
                                         formdata={'csrf_token': token,
                                                   'password': 'lcsvillela',
                                                   'username': 'lcsvillela'},
                                         callback=self.parse_info)

    def parse_info(self, response):
        pass

Conclusão

Tudo é HTTP e podemos fingir que somos um navegador, existem sites que inviabilizam o uso dessas ferramentas pelo tempo de trabalho, mas sempre é possível fazer algo do gênero. Até mesmo usar requests para passar por cima do RecapchaV2 do Google!