soulless Skrevet 25. februar 2013 Del Skrevet 25. februar 2013 Har gjort det til et mål å gjenopplive programmeringskunnskaper, og startet med Python gjennom codecademy + the hard way for 3-4 uker siden. Som en del av dette gjør jeg et lite læringsprosjekt prosjekt hvor jeg forsøker å hente ut værinfo via yr.no. Dette er første del av koden, men allerede får jeg en feil som jeg mistenker er relatert til æøå i xml koden. #-*- coding: utf-8 -*- from urllib2 import urlopen from xml.dom import minidom url = "http://www.yr.no/sted/Norge/Rogaland/Stavanger/Stavanger/varsel.xml" response = urlopen(url).read() weather = minidom.parseString(response) meldinger = weather.getElementsByTagName('title') f = open("vaermelding.txt","w") for melding in meldinger: f.write(melding.firstChild.nodeValue + "\n") f.close() Feilen jeg får i (windows) terminal er: Traceback (most recent call last): File "C:\temp\yr_api.py", line 17, in <module> f.write(melding.firstChild.nodeValue + "\n") UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 11: ordinal not in range(128) Jeg har og forsøkt å bare printe ut i konsollet, men får liknende feilmelding. Bruker Notepad++, win7 og har encodet som UTF-8 Hva er det jeg gjør feil, og hvordan kan jeg fikse det? BTW: output i filen er: mandag og tirsdag onsdag torsdag Den stopper altså på linjen som burde skrevet ut "fredag og lørdag". Lenke til kommentar
Lycantrophe Skrevet 25. februar 2013 Del Skrevet 25. februar 2013 (endret) Python2? Python2s unicode er latterlig broken (strings og unicode strings er forskjellige typer). Jeg ville sett på hvordan parseString fungerer og om du kan tvinge den til å lese unicode. Prøv dette: minidom.parseString( response.encode("utf-8") ) Endret 25. februar 2013 av Lycantrophe 1 Lenke til kommentar
soulless Skrevet 25. februar 2013 Forfatter Del Skrevet 25. februar 2013 2.7 :S, oh well, får vel kanskje prøve en av de andre modulene for XML parsing. Noen anbefalinger? Lenke til kommentar
Lycantrophe Skrevet 25. februar 2013 Del Skrevet 25. februar 2013 (endret) Funket ikke linjen jeg postet? Nei, aldri parset xml med python. Jeg har jobbet litt med å lese json (fra disk) som leser inn som unicode og måtte forandres til interne string-objekter. Ble en småsølete loop, det. Endret 25. februar 2013 av Lycantrophe Lenke til kommentar
FraXinuS Skrevet 25. februar 2013 Del Skrevet 25. februar 2013 Problemet her er at du kan ikke skrive en unicode string direkte til en fil åpnet med "open". Du må enten encode stringen manuelt før du skriver eller du kan bruke "codecs.open" f.write(melding.firstChild.nodeValue.encode('utf-8') + "\n") Eller bruk codecs modulen når du åpner filen, da kan du bruke unicode strings i f.write: import codecs f = codecs.open("vaermelding.txt","w", "utf-8") Du kan bruke den encodingen du vil, utf-8 her er bare et eksempel. 2 Lenke til kommentar
snippsat Skrevet 26. februar 2013 Del Skrevet 26. februar 2013 (endret) :S, oh well, får vel kanskje prøve en av de andre modulene for XML parsing. Noen anbefalinger? BeautifulSoup og lxml er begge veldig bra,jeg har brukt begge en god del,mest BeautifulSoup. Bruke noe annen er ikke aktuelt,begge kan lese søppel(xml/html) dette er viktig når det kommer til html,hvor søppel faktoren er stor. You didn't write that awful page. You're just trying to get some data out of it. Beautiful Soup is here to help Løsninger som er postet over virker viss du prøver dem. Her en med BeautifulSoup. from bs4 import BeautifulSoup from urllib2 import urlopen url = urlopen('http://www.yr.no/sted/Norge/Rogaland/Stavanger/Stavanger/varsel.xml') soup = BeautifulSoup(url, 'xml') tag = soup.find_all('title') weather = ', '.join(i.text for i in tag) print weather #mandag og tirsdag, onsdag, torsdag, fredag og lørdag, søndag til onsdag with open('vaermelding.txt', 'w') as f_out: for item in tag: f_out.write(item.text.encode('utf8') + '\n') Endret 26. februar 2013 av SNIPPSAT 1 Lenke til kommentar
soulless Skrevet 26. februar 2013 Forfatter Del Skrevet 26. februar 2013 Takk for alle svar! Lycanthrope: Nei, det virket heller ikke, jeg tror minidom modulen ikke helt støtter dette, og dropper nok denne. FraXinuS: Takk for denne, men det som skjer er at 1. output hopper over æøå og 2. linjeskift fungerer ikke lenger. Jeg tror problemene kan være relatert til det samme som jeg bemerket til Lycanthrope. SNIPPSAT: bs og lxml virker myyye bedre (btw: for å kunne printe weather måtte jeg legge til .encode('utf-8')). Takk Da fortsetter jeg det lille "prosjektet" mitt, tusen takk for god hjelp så langt! Lenke til kommentar
FraXinuS Skrevet 26. februar 2013 Del Skrevet 26. februar 2013 Jeg ser nå at codecs modulen automatisk åpner filen i binary mode så da blir ikke linjeskift fikset automatisk for windows. For å få linjeskift på windows med codecs modulen må du bruke "\r\n". Eller du kan bare bruke den vanlige open() funksjonen og encode manuelt: "f.write(melding.firstChild.nodeValue.encode('utf-8') + "\n")" Hvis ikke æøå vises korrekt når du åpner filen etterpå, må du passe på at editoren leser med utf-8 encoding. Problemet ditt her har ikke noe med xml parsingen å gjøre, men minidom er litt knotete. Jeg bruker vanligvis xml.etree.ElementTree som er inkludert i python. #-*- coding: utf-8 -*- from urllib2 import urlopen from xml.etree import ElementTree url = "http://www.yr.no/sted/Norge/Rogaland/Stavanger/Stavanger/varsel.xml" response = urlopen(url).read() tree = ElementTree.fromstring(response) titles = tree.findall('forecast/text/location/time/title') with open('vaermelding.txt', 'w') as f_out: for item in titles: f_out.write(item.text.encode('utf8') + '\n') 2 Lenke til kommentar
soulless Skrevet 26. februar 2013 Forfatter Del Skrevet 26. februar 2013 Takk for gode råd så langt! Inntil videre har jeg denne fungerende koden som lager en nettside som viser været: #-*- coding: utf-8 -*- from bs4 import BeautifulSoup from urllib2 import urlopen cache = open('yrstvg_cached.xml', "r") #åpner en cachet versjon av yr.no xml soup = BeautifulSoup(cache, 'xml') #parser XML fra siden title_tag = soup.find_all('title') #lager en liste over dager body_tag = soup.find_all('body') #lager en liste over værvarsel def clean_list(a_list): #fjerner xml markup b_list = [] for x in a_list: b_list.append(x.string.encode("utf-8")) return b_list with open('vaermelding.html', 'w') as f_out: #genererer html f_out.write("<HTML>" + '\n' + "<BODY>" +'\n') for x,y in zip(clean_list(title_tag),clean_list(body_tag)): f_out.write("<h2>" + x +"</h2>"+'\n'), f_out.write("<p>"+y+"</p>"+'\n' + '\n') f_out.write("</BODY>" + '\n' + "</HTML>") Problemet mitt er fremdeles relatert til æøå. Selv om koden nå kjører, kommer bokstavene ut slik som vist i skjermbildet under - hvordan kan dette ev. løses? Lenke til kommentar
Lycantrophe Skrevet 26. februar 2013 Del Skrevet 26. februar 2013 Sjekk hvilken encoding siden oppgir. Dette kan ligge i browseren din. 1 Lenke til kommentar
soulless Skrevet 26. februar 2013 Forfatter Del Skrevet 26. februar 2013 Sjekk hvilken encoding siden oppgir. Dette kan ligge i browseren din. Helt korrekt La til <head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /></head> og da funket det Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå