Seite 1 von 1
Eine Frage zu Regex-Modul
Verfasst: Sonntag 1. Juli 2018, 16:04
von LiorR91
Hallo
könnte mir jemand bitte erklären wie ich aus diesem Code:
Code: Alles auswählen
import re
string = "<b>foo</b> text text <b>bar</b> text text <b>foo</b>"
matches = re.findall(r'<b>[a-zA-Z]+</b>', string)
alle Treffer von foo und bar in die Liste 'matches' einfügen kann?
erwünschter Output:
print(matches)
# ['<b>foo</b>', '<b>bar</b>', <b>foo</b>']
tatsächlicher Output:
print(matches)
# ['<b>foo</b>', '<b>bar</b>']
Danke

Re: Eine Frage zu Regex-Modul
Verfasst: Sonntag 1. Juli 2018, 16:12
von __blackjack__
Also bei mir kommt da was anderes heraus als Du behauptest:
Code: Alles auswählen
In [162]: re.findall(r'<b>[a-zA-Z]+</b>', string)
Out[162]: ['<b>foo</b>', '<b>bar</b>', '<b>foo</b>']
Aber Du willst auch kein HTML mit regulären Ausdrücken verarbeiten. Dafür gibt es HTML-Parser:
Code: Alles auswählen
In [169]: from lxml import html
In [170]: html.fromstring(string)
Out[170]: <Element span at 0xaa71425c>
In [171]: html.fromstring(string).xpath('b')
Out[171]: [<Element b at 0xce164dc>, <Element b at 0xd04b784>, <Element b at 0xd04b39c>]
In [172]: html.fromstring(string).xpath('b/text()')
Out[172]: ['foo', 'bar', 'foo']
Re: Eine Frage zu Regex-Modul
Verfasst: Sonntag 1. Juli 2018, 17:44
von LiorR91
hmm okay. ich werde es mal nachschauen. Danke!
Re: Eine Frage zu Regex-Modul
Verfasst: Dienstag 3. Juli 2018, 14:45
von LiorR91
Hallo, ich bin wieder da.
Also ich habe das html Modul ausprobiert, bekomme aber das gleiche Problem. HTML Code:
Code: Alles auswählen
<a href="/unwantedtext/bar">
<tbody>
<tr class='whocares'
<td class="datatable-item-first" style="max-width: 120px; overflow: hidden;">
<a href="/foo/bar">
<b>foobar</b>
</a>
</td>
....
<td class="datatable-item-first" style="max-width: 120px; overflow: hidden;">
<a href="/something/bar">
<b>foobar</b>
</a>
</td>
<td class="datatable-item-first" style="max-width: 120px; overflow: hidden;">
<a href="/foo/bar">
<b>foobar</b>
</a>
</td>
....
</tr>
</tbody>
....
....
....
<a style="" href='/foo/bar' >Unnötige Info </a><br />
und ich habe erfolgreich die relevante Infos herausgezogen mit:
Code: Alles auswählen
list = tree.xpath('.//a[contains(@href,"/bar") and not(.//@style) and not (contains(@href, "unwantedtext"))]/@href')
aber wieder bekomme ich statt:
Code: Alles auswählen
print(list)
# ['/foo/bar', '/something/bar', '/foo/bar']
das:

Re: Eine Frage zu Regex-Modul
Verfasst: Dienstag 3. Juli 2018, 15:14
von __blackjack__
Also bei dem gezeigten HTML-Fragment bekomme ich das richtige raus:
Code: Alles auswählen
In [6]: doc = html.fromstring(source)
In [7]: doc.xpath('.//a[contains(@href,"/bar") and not(.//@style) and not (conta
...: ins(@href, "unwantedtext"))]/@href')
Out[7]: ['/foo/bar', '/something/bar', '/foo/bar']
Allerdings macht das ``not(.//@style)`` keinen Sinn -- kann es also sein das bei dem tatsächlichen HTML diese Bedingung dafür sorgen, dass das letzte Element nicht enthalten ist?
Re: Eine Frage zu Regex-Modul
Verfasst: Dienstag 3. Juli 2018, 16:14
von LiorR91
__blackjack__ hat geschrieben: Dienstag 3. Juli 2018, 15:14
kann es also sein das bei dem tatsächlichen HTML diese Bedingung dafür sorgen, dass das letzte Element nicht enthalten ist?
Genau, ich möchte nur diejenige haben, die exakt dieses Pattern <a href="/*/bar"> treffen (also ohne weitere attributes). Vielleicht gibt es einen effizienteren Weg aber die richtige Treffer bekomme ich, nur mit der falschen Anzahl.
Also bei dem gezeigten HTML-Fragment bekomme ich das richtige raus
Merkwürdig. also ich bekomme den HTML-Text durch:
Code: Alles auswählen
try:
html_response = requests.get(url)
except HTTPError as e:
print(e)
tree = html.fromstring(html_response.content)
es macht aber kein Unterschied, oder?
Re: Eine Frage zu Regex-Modul
Verfasst: Dienstag 3. Juli 2018, 22:05
von __blackjack__
Du bekommst bei dem gezeigten HTML tatsächlich nur zwei Ergebnisse? Da ist doch aber gar nichts mit einem Style-Attribut. Und bist Du sicher das Du tatsächlich ``not(.//@style)`` willst? Dir ist klar was das ``.//`` da bewirkt?
Wenn Du nur URLs willst die mit '/bar' *enden* ist `contains()` wohl auch die falsche Funktion.
Die Ausnahme”behandlung” mit `print()` ist übrigens nicht sinnvoll. Wenn da eine Ausnahme kommt, dann ist `html_response` ja nicht definiert und Du bekommst gleich danach deswegen einen `NameError`. Den Teil danach möchtest Du also vielleicht besser in einen ``else``-Zweig verschieben.
Re: Eine Frage zu Regex-Modul
Verfasst: Mittwoch 4. Juli 2018, 11:17
von LiorR91
__blackjack__ hat geschrieben: Dienstag 3. Juli 2018, 22:05
Du bekommst bei dem gezeigten HTML tatsächlich nur zwei Ergebnisse?
Es ist mir gerade erstmal aufgefallen dass ich gar keine Doppeltreffer im html_response habe! Krass. (Das gezeigte html war natürlich nur ein Exemplar, ich wollte kein 1000-Zeilen-HTML-Code hochladen). Ich dachte dass für identische Symbolen in einem Website bekommt man auch ein identisches html Code. Also mein Code funktioniert eigentlich. Danke für die Hilfe und sorry für meine Dummheit!
