Seite 1 von 1

Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 18:45
von YAPD
Guten Abend Zusammen,

ich möchte Euch um Hilfe bei folgendem Problem bitten, betreffend der
Auswertung von Website - Quelltext. Es geht hier aber gar nicht um die
Anfrage selbst, sondern um die Verarbeitung der Daten.

Problematik :

Ich möchte Quelltext von einer Website verarbeiten, der mittels HTTP
Request in folgendem Format ( Liste ) vorliegt :

Code: Alles auswählen

test = [
    '<p class="sg">European Scripts</p>',
    '<p class="mb"><a href="PDF/U0530.pdf" title="0530-058F">Armenian</a></p>',
    '<p class="pb"><a href="PDF/UFB00.pdf" title="FB13-FB17">Armenian Ligatures</a></p>',
    '<p class="mb"><a href="PDF/U102A0.pdf" title="102A0-102DF">Carian</a></p>',
    '<p class="mb"><a href="PDF/U10530.pdf" title="10530-1056F">Caucasian Albanian</a>&nbsp;</p>',
    '<p class="mb"><a href="PDF/U10800.pdf" title="10800-1083F">Cypriot Syllabary</a></p>',
    '<p class="mb"><a href="PDF/U0400.pdf" title="0400-04FF">Cyrillic</a></p>',
    '<p class="sb"><a href="PDF/U0500.pdf" title="0500-052F">Cyrillic Supplement</a></p>',
    '<p class="sb"><a href="PDF/U2DE0.pdf" title="2DE0-2DFF">Cyrillic Extended-A</a></p>',
    '<p class="sb"><a href="PDF/UA640.pdf" title="A640-A69F">Cyrillic Extended-B</a></p>',
    '<p class="sb"><a href="PDF/U1C80.pdf" title="1C80-1C8F">Cyrillic Extended-C</a></p>',
    '<p class="mb"><a href="PDF/U10500.pdf" title="10500-1052F">Elbasan</a></p>',
    '<p class="mb"><a href="PDF/U10A0.pdf" title="10A0-10FF">Georgian</a></p>',
    '<p class="sb"><a href="PDF/U1C90.pdf" title="1C90-1CBF">Georgian Extended</a></p>',
    '<p class="sb"><a href="PDF/U2D00.pdf" title="2D00-2D2F">Georgian Supplement</a></p>',
]
Ich möchte nun diese Eingabe auf die 3 Parameter href, title und code ( hier title )
beschränken. Dazu habe ich folgendes geschrieben :

Code: Alles auswählen

from collections import defaultdict

output = []

counter = 0

for element in test:

    if "</a>" not in element and element.endswith("</p>"):
        element_title = re.findall(r">(\D+)</p>", element)[0]

    if element.endswith("</a></p>"):
        element_title = re.findall(r">(\D+)</a></p>", element)[0]

    output.append(re.findall(r'"(.*?)"', element))
    output[counter][0] = output[counter][0].replace(output[counter][0], element_title)
    counter += 1

for o in output:
    print(o[0])
Meine Frage ist nun, wie die Effektivität der Regex - Befehle aussieht, oder ob man
hier noch etwas optimieren muss. Außerdem hätte ich gerne Eure Meinung wie ich
die Daten weiterverarbeiten soll. Ich habe an ein defaultdict gedacht, oder lieber
doch eine Tuple ?

Die Liste 'test' ist natürlich ein Beispiel und ursprünglich viel länger, als diese
15 Zeilen :)


Vielen Dank für Eure Unterstützung.

VG
YAPD

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 18:59
von rogerb
@YAPD,

muss es unbedingt Regex sein?

Mal angenommen der HTML Text wäre nicht in einzelne Zeilen unterteilt, was er wahrscheinlich von Anfang an auch nicht ist, dann wäre es mit bs4 viel einfacher:

Code: Alles auswählen

from bs4 import BeautifulSoup

