Probleme mit BeautifulSoup beim Extrahieren von JSON aus HTML Datei

  • Hallo,

    ich versuche aus einer Webseite (Beispiel: https://www.lovelybooks.de/autor/Fredrika…mer-1108974876/) ein JSON Element rauszulesen, welches folgende Form hat:

    Code
    <script type="application/ld+json">{"@context":"http://schema.org","@type":"ItemList","itemListElement":[{"@type":"Book","name":"Die Holzhammer-Methode","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/Die-Holzhammer-Methode-945569092-w/","author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"position":1},{"@type":"Book","name":"Teufelshorn","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/Teufelshorn-1046225387-w/","author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"position":2},{"@type":"Book","name":"Gut getroffen","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/Gut-getroffen-1112506490-w/","author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"position":3},{"@type":"Book","name":"Frühjahrsputz","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/Fr%C3%BChjahrsputz-1161904735-w/","author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"position":4},{"@type":"Book","name":"Mord am Toten Mann","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/Mord-am-Toten-Mann-1451954751-w/","author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"position":5}]}</script>

    Dazu habe ich 2 Seiten gefunden:


    https://stackoverflow.com/questions/4365…on-using-python

    https://stackoverflow.com/questions/3616…g-beautifulsoup


    nun versuche ich mein Glück:


    Das lesen der HTML Datei funktioniert scheinbar noch Problemlos, wohingegen ich aber in der Zeile soup = BeautifulSoup(html, "html.parser") folgende Fehlermeldung bekomme:



    Das versteh ich leider nicht... könnte mir bitte jemand helfen / TIpps geben wie ich weitermachen kann?

    Danke,
    Linkin

  • Ich hab mit BS nie gute Erfahrungen gemacht. Schlecht formatierte Seiten oder Sonderzeichen bringen den Parser oft durcheinander. Mittlerweile meide ich HTML generell.

    in deinem Fall würde ich das JSON "File" per Regex rausfiltern:

    Code
    h = re.compile('<script type="application/ld+json">(.+?)</script>', re.DOTALL).findall(html)[0]
    j = json.loads(h)
  • Danke dir, hab ich gerade versucht - bekomme dann aber einen neuen Fehler:

    Aber das müsste heißen die Liste ist leer - das macht doch keinen Sinn - ist da irgendwo ein Fehler in der RegEx? Ich bin kein RegEx-Experte, aber der Befehl sagt doch nur er soll ALLES finden, was zwischen <script type="application/ld+json"> und </script> steht, oder?

  • funktioniert perfekt, vielen Dank! Für alle die das Thema finden- hier ist die Lösung:

  • @membrane ich hätte doch noch eine Frage:

    Bei dieser Seite funktioniert die RegEx super:
    https://www.lovelybooks.de/autor/Fredrika…mer-1108974876/

    Bei dieser Seite bekomme ich nur None zurück:
    https://www.lovelybooks.de/autor/Fredrika…de-945569092-w/


    Ich seh aber im HTML Code keinen Unterschied:


    Code
    <script type="application/ld+json">{"@context":"http://schema.org","@type":"Book","bookFormat":"Paperback","isbn":"9783499258763","numberOfPages":272,"name":"Die Holzhammer-Methode","description":"Gestatten: Franz Holzhammer, Hauptwachtmeister in Berchtesgaden.\n\nMitten in der sommerlichen Alpenidylle stürzt ein Gleitschirmflieger vom Himmel. Der junge Mann ist auf der Stelle tot. Hauptwachtmeister Franz Holzhammer hat ein ganz schlechtes Gefühl bei der Sache. Sein Vorgesetzter will die Angelegenheit als Unfall abtun, doch Holzhammer ist es egal, wer unter ihm Chef ist \u2013 er beginnt zu ermitteln. Kurz darauf kommt eine Patientin der örtlichen Reha-Klinik ums Leben. Christine, ihre Ärztin, will nicht an einen natürlichen Tod glauben. Und so wird die Zugereiste unvermutet Holzhammers wichtigste Verbündete.\n","aggregateRating":{"@type":"AggregateRating","reviewCount":59,"ratingCount":85,"ratingValue":3.6,"bestRating":"5"},"author":{"@type":"Person","name":"Fredrika Gers","url":"https://www.lovelybooks.de/autor/Fredrika-Gers/"},"genre":"Krimi und Thriller","datePublished":"2012-06-01","image":"https://s3-eu-west-1.amazonaws.com/cover.allsize.lovelybooks.de/9783499258763_1491102367000_xxl.jpg","inLanguage":"ger"}</script>

    Siehst du was, was ich übersehe? Der Output vom .read() ist noch einwandfrei, der re.compile ist None :/

  • Danke dir - ich hatte:

    Code
    # coding: utf8

    Hab das irgendwo anders gefunden (ich glaub im SkyGo Addon), aber mit beiden Zeilen funktioniert es leider nicht :/

    edit: kann es sein, dass die " im zweiten Fall Probleme machen, d.h. ich die vorher durch ' ersetzen müsste?
    edit2: nope - selbes Problem ... ich glaub irgendwas passt mit dem Format nicht... ich zieh mir die Daten jetzt einfach per RegEx einzeln raus ;)
    Bin aber trotzdem froh, wenn mir jemand zeigen könnte was ich falsch gemacht hab :(

    Verdammt... das mit dem None war ein fehler von mir (hab die return-Variable mit "None" initialisiert und zu früh als [definition=12,4][definition='1','3']Debug[/definition][/definition] ausgegeben, deswegen lief es nicht... Ich vermute mal die neue Codierung von dir hat das Problem nun behoben, denn bei mir geht es jetzt, wenn ich die korrekt URL verwende... schau mir das mit der URL morgen mal an... ich vermute da ist irgendwo ein Encoding-Bug drin :)

    Vielen Dank!

  • Falls noch Interesse am BeautifulSoup Problem besteht,
    du vermischt BS4 und BS3 Syntax.
    Da dein Importstatement lautet from BeautifulSoup import BeautifulSoup
    gehe ich davon aus, dass Du mit einer Version 3 arbeitest.
    Da müsstest Du die Klasse nur mit dem html Parameter instanziieren.
    Desweiteren liefert dir BS durch die Funktion find nicht ein Filehandle zurück,
    was heisst Du musst die json Funktion loads und nicht load benutzen.
    Also sowas wie

    Python
    from BeautifulSoup import BeautifulSoup
    import urllib2
    import json
    url = 'https://www.lovelybooks.de/autor/Fredrika-Gers/reihe/Franz-Holzhammer-1108974876/'
    html = urllib2.urlopen(url).read()
    soup = BeautifulSoup(html)
    raw_data = soup.find('script', {'type':'application/ld+json'})
    data = json.loads(raw_data.string)
    print('JSON output %s' % (data))


    Das gibt dann so etwas zurück

    JSON output {u'@context': u'http://schema.org', u'itemListElement':
    [{u'url': u'https://www.lovelybooks.de/autor/Fredrika…de-945569092-w/', u'position': 1,
    u'author': {u'url': u'https://www.lovelybooks.de/autor/Fredrika-Gers/', u'@type': u'Person', u'name': u'Fredrika Gers'},
    u'@type': u'Book', u'name': u'Die Holzhammer-Methode'},
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika…n-1046225387-w/', u'position': 2, u'author':
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika-Gers/', u'@type': u'Person', u'name': u'Fredrika Gers'},
    u'@type': u'Book', u'name': u'Teufelshorn'},
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika…n-1112506490-w/', u'position': 3, u'author':
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika-Gers/', u'@type': u'Person', u'name': u'Fredrika Gers'},
    u'@type': u'Book', u'name': u'Gut getroffen'},
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika…z-1161904735-w/', u'position': 4, u'author':
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika-Gers/', u'@type': u'Person', u'name': u'Fredrika Gers'},
    u'@type': u'Book', u'name': u'Fr\xfchjahrsputz'},
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika…n-1451954751-w/', u'position': 5, u'author':
    {u'url': u'https://www.lovelybooks.de/autor/Fredrika-Gers/', u'@type': u'Person', u'name': u'Fredrika Gers'},
    u'@type': u'Book', u'name': u'Mord am Toten Mann'}], u'@type': u'ItemList'}

    Die Zeilenumbrüche sind natürlich von mir (wegen Lesbarkeit)

    Gruß
    Claudia

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!