Tutorial para iniciantes: Web Scraping em Python

Aprenda as ferramentas básicas para criar seus próprios datasets!

Lucas Morato
Data Hackers
8 min readMay 10, 2020

--

Aprender a extrair dados abre um mundo de novas possibilidades para um cientista de dados! Fonte

E aí comunidade, tudo certo? Gostaria de compartilhar hoje um tutorial básico de web scraping, ou raspagem de dados, um dos processos mais básicos de coleta de dados que todo aspirante a data scientist deveria dominar.

Para começar, a minha primeira dica é: escolha um tema que te interesse, de preferência um com o qual você tenha familiaridade, para que você possa entender quais dados serão interessantes de coletar, já pensando na utilização futura dessa informação em machine learning, visualizações, etc. Como você irá acompanhar a seguir, o código pode facilmente se tornar complexo para novatos, portanto, se você não trabalhar com um assunto que goste, a chance de deixar o projeto no meio do caminho é alta.

Dito isso, deixa eu te contextualizar no meu tema e projeto. Eu amo viajar, e já tive a oportunidade de dar a volta ao mundo, mochilando durante mais de um ano pelo planeta (inclusive foi durante essa viagem que comecei a aprender data science, mas essa história fica pra depois), e nesse período, virei um especialista em hostels. Para quem nunca ouviu falar, hostel é um tipo de acomodação onde você divide o quarto com mais uma galera, fazendo a hospedagem ser bem mais em conta do que um hotel tradicional. Pois bem, durante meu rolê eu usei bastante um site de busca e reserva de hostels chamado hostel world, onde é possível encontrar muitas informações sobre as opções de hospedagem, incluindo avaliações, localização, preço, etc.

Atualmente eu trabalho como analista de dados, ainda em começo de carreira, e mesmo que meu portfolio já tenha uns projetos bacanas, eu senti que era hora de dar um gás e fazer algo novo, por isso decidi ir atrás de dados sobre hostels, com o objetivo de entender o que faz um hostel ser melhor que o outro. Como pontapé inicial, decidi dar uma olhada nos hostels disponíveis na minha cidade favorita, Berlim, reunindo informações básicas sobre cada opção, e é isso que eu vou te ensinar a fazer hoje.

Agora chega de enrolação, faz um café, abre o jupyter notebook que eu preparei especialmente pra você, e bora pro tutorial!

Primeiro passo: definir os dados que você quer extrair

Usando as informações disponíveis no hostelworld.com/hostels/Berlin, nosso objetivo é criar uma tabela contendo:

Nome do hostel

Link para a página do hostel

Distância do hostel até o centro da cidade

Nota média de avaliação

Número de avalições feitas para aquele local

Preço médio por noite, em USD

Usando seus poderes ninjas de HTML: inspecionando o site

Se você, assim como eu, não tem muita familiaridade com HTML, é importante saber que aos trancos e barrancos alguma coisa teremos que aprender. A ideia básica é de que HTML é a linguagem utilizada para estruturar os sites, funcionando como uma árvore, com tags, elementos e atributos que compõem uma página agrupados hierarquicamente. Você pode ler um pouco mais sobre HTML aqui.

Para inspecionar a estrutura de uma página, caso você esteja usando o Chrome, basta clicar com o botão direito do mouse e selecionar inspecionar. O resultado será o seguinte:

Página de inspeção do site hostelworld.com.

À direita está toda estrura, que precisamos entender para poder codificar depois. Nessa parte, no canto superior esquerdo tem um botão com uma seta, selecione ele e depois passe o cursor do mouse pela primeira opção de hostel da tela, até todos os elementos do hostel estiverem selecionados, então você clica e repara no que acontece à direita:

O container com informação referente ao primeiro hostel.

Essa informação em azul claro é como se fosse o ‘tronco’ de informações relativo ao hostel. Repare que bem ao lado da palavra ‘div’ tem uma pequena seta apontando para o lado. Quando você clicar nela, todas as ramificações desse hostel aparecem.

Inspecionando um bloco de informações HTML

Essa mesma estrutura se repete para cada um dos elementos da página, e iremos chamar isso de container. O que identifica essa parte como um hostel, nesse caso, é o nome da classe ‘fabresult rounded clearfix hwta-property’, porém tenha em conta que essa informação muda de site para site. Com essas informações, já podemos criar os contêineres para cada um dos hostels presentes nessa página.

Quer uma sopa? Só se for bonita! Beautifulsoup!

Ok, não sou bom com piadas e trocadilhos, mas o que é bom mesmo é poder usar essa biblioteca incrível chamada Beautiful Soup, que é uma das mais populares para fazer web scraping. Junto com ela, ireamos usar a função get() da biblioteca resquests, que basicamente acessa a página e retorna o arquivo HTML solicitado em forma de texto. No bloco de código abaixo, nós iremos:

  • Importar as bibliotecas;
  • Criar a ‘sopa’ HTML utilizando get() e criando o objeto soup;
  • Utilizar a função findAll() com a tag ‘div’ e o atributo class_= ‘fabresult rounded clearfix hwta-property’ para criar cada um dos contêineres com informações dos hostels.
  • Checar quantos contêineres teremos no final. Se você contar manualmente, verá que existem 30 hostels listados nessa primeira página, então a expectativa é obter 30 contêineres no final.
Código para criar a ‘sopa’ e verificar quantos contêineres o código retorna.

