Postinumeroiden noutaminen Pythonilla webistä

soppakokeilu

Tein tuossa huvikseni pienen funktion, jolle annetaan parametreinä katuosoite ja kunta. Se palauttaa sitten listamuodossa kadut ja ko. postinumerot. Oletuksena esim Helsinginkatu Helsingistä palauttaa:

['Helsinginkatu', '56', '58', '00260', 'HELSINKI', 'Helsinki']
['Helsinginkatu', '1', '19', '00500', 'HELSINKI', 'Helsinki']
['Helsinginkatu', '2', '16', '00500', 'HELSINKI', 'Helsinki']
['Helsinginkatu', '21', '25', '00510', 'HELSINKI', 'Helsinki']
['Helsinginkatu', '18', '50', '00530', 'HELSINKI', 'Helsinki']

Jossa ensin katu, sitten katunumeroiden ala- ja yläarvot (jos on, muuten tyhjää), postinumero, postitoimipaikka ja kunta.

Seuraavaksi pitää kehitellä suodatus katunumeroiden perusteella, niin saa listaa lyhyemmäksi. Jos katuosoitteen numerokin on annettu, niin periaatteessahan ei pitäisi tulla kuin yksi postinumero.

Main-funktiossa oleva pääohjelma kyselee tietoja, ja jos laittaa pelkän katuosoitteen, niin kuntana on Helsinki. Pelkän katuosoitteen syöttämällä lopetetaan.

Koodista sitten pitää korvata "--->" neljällä välilyönnillä " ", koska tämä foorumi sotkee sisennykset.

Käytin Python 3:sta ja lisäksi pitää asentaa BeautifilSoup esim. komennolla:

sudo apt-get install python3-bs4

# koodi alkaa

from bs4 import BeautifulSoup
import requests
from urllib.request import urlopen
from requests.utils import quote

def haePostinumero(osoite="helsinginkatu",kunta="helsinki"):

--->url="http://www.verkkoposti.com/e3/"\
--->---> "postinumeroluettelo?streetname="\
--->---> quote(osoite.encode('ISO-8859-1'))\
--->---> "&postcodeorcommune="\
--->---> quote(kunta.encode('ISO-8859-1'))

--->html=urlopen(url).read().decode("ISO-8859-1")

--->lista=[]

--->if html.find("Postinumerohaun tulos") > 0:
--->--->soup=BeautifulSoup(html,"lxml")
--->--->table = soup.find(class_="hidden-xs")
--->--->kadut=table.find_all("td")
--->--->for katu in range(0,len(kadut),4):
--->--->--->rivi=[]
--->--->--->katunimi=""
--->--->--->katunro1=""
--->--->--->katunro2=""
--->--->--->postinro=""
--->--->--->toimipaikka=""
--->--->--->kunta=""
--->--->--->katun=kadut[katu].find_all("div")
--->--->--->if len(katun) > 0:
--->--->--->--->if len(katun) > 1:
--->--->--->--->--->katul=katun[1].string.strip().split(' ')
--->--->--->--->else:
--->--->--->--->--->katul=katun[0].string.strip().split(' ')
--->--->--->--->if len(katul) == 1:
--->--->--->--->--->katunimi=katul[0].strip()
--->--->--->--->if len(katul) == 2 or len(katul) == 4:
--->--->--->--->--->katunimi=katul[0].strip()
--->--->--->--->--->katunro1=katul[1].strip()
--->--->--->--->if len(katul) == 4:
--->--->--->--->--->katunro2=katul[3].strip()
--->--->--->toimip=kadut[katu 2].string.strip().split('\n')
--->--->--->postinro=toimip[0].strip()
--->--->--->toimipaikka=toimip[2].strip()
--->--->--->kunta=kadut[katu 3].string.strip()
--->--->
--->--->--->rivi.append(katunimi)
--->--->--->rivi.append(katunro1)
--->--->--->rivi.append(katunro2)
--->--->--->rivi.append(postinro)
--->--->--->rivi.append(toimipaikka)
--->--->--->rivi.append(kunta)
--->--->--->lista.append(rivi)

--->return lista

def main():
--->while True:--->--->
--->--->postinumerot=[]
--->--->kyskatu=input("Katuosoite: ")
--->--->kyskunta=input("Kunta: ")
--->--->if len(kyskatu)>0 and len(kyskunta)>0:
--->--->--->postinumerot=haePostinumero(kyskatu,kyskunta)
--->--->elif len(kyskatu)==0 and len(kyskunta)>0:
--->--->--->break
--->--->elif len(kyskatu)>0 and len(kyskunta)==0:
--->--->--->postinumerot=haePostinumero(osoite=kyskatu)
--->--->else:
--->--->--->postinumerot=haePostinumero()