test = """
<p class="sg">European Scripts</p>
<p class="mb"><a href="PDF/U0530.pdf" title="0530-058F">Armenian</a></p>
<p class="pb"><a href="PDF/UFB00.pdf" title="FB13-FB17">Armenian Ligatures</a></p>
<p class="mb"><a href="PDF/U102A0.pdf" title="102A0-102DF">Carian</a></p>
<p class="mb"><a href="PDF/U10530.pdf" title="10530-1056F">Caucasian Albanian</a>&nbsp;</p>
<p class="mb"><a href="PDF/U10800.pdf" title="10800-1083F">Cypriot Syllabary</a></p>
<p class="mb"><a href="PDF/U0400.pdf" title="0400-04FF">Cyrillic</a></p>
<p class="sb"><a href="PDF/U0500.pdf" title="0500-052F">Cyrillic Supplement</a></p>
<p class="sb"><a href="PDF/U2DE0.pdf" title="2DE0-2DFF">Cyrillic Extended-A</a></p>
<p class="sb"><a href="PDF/UA640.pdf" title="A640-A69F">Cyrillic Extended-B</a></p>
<p class="sb"><a href="PDF/U1C80.pdf" title="1C80-1C8F">Cyrillic Extended-C</a></p>
<p class="mb"><a href="PDF/U10500.pdf" title="10500-1052F">Elbasan</a></p>
<p class="mb"><a href="PDF/U10A0.pdf" title="10A0-10FF">Georgian</a></p>
<p class="sb"><a href="PDF/U1C90.pdf" title="1C90-1CBF">Georgian Extended</a></p>
<p class="sb"><a href="PDF/U2D00.pdf" title="2D00-2D2F">Georgian Supplement</a></p>
"""


soup = BeautifulSoup(test)
for tag in soup.find_all("a"):
    print(tag.text)
Das macht das gleiche wie dein aktueller Code

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 19:11
von YAPD
Hi Roger,

