Web scraping para construção de ontologia

Leticia Maria Caetano
IA Biblio BR Grupo
Published in
10 min readOct 27, 2023

--

No mundo digital em constante evolução, como podemos moldar o conhecimento de forma eficaz?

Foto de Markus Spiske na Unsplash

A resposta a esse desafio reside na construção de ontologias, uma ferramenta poderosa para organizar e estruturar informações. Como bibliotecárias, compreendemos a complexidade de projetar uma ontologia, especialmente quando se trata de coletar dados de fontes online.

Enfrentamos um dilema significativo: muitos sites e fontes de dados não adotam a marcação do Schema.org, essencial para a organização da web. Isso cria um obstáculo formidável na obtenção de informações organizadas. Inicialmente, recorremos ao web scraping, seguindo o padrão do Schema.org, mas logo descobrimos que, em muitos casos, era necessário mergulhar mais fundo, raspando dados diretamente do HTML, para alimentar nossa ontologia.

Neste artigo, documentaremos nossa jornada e aprendizados ao longo desse processo. Nosso objetivo é inspirar entusiastas a explorar as vastas possibilidades que as ontologias oferecem no mundo da informação e tecnologia, enquanto destacamos o papel fundamental que o web scraping desempenha na obtenção dos dados necessários para impulsionar projetos como o nosso.

O que é uma ontologia?

Antes de mergulharmos no processo detalhado de construção de nossa ontologia, é fundamental entender o que exatamente é uma ontologia. Em termos simples, uma ontologia é um sistema de categorização que busca representar o conhecimento de forma estruturada. Ela define conceitos, suas propriedades e as relações entre eles, criando assim um modelo de domínio específico.

No contexto da Ciência da Informação, as ontologias desempenham um papel fundamental na organização e recuperação de informações. Elas ajudam a tornar os dados mais compreensíveis e acessíveis, facilitando a busca e a análise.

Confira esses links para saber mais:

Ontologia (ciência da computação)

Ontologies (as knowledge organization systems)

Ontologia e método utilizado

Agora que compreendemos o conceito de ontologia, vamos explorar como aplicamos essa ideia na prática. Escolhemos o domínio de lanches saudáveis por ser um tema de interesse comum entre nós e para o processo de construção da ontologia, adotamos a metodologia 101, de Natalya F. Noy and Deborah L. McGuinness, seguindo as seguintes etapas:

  1. Determinação do domínio e escopo: o domínio da ontologia são “receitas de lanches saudáveis”, no sentido de “comida de verdade”, destinadas para pessoas não especializadas em nutrição ou culinária, que irão preparar as receitas em um contexto doméstico. Nesta etapa, elaboramos algumas questões de competência para conseguir delimitar melhor o que a nossa ontologia deveria responder ou não. Nesta etapa também definimos que utilizaremos o Protégé como software para a construção e gerenciamento da ontologia.
  2. Considerar a reutilização de ontologias existentes: em nossa pesquisa, não identificamos nenhuma ontologia especificamente sobre “receitas de lanches saudáveis”. Para nos ajudar na modelagem, selecionamos como referência a ontologia de receitas What To Make Ontology and Application e utilizaremos o Schema.org para definição de propriedades e tipos de dados. Nesta etapa também buscamos por sites de receitas como fonte de dados, conforme abaixo:
    a. Panelinha
    b. Receitas Nestlé
    c. Receiteria
    d. Receitas sem fronteiras
    e. Cozinha Vibrante
    f. Comidinhas do Chef
  3. Enumerar termos importantes: nesta etapa, elencamos os principais conceitos que identificamos a partir das questões de competências.
  4. Definir as classes e a hierarquia: com base na lista de termos formada na etapa anterior, identificamos as principais classes da ontologia. Neste ponto, para nos ajudar a diferenciar quais conceitos da lista se configuram como classes e quais seriam os seus atributos, buscamos as aulas do curso de Introdução a Ontologias e à Web Semântica, do Prof. Thiago Castro Ferreira, de forma complementar à metodologia 101 que estamos seguindo. As aulas estão disponíveis no Youtube (Introdução a Ontologias e à Web Semântica). Na aula 1.5, fizemos o exercício para definir as classes e as propriedades. Basicamente, identificamos na lista de termos quais eram substantivos e quais eram verbos. Os substantivos foram identificados como classes e os verbos como propriedade. A partir disso, montamos uma tabela em que construímos as “triplas”, relacionando as classes por meio das propriedades. As “triplas” são unidades básicas de informação. Elas consistem em três partes: sujeito, predicado e objeto. O sujeito representa um conceito ou entidade (domain), o predicado descreve a relação entre o sujeito e o objeto (propriedade), e o objeto é o valor ou outra entidade relacionada (range).