--->--->for postinumero in postinumerot:
--->--->--->print(postinumero)


if __name__ == "__main__":
--->main()
--->

12

1210

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Koodi-tuonne-vaivatonta

      Aivan just, tää sivusto on erittäin huono silloin kun pitää välittää toiselle ohjelmakoodia. Python jos mikä on vielä erittäin tarkka syntaksistaan. Sinun kannattaa tehdä tili tuonne http://pastebin.com sivulle, joka on juuri tätä varten.

      Sinne kun koodidisi laitat, ja vielä valitset sieltä sen python kohdan, niin jopa on helppo ja nopea toisen testata.

      Linux Mint 18 Sarah
      Xfce 64-bit

      • soppakokeilu

        Kiitos vinkistä, otin käyttöön tuon Pastebinin. Ensimmäinen kokeilu:

        http://pastebin.com/tFfGPZGd

        Tein toisen funktion "postiNroToimipaikka()", joka hyödyntää aikaisempaa webistä tiedot hakeavaa "haePostinumero()"-funktiota. Se palauttaa nyt hakua vastaavan merkkijonon muodossa "postinro postitoimipaikka". Lisäksi on yksi apufunktio "suodataOsoite()", jolla suodatetaan katuosoitteesta pois mahdolliset rappujen kirjaimet ja huoneistojen numerot, koska postin haku ei niitä aina ymmärrä.

        Esim:
        suodataOsoite("Jokuosoite 1 A 2")
        palauttaa: "Jokuosoite 1".

        Oletuksena kunta on Helsinki, esim:

        osoite=suodataOsoite("Mannerheimintie 15")
        lista=haePostinumero(osoite=osoite)
        print(postiNroToimipaikka(osoite=osoite,lista=lista))

        tulostaa: 00260 HELSINKI

        Jos kunta on toinen, niin esim:

        osoite=suodataOsoite("Saapastie 2")
        kunta="Pirkkala"
        lista=haePostinumero(osoite,kunta)
        print(postiNroToimipaikka(osoite,kunta,lista))

        tulostaa: 33950 PIRKKALA


    • Ahkera-koodari-oot

      Kirjoitatko Windows ympäristössä, koska rivien

      109. kyskatu=input("Katuosoite: ")
      110. kyskunta=input("Kunta: ")

      input() funktio ottaa vastaan luku muotoista tietoa ja minä jouduin tuo muuttamaan muotoon:

      109. kyskatu=raw_input("Katuosoite: ")
      110. kyskunta=raw_input("Kunta: ")

      koska raw_input() funktio ottaa vastaan merkkijonoja.

      Lisäksi tuo suodin on niin tehokas että lähes aina tulee osoitteen sijasta

      "Useampi kuin yksi vaihtoehto"

      Saattaa olla että tuon tekstin sijaan kuuluusi tulla

      "Haku ei tuottanut tulosta"

      Linux Mint 18 Sarah
      Xfce 64-bit

      • Unohtu-tuo-kuva

      • soppakokeilu

        Käyttelen siis Python 3 -versiota, jossa ei ymmärtääkseni ole enää tuota raw_input()-funktiota lainkaan, vaan pelkkä input(). Lisäksi esim. print on korvauttu funktiolla print(). Linuxilla teen ja Idlellä.

        Haku "kemi" ja "kemi" palauttaa vain sen sanoman "Useampi kuin yksi vaihtoehto". Se johtuu siitä, että silloin Postin palvelu palauttaa liikaa arvoja, eli samalle haulle ei ole yksittäistä tulosta. Tuonhan se siis käytännössä tekee:

        https://www.verkkoposti.com/e3/postinumeroluettelo?streetname=kemi&postcodeorcommune=kemi

        Näyttäisi sinulla menevän merkistökoodaus väärin. Kopioin äsken pastebinistä ja kokeilin, niin minulla toimii silti aivan kuten pitääkin, eli pastebin ei ainakaan ole syyllinen.

        Auttaakohan jos laittaa ensimmäiseksi riviksi koodiin?

        # -*- coding: utf-8 -*-


      • Toimiiko-sulla
        soppakokeilu kirjoitti:

        Käyttelen siis Python 3 -versiota, jossa ei ymmärtääkseni ole enää tuota raw_input()-funktiota lainkaan, vaan pelkkä input(). Lisäksi esim. print on korvauttu funktiolla print(). Linuxilla teen ja Idlellä.

        Haku "kemi" ja "kemi" palauttaa vain sen sanoman "Useampi kuin yksi vaihtoehto". Se johtuu siitä, että silloin Postin palvelu palauttaa liikaa arvoja, eli samalle haulle ei ole yksittäistä tulosta. Tuonhan se siis käytännössä tekee:

        https://www.verkkoposti.com/e3/postinumeroluettelo?streetname=kemi&postcodeorcommune=kemi

        Näyttäisi sinulla menevän merkistökoodaus väärin. Kopioin äsken pastebinistä ja kokeilin, niin minulla toimii silti aivan kuten pitääkin, eli pastebin ei ainakaan ole syyllinen.

        Auttaakohan jos laittaa ensimmäiseksi riviksi koodiin?

        # -*- coding: utf-8 -*-

        Virhettä pukkaa
        https://vimeo.com/196116290

        Mitä se sinulla antaa näillä tiedoilla
        Kemilänkatu
        KEMI


        Linux Mint 18 Sarah
        Xfce 64-bit


      • soppakokeilu
        Toimiiko-sulla kirjoitti:

        Virhettä pukkaa
        https://vimeo.com/196116290

        Mitä se sinulla antaa näillä tiedoilla
        Kemilänkatu
        KEMI


        Linux Mint 18 Sarah
        Xfce 64-bit

        Toimii minulla niin kuin ajattelinkin:

        Katuosoite: Kemilänkatu
        Kunta: KEMI
        94200 KEMI

        Käyttelit ilmeisesti 2.x versiota? Siinä kuuluu olevan jotain ongelmia quote():n kanssa.

        http://stackoverflow.com/questions/1695183/how-to-percent-encode-url-parameters-in-python

        Minä käytin requests-moduulin quotea. Toimiiko jos vaihdat sen urllib:n vastaavaan? Eli korvaat tuon requests.utils-rivin tuolla urllib.request-versiolla. Minulla toimii silläkin.

        #from requests.utils import quote
        from urllib.request import quote


      • Anonyymi
        soppakokeilu kirjoitti:

        Käyttelen siis Python 3 -versiota, jossa ei ymmärtääkseni ole enää tuota raw_input()-funktiota lainkaan, vaan pelkkä input(). Lisäksi esim. print on korvauttu funktiolla print(). Linuxilla teen ja Idlellä.

        Haku "kemi" ja "kemi" palauttaa vain sen sanoman "Useampi kuin yksi vaihtoehto". Se johtuu siitä, että silloin Postin palvelu palauttaa liikaa arvoja, eli samalle haulle ei ole yksittäistä tulosta. Tuonhan se siis käytännössä tekee:

        https://www.verkkoposti.com/e3/postinumeroluettelo?streetname=kemi&postcodeorcommune=kemi

        Näyttäisi sinulla menevän merkistökoodaus väärin. Kopioin äsken pastebinistä ja kokeilin, niin minulla toimii silti aivan kuten pitääkin, eli pastebin ei ainakaan ole syyllinen.

        Auttaakohan jos laittaa ensimmäiseksi riviksi koodiin?

        # -*- coding: utf-8 -*-

        Harvinaisen typerä tuo postin palvelu, kun ei palauta jsonia.


    • Varmistan-vain

      Kirjotappa järjestelmän Dash Shellissä komento:

      python -V

      mitä se pukkaa sulla (mulla Python 2.7.12)


      Linux Mint 18 Sarah
      Xfce 64-bit

      • soppakokeilu

        Kakkosversio:

        python -V
        Python 2.7.12

        Kolmosversio:

        python3 -V
        Python 3.5.2


      • Thanks-are-in-order

        NYT TOIMII

        Pistin samanlaisen ympäristön pystyyn, eikös vaan heti ruvennut pelittämään. No nyt tuosta sitten rupean kaivelemaan, itelleni jotain opiksi. Sinähän olet parempi kuin hyvä pythonin kanssa.

        Nyt kun teet vielä tilin tuonne http://pastebin.com sivulle, niin jatkossakin pääsen sinun koodeja kopioimaan. Tilinteko tuonne ei vaadi mitään aitoja tietoja, ja voi sitten muokatakin jos johonkin pääsi TYPO mukaan.

        Thanks are in order. (Kiitokset ovat paikallaan)


        Linux Mint 18 Sarah
        Xfce 64-bit


      • soppakokeilu
        Thanks-are-in-order kirjoitti:

        NYT TOIMII

        Pistin samanlaisen ympäristön pystyyn, eikös vaan heti ruvennut pelittämään. No nyt tuosta sitten rupean kaivelemaan, itelleni jotain opiksi. Sinähän olet parempi kuin hyvä pythonin kanssa.

        Nyt kun teet vielä tilin tuonne http://pastebin.com sivulle, niin jatkossakin pääsen sinun koodeja kopioimaan. Tilinteko tuonne ei vaadi mitään aitoja tietoja, ja voi sitten muokatakin jos johonkin pääsi TYPO mukaan.

        Thanks are in order. (Kiitokset ovat paikallaan)


        Linux Mint 18 Sarah
        Xfce 64-bit

        Hyvä että sait pelaamaan. Aikamoista kantapään kautta opetteluahan tämä tahtoo välillä olla. Onneksi löytyy hakemalla suhteellisen helposti ratkaisumalleja ongelmiin.

        Eniten olen Pythonin opettelun alkuvaiheessa törmännyt juuri näihin yhteensopivuusongelmiin kakkos- ja kolmosversion kanssa. Itse lähdin siis suoraan tekemään tuolla kolmosella. Lisäksi on ollut aika kiitettävästi säätämistä merkistökoodauksien kanssa.

        No jospa se tästä vähän kerrallaan etenisi. Seuraavaksi voisi alkaa opettelemaan graafisen käyttöliittymän tekemistä, Tkinter olisi ilmeisesti silloin aiheena.


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

    Luetuimmat keskustelut

    1. Kiva kun SDP alkaa hallitsemaan Suomea

      Vanhat hyvät ajat taas palaavat ja kansa vaurastuu. Muistatteko vielä Sorsan aikakauden? Silloin Suomessa tehtiin jopa
      Maailman menoa
      275
      7440
    2. Säästäminen on typerää, muistakaa äänestää demareita

      Säästäminen on typerää, koska aiheuttaa vain talouden taantumista ja lopulta tappaa potilaan. Demareiden tapa on satsat
      Maailman menoa
      64
      4149
    3. Olli Rehn: Eläkkeistä pitää leikata. Nyt tuli Lindtmanille kauhun paikka

      jos johtaa seuraavaa hallitusta. Purra: eläkkeisiin ei kosketa. Eikä tällä hallituskaudella varmasti kosketa, mutta seur
      Maailman menoa
      276
      3480
    4. SDP:n budjetin peruskivi: "Rahaa nimittäin on!"

      Demarien talouspolitiikan ydin on usein tiivistetty klassiseen meemiin: rahaa on, kunhan se on jonkun muun rahaa. Vuoden
      Maailman menoa
      52
      2179
    5. Sara Sieppi umpirehellisenä Amazing Race -kulissien takaisesta elämästä

      Sara Sieppi oli mukana Amazing Race Suomi -realityssä. Somevaikuttajalla oli takana raskasta aikaa ja isoja suruja, eikä
      Suomalaiset julkkikset
      1
      1647
    6. Herkkua vai hötöä? Kaksi Beck-leffaa tällä vkolla tv:stä

      Beck-elokuvat tuntuvat olevan suomalaisten makuun. Tällä viikolla televisiosta tulee kaksi ruotsalaista taidonnäytettä,
      Elokuva
      3
      1352
    7. Hatunnosto! Mari Hynynen (os. Perankoski) ja Jouni Hynynen auttavat vähäosaisia upealla tavalla!

      Hatunnosto! Mari ja Jouni Hynynen ovat Vailla vakinaista asuntoa ry:n uudet kummit. Hynysiä motivoi halu lisätä ymmärr
      Maailman menoa
      5
      1207
    8. Ajattelin silloin

      että jos olet kiinnostunut, ihan oikeasti, niin kuulen sinusta vielä.
      Ikävä
      105
      1181
    9. TTP avajaiset

      Tuhannen Taalan Paikka avautuu 1.3-26. Onpa tosi mukavaa! Kiitos Jaanalle kun olet niin aktiivinen ja jaksat yrittää ja
      Haapavesi
      40
      1112
    10. Tiesitkö? Tämä suomalainen keksi Elämäni biisi -sarjan - Viinin lipittely mainittu!

      Tiesitkö? Elämäni biisi on suomalainen formaatti ja sen takana on Petja Peltomaa. Hänen kynästä ovat lähtöisin myös mm.
      Tv-sarjat
      0
      1091
    Aihe