HTML dividida após N palavras em python
Pergunta
Existe alguma maneira de dividir uma longa seqüência de HTML após as palavras N? Obviamente eu poderia usar:
' '.join(foo.split(' ')[:n])
para obter os primeiros n palavras de uma cadeia de texto simples, mas que dividir poder no meio de uma tag html, e não produzirá html válido porque ele não vai fechar as tags que foram abertas.
Eu preciso fazer isso em um site Zope / Plone - se há algo como padrão nesses produtos que podem fazê-lo, isso seria ideal
.Por exemplo, digamos que eu tenho o texto:
<p>This is some text with a
<a href="http://www.example.com/" title="Example link">
bit of linked text in it
</a>.
</p>
E eu pedi-lo a dividir depois de 5 palavras, ele deve retornar:
<p>This is some text with</p>
7 palavras:
<p>This is some text with a
<a href="http://www.example.com/" title="Example link">
bit
</a>
</p>
Solução
Dê uma olhada na função truncate_html_words em django.utils.text. Mesmo se você não estiver usando Django, o código não faz exatamente o que você quer.
Outras dicas
Ouvi dizer que Beautiful Soup é muito bom em análise de HTML. Provavelmente será capaz de ajudá-lo a obter HTML correto para fora.
Eu ia mencionar a base HTMLParser que é construído em Python, desde que eu não tenho certeza do que o resultado final a sua tentativa de chegar ao é, ele pode ou não chegar lá, você vai trabalhar com os manipuladores principalmente
Você pode usar uma mistura de regex, BeautifulSoup ou Tidy (eu prefiro BeautifulSoup). A idéia é simples - tira todas as tags HTML primeiro. Encontre a palavra n (n = 7 aqui), encontrar o número de vezes que a palavra 'enésimo' aparece na seqüência de até n palavras -. Coz u estão olhando apenas para a última ocorrência a ser utilizado para truncagem
Aqui está um pedaço de código, embora um pouco confuso, mas funciona
import re
from BeautifulSoup import BeautifulSoup
import tidy
def remove_html_tags(data):
p = re.compile(r'<.*?>')
return p.sub('', data)
input_string='<p>This is some text with a <a href="http://www.example.com/" '\
'title="Example link">bit of linked text in it</a></p>'
s=remove_html_tags(input_string).split(' ')[:7]
###required to ensure that only the last occurrence of the nth word is
# taken into account for truncating.
# coz if the nth word could be 'a'/'and'/'is'....etc
# which may occur multiple times within n words
temp=input_string
k=s.count(s[-1])
i=1
j=0
while i<=k:
j+=temp.find(s[-1])
temp=temp[j+len(s[-1]):]
i+=1
####
output_string=input_string[:j+len(s[-1])]
print "\nBeautifulSoup\n", BeautifulSoup(output_string)
print "\nTidy\n", tidy.parseString(output_string)
A saída é o que vc quiser
BeautifulSoup
<p>This is some text with a <a href="http://www.example.com/" title="Example link">bit</a></p>
Tidy
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux/x86 (vers 6 November 2007), see www.w3.org">
<title></title>
</head>
<body>
<p>This is some text with a <a href="http://www.example.com/"
title="Example link">bit</a></p>
</body>
</html>
Espero que isso ajude
Editar: A melhor regex
`p = re.compile(r'<[^<]*?>')`