Opettelin WWW-ohjelmointia itsekseni Pythonilla, mutta en keksinyt, miten voin tarkistaa sen, että kone saa yhteyden sivustolle. Miten tämä ohjelma korjataan siten, että se ei kaadu jos verkkopiuha ei ole koneessa? Ja tarvitaanko muita tarkistuksia?
import sys import time import urllib3 # Gets the weather from foreca.fi. def get_weather(url): http = urllib3.PoolManager() try: r = http.request('GET', url) except http.gaierror: print("Palvelimelle ei saatu yhteyttä!") sys.exit() return (r.data) time = time.strftime("%Y%m%d") url = "http://www.foreca.fi/Finland/Kuopio/Saaristokaupunki/details/" + time weather_all = get_weather(url) counter = 0 temp = list() klo = list() for i in range(0,len(weather_all)): if weather_all[i:i + len("csuntime")] == b"csuntime": if counter == 0: print("Aurinko nousee klo {sunrise}.".format(sunrise = str(weather_all[i+18:i+23])[2:7])) elif counter == 1: print("Aurinko laskee klo {sunset}.".format(sunset = str(weather_all[i+18:i+23])[2:7])) counter += 1 if weather_all[i:i+len("warm")] == b"warm": temp.append(str(weather_all[i + 14:i + 35])[2:4]) if weather_all[i:i+len("c0")] == b"c0": klo.append(str(weather_all[i + 13:i + 18])) for i in range(2,len(temp)): print("{klo} {temp} astetta.".format(klo = str((klo[i])[2:7]),temp = temp[i]))
Selvisi.
# Gets the weather from foreca.fi. def get_weather(url): http = urllib3.PoolManager() try: r = http.request('GET', url) except urllib3.exceptions.MaxRetryError: print("Palvelimeen ei saatu yhteyttä!") sys.exit() return r.data
Muoks.
No, nyt nuo lämpötilat tulee parsittua toisella tavalla.
import sys import time import urllib3 # Gets the weather from foreca.fi. def get_weather(url): http = urllib3.PoolManager() try: r = http.request('GET', url) except http.gaierror: print("Palvelimelle ei saatu yhteyttä!") sys.exit() return ((r.data).decode()) pvm = time.strftime("%Y%m%d") url = "http://www.foreca.fi/Finland/Kuopio/Saaristokaupunki/details/" + pvm weather_all = get_weather(url) counter = 0 temperature = list() klo = list() print("Sää Saaristokaupungissa " + str(time.strftime("%d.%m.%Y")) + " alkaen.") for i in range(0,len(weather_all)): # Haetaan ensiksi auringon nousu- ja laskuaika. if weather_all[i:i + len("csuntime")] == "csuntime": if counter == 0: print("Aurinko nousee klo {sunrise}.".format(sunrise = str(weather_all[i+18:i+23])[0:7])) elif counter == 1: print("Aurinko laskee klo {sunset}.".format(sunset = str(weather_all[i+18:i+23])[0:7])) counter += 1 # Haetaan sitten aika ja lämpötila kulkemalla c4-tagista edelliseen ja seuraavaan strong-tagiin. elif weather_all[i:i + len('<div class="c4">')] == '<div class="c4">': how_much_back = 0 while weather_all[i + how_much_back:i + how_much_back + len('strong')] != 'strong': how_much_back -= 1 strongstart = i + how_much_back if str(weather_all[strongstart - 7:strongstart - 2])[0:1]!="0": klo.append(str(weather_all[strongstart - 7:strongstart - 2])[0:7]) else: klo.append(str(weather_all[strongstart - 7:strongstart - 2])[1:7]) how_much_back += 1 while weather_all[i + how_much_back:i + how_much_back + len('strong')] != 'strong': how_much_back += 1 l = i + how_much_back + 1 lstart = l lend = l while weather_all[l:l + 1] != "&": if weather_all[l:l + 1] != ">": lend = l l += 1 temperature.append(weather_all[lstart + 6:lend + 1]) for i in range(0,len(temperature)): print(klo[i] + ": " + temperature[i])
Hyvä. Muita keinoja tietojen poimimiseen nettisivulta on säännöllisten lausekkeiden (re-moduuli) tai jonkin xhtml-parserin käyttäminen. Viimeksi mainittua pidetään yleensä oikeaoppisimpana tapana. Mikään näistä ei kuitenkaan ole täysin immuuni nettisivun rakenteen muuttumiselle ja jokaisella tavalla on omat heikkoutensa.
Meinasin ensin moittia epämääräisen temp-muuttujan (temporary) käytöstä, mutta se olikin kuvaava lyhennys temperaturesta, heh. No "klo" on sentään eri kielellä kuin muut muuttujanimet.
Oikeastaan tuokin on vähän huonosti tehty parseri, kun tuo warm voi olla välillä cold. Tein sen uudestaan etsimällä tagit "<div class="c4">", josta kellonaika ja lämpötilat saadaan lukemalla edellisen ja seuraavan strong-tagin sisältö. Totta, pitäisi nimetä muuttujat yhtenäisella tavalla ja tutustua parsereihin. Tuo klo jäi nyt sinne, kun käytin timeä päivämäärän hakuun. En keksinyt järkevää englanninkielistä synonyymiä ajalle.
Tässä regexp-version parsinta ja tulostus. Nettisivun lähdekoodi on muuttujassa s.
degs = re.findall(r'<strong>([^<>]+)°</strong></span>', s) times = re.findall(r'<div class="c0"> <strong>([^<>]+)</strong></div>', s) sun_times = re.findall(r'<div class="csuntime"><strong>([^<>]+)</strong>', s) sun_actions = zip(('nousee', 'laskee'), sun_times) for action, time in sun_actions: print("Aurinko {action} klo {time}.".format(action=action, time=time)) for time, degs in zip(times, degs): print("{time}: {degs}".format(time=time, degs=degs))
Aihe on jo aika vanha, joten et voi enää vastata siihen.