Verarbeitung von Quelltext

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
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

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
Zuletzt geändert von YAPD am Samstag 21. August 2021, 19:02, insgesamt 1-mal geändert.
-----
Yet Another Python Developer
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@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
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

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
-----
Yet Another Python Developer
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

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.
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

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:
-----
Yet Another Python Developer
Benutzeravatar
YAPD
User
Beiträge: 120
Registriert: Dienstag 27. Juli 2021, 23:23
Wohnort: Frankfurt am Main

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
-----
Yet Another Python Developer
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

@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.
Benutzeravatar
snafu
User
Beiträge: 6872
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Die passende join-Methode befindet sich übrigens im urllib.parse Modul und nennt sich urljoin().
Antworten