Segue abaixo um extrato da tabela que exemplifica como foi o exercício:

Até este ponto, nosso trabalho estava focado exclusivamente nos termos que identificamos com base nas questões de competências. Contudo, começamos a sentir a necessidade de expandir nossos horizontes, buscando identificar conceitos adicionais que enriqueceriam nossa ontologia e a tornaria mais completa.

Para alcançar esse objetivo, decidimos explorar um contexto real: receitas reais.

Nosso objetivo era criar um conjunto de dados robusto que servisse como base sólida para a modelagem da ontologia. Nas etapas iniciais do projeto, havíamos selecionado alguns sites de receitas como nossas fontes de dados potenciais. No entanto, percebemos que coletar manualmente os termos necessários desses sites seria demorado e ineficaz. Nesse momento, começamos a buscar soluções automatizadas para agilizar a coleta de dados. Foi nesse contexto que nos deparamos com a técnica do Web scraping.

Web scraping: coleta de dados e escolha da fonte

Web scraping é também conhecida como raspagem de dados. Iremos aprofundar um pouco mais sobre o conceito a seguir, mas em geral é uma técnica muito popular e muito eficiente para coletar informações em páginas na web que não estão estruturadas como dados abertos. Essa é uma distinção importante, pois diferente de alguns casos em que o problema é a organização dos dados, neste caso, o problema realmente está na obtenção deles. Ela pode ser realizada de diversas maneiras, desde soluções com interfaces gráficas ao desenvolvimento de códigos próprios, que foi o nosso caso.

Nesta etapa, percebemos que precisaríamos de ajuda, pois, apesar de haver uma imensa gama de tutoriais na internet, é preciso ter um conhecimento mínimo de HTML para conseguir identificar os elementos que serão raspados em uma página. Por sorte, na mesma época em que procurávamos entender como faríamos essa parte, nos deparamos com um texto do Francisco Foz no Medium falando justamente sobre esse processo de coleta de dados, e como o Francisco também é bibliotecário, logo percebemos que ele seria a pessoa ideal para nos ajudar. Entramos em contato e ele topou nos ajudar construindo um script do zero para nosso projeto. Além do código, ainda fez questão de explicar detalhadamente como foi o processo e é isso que demonstraremos nos próximos parágrafos. A ideia principal era começar com as receitas do site Panelinha, da Rita Lobo, ou do site Receitas Nestlé, mas Francisco nos explicou que alguns sites bloqueiam ou restringem o acesso quando identificam tentativas de raspagem.

Para verificar estas permissões de acesso, Francisco utilizou o “robots.txt” que é um arquivo de texto que os sites da web disponibilizam publicamente para instruir os robôs (ou “bots”) da web sobre quais partes do site podem ou não ser rastreadas e indexadas pelos motores de busca e outros bots automatizados, como é o caso do web scraping. Para verificar a permissão de rastreamento em um site, basta acrescentar “robots.txt” ao final da URL. O arquivo resultante indicará se o site autoriza ou não o acesso dos bots para rastrear seu conteúdo. Na Central da Pesquisa Google é possível ter mais informações sobre como funciona o “robots.txt”.

Os sites Panelinha e Receitas Nestlé não permitem a raspagem de dados, por isso optamos por seguir com o site Comidinhas do Chef.

Uma vez definido o site, foram elencados os metadados que precisariam ser coletados neste site, conforme abaixo:

  • Tempo de preparo
  • Categoria
  • Ingredientes
  • Modo de preparo
  • Rendimento
  • Nível de dificuldade

Com isso, o próximo passo foi efetivamente a escrita do código. Foram utilizadas as seguintes bibliotecas (pacotes) do Python:

  • Requests: para fazer solicitações HTTP (protocolo de comunicação utilizado para transferir dados);
  • Pandas: para manipulação de dados tabulares (tabelas);
  • Beautifulsoup: para análise HTML (uma linguagem de marcação usada para estruturar o conteúdo de uma página da web).

FUNÇÕES

import requests
import pandas as pd
from bs4 import BeautifulSoup

def requisicao(url):

response = requests.get(url)

html_text = response.text

return html_text

def scraping_receita(html_text):

try:
soup = BeautifulSoup(html_text, "html.parser")

nome = soup.find('h1').get_text()
tempo_total = soup.find('table', class_='recipe-info').find_all('td')[0].get_text().strip()
categoria = soup.find(class_='category').get_text().strip()

