之前做了一个天气预报签名档,实际上只是显示了即时天气,这两天终于晴朗起来了(或者说,至少不下雨了),于是心情好更新了一下,顺便从 Yahoo Weather 上把未来五天的天气情况也抓下来放到图片里。总算对得起天气预报这个词了。
效果如右图所示。代码没有什么大的变化,只是实验室网络不知道为什么最近奇慢无比,由于新版本现在要下载不少图标,所以我加了本地缓存。缓存的办法很简单,就是把图标保存到一个本地文件中,要找出 URL 和本地文件的对应关系最简单的办法就是用 URL 作为本地文件名,不过通常 URL 并不是一个合法的文件名,因此,为了避免冲突,平时大家用得最多的办法就是对 URL 取一个 hash digest (比如,用 MD5 或者 SHA-1 之类的)来得到文件名。这个在 Python 中也是很容易的事,因为相关的库已经可以直接拿来用了。
不过细节的代码我就不介绍了,直接把整个代码贴上来好了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #!/usr/bin/python from __future__ import with_statement import urllib2 import re import time import os import hashlib from os import path from PIL import Image, ImageDraw, ImageFont degree = None icon = None background = Image.open('bg.png') background_nt = Image.open('bg_night.png') font = ImageFont.truetype('font.ttf', 24) font_small = ImageFont.truetype('font.ttf', 10) pat_degree = re.compile(r'<h3>(\d+)&(?:#176|deg);</h3>') pat_icon = re.compile('class="forecast-icon" style="background:url\\(\'' + '([^\']+)\'\\);') pat_night = re.compile(r'<div id="yw-forecast" class="night">') pat_forecast = re.compile(r'<tr class="fiveday-icons">(.*?)</tr>', re.DOTALL) pat_forecast_icon = re.compile("image:url\\('([^']+)'\\);") cache_dir = 'cache' if not path.exists(cache_dir): os.makedirs(cache_dir) def get_icon(url): digest = hashlib.sha1(url).hexdigest() fn = path.join(cache_dir, digest) if not path.exists(fn): with open(fn, 'wb') as ous: ous.write(urllib2.urlopen(url).read()) return Image.open(fn) while True: page = urllib2.urlopen('http://weather.yahoo.com/forecast/' + \ 'CHXX0044_c.html').read() degree = pat_degree.search(page).group(1) icon_url = pat_icon.search(page).group(1) icon = get_icon(icon_url) img = Image.new('RGBA', (240, 155)) if pat_night.search(page): img.paste(background_nt, (40, 46), background_nt) else: img.paste(background, (40, 46), background) img.paste(icon, (5, 5), icon) draw = ImageDraw.Draw(img) draw.text((180, 53), '%-2sC'%degree, font=font) draw.text((203, 53), 'o', font=font_small) del draw # the weather for the next 5 days forecast = pat_forecast.search(page).group(1) forecast_icon_urls = pat_forecast_icon.findall(forecast) xpos = 2; xpos_inc = 47 for forecast_icon in [get_icon(url) for url in forecast_icon_urls]: img.paste(forecast_icon, (xpos, 120), forecast_icon) xpos += xpos_inc img.save('weather.png', 'PNG') print '%s deg. [%s]' % (degree, time.ctime(time.time())) time.sleep(10*60) |
不过,天气预报始终是不能完全信任的,在杭州这种地方,还是建议出行随身带伞。这一点上 binghe 同学算是典范了! 🙂
很强大,呵呵
改过了几个正则表达式: