Netissä olevan Alkon txt-tiedoston parsinta/python

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.
132137
Äänestä

Muut lukivat myös

Vastaukset 13

Vanhimmat

Tabulaattori erottimena teksti menee soluihin nätisti Calcissa.

Äänestä

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.

Äänestä

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

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

    Äänestä

  • 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

    Äänestä

  • 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'])

    Äänestä

  • 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

    Äänestä

  • 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+ViinaKoskenkorva+ViinaKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Vodka+40+%Koskenkorva+Vodka+40+%++muovipulloKoskenkorva+Vodka+40+%++muovipulloKoskenkorva+Vodka+60+%++muovipulloKoskenkorva+Vodka+Sauna+BarrelKoskenkorva+Vodka+Vanilla++muovipulloKoskenkorva+Viina+30+%++muovipulloKoskenkorva+Viina+30%++muovipulloKoskenkorva+Viina+30%++muovipulloKoskenkorva+Viina+32+%Koskenkorva+Viina+Omena++muovipulloKoskenkorva+Pure+Apple++tölkkiKoskenkorva+Pure+Cranberry++tölkkiKoskenkorva+Pure+Strawberry+Lime++tölkkiKoskenkorva+The+Original+Strawberry++muovipulloKoskenkorva+The+Original+Peach++muovipulloKoskenkorva+Minttu++muovipulloKoskenkorva+LakritsiKoskenkorva+SalmiakkiKoskenkorva+Salmiakki++muovipulloKoskenkorva+Salmiakki++muovipulloKoskenkorva+Salmiakki++muovipulloKoitan+löytää+ratkaisun+tuonnempana+mikäli+mennään+oikeaan+suuntaa+tään+ohjelman+kanssa.Affiliate-JulkaisiaLinux+Mint+18+SarahXfce+64-bit

    Äänestä

  • 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+ViinaKoskenkorva+ViinaKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Viina++muovipulloKoskenkorva+Vodka+40+%Koskenkorva+Vodka+40+%++muovipulloKoskenkorva+Vodka+40+%++muovipulloKoskenkorva+Vodka+60+%++muovipulloKoskenkorva+Vodka+Sauna+BarrelKoskenkorva+Vodka+Vanilla++muovipulloKoskenkorva+Viina+30+%++muovipulloKoskenkorva+Viina+30%++muovipulloKoskenkorva+Viina+30%++muovipulloKoskenkorva+Viina+32+%Koskenkorva+Viina+Omena++muovipulloKoskenkorva+Pure+Apple++tölkkiKoskenkorva+Pure+Cranberry++tölkkiKoskenkorva+Pure+Strawberry+Lime++tölkkiKoskenkorva+The+Original+Strawberry++muovipulloKoskenkorva+The+Original+Peach++muovipulloKoskenkorva+Minttu++muovipulloKoskenkorva+LakritsiKoskenkorva+SalmiakkiKoskenkorva+Salmiakki++muovipulloKoskenkorva+Salmiakki++muovipulloKoskenkorva+Salmiakki++muovipulloKoitan+löytää+ratkaisun+tuonnempana+mikäli+mennään+oikeaan+suuntaa+tään+ohjelman+kanssa.Affiliate-JulkaisiaLinux+Mint+18+SarahXfce+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+requestsfrom+urllib.request+import+urlopen#koodi+alkaatuotteet=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+alkuif+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+loppuuEsimerkiksi+haettassa+sanalla+"Koskenkorva"+saadaan+tulokseksi:Hakuarvo:+Koskenkorva!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Rivillä+nro+1329+virheellinen+määrä+(31)+sarakkeita!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!000132:+Koskenkorva+Viina101328:+Koskenkorva+Viina101316:+Koskenkorva+Viina++muovipullo101327:+Koskenkorva+Viina++muovipullo101334:+Koskenkorva+Viina++muovipullo101333:+Koskenkorva+Viina++muovipullo101338:+Koskenkorva+Viina++muovipullo100147:+Koskenkorva+Vodka+40+%100154:+Koskenkorva+Vodka+40+%++muovipullo100153:+Koskenkorva+Vodka+40+%++muovipullo148013:+Koskenkorva+Vodka+60+%++muovipullo188477:+Koskenkorva+Vodka+Sauna+Barrel100696:+Koskenkorva+Vodka+Vanilla++muovipullo930498:+Koskenkorva+Viina+30+%++muovipullo112646:+Koskenkorva+Viina+30%++muovipullo112647:+Koskenkorva+Viina+30%++muovipullo000102:+Koskenkorva+Viina+32+%174956:+Koskenkorva+Viina+Omena++muovipullo746804:+Koskenkorva+Pure+Apple++tölkki772364:+Koskenkorva+Pure+Cranberry++tölkki778134:+Koskenkorva+Pure+Strawberry+Lime++tölkki200507:+Koskenkorva+The+Original+Strawberry++muovipullo287437:+Koskenkorva+The+Original+Peach++muovipullo197456:+Koskenkorva+Minttu++muovipullo906276:+Koskenkorva+Lakritsi003129:+Koskenkorva+Salmiakki154656:+Koskenkorva+Salmiakki++muovipullo154654:+Koskenkorva+Salmiakki++muovipullo154653:+Koskenkorva+Salmiakki++muovipullo>>>

    Äänestä

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

Äänestä

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.

Äänestä
  • 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

    Äänestä

Kommentoi aloitusta


Alkopythonisti kirjoitti:

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.

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu