2010-07-03 2 views
4

Je connais des utilitaires comme html2text, BeautifulSoup etc. mais le problème est qu'ils extraient également javascript et l'ajoutent au texte, rendant difficile leur séparation.Extraction de texte lisible à partir de HTML en utilisant Python?

htmlDom = BeautifulSoup(webPage) 

htmlDom.findAll(text=True) 

Alternativement,

from stripogram import html2text 
extract = html2text(webPage) 

Ces deux extraire tout le javascript sur la page ainsi, cela est indésirable.

Je voulais juste que le texte lisible que vous pourriez copier de votre navigateur soit extrait.

Répondre

5

Si vous voulez éviter d'extraire tout du contenu de script étiquettes avec BeautifulSoup,

nonscripttags = htmlDom.findAll(lambda t: t.name != 'script', recursive=False) 

fera pour vous, obtenir les enfants immédiats de la racine qui sont des balises non script (et un htmlDom.findAll(recursive=False, text=True) séparé recevront des chaînes qui sont les enfants immédiats de la racine). Vous devez le faire de manière récursive; par exemple, en tant que générateur:

def nonScript(tag): 
    return tag.name != 'script' 

def getStrings(root): 
    for s in root.childGenerator(): 
    if hasattr(s, 'name'): # then it's a tag 
     if s.name == 'script': # skip it! 
     continue 
     for x in getStrings(s): yield x 
    else:      # it's a string! 
     yield s 

J'utilise childGenerator (au lieu de findAll) pour que je peux obtenir tous les enfants pour faire mon propre filtrage.

+0

Merci! Ça fonctionne parfaitement. – demos

+0

@demos, de rien, heureux d'entendre ça! BTW, pourquoi l'accepter (et btw tx pour cela!) Sans un upvote? Semble étrange! -) –

+0

@Alex Martelli Le premier upvote est de moi. Quel dommage qu'il n'y ait eu aucun upvote sur cette réponse depuis 19 mois! – eyquem

0

En utilisant BeautifulSoup, quelque chose le long de ces lignes:

def _extract_text(t): 
    if not t: 
     return "" 
    if isinstance(t, (unicode, str)): 
     return " ".join(filter(None, t.replace("\n", " ").split(" "))) 
    if t.name.lower() == "br": return "\n" 
    if t.name.lower() == "script": return "\n" 
    return "".join(extract_text(c) for c in t) 
def extract_text(t): 
    return '\n'.join(x.strip() for x in _extract_text(t).split('\n')) 
print extract_text(htmlDom) 
1

vous pouvez supprimer les balises de script dans une belle soupe, quelque chose comme:

for script in soup("script"): 
    script.extract() 

Removing Elements

+0

On dirait une solution rapide, mais quelle est la peine pour l'extraction de l'étiquette? – demos

Questions connexes