re.findall mit HTML-Mehrzeiler

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Hallöchen

Ich hab ein kleines Problem mit RE bzw re.findall und zwar möchte ich "Titel" und "ID" aus einem HTML-Dokument extrahieren.

Bei meinen Versuchen wird immer nur die "ID", gar nichts, zuviel gefunden oder es wird beides gefunden jedoch nur EIN Treffer!

HTML:

Code: Alles auswählen

<item>
<title>FOOBAR  TITEL</title>
<category>Mein Foobar</category>
<description>Hier findet Ihr Foobar über meine Foobar</description>
<link>http://foobar.org/about.php?id=111111&</link>
</item>
Versucht hab ich es mit folgendem:

Code: Alles auswählen

findall('<title>(.*)</title>\s.*id=([\d]+)&amp', self.opener.open(self.db_hostname + self.db_rss % cat).read(), re.DOTALL)
Extrahiert sollte alle "FOOBAR TITEL" und alle "111111" werden.
Zuletzt geändert von AngelusNoctis am Dienstag 27. Oktober 2015, 22:35, insgesamt 1-mal geändert.
BlackJack

@AngelusNoctis: Das ist kein HTML und weder HTML noch XML sollte man mit regulären Ausdrücken verarbeiten sondern mit den dafür passenden Werkzeugen:

Code: Alles auswählen

from urlparse import parse_qs, urlparse
from lxml import etree

SOURCE = """\
<root>
<item>
<title>FOOBAR  TITEL</title>
<category>Mein Foobar</category>
<description>Hier findet Ihr Foobar über meine Foobar</description>
<link>http://foobar.org/about.php?id=111111&</link>
</item>
<item>
<title>FOOBAR  TITEL 2</title>
<category>Mein Foobar</category>
<description>Hier findet Ihr Foobar über meine Foobar</description>
<link>http://foobar.org/about.php?id=222222&</link>
</item>
</root>"""


def main():
    document = etree.fromstring(SOURCE)  # Use `etree.parse()` here if you have an URL.
    for item in document.findall('item'):
        title = item.find('title').text
        id_ = parse_qs(urlparse(item.find('link').text).query)['id'][0]
        print(title, id_)


if __name__ == '__main__':
    main()
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das Problem ist, dass deine Zeichengruppe '[\d]+' nicht auf beliebige Zahlen matcht, was du beabsichtigst, sondern auf die _Zeichen_ '\' und 'd'.
Du willst da keine Zeichengruppe, also lass die eckigen Klammern weg.

Aber du solltest dafuer wirklich einen HTML-Parser wie zB BeautifulSoup benutzen. RE sind kein Werkzeug fuer HTML.
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Mein Fehler, es ist die Ausgabe eines RSS-Links also "<?xml version="1.0" encoding="utf-8"?><rss version="0.91">"

@cofi
ID bekomme ich, Titel jedoch nicht bzw alle vor <titel> wird auch genommen obwohl ich nur das zwischen <title></title> möchte

@BlackJack
Werde ich mal versuchen, danek
AngelusNoctis
User
Beiträge: 92
Registriert: Sonntag 16. Dezember 2007, 20:03

Hab gerade gesehen... "feedparser" tut was ich brauche.


Danke für eure Hilfe :)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das kann ich nicht nachvollziehen:

Code: Alles auswählen

In [1]: s = """
   ...:     <item>
   ...:     <title>FOOBAR  TITEL</title>
   ...:     <category>Mein Foobar</category>
   ...:     <description>Hier findet Ihr Foobar über meine Foobar</description>
   ...:     <link>http://foobar.org/about.php?id=111111&</link>
   ...:     </item>
   ...: """

In [2]: import re

In [3]: re.findall('<title>(.*?)</title>\s.*id=(\d+)&amp', s, re.DOTALL)
Out[3]: [('FOOBAR  TITEL', '111111')]
Fuer Feeds gibt es auch noch Feedparser: https://pypi.python.org/pypi/feedparser
Antworten