Netissä olevan Alkon txt-tiedoston parsinta/python

Alkopythonisti

Moi! Suht aloitteleva koodari täällä ja tarvisin apua. Koitan rakentaa Alkon API:n pohjalle toimivaa hyvin yksinkertaista pikku python-ohjelmaa, jossa pyydetään tietoa halutun tuotteen saatavuudesta halutussa kaupungissa. Itse apista datan hakeminen oli helppoa, mutta ongelmia aiheuttaa Alkon sivuillaan ylläpitämä tekstitiedosto tuotehinnastosta, jota en saa parsittua millään tavalla järkevään muotoon: http://www.alko.fi/tuotteet/tallennahinnasto/

Saan tuon parsittua vain massiiviseksi stringiksi enkä saa millään tavalla siihen mitään struktuuria. Olen kokeillut ties mitä splittejä sun muita, mutta tuo string ei tahdo muuntua edes listaksi vaikka mitä yritän.

Regular expressioneilla onnistuin parsimaan tuoteID:n, mitä tarvitaan API:n käyttöön, mutta haluaisin ensiksi tarjota käyttäjällä listan eri tuotekategerioista ja tämän alta listan tuotteista, jotta käyttäjä voi valita haluamansa tuotteen, jota hakea.

Tässä toistaiseksi tekemäni koodi, jossa tietyn tuotteen valinnan sijaan valitaan täysin satunnainen tuote Alkon listalta ja haetaan sen tiedot annetun kaupungin Alkoista:

import requests
from urllib.request import urlopen
import re
import random
import pandas


tuotteet= urlopen('http://www.alko.fi/contentassets/df76c4146bb74ac08089e5bf610e6d67/fi/alkon-hinnasto-tekstitiedostona.txt').read().decode('utf_8')

tuotenro = re.findall('[0-9][0-9][0-9][0-9][0-9][0-9]', tuotteet)
tuote = random.choice(tuotenro)

print("Anna kaupunki, jonka Alkoista haetaan")
kaupunki=input()

haku=requests.get('http://www.alko.fi/api/product/Availability?productId=' tuote '&cityId=' kaupunki '&language=fi')
data = haku.json()

maara=[]
kauppa=[]

for list in data:
maara.append(list['Amount'])
kauppa.append(list['StoreName'])

DataSet= pandas.DataFrame(maara,kauppa)
print(DataSet)


Saako tuohon Alkon tuotelista-tekstitiedostoon mitään struktuuria kun sen hakee Pythoniin? Haluaisin parsia sieltä tuoteID:n lisäksi ainakin tuotteen nimen sekä tyypin.

Käytössä Python 3.5 Windowsilla.

13