lista_ingredientes = []
for i in soup.find_all(class_='content-text-shadow')[1].find_all('ul'):
lista_ingredientes.extend(i.get_text().strip().splitlines())

ingredientes = lista_ingredientes

lista_modo_de_preparo = []
for i in soup.find(class_ ='accordeon-text').find_all('p'):
lista_modo_de_preparo.append(i.get_text().strip())

modo_de_preparo = lista_modo_de_preparo

rendimento = soup.find('table', class_='recipe-info').find_all('td')[1].get_text().strip()
dificuldade = soup.find('table', class_='recipe-info').find_all('td')[2].get_text().strip()

dicionario = {
'nome': nome,
'tempo_total': tempo_total,
'categoria': categoria,
'ingredientes': ingredientes,
'modo_de_preparo': modo_de_preparo,
'rendimento': rendimento,
'dificuldade': dificuldade
}

return dicionario

except:
return None #Ignorei todos os links que pudessem ter algum erro no HTML (falta de padronização do site).

#A próxima função irá iterar sob o link dessa página: https://comidinhasdochef.com/receitas/lanche/page/

def scraping_links_paginas(numero_pagina_final):
lista_links_receitas = []

for i in range(1,numero_pagina_final+1):

url_lanches = f'https://comidinhasdochef.com/receitas/lanche/page/{i}'

html_lanches = requisicao(url_lanches)

soup = BeautifulSoup(html_lanches, "html.parser")

for link in soup.find_all(class_='receita-big-image'):
lista_links_receitas.append(link.find('a').get("href"))

return lista_links_receitas

dados_gerais = scraping_receita(requisicao('https://comidinhasdochef.com/choripan-com-chimichurri/'))
def df_scraping(lista_links):


dados_gerais = {}

for i in lista_links:

html_text = requisicao(i)

dados_pagina = scraping_receita(html_text)

if dados_pagina is None:
continue

for chave, valor in dados_pagina.items():
if chave in dados_gerais:
dados_gerais[chave].append(valor)
else:
dados_gerais[chave] = [valor]


df_scraping = pd.DataFrame.from_dict(dados_gerais,orient='index').T

return df_scraping

Segue abaixo uma explicação detalhada do código:

  1. O código importa as bibliotecas Python citadas acima;
  2. A função chamada requisicao(url) recebe a URL (endereço do site Comidinhas do Chef) como entrada e retorna o conteúdo HTML deste site;
  3. Em seguida, a função chamada scraping_receita(html_text) realiza o scraping das informações de uma única página de receita. Ela recebe o conteúdo HTML dessa página como entrada e retorna um dicionário contendo os metadados que definimos, citados acima;
  4. A função scraping_links_paginas(numero_pagina_final) é responsável por obter os links para as páginas individuais de cada receita. Ela recebe o número da última página como entrada e itera sobre as páginas de 1 até o número fornecido, ou seja, repete o mesmo processo em todas as páginas de receitas do site. Em cada página, esta função extrai os links das receitas e os adiciona a uma lista de links;
  5. A variável dados_gerais é inicializada com as informações de uma única receita. No código, a função scraping_receita() é chamada com a URL https://comidinhasdochef.com/choripan-com-chimichurri/ para obter as informações dessa receita específica;
  6. A função df_scraping(lista_links) recebe como entrada a lista de links de receitas e realiza o scraping das informações de cada página de receita. Para cada link na lista, a função faz uma requisição HTTP para obter o conteúdo HTML da página da receita correspondente. Em seguida, chama a função scraping_receita() para extrair os metadados da receita correspondente e os armazena em um dicionário chamado dados_gerais. No final, o dicionário dados_gerais é convertido em um DataFrame do Pandas. O DataFrame é uma estrutura de dados tabular, que organiza os dados em colunas e linhas, ou seja, como uma tabela. Cada coluna do DataFrame representa um metadado e cada linha representa uma página de receita, com os valores de metadados para cada receita.

Em resumo, a função percorre uma lista de links de receitas de um site, extrai as informações dessas receitas e organiza tudo em um DataFrame para facilitar a análise dos dados.

SCRAPING

lista_links_receitas = scraping_links_paginas(92)

Quantidade total de receitas:

len(lista_links_receitas)

df_total = df_scraping(lista_links_receitas)

df_total

df_total

len(df_total)

df_total

df_total.to_excel('recipes.xlsx',index=False)

