Basicamente, quero usar o BeautifulSoup para capturar estritamente o texto visível em uma página da web. Por exemplo, esta página é meu caso de teste. E quero principalmente obter o texto do corpo (artigo) e talvez até alguns nomes de guias aqui e ali. Eu tentei a sugestão nesta pergunta SO que retorna muitas <script>
tags e comentários html que eu não quero. Não consigo descobrir os argumentos necessários para a função findAll()
para obter apenas os textos visíveis em uma página da web.
Então, como devo encontrar todo o texto visível, exceto scripts, comentários, css etc.?
python
text
beautifulsoup
html-content-extraction
user233864
fonte
fonte
soup.findAll(text=True)
nunca soube sobre esse recursoisinstance(element, Comment)
vez de corresponder a um regex.soup = BeautifulSoup(html)
elif isinstance(element,bs4.element.Comment):
. Eu também adicionei 'meta' à lista de pais.elif re.match(r"[\s\r\n]+",str(element)): return False
A resposta aprovada do @jbochi não funciona para mim. A chamada da função str () gera uma exceção porque não pode codificar os caracteres não-ascii no elemento BeautifulSoup. Aqui está uma maneira mais sucinta de filtrar a página da Web de exemplo para o texto visível.
fonte
str(element)
falhar com problemas de codificação, você deve tentarunicode(element)
em vez se você estiver usando o Python 2.fonte
Eu respeito completamente o uso da Beautiful Soup para obter conteúdo renderizado, mas pode não ser o pacote ideal para adquirir o conteúdo renderizado em uma página.
Eu tive um problema semelhante para obter conteúdo renderizado ou o conteúdo visível em um navegador típico. Em particular, tive muitos casos talvez atípicos para trabalhar com um exemplo tão simples abaixo. Nesse caso, a marca não exibível está aninhada em uma marca de estilo e não é visível em muitos navegadores que verifiquei. Existem outras variações, como definir uma exibição de configuração de tag de classe como nenhuma. Em seguida, use esta classe para a div.
Uma solução postada acima é:
Essa solução certamente possui aplicativos em muitos casos e funciona muito bem em geral, mas no html postado acima, ele mantém o texto que não é renderizado. Depois de pesquisar no SO, algumas soluções surgiram aqui BeautifulSoup get_text não remove todas as tags e JavaScript e aqui Renderizou HTML em texto sem formatação usando Python
Tentei as duas soluções: html2text e nltk.clean_html e fiquei surpreso com os resultados do tempo, por achar que eles mereciam uma resposta para a posteridade. Obviamente, as velocidades dependem muito do conteúdo dos dados ...
Uma resposta aqui do @Helge foi sobre o uso do nltk de todas as coisas.
Funcionou muito bem para retornar uma string com html renderizado. Esse módulo nltk foi mais rápido que o html2text, embora talvez o html2text seja mais robusto.
fonte
Se você se preocupa com o desempenho, aqui está outra maneira mais eficiente:
soup.strings
é um iterador e retornaNavigableString
para que você possa verificar diretamente o nome da tag pai, sem passar por vários loops.fonte
O título está dentro de uma
<nyt_headline>
tag, que está aninhada dentro de uma<h1>
tag e uma<div>
tag com o ID "article".Deveria trabalhar.
O corpo do artigo está dentro de uma
<nyt_text>
tag, que é aninhada dentro de uma<div>
tag com o ID "articleBody". Dentro do<nyt_text>
elemento, o próprio texto está contido nas<p>
tags. As imagens não estão nessas<p>
tags. É difícil para mim experimentar a sintaxe, mas espero que um rascunho de trabalho se pareça com isso.fonte
Embora eu sugira completamente o uso de beautiful-soup em geral, se alguém estiver olhando para exibir as partes visíveis de um html malformado (por exemplo, onde você tem apenas um segmento ou linha de uma página da web) por qualquer motivo, o seguinte removerá o conteúdo entre
<
e>
tags:fonte
Usando BeautifulSoup da maneira mais fácil, com menos código, para obter apenas as strings, sem linhas vazias e porcaria.
fonte
A maneira mais simples de lidar com esse caso é usando
getattr()
. Você pode adaptar este exemplo às suas necessidades:Isso localizará o elemento de texto
"3.7"
, no objeto de tag<span class="ratingsContent">3.7</span>
quando ele existir, no entanto, será o padrão quando não existirNoneType
.fonte
fonte