1897

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • juopporatti

      Tabulaattori erottimena teksti menee soluihin nätisti Calcissa.

    • tyhmää-hienostelua

      Eikö sen näe siellä kaupassa paikanpäällä onko juuri sitä haluamaansa laatua olevaa pulloa vai ei.
      Jos ei ole niin ostaa vähän toista laatua sitten.

    • kossua.ei.vissyä

      Kokeilin hakea kossupulloa Varkauden viinakaupasta, syöttämällä selaimen osoiteriville (katsoin tuoteid:n Alkon sivuilta):

      http://www.alko.fi/api/product/Availability?productId=000132&cityId=Varkaus&language=fi

      Selain palautti:

      [{"StoreName":"Varkaus","StoreLink":"/myymalat-palvelut/2736/","Amount":"18","LastUpdated":"17.11."}]

      Tuloksesta sain irroitetuksi myymälän ja määrän esim näin:

      #koodi alkaa
      tiedot = [{"StoreName":"Varkaus","StoreLink":"/myymalat-palvelut/2736/","Amount":"18","LastUpdated":"17.11."}]

      for rivi in tiedot:
      print("Alko:", rivi["StoreName"])
      print("Määrä: ", rivi["Amount"])
      #koodi loppuu

      Joka tulosti:

      Alko: Varkaus
      Määrä: 18

      Nuo aaltosulkeet oli itselleni uusi tuttavuus, niiden käyttöä selitetty:
      http://stackoverflow.com/questions/9197324/curly-braces-in-python

      CSV-tiedostojen käsittelystä on juttua:
      https://docs.python.org/2/library/csv.html

      • kossua.ei.vissyä

        En näköjään vastannut varsinaiseen kysymykseesi, pitänee tutkia tuota CSV-osastoa tarkemmin.


      • kossua.ei.vissyä
        kossua.ei.vissyä kirjoitti:

        En näköjään vastannut varsinaiseen kysymykseesi, pitänee tutkia tuota CSV-osastoa tarkemmin.

        Ei tarvinnut käyttää CSV:tä. Tässä esimerkissä kysytään hakuarvo, jota haetaan taulukon "Nimi"-sarakkeesta ja palautetaan "Numero"-sarakkeen arvo, jos hakuarvo löytyy.

        #koodi alkaa
        import requests
        from urllib.request import urlopen

        tuotteet=urlopen('http://www.alko.fi/contentassets/df76c4146bb74ac08089e5bf610e6d67/fi/alkon-hinnasto-tekstitiedostona.txt').read().decode('utf_8')
        pos=tuotteet.find("Numero"); # etsitään vars. taulukon alku

        if pos>0: # jos taulukon alku löytyi, niin
        tuotteet=tuotteet[pos:].splitlines() # pilkotaan taulukko riveihin
        otsikot=tuotteet[0].split("\t") # otsikkorivin sarakkeet listaksi
        nimisarake=otsikot.index("Nimi") # tuotenimen sarakeindeksi
        palautussarake=otsikot.index("Numero") # paluuarvosarake

        hakunimi=input("Hakuarvo: ")

        rivit=len(tuotteet) # rivien määrä
        for r in range(rivit):
        rivi=tuotteet[r].split("\t")
        if rivi[nimisarake].find(hakunimi) >= 0:
        print(rivi[palautussarake])
        #koodi päättyy


      • juopporatti

        Sehän on jsonia

        import json
        alko='{"StoreName":"Varkaus","StoreLink":"/myymalat-palvelut/2736/","Amount":"18","LastUpdated":"17.11."}'

        parsed = json.loads(alko)
        print(parsed['StoreName'])


    • awertw45t
      • sert5w45t

        Tietysti sinne tuli virhe, rivi 41 näin

        Numerot = line.split('\t')

        Eli rivi puretaan sarakketiedoksi tabulointi merkillä. Lisäksi huomaa että käsittelen ohjelmassa "HINNASTOA" paikallisena tiedostona, verkkoa kuormittamatta.

        Ja vielä kannattaa huomioida että hinaston tallenus teksti-tiedostoksi ei ole onnistunut alunalkaen oikein, kettien määrä eri tuotteilla on erillainen. Eli kun alunperin hinnastoa on luotu, kokaisen kentän pitäisi sisältää vaikka välilyönti, ei näytä muuten tieksitiedostoksi viedessä säilyvän kenttäjako, tai ne katoaa Windows <--> Linux syystä.




        Affiliate-Julkaisia
        Linux Mint 18 Sarah
        Xfce 64-bit


      • srtyt
        sert5w45t kirjoitti:

        Tietysti sinne tuli virhe, rivi 41 näin

        Numerot = line.split('\t')

        Eli rivi puretaan sarakketiedoksi tabulointi merkillä. Lisäksi huomaa että käsittelen ohjelmassa "HINNASTOA" paikallisena tiedostona, verkkoa kuormittamatta.

        Ja vielä kannattaa huomioida että hinaston tallenus teksti-tiedostoksi ei ole onnistunut alunalkaen oikein, kettien määrä eri tuotteilla on erillainen. Eli kun alunperin hinnastoa on luotu, kokaisen kentän pitäisi sisältää vaikka välilyönti, ei näytä muuten tieksitiedostoksi viedessä säilyvän kenttäjako, tai ne katoaa Windows <--> Linux syystä.




        Affiliate-Julkaisia
        Linux Mint 18 Sarah
        Xfce 64-bit

        Vielkäin on jokin TYPO mukana.

        Kun yrität noutaa kakki ne tuotteet jotka sisältävät "Koskenkorva" joutuu jättämään ensimmäisen kirjaimen pois, eli näin:

        for x in tuotteet[Nimi]:
        if x.find('oskenkorv') > 0:
        print(x)

        Vain näin löytyy kaikki:
        Koskenkorva Viina
        Koskenkorva Viina
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Vodka 40 %
        Koskenkorva Vodka 40 % muovipullo
        Koskenkorva Vodka 40 % muovipullo
        Koskenkorva Vodka 60 % muovipullo
        Koskenkorva Vodka Sauna Barrel
        Koskenkorva Vodka Vanilla muovipullo
        Koskenkorva Viina 30 % muovipullo
        Koskenkorva Viina 30% muovipullo
        Koskenkorva Viina 30% muovipullo
        Koskenkorva Viina 32 %
        Koskenkorva Viina Omena muovipullo
        Koskenkorva Pure Apple tölkki
        Koskenkorva Pure Cranberry tölkki
        Koskenkorva Pure Strawberry Lime tölkki
        Koskenkorva The Original Strawberry muovipullo
        Koskenkorva The Original Peach muovipullo
        Koskenkorva Minttu muovipullo
        Koskenkorva Lakritsi
        Koskenkorva Salmiakki
        Koskenkorva Salmiakki muovipullo
        Koskenkorva Salmiakki muovipullo
        Koskenkorva Salmiakki muovipullo


        Koitan löytää ratkaisun tuonnempana mikäli mennään oikeaan suuntaa tään ohjelman kanssa.



        Affiliate-Julkaisia
        Linux Mint 18 Sarah
        Xfce 64-bit


      • kossua.ei.vissyä
        srtyt kirjoitti:

        Vielkäin on jokin TYPO mukana.

        Kun yrität noutaa kakki ne tuotteet jotka sisältävät "Koskenkorva" joutuu jättämään ensimmäisen kirjaimen pois, eli näin:

        for x in tuotteet[Nimi]:
        if x.find('oskenkorv') > 0:
        print(x)

        Vain näin löytyy kaikki:
        Koskenkorva Viina
        Koskenkorva Viina
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Viina muovipullo
        Koskenkorva Vodka 40 %
        Koskenkorva Vodka 40 % muovipullo
        Koskenkorva Vodka 40 % muovipullo
        Koskenkorva Vodka 60 % muovipullo
        Koskenkorva Vodka Sauna Barrel
        Koskenkorva Vodka Vanilla muovipullo
        Koskenkorva Viina 30 % muovipullo
        Koskenkorva Viina 30% muovipullo
        Koskenkorva Viina 30% muovipullo
        Koskenkorva Viina 32 %
        Koskenkorva Viina Omena muovipullo
        Koskenkorva Pure Apple tölkki
        Koskenkorva Pure Cranberry tölkki
        Koskenkorva Pure Strawberry Lime tölkki
        Koskenkorva The Original Strawberry muovipullo
        Koskenkorva The Original Peach muovipullo
        Koskenkorva Minttu muovipullo
        Koskenkorva Lakritsi
        Koskenkorva Salmiakki
        Koskenkorva Salmiakki muovipullo
        Koskenkorva Salmiakki muovipullo
        Koskenkorva Salmiakki muovipullo


        Koitan löytää ratkaisun tuonnempana mikäli mennään oikeaan suuntaa tään ohjelman kanssa.



        Affiliate-Julkaisia
        Linux Mint 18 Sarah
        Xfce 64-bit

        Lähdemateriaaliin voi tosiaan jäädä virheitä. Muokkasin nyt omaa koodiani siten, että tehdään ilmoitus, mikäli rivin sarakkeiden määrä poikkeaa otsikkosarakkeiden määrästä. Yritetään silti hakea tuotetta siltä riviltä, mutta ympäröidään mahdollinen tulos huutomerkkiriveillä, koska tulos ei ole välttämättä oikein. Lisäksi näytetään tuotenro:n lisäksi tuotteen nimi (sama siis mihin hakuarvoa verrataan joka rivillä)

        Linkki oli näköjään muuttunut myös.

        import requests
        from urllib.request import urlopen

        #koodi alkaa
        tuotteet=urlopen('https://www.alko.fi/INTERSHOP/static/WFS/Alko-OnlineShop-Site/-/Alko-OnlineShop/fi_FI/Muut ladattavat tiedostot/Hinnastot/alkon-hinnasto-tekstitiedostona-21-11.txt').read().decode('utf_8')

        pos=tuotteet.find("Numero"); # etsitään vars. taulukon alku

        if pos>0: # jos taulukon alku löytyi, niin
        tuotteet=tuotteet[pos:].splitlines() # pilkotaan taulukko riveihin
        otsikot=tuotteet[0].split("\t") # otsikkorivin sarakkeet listaksi
        nimisarake=otsikot.index("Nimi") # tuotenimen sarakeindeksi
        palautussarake=otsikot.index("Numero") # paluuarvosarake

        hakunimi=input("Hakuarvo: ")

        rivit=len(tuotteet) # rivien määrä
        for r in range(rivit):
        rivi=tuotteet[r].split("\t")
        if len(rivi) != len(otsikot):
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        print("Rivillä nro",str(r 1),"virheellinen määrä (" \
        str(len(rivi)) ") sarakkeita")
        if rivi[nimisarake].find(hakunimi) >= 0:
        print(rivi[palautussarake] ": ",end="")
        print(rivi[nimisarake])
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        continue
        if rivi[nimisarake].find(hakunimi) >= 0:
        print(rivi[palautussarake] ": ",end="")
        print(rivi[nimisarake])
        #koodi loppuu

        Esimerkiksi haettassa sanalla "Koskenkorva" saadaan tulokseksi:

        Hakuarvo: Koskenkorva
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Rivillä nro 1329 virheellinen määrä (31) sarakkeita
        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        000132: Koskenkorva Viina
        101328: Koskenkorva Viina
        101316: Koskenkorva Viina muovipullo
        101327: Koskenkorva Viina muovipullo
        101334: Koskenkorva Viina muovipullo
        101333: Koskenkorva Viina muovipullo
        101338: Koskenkorva Viina muovipullo
        100147: Koskenkorva Vodka 40 %
        100154: Koskenkorva Vodka 40 % muovipullo
        100153: Koskenkorva Vodka 40 % muovipullo
        148013: Koskenkorva Vodka 60 % muovipullo
        188477: Koskenkorva Vodka Sauna Barrel
        100696: Koskenkorva Vodka Vanilla muovipullo
        930498: Koskenkorva Viina 30 % muovipullo
        112646: Koskenkorva Viina 30% muovipullo
        112647: Koskenkorva Viina 30% muovipullo
        000102: Koskenkorva Viina 32 %
        174956: Koskenkorva Viina Omena muovipullo
        746804: Koskenkorva Pure Apple tölkki
        772364: Koskenkorva Pure Cranberry tölkki
        778134: Koskenkorva Pure Strawberry Lime tölkki
        200507: Koskenkorva The Original Strawberry muovipullo
        287437: Koskenkorva The Original Peach muovipullo
        197456: Koskenkorva Minttu muovipullo
        906276: Koskenkorva Lakritsi
        003129: Koskenkorva Salmiakki
        154656: Koskenkorva Salmiakki muovipullo
        154654: Koskenkorva Salmiakki muovipullo
        154653: Koskenkorva Salmiakki muovipullo
        >>>


    • verkkokaupan.viinat

      Alko on uudistanut sivujaan ja taisi tuo API mennä samalla rikki.

    • Alkopythonisti

      Kiitos näistä. Toisaalla sain vinkin seuraavasta pätkästä, jolla saadaan Alkon txt-tiedosto käteväksi pandas-dataframeksi:


      with urlopen('http://www.alko.fi/contentassets/df76c4146bb74ac08089e5bf610e6d67/fi/alkon-hinnasto-tekstitiedostona.txt') as f:
      hinnasto = pd.read_table(io.BytesIO(f.read()), header=1, error_bad_lines=False)

      Tuon avulla saa datan helposti käytettävään muotoon. Tuo error_bad_lines=False-optio korvaa tuon yllä nähdyn kikkailun txt-tiedoston puutteiden korjaamiseksi.

      Toivottavasti Alko saisi jotain järkeä apiinsa, jotta samasta paikasta saisi ladattua hinnaston kuin myös haettua tuotteen saatavuuden eikä tätä kikkailua tarvitsisi tehdä. Mutta hyvää treeniä tämä on toki ja näitäkin vastauksia lukemalla olen oppinut.

      • r5y45y4

        Kiitos vaan itsellesi, tämä oli hyvä ja opettavainen avaus. Minäkin löysin vian ja nyt hakee Numeron, Hinnan, Nimen ja Tyypin.


        Affiliate-Julkaisia
        Linux Mint 18 Sarah
        Xfce 64-bit


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Purra hyökkää nyt suomalaisen duunarin kimppuun teettämällä mamuilla palkatonta työtä

      Niinpä niin. Persut duunaripuolue, HAH. Joko alkaa kovapäisinkin persu älyämään, että persut ovat Suomen kansan vastain
      Maailman menoa
      357
      12283
    2. Purra ehdottaa vaan Tanskan mallia, joka on erittäin hyvä malli

      Purra ehdotti helmikuussa Suomeen Tanskan mallia, jossa maahanmuuttajilta vaaditaan työntekoa sosiaalitukien saamiseksi.
      Maailman menoa
      255
      5367
    3. Kokoomusnuoret: Sosiaalitukien työvelvoitteen tulisi koskea kaikkia

      Riikka Purra on esittänyt, että maahanmuuttajilta tulisi edellyttää palkatonta työtä sosiaalitukien vastineeksi. Kokoom
      Maailman menoa
      211
      3906
    4. Purra vaatii: Työvelvoite maahanmuuttajille ja kantasuomalaisille pitkäaikaistyöttömille

      Jos Perussuomalaiset ja Kokoomus ovat seuraavan hallituksen kaksi johtavaa puoluetta, on suomalaisille pitkäaikaistyöttö
      Perussuomalaiset
      195
      2573
    5. Jyrki Linnankivi, Jyrki 69 - Goottirokkarista kirkonmieheksi Lappiin!

      Jyrki Linnankivi eli Jyrki 69 on The 69 Eyes -rockyhtyeen vokalisti. Lauluhommien lisäksi hän sanoittaa, säveltää ja sov
      Työ ja opiskelu
      15
      1962
    6. Onnea Maria ja Vilma Amazing Race -voitosta!

      Maria Guzenina ja Vilma Vähämaa voittivat Amazing Race Suomi -kisan. Voiton hetkellä Guzenina paljasti, miksi valitsi Vi
      Tv-sarjat
      19
      1824
    7. Mikä on mielestäsi paras miestyyppi?

      Esimerkit kärjistettyinä: a) perustavallinen/tasainen b) himourheilija c) varakas, turvallinen elättäjä d) puolikrimina
      Ikävä
      167
      860
    8. Martina Aitolehti

      Instagramissa pomppas esille Martinan kumipallot. Ihan säikähin. Ja tää on Martina-ketju!
      Kotimaiset julkkisjuorut
      271
      832
    9. No kolahtaako kukaan

      Samalla tavalla kuin mä? Harmi kun et uskaltanut kohdata. Ehkä me löydetään jotkut muut jotka voi olla konkreettisempiak
      Ikävä
      74
      742
    10. Rippituoli

      Kerro joku synkkä tai outo salaisuus, joka liittyy ikävääsi kaivattuasi kohtaan. Tee tunnustus anonyyminä. Se helpottaa
      Ikävä
      59
      696
    Aihe