Bela Sopa - Solução de Problemas

Manipulação de erros

Existem dois tipos principais de erros que precisam ser tratados no BeautifulSoup. Esses dois erros não são do seu script, mas da estrutura do snippet porque a API BeautifulSoup gera um erro.

Os dois erros principais são os seguintes -

AttributeError

É causado quando a notação de ponto não encontra uma marca irmã para a marca HTML atual. Por exemplo, você pode ter encontrado este erro, devido à falta da “etiqueta âncora”, a chave de custo lançará um erro ao passar e requer uma etiqueta âncora.

KeyError

Este erro ocorre se o atributo de tag HTML necessário estiver ausente. Por exemplo, se não tivermos o atributo data-pid em um snippet, a chave pid lançará o erro de chave.

Para evitar os dois erros listados acima ao analisar um resultado, esse resultado será ignorado para garantir que um snippet malformado não seja inserido nos bancos de dados -

except(AttributeError, KeyError) as er:
pass

diagnosticar()

Sempre que encontrarmos alguma dificuldade em entender o que o BeautifulSoup faz em nosso documento ou HTML, basta passá-lo para a função diagnose (). Ao passar o arquivo de documento para a função diagnose (), podemos mostrar como uma lista de diferentes analisadores lida com o documento.

Abaixo está um exemplo para demonstrar o uso da função diagnose () -

from bs4.diagnose import diagnose

with open("20 Books.html",encoding="utf8") as fp:
   data = fp.read()
   
diagnose(data)

Resultado

Erro de análise

Existem dois tipos principais de erros de análise. Você pode obter uma exceção como HTMLParseError, ao alimentar seu documento no BeautifulSoup. Você também pode obter um resultado inesperado, em que a árvore de análise BeautifulSoup parece muito diferente do resultado esperado do documento de análise.

Nenhum dos erros de análise é causado por BeautifulSoup. É por causa do analisador externo que usamos (html5lib, lxml), pois BeautifulSoup não contém nenhum código de analisador. Uma maneira de resolver o erro de análise acima é usar outro analisador.

from HTMLParser import HTMLParser

try:
   from HTMLParser import HTMLParseError
except ImportError, e:
   # From python 3.5, HTMLParseError is removed. Since it can never be
   # thrown in 3.5, we can just define our own class as a placeholder.
   class HTMLParseError(Exception):
      pass

O analisador HTML embutido no Python causa dois erros de análise mais comuns, HTMLParser.HTMLParserError: tag de início malformada e HTMLParser.HTMLParserError: tag de fim ruim e, para resolver isso, é usar outro analisador principalmente: lxml ou html5lib.

Outro tipo comum de comportamento inesperado é que você não consegue encontrar uma marca que sabe que está no documento. No entanto, quando você executa find_all () retorna [] ou find () retorna None.

Isso pode ser devido ao analisador HTML integrado do Python, que às vezes pula tags que não entende.

Erro do analisador XML

Por padrão, o pacote BeautifulSoup analisa os documentos como HTML, entretanto, é muito fácil de usar e manipula XML malformado de uma maneira muito elegante usando beautifulsoup4.

Para analisar o documento como XML, você precisa ter o analisador lxml e apenas passar o “xml” como o segundo argumento para o construtor Beautifulsoup -

soup = BeautifulSoup(markup, "lxml-xml")

ou

soup = BeautifulSoup(markup, "xml")

Um erro comum de análise de XML é -

AttributeError: 'NoneType' object has no attribute 'attrib'

Isso pode acontecer caso algum elemento esteja faltando ou não esteja definido ao usar a função find () ou findall ().

Outros erros de análise

A seguir estão alguns dos outros erros de análise que discutiremos nesta seção -

Questão ambiental

Além dos erros de análise mencionados acima, você pode encontrar outros problemas de análise, como problemas ambientais onde seu script pode funcionar em um sistema operacional, mas não em outro sistema operacional ou pode funcionar em um ambiente virtual, mas não em outro ambiente virtual ou pode não funcionar fora do ambiente virtual. Todos esses problemas podem ocorrer porque os dois ambientes têm diferentes bibliotecas de analisador disponíveis.

Recomenda-se conhecer ou verificar seu analisador padrão em seu ambiente de trabalho atual. Você pode verificar o analisador padrão atual disponível para o ambiente de trabalho atual ou então passar explicitamente a biblioteca do analisador necessária como segundos argumentos para o construtor BeautifulSoup.

Não diferencia maiúsculas de minúsculas

Como as tags e atributos HTML não diferenciam maiúsculas de minúsculas, todos os três analisadores HTML convertem nomes de tags e atributos em letras minúsculas. No entanto, se você deseja preservar as tags e atributos com letras maiúsculas ou maiúsculas, é melhor analisar o documento como XML.

UnicodeEncodeError

Vamos dar uma olhada no segmento de código abaixo -

soup = BeautifulSoup(response, "html.parser")
   print (soup)

Resultado

UnicodeEncodeError: 'charmap' codec can't encode character '\u011f'

O problema acima pode ser devido a duas situações principais. Você pode estar tentando imprimir um caractere Unicode que seu console não sabe como exibir. Em segundo lugar, você está tentando gravar em um arquivo e passa um caractere Unicode que não é compatível com a codificação padrão.

Uma maneira de resolver o problema acima é codificar o texto / caractere de resposta antes de fazer a sopa para obter o resultado desejado, como segue -

responseTxt = response.text.encode('UTF-8')

KeyError: [attr]

É causado pelo acesso à tag ['attr'] quando a tag em questão não define o atributo attr. Os erros mais comuns são: “KeyError: 'href'” e “KeyError: 'class'”. Use tag.get ('attr') se não tiver certeza se attr está definido.

for item in soup.fetch('a'):
   try:
      if (item['href'].startswith('/') or "tutorialspoint" in item['href']):
      (...)
   except KeyError:
      pass # or some other fallback action

AttributeError

Você pode encontrar AttributeError da seguinte forma -

AttributeError: 'list' object has no attribute 'find_all'

O erro acima ocorre principalmente porque você esperava que find_all () retornasse uma única tag ou string. No entanto, soup.find_all retorna uma lista de elementos python.

Tudo o que você precisa fazer é iterar pela lista e coletar dados desses elementos.