2009-10-23 6 views
5

Sto cercando di estrarre testo da pagine html arbitrarie. Alcune pagine (di cui non ho alcun controllo) hanno html o script malformati che rendono questo difficile. Inoltre sono su un ambiente di hosting condiviso, quindi posso installare qualsiasi lib python, ma non posso installare solo quello che voglio sul server.Strategia di Python per l'estrazione di testo da pagine html malformate

pyparsing e html2text.py inoltre non sembrano funzionare per pagine html non formattate.

Esempio URL è http://apnews.myway.com/article/20091015/D9BB7CGG1.html

mio attuale implementazione è di circa il seguente:

# Try using BeautifulSoup 3.0.7a 
soup = BeautifulSoup.BeautifulSoup(s) 
comments = soup.findAll(text=lambda text:isinstance(text,Comment)) 
[comment.extract() for comment in comments] 
c=soup.findAll('script') 
for i in c: 
    i.extract()  
body = bsoup.body(text=True) 
text = ''.join(body) 
# if BeautifulSoup can't handle it, 
# alter html by trying to find 1st instance of "<body" and replace everything prior to that, with "<html><head></head>" 
# try beautifulsoup again with new html 

se BeautifulSoup ancora non funziona, allora mi ricorrere all'utilizzo di un'euristica di guardare il 1 ° car, ultimo char (per vedere se assomiglia ad una linea di codice # < e prendere un campione della linea e poi controllare se i token sono parole o numeri in inglese.Se a pochi dei token sono parole o numeri, allora suppongo che il la linea è codice

Potrei usare l'apprendimento automatico per ispezionare ogni linea, ma mi sembra un po 'costoso e probabilmente dovrei addestrarlo (dato che non ne so molto sulle macchine di apprendimento senza supervisione), e ovviamente lo scrivo anche io.

Qualsiasi consiglio, strumento, strategia sarebbe il benvenuto. Inoltre, mi rendo conto che l'ultima parte di questo è piuttosto caotica poiché se ottengo una riga che è determinata a contenere il codice, attualmente butto via l'intera riga, anche se c'è una piccola quantità di testo inglese nella riga.

+0

Bene, la soluzione non ha resistito, la cronaca di notizie a cui si collegava era di grande lettura. Alcune persone, eh? :) –

+1

@Lesse, immagino ci siano anche persone malformate. – Johnny4000

risposta

5

cercare di non ridere, ma:

class TextFormatter: 
    def __init__(self,lynx='/usr/bin/lynx'): 
     self.lynx = lynx 

    def html2text(self, unicode_html_source): 
     "Expects unicode; returns unicode" 
     return Popen([self.lynx, 
         '-assume-charset=UTF-8', 
         '-display-charset=UTF-8', 
         '-dump', 
         '-stdin'], 
         stdin=PIPE, 
         stdout=PIPE).communicate(input=unicode_html_source.encode('utf-8'))[0].decode('utf-8') 

spero che hai lynx!

+0

Non ho lynx = (e non lo installeranno. Hanno installato ELinks che mi hanno detto che si suppone siano simili Guardando la documentazione di ELinks per vedere se funzionerà Bene a sapere di lynx none the meno – Johnny4000

+0

Elinks e Lynx kick butt Grazie per avermi fatto sapere di loro – Johnny4000

+0

E 'nato dalla disperazione dalla mia parte, posso dirti, sono contento che ti sia utile! –

0

Bene, dipende da quanto buona deve essere la soluzione. Ho avuto un problema simile, importando centinaia di vecchie pagine html in un nuovo sito web. Ho praticamente fatto

# remove all that crap around the body and let BS fix the tags 
newhtml = "<html><body>%s</body></html>" % (
    u''.join(unicode(tag) for tag in BeautifulSoup(oldhtml).body.contents)) 
# use html2text to turn it into text 
text = html2text(newhtml) 

e ha funzionato, ma naturalmente i documenti potuto essere così male che persino BS non possono salvare più di tanto.

0

BeautifulSoup farà male con HTML malformato. Che dire di alcune regex-fu?

>>> import re 
>>> 
>>> html = """<p>This is paragraph with a bunch of lines 
... from a news story.</p>""" 
>>> 
>>> pattern = re.compile('(?<=p>).+(?=</p)', re.DOTALL) 
>>> pattern.search(html).group() 
'This is paragraph with a bunch of lines\nfrom a news story.' 

è quindi possibile il montaggio di un elenco di tag validi da cui si desidera estrarre le informazioni.

Problemi correlati