Inhalte zwischen zwei Wörtern mit Regex, BeautifulSoup, LXML ... usw. finden
-
12-09-2019 - |
Frage
Wie finde ich den Inhalt zwischen zwei oder zwei Sätzen zufälliger Zeichen heraus?
Es ist nicht garantiert, dass die abgekratzte Seite nur HTML ist und die wichtigen Daten in einem JavaScript -Block enthalten sind. Ich kann das JavaScript nicht entfernen.
bedenken Sie:
<html>
<body>
<div>StartYYYY "Extract HTML", ENDYYYY
</body>
Some Java Scripts code STARTXXXX "Extract JS Code" ENDXXXX.
</html>
Wie Sie sehen, ist das HTML -Markup möglicherweise nicht vollständig. Ich kann die Seite abrufen und ohne mir Sorgen um irgendetwas zu machen, möchte ich den Inhalt "Extrahieren Sie den Namen extrahieren" und "Die Daten hier in einem JavaScript extrahieren" finden.
Was ich suche, ist in Python:
So was:
data = FindBetweenText(UniqueTextBeforeContent, UniqueTextAfterContent, page)
Wobei die Seite heruntergeladen wird und Daten den Text haben, den ich suche. Ich halte mich lieber von Regex fern, da einige der Fälle für Regex zu komplex sein können.
Lösung
Hier ist mein Versuch, das wird getestet. Obwohl es rekursiv ist, sollte es keine unnötige String -Duplikation geben, obwohl ein Generator möglicherweise optimaler ist
def bracketed_find(s, start, end, startat=0):
startloc=s.find(start, startat)
if startloc==-1:
return []
endloc=s.find(end, startloc+len(start))
if endloc == -1:
return [s[startloc+len(start):]]
return [s[startloc+len(start):endloc]] + bracketed_find(s, start, end, endloc+len(end))
Und hier ist eine Generatorversion
def bracketed_find(s, start, end, startat=0):
startloc=s.find(start, startat)
if startloc==-1:
return
endloc=s.find(end, startloc+len(start))
if endloc == -1:
yield s[startloc+len(start):]
return
else:
yield s[startloc+len(start):endloc]
for found in bracketed_find(s, start, end, endloc+len(end)):
yield found
Andere Tipps
Wenn Sie sicher sind, dass Ihre Marker einzigartig sind, tun Sie so etwas
s="""
<html>
<body>
<div>StartYYYY "Extract HTML", ENDYYYY
</body>
Some Java Scripts code STARTXXXX "Extract JS Code" ENDXXXX.
</html>
"""
def FindBetweenText(startMarker, endMarker, text):
startPos = text.find(startMarker)
if startPos < 0: return
endPos = text.find(endMarker)
if endPos < 0: return
return text[startPos+len(startMarker):endPos]
print FindBetweenText('STARTXXXX', 'ENDXXXX', s)
Nun, das wäre es in PHP. Kein Zweifel gibt es eine viel sexier pythonische Art.
function FindBetweenText($before, $after, $text) {
$before_pos = strpos($text, $before);
if($before_pos === false)
return null;
$after_pos = strpos($text, $after);
if($after_pos === false || $after_pos <= $before_pos)
return null;
return substr($text, $before_pos, $after_pos - $before_pos);
}
Leicht getestet
def bracketed_find_first(prefix, suffix, page, start=0):
prefixpos = page.find(prefix, start)
if prefixpos == -1: return None # NOT ""
startpos = prefixpos + len(prefix)
endpos = page.find(suffix, startpos) # DRY
if endpos == -1: return None # NOT ""
return page[startpos:endpos]
Hinweis: Das obige gibt nur das erste Ereignis zurück. Hier ist ein Generator, der jedes Ereignis ergibt.
def bracketed_finditer(prefix, suffix, page, start_at=0):
while True:
prefixpos = page.find(prefix, start_at)
if prefixpos == -1: return # StopIteration
startpos = prefixpos + len(prefix)
endpos = page.find(suffix, startpos)
if endpos == -1: return
yield page[startpos:endpos]
start_at = endpos + len(suffix)