Recebendo Informações do Transfermarkt: Uma Introdução ao Web Scraping
Tags: python, beautifulsoup, pandas, transfermarkt
Published: 2020-07-25 20:41:14

Conseguir dados e transformá-los em informação é a base de áreas da computação como a Ciência de Dados. Às vezes essa obtenção é bem simples, por exemplo, você pode, agora mesmo, visitar o site do governo brasileiro [dados.gov.br](http://www.dados.gov.br/) e conseguir acesso a diversos arquivos de dados brutos e depois realizar a análise de um arquivo .csv (um tipo de arquivo que transmite dados) de forma fácil, simples e rápida.

Contudo, em algumas situações essa obtenção é dificultada, por exemplo, você pode precisar receber dados que estão disponíveis somente em uma página da web para realizar uma análise. Nessa situação você pode usar a biblioteca **Beautiful Soup** do *Python* para realizar um *web scraping*, isto é, uma raspagem dos dados que você necessita na página.

### A Biblioteca Beautiful Soup

Beautiful Soup é a biblioteca mais popular para receber dados web de python, ela é capaz de realizar a extração de dados de arquivos HTML e XML. Além de possuir vários métodos que facilitam a busca de dados específicos em páginas web.

## Os Dados que Usaremos

Para o tutorial, iremos extrair dados do portal [Transfermarkt](https://www.transfermarkt.co.uk/) que é um site que contém notícias e dados sobre jogos, tranferências, clubes e jogadores de futebol.

![Página Inicial do Transfermarkt](https://dev-to-uploads.s3.amazonaws.com/i/4hmpvi3ianfhjw84osrk.png)
*Página Inicial do Transfermarkt*

Iremos receber o nome, a o país da liga de origem e o preço dos 25 jogadores mais caros da história do clube AFC Ajax, essas informações podem ser encontradas na página do [Transfermarkt](https://www.transfermarkt.co.uk/ajax-amsterdam/transferrekorde/verein/610/saison_id//pos//detailpos/0/w_s//altersklasse//plus/1/).
![Página com as informações sobre as 25 maiores transferências do AFC Ajax](https://dev-to-uploads.s3.amazonaws.com/i/xpqwdoj72u781b55hxv4.png)
*Página com as informações sobre as 25 maiores transferências do AFC Ajax*

## Obtendo os Dados

Antes de obter os dados em si, iremos importar as bibliotecas necessárias para a execução do programa, essas serão: *Beautiful Soup*, *Pandas* e *Requests*.

```python
import requests
from bs4 import BeautifulSoup
import pandas as pd
```
Depois disso, iremos receber a página no nosso programa usando a biblioteca requests, que solicita as informações da página, e a biblioteca BeautifulSoup, que transforma os dados recebidos no requests (um objeto `Response`) em um objeto `BeautifulSoup` que será usado na extração dos dados.

```python
"""
Para realizar a solicitação à página temos que informar ao site que somos um navegador
e é para isso que usamos a variável headers
"""
headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'}

# endereco_da_pagina representa o link que direciona a página com os dados
endereco_da_pagina = "https://www.transfermarkt.co.uk/ajax-amsterdam/transferrekorde/verein/610/saison_id//pos//detailpos/0/w_s//altersklasse//plus/1"

# no objeto_response iremos realizar o download da página da web 
objeto_response = requests.get(endereco_da_pagina, headers=headers)

"""
Agora criaremos um objeto BeautifulSoup a partir do nosso objeto_response.
O parâmetro 'html.parser' representa qual parser usaremos na criação do nosso objeto,
um parser é um software responsável por realizar a conversão de uma entrada para uma estrutura de dados.
"""
pagina_bs = BeautifulSoup(objeto_response.content, 'html.parser')
```
`pagina_bs` agora é uma variável que contém todo o HTML existente na nossa página.

Agora vamos extrair os dados que estão na nossa variável, note que as informações que precisamos estão em uma tabela. Cada linha dessa tabela representa um jogador, com seu nome, representado no HTML por uma âncora (`<a>`) com a classe "spielprofil_tooltip", país de liga de origem, representado como uma bandeira de classe "flaggenrahmen" na sétima coluna (`<td>`) de cada linha, e custo representado por uma célula (`<td>`) de classe "rechts hauptlink". 

Vamos então conseguir esses dados usando a biblioteca BeautifulSoup.

Primeiro iremos conseguir os nomes dos jogadores
```python
nomes_jogadores = [] # Lista ordenada dos nomes de todos os jogadores

# O método find_all() consegue retornar todas as tags que cumprem as restrições dentro dos parênteses
tags_jogadores = pagina_bs.find_all("a", {"class": "spielprofil_tooltip"})
# No nosso caso estamos encontrando todas as âncoras com a classe "spielprofil_tooltip"

# Agora iremos conseguir somente os nomes de todos os jogadores
for tag_jogador in tags_jogadores:
    nomes_jogadores.append(tag_jogador.text)
```

Agora conseguiremos os países das ligas de origem dos jogadores.

```python
pais_jogadores = [] # Lista ordenada dos nomes do país da liga de origem de todos os jogadores

tags_ligas = pagina_bs.find_all("td",{"class": None})
# Agora iremos receber todas as células da tabela que não possuem classe

for tag_liga in tags_ligas:
    # A função find irá encontrar a primeira imagem cuja classe é "flaggenrahmen" e possui um título
    imagem_pais = tag_liga.find("img", {"class": "flaggenrahmen"}, {"title":True})
    # A variável imagem_país será uma estrutura com todas as informações da imagem,
    # uma delas é o title que contem o nome do país da bandeira
    if(imagem_pais != None): # Testaremos se o método encontrou alguma correspondência
        pais_jogadores.append(imagem_pais['title'])
```

Por fim conseguiremos os custos dos jogadores.
```python
custos_jogadores = []

tags_custos = pagina_bs.find_all("td", {"class": "rechts hauptlink"})

for tag_custo in tags_custos:
    texto_preco = tag_custo.text
    # O texto do preço contém caracteres que não precisamos como £ (euros) e m (milhão) então iremos retirá-los
    texto_preco = texto_preco.replace("£", "").replace("m","")
    # Converteremos agora o valor para uma variável numérica
    preco_numerico = float(texto_preco)
    custos_jogadores.append(preco_numerico)
```
Agora que conseguimos todos os dados que queríamos, vamos tornar eles entendíveis para melhorar qualquer análise que desejamos fazer. Para isso, usaremos a biblioteca pandas e sua classe `DataFrame` que é uma classe que representa uma estrutura de dados tabular, ou seja, é parecida com uma tabela comum.

```python
# Criando um DataFrame a partir de nossos dados
df = pd.DataFrame({"Jogador":nomes_jogadores,"Preço (milhão de euro)":custos_jogadores,"País de Origem":pais_jogadores})

# Imprimindo os dados que obtemos
print(df)
```
Agora podemos ver todos os nossos dados obtidos com o `web scraping` organizados no DataFrame!

O programa desenvolvido nesse tutorial está disponível no meu [repositório do gitlab](https://gitlab.com/veronicamars73/introducao-ao-web-scraping). Espero ter ajudado e se você estiver com algum problema ou dúvida sinta-se convidado a comentar esse post ou enviar um [e-mail para mim](mailto:mendie73@gmail.com) ;).