Para nossa grande satisfação, se você rodar o código, a resposta será 30, ou seja, temos informações a respeito de 30 hostels para explorar.

Separar um hostel para descobrir os atributos de acesso necessários

Todos os contêineres contém a mesma estrutura, e o que muda, logicamente, é a informação armazenada dentro de cada um. Para facilitar a análise, iremos criar um objeto apenas com a informação do primeiro hostel, e depois iremos explorar esse container para descobrir onde estão os dados que desejamos. No exemplo abaixo, temos o código para extrair o nome do hostel.

Repare que eu acessei o primeiro header ‘h2’, depois selecionei a tag ‘a’, e então extraí apenas o texto. Como eu descobri isso? Explorando a estrutura HTML do contêiner. Para acessar essa informação, basta utilizar a linha de código abaixo:

print(first_hostel.prettify())

Dessa forma você terá acesso à toda a estrutura do contêiner, e então é só usar suas habilidades de detetive para fuçar e descobrir onde está a informação desejada. É um jogo de tentativa e erro, e a documentação do Beautiful Soup é excelente para te mostrar os comandos necessários em cada caso. No exemplo que eu dei, relativo ao nome do hostel, encontrei ele aqui:

Localizando o nome do hostel.

Usando essa mesma tática de tentar, errar, tentar de novo, usando muito o stackoverflow para os casos mais complexos, consegui definir o código necessário para retirar cada uma das informações que eu precisava. Daí foi só ver quantas páginas com opções de hostel haviam disponíveis, nesse caso eram 3, e então criar dois for loops, um para entrar em cada página e separar cada hostel em um contêiner, e outro para retirar de cada contêiner os dados, para então armazenar o resultado em listas. O código para isso ficou assim:

Código para iterar nas páginas e extrair as informações desejadas.

Sobre o código, algumas observações que eu queria deixar são:

  • É importante ver como o link muda de acordo com a página desejada. No hostel world, ele segue o fluxo padrão de utilizar ‘?page=’ + o número da página;
  • Na minha opinião, os primeiros comandos de Beautiful Soup que você deve enteder a fundo são esses que usei no código: findAll(), find() e get(). É com eles que você vai conseguir extrair quase tudo em um projeto de raspagem de dados;
  • Note que eu utilizei no loop velhos conhecidos de quem usa pandas: strip() e replace(). Fiz isso para conseguir retirar letras e espaços indesejados. Você pode e deve combinar várias técnicas de pré processamento, para deixar só o filé dos dados que você deseja.

Hora de juntar tudo e criar sua tabela!

Se você nunca criou um data frame, para juntar esse monte de listas em uma tabela show de bola, uma das técnicas possíveis é usar o pd.DataFrame() e dentro criar um dicionário, como key você coloca o nome que você quer dar à coluna, e como value, basta colocar a sua lista:

Criando uma tabela a partir de múltiplas listas.

E como ficou nosso bebê? Vamos dar uma olhada nas primeiras linhas?

Primeiras cinco linhas da tabela com os hostels disponíveis em Berlim.

Bacana, não é? Ela está quase perfeita para o que eu preciso. Note que na coluna distance_centre_km, na linha 4 aparecem as letras ‘fr’, onde deveria apenas ter o número um. Bom, corrigir isso é simples, por isso eu vou incluir nesse tutorial um REGEX BONUS EXCLUSIVO PARA VOCÊ QUE CHEGOU ATÉ AQUI!

Eliminando o mal com o poder de REGEX!

Se para você regex soa grego, a palavra vem de Regular Expressions, e é uma ferramenta extremamente poderosa para filtrar texto a partir de padrões pré definidos e altamente customizáveis. Porém, eu não vou mentir, aprender a escrever expressões em regex não é uma tarefa fácil, que exige muita paciência e persistência. Nessa compreensão de lista criada no código, eu estou:

  • Usando a função sub(), ou substituir, da biblioteca de operações em regex re;
  • Criando uma compreensão de lista que retorna todas as linhas da coluna distance_centre_km;
  • A cada linha retornada, aplicando a expressão regular ‘[^ 0-9.]’, que exclui tudo o que não seja número ou um ponto.

Pronto, com apenas essa linha de código eu resolvi meu problema e fiquei apenas com os números que eu queria!

Conclusão

Sei que esses tutoriais com programação podem ser cansativos e complicados de entender, afinal o que é claro para mim nem sempre é claro para você, porém eu tentei fazer um passo a passo o mais detalhado possível de um processo de web scraping para iniciantes, e a minha ideia é que agora você pode quebrar sua cabeça em seus próprios projetos de raspagem de dados.

Minha dica final é para você persistir, pois de vez em quando vai demorar até um ou dois dias para você encontrar uma solução, como aconteceu comigo inclusive ao escrever esse tutorial, por isso a importância de ter em mente seus objetivos e, de preferência, curtir o assunto que se está pesquisando.

E é isso por hoje. Gostaria muito de ver seu feedback nos comentários. Você já fez projetos de web scraping? Tem uma abordagem diferente da que eu mostrei? Algo na minha explicação não ficou claro? Bora trocar conhecimento e aprender mais juntos!

Para quem quiser me seguir aí nas redes, pode me adicionar no LinkedIn e no Twitter.

--

--

Lucas Morato
Data Hackers

Senior Data Analyst @ JET, transforming data into reports that drive business decisions.