Seite 1 von 1

re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 20:58
von AngelusNoctis
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.

Re: re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 21:30
von 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()

Re: re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 21:33
von cofi
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.

Re: re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 22:18
von AngelusNoctis
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

Re: re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 22:34
von AngelusNoctis
Hab gerade gesehen... "feedparser" tut was ich brauche.


Danke für eure Hilfe :)

Re: re.findall mit HTML-Mehrzeiler

Verfasst: Dienstag 27. Oktober 2015, 22:35
von cofi
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