» »

[Python] json.decoder.JSONDecodeError

[Python] json.decoder.JSONDecodeError

HotBurek ::

Dobro jutro.

Evo, ker se za pravega moškega spodobi double trouble, nadaljujem in odpiram novo temo.

Včeraj sem naletel na situacijo, kjer je parser začel vračat error: json.decoder.JSONDecodeError

In to brez razloga. Ker, nekaj tednov nazaj je delal, sedaj pa ne več.

Schema.org parser pravi, da je vse vredu: https://validator.schema.org/#url=https...

V zgodbo sem vključil spletnega pomočnika.

In ta mi je pokazal pot.

Izsek iz kode, ki mi jo je ponudil:

soup = BeautifulSoup(html, 'html.parser')
for i, tag in enumerate(soup.find_all('script', type='application/ld+json')):
    print(f"\n--- JSON-LD Block {i} ---")
    print(tag.string)

In sem začel raziskovat, kaj vse od "script" in "ld+json" je v HTML fajlu.

Ter našel, da je v samem source HTML fajlu (response, ki pride nazaj), več teh script ld+json blokov. Tako, na oko se to ne opazi hitro. V brskalniku sicer Ctrl+F ter iskalni niz "ld+json" najde oba...

Tale je bil tist, ta interesantni:

<script type="application/ld+json" id="ts_rich_snippet"
    data-ts-ean="4242002500140" data-ts-mpn="SMZ2014" data-ts-man="Bosch">
</script>

In ker je prazen, parser vrača error.

Takole je to opisal spletni pomočnik:

There&#8217;s a <script type="application/ld+json"> block that is empty or contains invalid JSON

Skratka empty or contains... Empty. Empty.

In sedaj še končna rešitev (Ki je sicer prirejena, ker v mojem primeru se na koncu for loop-a prepiše input_html z str(soup), potem pa se input_html parsa naprej. Ampak logika, kako odkrit preveč robate script ld+json elemente, je pa ista.):

import requests;
import json;
import bs4;
import pprint;

# set url and headers
url = "https://www.multitronic.fi/ru/products/3031127";
headers = { "User-Agent": "Mozilla/5.0" };

# call get and get response
response = requests.get(url, headers=headers);
input_html = response.text;

# soup
soup = bs4.BeautifulSoup(input_html, "html.parser");

# find all script with application/ld+json
all_scripts = soup.find_all("script", type="application/ld+json");

# go after each script
for i in range(0, len(all_scripts)):

    # set script
    script_ld_json = all_scripts[i];

    # set script text
    script_ld_json_text = str(script_ld_json.text);

    # check for empty string
    if script_ld_json_text.strip() == "":

        # remove script from source
        script_ld_json.decompose();

    else:

        try:

            # load json to check if it is valid
            jl_data = json.loads(script_ld_json_text);

            # TODO
            # pprint
            pprint.pprint(jl_data);

        except json.JSONDecodeError:

            # remove script from source
            script_ld_json.decompose();

        except:

            # pass
            pass;

Output:
{'@context': 'https://schema.org',
 '@graph': [{'@type': 'WebSite',
             'name': 'Multitronic',
             'url': 'https://www.multitronic.fi'},
            {'@type': 'Product',
             'brand': {'@type': 'Brand', 'name': 'Bosch'},
             'description': '&#1050;&#1091;&#1087;&#1080;&#1090;&#1100; Bosch SMZ2014 - Basket for dishwasher &#1074; '
                            '&#1060;&#1080;&#1085;&#1083;&#1103;&#1085;&#1076;&#1080;&#1080;, &#1074; &#1084;&#1072;&#1075;&#1072;&#1079;&#1080;&#1085;&#1077; &#1052;&#1091;&#1083;&#1100;&#1090;&#1080;&#1090;&#1088;&#1086;&#1085;&#1080;&#1082; &#1087;&#1086; &#1074;&#1099;&#1075;&#1086;&#1076;&#1085;&#1086;&#1081; '
                            '&#1094;&#1077;&#1085;&#1077; &#1085;&#1072; &#1089;&#1072;&#1081;&#1090;&#1077; multitronic.fi. &#1054;&#1092;&#1086;&#1088;&#1084;&#1080; &#1080;&#1085;&#1074;&#1086;&#1081;&#1089; &#1080;&#1083;&#1080; '
                            '&#1090;&#1072;&#1082;&#1089; &#1092;&#1088;&#1080; &#1074; &#1085;&#1072;&#1096;&#1077;&#1084; &#1084;&#1072;&#1075;&#1072;&#1079;&#1080;&#1085;&#1077; &#1074; &#1051;&#1072;&#1087;&#1087;&#1077;&#1077;&#1085;&#1088;&#1072;&#1085;&#1090;&#1077;.',
             'gtin13': '4242002500140',
             'image': 'https://www.multitronic.fi/images/prod/2/F/SMZ2014-1.webp',
             'mpn': 'SMZ2014',
             'name': 'Bosch SMZ2014 - Basket for dishwasher',
             'offers': [{'@type': 'Offer',
                         'availability': 'https://schema.org/LimitedAvailability',
                         'price': '71.90',
                         'priceCurrency': 'EUR',
                         'url': 'https://www.multitronic.fi/ru/products/3031127'}],
             'sku': 3031127},
            {'@type': 'BreadcrumbList',
             'itemListElement': [{'@type': 'ListItem',
                                  'item': 'https://www.multitronic.fi/',
                                  'name': '&#1043;&#1083;&#1072;&#1074;&#1085;&#1072;&#1103; &#1089;&#1090;&#1088;&#1072;&#1085;&#1080;&#1094;&#1072;',
                                  'position': 1},
                                 {'@type': 'ListItem',
                                  'item': 'https://www.multitronic.fi/bytovaia-elektronika',
                                  'name': '&#1041;&#1099;&#1090;&#1086;&#1074;&#1072;&#1103; &#1101;&#1083;&#1077;&#1082;&#1090;&#1088;&#1086;&#1085;&#1080;&#1082;&#1072;',
                                  'position': 2},
                                 {'@type': 'ListItem',
                                  'item': 'https://www.multitronic.fi/bytovaia-elektronika/white-goods--bytovaia-elektroni',
                                  'name': 'White Goods (&#1041;&#1099;&#1090;&#1086;&#1074;&#1072;&#1103; &#1101;&#1083;&#1077;&#1082;&#1090;&#1088;&#1086;&#1085;&#1080;',
                                  'position': 3},
                                 {'@type': 'ListItem',
                                  'item': 'https://www.multitronic.fi',
                                  'name': '&#1040;&#1082;&#1089;&#1077;&#1089;&#1089;&#1091;&#1072;&#1088;&#1099;',
                                  'position': 4}]}]}

To je to.

Ter končni rezultat: https://www.akopli.com/product/00000005...

Well done.

Pa še nekaj glasbe za pomoč pri premagovanju vsakodnevnih izzivov:

root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
  • spremenilo: HotBurek ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

CSV file

Oddelek: Programiranje
262081 (1285) kunigunda
»

Davčne blagajne (strani: 1 2 3 424 25 26 27 )

Oddelek: Programiranje
1344346058 (86061) Macketina
»

Bolha parser/pajek - prejemanje obvestil o novih oglasih

Oddelek: Programiranje
214686 (3684) rokko
»

Masterpage in jQuery(ajax call)

Oddelek: Programiranje
61440 (1268) hatchette
»

java v javascript?

Oddelek: Programiranje
212153 (1856) boss-tech

Več podobnih tem