vielen Dank für deine Antwort. Ich möchte ja die 3 genannten Werte weiterverarbeiten ( href, title & code ). Ich fürchte, dein Beispiel ist
leider nicht flexibel genug. Als Beispiel wird "European Scripts' bei dir nicht angezeigt, da das nicht angefangen wird. Außerdem geht
dein Code leider nur mehrzeiligem Text ( '''' ), nicht mit Listen. Kann man das mit deiner Lösung auch abfangen, oder muss ich hier doch
Regex benutzen ? Das 'Problem' ist halt, dass das Tag <class> immer unterschiedlich sein kann, hinten manchmal mit '</a></p>' und
manchmal nur mit '</p>'. Wenn ich ich aus dem 'a' Tag ein 'p' Tag mache, bekomme ich das Ergebnis wie bei Regex. Bleibt noch die
Frage : Wie mache ich es mit einer Liste :

Code: Alles auswählen

TypeError: expected string or bytes-like object
VG
YAPD

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 19:40
von Sirius3
Natürlich löst rogerbs nicht Dein komplettes Problem, sondern zeigt nur, wie man das Problem generell löst. Nämlich nicht per Regulärem Ausdruck. Lies Dich doch mal in das Modul Beautiful-Soup ein, arbeite das Tutorial durch und dann kannst Du hier nochmal fragen, falls Du bei der Benutzung von bs4 nicht weiterkommst.

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 19:54
von rogerb
Man kann auch noch "title", "href" und "text" in einer Liste von Dictionaries speichern.
Ich weiß nicht wie du die Daten später verwenden willst, daher könnte man vielleicht auch eine andere Datenstruktur verwenden.

Code: Alles auswählen

from bs4 import BeautifulSoup
import pprint

test = """
<p class="sg">European Scripts</p>
<p class="mb"><a href="PDF/U0530.pdf" title="0530-058F">Armenian</a></p>
<p class="pb"><a href="PDF/UFB00.pdf" title="FB13-FB17">Armenian Ligatures</a></p>
<p class="mb"><a href="PDF/U102A0.pdf" title="102A0-102DF">Carian</a></p>
<p class="mb"><a href="PDF/U10530.pdf" title="10530-1056F">Caucasian Albanian</a>&nbsp;</p>
<p class="mb"><a href="PDF/U10800.pdf" title="10800-1083F">Cypriot Syllabary</a></p>
<p class="mb"><a href="PDF/U0400.pdf" title="0400-04FF">Cyrillic</a></p>
<p class="sb"><a href="PDF/U0500.pdf" title="0500-052F">Cyrillic Supplement</a></p>
<p class="sb"><a href="PDF/U2DE0.pdf" title="2DE0-2DFF">Cyrillic Extended-A</a></p>
<p class="sb"><a href="PDF/UA640.pdf" title="A640-A69F">Cyrillic Extended-B</a></p>
<p class="sb"><a href="PDF/U1C80.pdf" title="1C80-1C8F">Cyrillic Extended-C</a></p>
<p class="mb"><a href="PDF/U10500.pdf" title="10500-1052F">Elbasan</a></p>
<p class="mb"><a href="PDF/U10A0.pdf" title="10A0-10FF">Georgian</a></p>
<p class="sb"><a href="PDF/U1C90.pdf" title="1C90-1CBF">Georgian Extended</a></p>
<p class="sb"><a href="PDF/U2D00.pdf" title="2D00-2D2F">Georgian Supplement</a></p>"""

soup = BeautifulSoup(test, "html.parser")

items = []
for tag in soup.find_all("p"):
    a_tag = tag.find("a")

    # prüfen je nachdem ob es ein verschaachteltes "a"-Tag gibt, werden andere Attribute gespeichert
    if a_tag:
        # a - tag vorhanden also dessen Attribute speichern
        items.append(
            {
                "text": a_tag.text,
                "href": a_tag.attrs["href"],
                "title": a_tag.attrs["title"],
            }
        )
    else:
        # kein a -tag vorhanden also nur text speichern
        items.append(
            {
                "text": tag.text,
                "href": "",
                "title": "",
            }
        )

pprint.pprint(items)

"""
Ausgabe:

[{'href': '', 'text': 'European Scripts', 'title': ''},
 {'href': 'PDF/U0530.pdf', 'text': 'Armenian', 'title': '0530-058F'},
 {'href': 'PDF/UFB00.pdf', 'text': 'Armenian Ligatures', 'title': 'FB13-FB17'},
 {'href': 'PDF/U102A0.pdf', 'text': 'Carian', 'title': '102A0-102DF'},
 {'href': 'PDF/U10530.pdf',
  'text': 'Caucasian Albanian',
  'title': '10530-1056F'},
 {'href': 'PDF/U10800.pdf',
  'text': 'Cypriot Syllabary',
  'title': '10800-1083F'},
 {'href': 'PDF/U0400.pdf', 'text': 'Cyrillic', 'title': '0400-04FF'},
 {'href': 'PDF/U0500.pdf', 'text': 'Cyrillic Supplement', 'title': '0500-052F'},
 {'href': 'PDF/U2DE0.pdf', 'text': 'Cyrillic Extended-A', 'title': '2DE0-2DFF'},
 {'href': 'PDF/UA640.pdf', 'text': 'Cyrillic Extended-B', 'title': 'A640-A69F'},
 {'href': 'PDF/U1C80.pdf', 'text': 'Cyrillic Extended-C', 'title': '1C80-1C8F'},
 {'href': 'PDF/U10500.pdf', 'text': 'Elbasan', 'title': '10500-1052F'},
 {'href': 'PDF/U10A0.pdf', 'text': 'Georgian', 'title': '10A0-10FF'},
 {'href': 'PDF/U1C90.pdf', 'text': 'Georgian Extended', 'title': '1C90-1CBF'},
 {'href': 'PDF/U2D00.pdf', 'text': 'Georgian Supplement', 'title': '2D00-2D2F'}]
"""
Ich verwende bs4 nicht sehr oft. Möglicherweise kann man das auch noch eleganter lösen.

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 21:54
von YAPD
rogerb hat geschrieben: Samstag 21. August 2021, 19:54 Man kann auch noch "title", "href" und "text" in einer Liste von Dictionaries speichern.
Ich weiß nicht wie du die Daten später verwenden willst, daher könnte man vielleicht auch eine andere Datenstruktur verwenden.

Code: Alles auswählen

from bs4 import BeautifulSoup
import pprint

test = """
<p class="sg">European Scripts</p>
<p class="mb"><a href="PDF/U0530.pdf" title="0530-058F">Armenian</a></p>
<p class="pb"><a href="PDF/UFB00.pdf" title="FB13-FB17">Armenian Ligatures</a></p>
<p class="mb"><a href="PDF/U102A0.pdf" title="102A0-102DF">Carian</a></p>
<p class="mb"><a href="PDF/U10530.pdf" title="10530-1056F">Caucasian Albanian</a>&nbsp;</p>
<p class="mb"><a href="PDF/U10800.pdf" title="10800-1083F">Cypriot Syllabary</a></p>
<p class="mb"><a href="PDF/U0400.pdf" title="0400-04FF">Cyrillic</a></p>
<p class="sb"><a href="PDF/U0500.pdf" title="0500-052F">Cyrillic Supplement</a></p>
<p class="sb"><a href="PDF/U2DE0.pdf" title="2DE0-2DFF">Cyrillic Extended-A</a></p>
<p class="sb"><a href="PDF/UA640.pdf" title="A640-A69F">Cyrillic Extended-B</a></p>
<p class="sb"><a href="PDF/U1C80.pdf" title="1C80-1C8F">Cyrillic Extended-C</a></p>
<p class="mb"><a href="PDF/U10500.pdf" title="10500-1052F">Elbasan</a></p>
<p class="mb"><a href="PDF/U10A0.pdf" title="10A0-10FF">Georgian</a></p>
<p class="sb"><a href="PDF/U1C90.pdf" title="1C90-1CBF">Georgian Extended</a></p>
<p class="sb"><a href="PDF/U2D00.pdf" title="2D00-2D2F">Georgian Supplement</a></p>"""

soup = BeautifulSoup(test, "html.parser")

items = []
for tag in soup.find_all("p"):
    a_tag = tag.find("a")

    # prüfen je nachdem ob es ein verschaachteltes "a"-Tag gibt, werden andere Attribute gespeichert
    if a_tag:
        # a - tag vorhanden also dessen Attribute speichern
        items.append(
            {
                "text": a_tag.text,
                "href": a_tag.attrs["href"],
                "title": a_tag.attrs["title"],
            }
        )
    else:
        # kein a -tag vorhanden also nur text speichern
        items.append(
            {
                "text": tag.text,
                "href": "",
                "title": "",
            }
        )

pprint.pprint(items)

"""
Ausgabe:

[{'href': '', 'text': 'European Scripts', 'title': ''},
 {'href': 'PDF/U0530.pdf', 'text': 'Armenian', 'title': '0530-058F'},
 {'href': 'PDF/UFB00.pdf', 'text': 'Armenian Ligatures', 'title': 'FB13-FB17'},
 {'href': 'PDF/U102A0.pdf', 'text': 'Carian', 'title': '102A0-102DF'},
 {'href': 'PDF/U10530.pdf',
  'text': 'Caucasian Albanian',
  'title': '10530-1056F'},
 {'href': 'PDF/U10800.pdf',
  'text': 'Cypriot Syllabary',
  'title': '10800-1083F'},
 {'href': 'PDF/U0400.pdf', 'text': 'Cyrillic', 'title': '0400-04FF'},
 {'href': 'PDF/U0500.pdf', 'text': 'Cyrillic Supplement', 'title': '0500-052F'},
 {'href': 'PDF/U2DE0.pdf', 'text': 'Cyrillic Extended-A', 'title': '2DE0-2DFF'},
 {'href': 'PDF/UA640.pdf', 'text': 'Cyrillic Extended-B', 'title': 'A640-A69F'},
 {'href': 'PDF/U1C80.pdf', 'text': 'Cyrillic Extended-C', 'title': '1C80-1C8F'},
 {'href': 'PDF/U10500.pdf', 'text': 'Elbasan', 'title': '10500-1052F'},
 {'href': 'PDF/U10A0.pdf', 'text': 'Georgian', 'title': '10A0-10FF'},
 {'href': 'PDF/U1C90.pdf', 'text': 'Georgian Extended', 'title': '1C90-1CBF'},
 {'href': 'PDF/U2D00.pdf', 'text': 'Georgian Supplement', 'title': '2D00-2D2F'}]
"""
Ich verwende bs4 nicht sehr oft. Möglicherweise kann man das auch noch eleganter lösen.
Super. Ich danke dir. Probier ich gleich mal aus. :)

@Sirius : Ohne Worte :roll:

Re: Verarbeitung von Quelltext

Verfasst: Samstag 21. August 2021, 22:22
von YAPD
Noch eine kurze Frage :

Was würdet ihr bevorzugen :

Code: Alles auswählen

path_file = "{}/{}".format(path_dir, filename)
oder

Code: Alles auswählen

os.sep = "/"
path_file = os.sep.join([path_dir, filename])
Da es sich um eine HTTP Adresse handelt, ist der Trenner immer ein normaler Slash :)

VG
YAPD

Re: Verarbeitung von Quelltext

Verfasst: Sonntag 22. August 2021, 05:14
von sparrow
@YAPD: Welchen Sinn soll es denn haben, den Pfadtrenner für das _Dateisystem_ im os Modul zu überschreiben, wenn du URLs zusammenbauen willst?
Das Überschreiben macht sowieso nie Sinn.
Ich frage mich auch etwas, wie man darauf kommt, denn der Wert lässt sich ja an einen beliebigen Namen binden. Warum sollte man da wichtige Dinge in einem Modul überschreiben, das man für die Operation nicht nutzt und sich damit das Modul potentiell unbrauchbar machen?!

Bei einfachen URLs reicht String-Formatierung in meinen Augen. Ich empfehle aber, sich auch mal mit dem urllib Bibliothek beschäftigt zu haben.

Re: Verarbeitung von Quelltext

Verfasst: Sonntag 22. August 2021, 06:01
von snafu
Die passende join-Methode befindet sich übrigens im urllib.parse Modul und nennt sich urljoin().