Parsen Festformat-Daten in HTML eingebettet in Python
-
03-07-2019 - |
Frage
Ich bin mit Googles appengine api
from google.appengine.api import urlfetch
eine Webseite zu holen. Das Ergebnis
result = urlfetch.fetch("http://www.example.com/index.html")
ist ein String des HTML-Inhalts (in result.content). Das Problem ist, die Daten, die ich analysieren möchte in HTML-Formular nicht wirklich ist, so dass ich glaube nicht, ein Python-HTML-Parser verwendet, wird für mich arbeiten. Ich brauche alle Klartext im Körper des HTML-Dokuments zu analysieren. Das einzige Problem ist, dass urlfetch eine einzelne Zeichenfolge des gesamten HTML-Dokument zurückgibt, alle Zeilenumbrüche und zusätzliche Leerzeichen zu entfernen.
EDIT: Okay, Ich habe versucht, eine andere URL zu holen und anscheinend nicht urlfetch nicht die Zeilenumbrüche abzustreifen, war es die Original-Webseite Ich habe versucht, das zu analysieren, diente die HTML-Datei auf diese Weise ... END EDIT
Wenn das Dokument ist so etwas wie folgt aus:
<html><head></head><body>
AAA 123 888 2008-10-30 ABC
BBB 987 332 2009-01-02 JSE
...
A4A 288 AAA
</body></html>
result.content wird dies nach urlfetch es holt:
'<html><head></head><body>AAA 123 888 2008-10-30 ABCBBB 987 2009-01-02 JSE...A4A 288 AAA</body></html>'
einen HTML-Parser wird mir nicht zwischen den Body-Tags mit den Daten helfen, so wollte ich regelmäßig expresions verwenden, um meine Daten zu analysieren, aber wie Sie den letzten Teil einer Zeile sehen können mit dem ersten Teil kombiniert wird von die nächste Zeile, und ich weiß nicht, wie es zu spalten. Ich habe versucht,
result.content.split('\n')
und
result.content.split('\r')
aber die resultierende Liste war alles nur ein Element. Ich sehe keine Optionen in Googles urlfetch Funktion nicht Zeilenumbrüche zu entfernen.
Irgendwelche Ideen, wie ich diese Daten analysieren kann? Vielleicht muss ich es anders holen?
Vielen Dank im Voraus!
Lösung
Ich verstehe, dass das Format des Dokuments ist, die Sie gebucht haben. In diesem Fall stimme ich zu, dass ein Parser wie Schöne Suppe keine gute Lösung sein kann.
Ich gehe davon aus, dass Sie bereits die interessanten Daten zu erhalten (zwischen den BODY-Tags) mit einem regulären Ausdruck wie
import re
data = re.findall('<body>([^\<]*)</body>', result)[0]
dann, sollte es so einfach wie:
start = 0
end = 5
while (end<len(data)):
print data[start:end]
start = end+1
end = end+5
print data[start:]
. (Anmerkung: Ich habe nicht überprüfe diesen Code gegen Grenzfälle, und ich erwarte, dass es zum Scheitern verurteilt Es wird hier nur die allgemeine Idee zeigen)
Andere Tipps
Nur Vorschlag, den ich denken kann, ist es zu analysieren, als ob es Breite Spalten festgelegt hat. Zeilenumbrüche werden nicht in Betracht für HTML gemacht.
Wenn Sie die Kontrolle der Quelldaten haben, legen Sie sie in eine Textdatei und nicht als HTML.
Wenn Sie den Nachrichtentext als eine einzige, lange Zeichenfolge haben, können Sie es brechen wie folgt. Dies setzt voraus, dass jeder Datensatz 26 Zeichen ist.
body= "AAA 123 888 2008-10-30 ABCBBB 987 2009-01-02 JSE...A4A 288 AAA"
for i in range(0,len(body),26):
line= body[i:i+26]
# parse the line
EDIT: Leseverstehen ist eine wünschenswerte Sache. Ich vermisste die wenig über die Linien werden ohne Trennzeichen zwischen ihnen laufen zusammen, die irgendwie der ganze Sinn sein würde, wäre es nicht? Also, nevermind meine Antwort, es ist nicht wirklich relevant.
Wenn Sie wissen, dass jede Zeile 5 durch Leerzeichen getrennte Spalten, dann (wenn Sie die HTML-gezupft haben) können Sie etwas tun könnte, wie (nicht getestet):
def generate_lines(datastring):
while datastring:
splitresult = datastring.split(' ', 5)
if len(splitresult) >= 5:
datastring = splitresult[5]
else:
datastring = None
yield splitresult[:5]
for line in generate_lines(data):
process_data_line(line)
Natürlich können Sie das Split-Zeichen und die Anzahl der Spalten nach Bedarf ändern (möglicherweise sogar in die Generatorfunktion als zusätzliche Parameter übergeben) und Fehler hinzufügen, um sachgemäße Handhabung.
Weitere Vorschläge zur Aufspaltung des String s
in 26-Zeichenblöcke:
Als Liste:
>>> [s[x:x+26] for x in range(0, len(s), 26)]
['AAA 123 888 2008-10-30 ABC',
'BBB 987 2009-01-02 JSE',
'A4A 288 AAA']
Als Generator:
>>> for line in (s[x:x+26] for x in range(0, len(s), 26)): print line
AAA 123 888 2008-10-30 ABC
BBB 987 2009-01-02 JSE
A4A 288 AAA
Ersetzen range()
mit xrange()
in Python 2.x wenn s
sehr lang ist.