from google.colab import files
df_total.to_csv('recipes.csv')
files.download('recipes.csv')
  1. Uma vez que foram definidos os metadados e como será o processo de raspagem, chamamos a função scraping_links_paginas para atuar sobre a lista de links obtidos na etapa anterior, para isso é importante destacar também o argumento da função, que é 92, ou seja, a raspagem será feita em 92 páginas;
  2. Em seguida, utiliza-se a função len, para obter o número total de receitas com len(lista_links_receitas);
  3. A próxima função utilizada, que foi a df_total = df_scraping(lista_links_receitas) teve como objetivo chamar a função df_scraping passando a lista de links lista_links_receitas como argumento. O resultado dessa função é atribuído a variável df_total. Com isso, ao usar a função df_total, imprimimos o conteúdo raspado efetivamente na estrutura tabular;
  4. Por fim, usamos novamente a função len em len(df_total) para calcular o número de linhas que teremos no DataFrame df_total, imprimimos o resultado e a seguir, como estamos trabalhando no ambiente do Google Colab, importamos o módulo files e usamos a função df_total.to_csv(‘recipes.csv’) para salvar os dados em um arquivo CSV com o nome recipes.csv”;
  5. Por fim, usamos o files.download(‘recipes.csv’) para fazer o download do arquivo CSV gerado anteriormente (“recipes.csv”) para o ambiente local.

Considerações finais

Durante o processo de construção dessa ontologia, lidar com o aprendizado da técnica de web scraping foi apenas mais um de tantos outros desafios que tivemos ao trabalhar com um projeto real. Uma das muitas coisas que aprendemos foi a trabalhar melhor com fluxo de dados, ou data pipeline, como também é conhecido.
Na figura abaixo podemos entender melhor como funciona:

Figura “Data pipeline ou o fluxo de trabalho com dados”, do livro FLUXO DO TRABALHO COM DADOS: DO ZERO À PRÁTICA — Escola de Dados

O web scraping, se encaixa na terceira etapa: Obtenha. No livro citado acima, é explicado que existem três formas principais de se obter dados:

  1. Coleta por conta própria;
  2. Obtenção de dados inéditos;
  3. Obtenção de dados os encontrando.

Essa terceira forma é quando as informações que você precisa já estão disponíveis na internet, mas muitas vezes (senão todas as vezes) é preciso existir uma curadoria, pois apesar dos dados estarem disponíveis não é tão fácil assim localizá-los efetivamente.

Partindo desse princípio, tentamos obter os dados a partir de alguma base já existente na web. Alguns sites disponibilizam dados já coletados e muitas vezes até tratados, dependendo do tema.
Podemos citar alguns sites como: Base dos Dados, Google Dataset Search, Open Data on AWS, Dados Abertos do Governo, Datasets no Reddit e o clássico Kaggle.

Os dados que queríamos utilizar estavam disponíveis, mas apenas para serem visualizados e por se tratar de um domínio que não é de grande interesse para análise, não conseguimos localizar nenhuma base de dados pronta. Se optássemos por não fazer o web scraping, teríamos que realizar a tediosa tarefa de copiar e colar todas as receitas que queríamos e depois organizar os dados no formato que desejávamos.

Em resumo, a aplicação do web scraping revelou-se fundamental para o nosso projeto. Essa abordagem nos permitiu obter as informações necessárias de forma eficiente e automatizada. Para saber mais sobre esta técnica, acesse: Tutorial para iniciantes: Web Scraping em Python | by Lucas Morato | Data Hackers | Medium.

Nossa jornada no caminho da organização do conhecimento é contínua e dinâmica, e esperamos compartilhá-la com vocês. Desejamos inspirar outros a explorar as inúmeras possibilidades nesta área, considerando a aplicação de tecnologia no desenvolvimento de ontologias. Este é apenas o começo, e convidamos todos a nos acompanharem enquanto aprofundamos nosso entendimento e aprimoramos nossa ontologia.

Para continuar acompanhando nossa jornada, siga nossos perfis:

Francisco Tadeu Foz
https://franciscofoz.medium.com/
https://www.linkedin.com/in/francisco-tadeu-foz/

Leticia Maria Caetano
https://medium.com/@leticiamariacaetano
https://www.linkedin.com/in/leticiamariacaetano/

Luzane Ruscher
https://medium.com/@luzane
https://www.linkedin.com/in/luzanerus

👩‍💻 LinkedIn do IA Biblio BR: http://bit.ly/IABiblioBRLinkedIn

🎬 YouTube do IA Biblio BR: https://youtube.com/@IABiblioBRGrupo

📰 Conheça nossa publicação: https://medium.com/ia-biblio-br

--

--