from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
Ao imprimir uma linha em um arquivo HTML, estou tentando encontrar uma maneira de mostrar apenas o conteúdo de cada elemento HTML e não a formatação em si. Se encontrar '<a href="whatever.com">some text</a>'
, ele imprimirá apenas 'algum texto', '<b>hello</b>'
imprimirá 'olá', etc. Como alguém faria isso?
&
). Você pode 1) removê-los junto com as tags (geralmente indesejáveis e desnecessárias, pois são equivalentes ao texto sem formatação), 2) deixá-los inalterados (uma solução adequada se o texto retirado estiver voltando ao contexto HTML) ou 3 ) decodifique-os para texto sem formatação (se o texto removido estiver entrando em um banco de dados ou em outro contexto não HTML, ou se sua estrutura da Web executar automaticamente a saída de texto HTML para você).Respostas:
Eu sempre usei essa função para remover tags HTML, pois requer apenas o stdlib do Python:
Para Python 3:
Para Python 2:
fonte
&
), além de tags.__init__
função da classe pai . Veja aqui: stackoverflow.com/questions/11061058/… .parser = HTMLParser()
ehtml = parser.unescape(html)
no início da função strip_tags.Não pensei muito nos casos que ele perderá, mas você pode fazer uma simples expressão regular:
Para aqueles que não entendem regex, isso procura por uma string
<...>
, onde o conteúdo interno é composto de um ou mais+
caracteres ( ) que não são a<
. O?
meio que corresponderá à menor string que encontrar. Por exemplo<p>Hello</p>
, ele corresponderá<'p>
e</p>
separadamente com o?
. Sem ele, ele corresponderá a toda a cadeia<..Hello..>
.Se não-tag
<
aparecer em html (por exemplo2 < 3
), deve ser escrito como uma sequência de escape de&...
qualquer maneira, para que^<
possa ser desnecessário.fonte
&
) inalteradas na saída.cgi.escape(s, True)
), mesmo que "saiba" que ela não contém HTML (por exemplo, porque você retirou o conteúdo HTML) . No entanto, não foi sobre isso que o OP perguntou.Você pode usar o
get_text()
recurso BeautifulSoup .É aconselhável especificar explicitamente o analisador , por exemplo
BeautifulSoup(html_str, features="html.parser")
, para que a saída seja reproduzível.fonte
Versão curta!
Fonte Regex: MarkupSafe . A versão deles também lida com entidades HTML, enquanto essa rápida não.
Por que não posso simplesmente retirar as tags e deixá-las?
Uma coisa é manter as pessoas longe das
<i>italicizing</i>
coisas, sem deixari
s flutuando. Mas é outra forma de receber informações arbitrárias e torná-las completamente inofensivas. A maioria das técnicas desta página deixará intactos comentários não fechados (<!--
) e colchetes angulares que não fazem parte das tags (blah <<<><blah
). A versão HTMLParser pode até deixar tags completas, se elas estiverem em um comentário não fechado.E se o seu modelo for
{{ firstname }} {{ lastname }}
?firstname = '<a'
elastname = 'href="http://evil.com/">'
será liberado por todos os removedores de tags desta página (exceto @ Medeiros!), porque eles não são tags completos por si próprios. Retirar tags HTML normais não é suficiente.O Django
strip_tags
, uma versão melhorada (veja o próximo cabeçalho) da resposta principal a esta pergunta, dá o seguinte aviso:Siga os conselhos deles!
Para remover tags com o HTMLParser, você deve executá-lo várias vezes.
É fácil contornar a resposta principal para esta pergunta.
Veja esta string ( fonte e discussão ):
A primeira vez que o HTMLParser o vê, não é possível dizer que
<img...>
é uma tag. Parece quebrado, então o HTMLParser não se livra dele. Só tira o<!-- comments -->
, deixando você comEsse problema foi divulgado ao projeto Django em março de 2014. O antigo
strip_tags
era basicamente o mesmo que a principal resposta a essa pergunta. A nova versão deles basicamente roda em um loop até que a execução novamente não mude a string:Obviamente, nada disso é um problema se você sempre escapar do resultado
strip_tags()
.Atualização 19 de março de 2015 : Houve um bug nas versões do Django anteriores à 1.4.20, 1.6.11, 1.7.7 e 1.8c1. Essas versões podem inserir um loop infinito na função strip_tags (). A versão fixa é reproduzida acima. Mais detalhes aqui .
Coisas boas para copiar ou usar
Meu código de exemplo não lida com entidades HTML - as versões empacotadas do Django e MarkupSafe.
Meu código de exemplo é extraído da excelente biblioteca MarkupSafe para prevenção de scripts entre sites. É conveniente e rápido (com acelerações em C para sua versão nativa do Python). Ele está incluído no Google App Engine e é usado por Jinja2 (2.7 e superior) , Mako, Pylons e muito mais. Ele funciona facilmente com modelos do Django do Django 1.7.
O strip_tags do Django e outros utilitários html de uma versão recente são bons, mas eu os acho menos convenientes que o MarkupSafe. Eles são bem independentes, você pode copiar o que precisa desse arquivo .
Se você precisar remover quase todas as tags, a biblioteca Bleach é boa. Você pode fazer cumprir regras como "meus usuários podem colocar itálico nas coisas, mas eles não podem criar iframes".
Entenda as propriedades do seu removedor de etiquetas! Execute testes de fuzz nele! Aqui está o código que eu usei para fazer a pesquisa para esta resposta.
observação tímida - A pergunta em si é sobre a impressão no console, mas este é o principal resultado do Google para "python strip html from string"; é por isso que essa resposta é 99% sobre a web.
fonte
Eu precisava de uma maneira de remover tags e decodificar entidades HTML em texto sem formatação. A solução a seguir é baseada na resposta de Eloff (que eu não poderia usar porque retira entidades).
Um teste rápido:
Resultado:
Manipulação de erros:
&#apos;
válidas em XML e XHTML, mas não em HTML simples) causarão umaValueError
exceção.ValueError
exceção.Nota de segurança: Não confunda a remoção de HTML (convertendo HTML em texto sem formatação) com higienização HTML (convertendo texto sem formatação em HTML). Esta resposta removerá o HTML e decodificará as entidades em texto sem formatação - o que não torna o resultado seguro para uso em um contexto HTML.
Exemplo:
<script>alert("Hello");</script>
será convertido para<script>alert("Hello");</script>
, que é um comportamento 100% correto, mas obviamente não será suficiente se o texto simples resultante for inserido como está em uma página HTML.A regra não é difícil: sempre que você inserir uma sequência de texto sem formatação na saída HTML, você deve sempre escapá-la (usando
cgi.escape(s, True)
), mesmo que "saiba" que ela não contém HTML (por exemplo, porque você retirou o conteúdo HTML) .(No entanto, o OP perguntou sobre a impressão do resultado no console, caso em que nenhum escape de HTML é necessário.)
Versão do Python 3.4+: (com doctest!)
Observe que o HTMLParser foi aprimorado no Python 3 (o que significa menos código e melhor tratamento de erros).
fonte
Existe uma maneira simples de fazer isso:
A ideia é explicada aqui: http://youtu.be/2tu9LTDujbw
Você pode vê-lo funcionando aqui: http://youtu.be/HPkNPcYed9M?t=35s
PS - Se você estiver interessado na classe (sobre depuração inteligente com python), eu lhe dou um link: http://www.udacity.com/overview/Course/cs259/CourseRev/1 . É grátis!
De nada! :)
fonte
<b class="o'>x</b>
como saída a função de entradax
. Mas, na verdade, essa entrada é inválida. Eu acho que é por isso que as pessoas preferem libs.Se você precisar preservar entidades HTML (ou seja
&
), adicionei o método "handle_entityref" à resposta de Eloff .fonte
Se você deseja remover todas as tags HTML, a maneira mais fácil que encontrei é usar o BeautifulSoup:
Tentei o código da resposta aceita, mas estava recebendo "RuntimeError: profundidade máxima de recursão excedida", o que não aconteceu com o bloco de código acima.
fonte
''.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
. Aqui a saída é "helloworld", enquanto você provavelmente deseja que seja "hello world".' '.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
não ajuda, pois se torna "ele mundo".Aqui está uma solução simples que retira tags HTML e decodifica entidades HTML com base na
lxml
biblioteca incrivelmente rápida :fonte
text_content()
retornalxml.etree._ElementUnicodeResult
para que você precise convertê-lo em string primeirostr
para operações como string+
e indexação[]
. De qualquer forma, foi adicionado um elenco para uma boa medida.Uma solução baseada em lxml.html (lxml é uma biblioteca nativa e, portanto, muito mais rápida que qualquer solução python pura).
Se você precisar de mais controle sobre o que exatamente é higienizado antes de converter em texto, convém usar o Cleaner lxml explicitamente passando as opções desejadas no construtor, por exemplo:
fonte
O pacote Beautiful Soup faz isso imediatamente para você.
fonte
Aqui está a minha solução para python 3.
Não tenho certeza se é perfeito, mas resolvi meu caso de uso e parece simples.
fonte
Você pode usar um analisador HTML diferente ( como lxml ou Beautiful Soup ) - que oferece funções para extrair apenas texto. Ou, você pode executar uma regex na sua string de linha que retira as tags. Veja a documentação do Python para mais.
fonte
lxml.html.fromstring(s).text_content()
&
) em texto.Eu usei a resposta de Eloff com sucesso para o Python 3.1 [muito obrigado!].
Atualizei para o Python 3.2.3 e encontrei erros.
A solução, fornecida aqui graças ao respondedor Thomas K, é inserir
super().__init__()
o seguinte código:... para que fique assim:
... e funcionará para o Python 3.2.3.
Mais uma vez, obrigado a Thomas K pela correção e pelo código original de Eloff fornecido acima!
fonte
Você pode escrever sua própria função:
fonte
As soluções com o analisador de HTML são todas quebráveis, se executadas apenas uma vez:
resulta em:
o que você pretende impedir. se você usar um analisador de HTML, conte as tags até que zero seja substituído:
fonte
html_to_text
e incorporar o texto que está sendo produzido nessa função dentro de html sem escapar desse texto, é a falta de escape, que é uma vulnerabilidade de segurança, não ahtml_to_text
função. Ahtml_to_text
função nunca prometeu que a saída seria texto. E inserir texto no html sem escapar é uma vulnerabilidade de segurança em potencial, independentemente de você ter obtido o textohtml_to_text
ou alguma outra fonte.Essa é uma solução rápida e pode ser ainda mais otimizada, mas funcionará bem. Esse código substituirá todas as tags não vazias por "" e remove todas as tags html de um determinado texto de entrada. Você pode executá-lo usando a saída de entrada ./file.py
fonte
Uma adaptação python 3 da resposta de søren-løvborg
fonte
Para um projeto, eu precisava remover o HTML, mas também css e js. Assim, fiz uma variação da resposta de Eloffs:
fonte
Aqui está uma solução semelhante à resposta atualmente aceita ( https://stackoverflow.com/a/925630/95989 ), exceto que ela usa a
HTMLParser
classe interna diretamente (ou seja, sem subclassificação), tornando-a significativamente mais concisa:fonte
Estou analisando os readmes do Github e acho que o seguinte realmente funciona bem:
E depois
Remove todas as remarcações e html corretamente.
fonte
Usando BeautifulSoup, html2text ou o código de @Eloff, na maioria das vezes, permanecem alguns elementos html, código javascript ...
Portanto, você pode usar uma combinação dessas bibliotecas e excluir a formatação de markdown (Python 3):
Funciona bem para mim, mas pode ser aprimorado, é claro ...
fonte
Código simples! Isso removerá todos os tipos de tags e conteúdo dentro dele.
Mas não dará o resultado completo se o texto contiver símbolos <> .
fonte
fonte
Este método funciona perfeitamente para mim e não requer instalações adicionais:
fonte