為什么要學Python
對我來說學習Python完全是一種偶然庶灿,就職在杭州纵搁,因為工作的緣故,經常會關注浙江省內的高速公路路況信息往踢。
當然腾誉,現(xiàn)在這種路況事件信息可以很輕松的隨時查詢到,渠道也挺多,電話妄辩、網站惑灵、APP山上、微信等等眼耀。但我的需求比較特別。
首先佩憾,目前已有的查詢渠道基本上都是定向查詢哮伟,需要用戶先指定要查詢的路名,然后它會把這條高速的路況信息一條一條的列出來妄帘。但我希望是頁面一打開楞黄,就告訴我全部的路況事件信息。
然后抡驼,不要無關緊要的信息鬼廓。比如今天幾點到幾點,哪里到哪里有施工致盟。這種信息其實很無聊碎税。開車上高速前,你會因為這么個施工信息而考慮改變今天的行程么馏锡?
最后雷蹂,總結合自己的需求,我關注是應該是擁堵杯道、緩行匪煌、排隊、及交通管制等等這些路況信息党巾。
為什么選擇了Python
找來找去萎庭,沒找到符合我需求的,所以想著就只有自己動手了齿拂。目標是一個簡單的網頁通贞,專門用來實現(xiàn)以上兩個需求。
交待一下自己的背景浙踢,交通工程專業(yè)瞎访,2000年畢業(yè),大學里學過C和Foxpro叹侄,這是僅有的一點編程實踐巩搏。
本來應該交待一下選Python的前因后果,可是寫不出來趾代,因為根本就沒有原因贯底,也許只是因為看著Python這個單詞比較順眼吧。現(xiàn)在看看上邊的三個需求,似乎很簡單禽捆,但對于我來說笙什,過程其實相當折騰,畢竟有毛20年沒寫過哪怕一行的代碼胚想,一切幾乎都是從零開始琐凭。雖然全程碰到的問題用搜索引擎都解決了,但反反復復在所難免浊服。記憶最深刻的是編碼問題统屈,一度想放棄算了,擱置了將近三個星期牙躺,還是不甘心愁憔,又硬著頭皮到處尋找問題原因,總算解決了孽拷《终疲可是總結下來,Python確實讓我非常驚喜脓恕。
大致的步驟
如下:
一膜宋、先寫個爬蟲,每5分鐘去指定網站把高速公路路況事件信息抓下來进肯。
二激蹲、把滿足前提條件的事件信息保存下來。
三江掩、展示学辱。
簡單的成果
最后的成果是一個非常簡單的網頁:
六耳高速網。
為什么要在高速前面加62這個數(shù)字呢环形?因為在杭州話里策泣, 62這個數(shù)字有著相當?shù)暮x,表示的是呆子抬吟、傻的意思萨咕,所以就是想表達不用動腦筋,打開就能用的意思火本。
程序部署在新浪的SAE危队,沒有用數(shù)據庫,用Memcached保存事件信息钙畔,反正每5分鐘更新茫陆,也沒作長期保存的打算。在手機上打開的效果是這樣的:
原代碼
貼上原代碼擎析,因為沒有系統(tǒng)性的學習過簿盅,純粹為了解決自己的特定需求而現(xiàn)查現(xiàn)改現(xiàn)寫,莫名其妙之處,請一笑了之桨醋。為減少不必要的麻煩棚瘟,將爬蟲目標網址用星號代替了去。
import sae, urllib, urllib2, json, pylibmc
from werkzeug.wrappers import Request
def gsspider():
url = '***'
#事件列表
causename = [u'緩行', u'緩慢', u'分流', u'排隊', u'管制', u'大流量']
#定義一個空的路況事件列表
LqTxtList = []
for roadid in range(1, 51): #高速公路編號
values = {"roadlineid" : str(roadid)}
request = urllib2.Request(url, urllib.urlencode(values))
html = urllib2.urlopen(request, timeout = 1).read()
html = json.loads(html)
data = html['data']
for i in range(len(data)):
reportout = data[i]['reportout']
for cause in range(len(causename)):
#路況事件信息內只有含有事件列表內的一個元素
#就將該條信息寫入路況事件列表內
if causename[cause] in reportout:
LqTxtList.append(reportout)
break
#按時間倒序喜最,然后輸出成路況事件信息字符串
LqInfoList = sorted(LqTxtList, reverse=True)
LqInfoTxt = ''
for i in range(len(LqInfoList)):
LqInfoTxt = LqInfoTxt + LqInfoList[i] + '<br><br>'
#如果文本長度小于5偎蘸,認為目前無異常路況
if len(LqInfoTxt) < 5:
LqInfoTxt = u'目前浙江省內高速公路通行正常。'
#初始化memcache
mc = pylibmc.Client()
#將符合條件的路況事件信息字符串存入memcache
mc.set('info', LqInfoTxt)
def app(environ, start_response):
#定義輸出樣式
htmlstyle = '''
<html>
<head>
<title>六耳高速網 | 浙江高速路況</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="浙江高速路況,杭州高速路況,浙江高速出行,杭州高速出行,高速公路路況,高速事故,高速事件,杭州繞城高速,杭金衢高速,杭寧高速,杭徽高速,滬杭高速,杭甬高速,上三高速,甬臺溫高速,諸永高速">
<meta name="description" content="六耳高速網實時發(fā)布浙江高速公路路況返顺,為開車上高速的車友提供最簡單的高速路況與高速出行信息服務禀苦。">
</head>
<body>
%s<br>
</body>
<footer>浙ICP備16003482號`</footer>
</html>
'''
#如果訪問的地址中含有spider蔓肯,則判斷是cron計劃任務遂鹊,執(zhí)行zhgsspider
if "index.wsgi" in Request(environ).url:
gsspider()
#否則認為是用戶在瀏覽器端發(fā)起的訪問,輸出結果
else:
mc = pylibmc.Client()
value = mc.get('info')
output = htmlstyle % value.encode('utf-8')
status = "200 OK"
response_headers = [
("Content-type", "text/html; charset = utf-8"),
("Content-Length", str(len(output)))
]
start_response(status, response_headers)
return [output]
application = sae.create_wsgi_app(app)
還有些問題
本來想把爬蟲部分另存成一個py文件蔗包,用SAE的計劃任務cron去周期性調用秉扑,然后把路況信息保存下來,卻發(fā)現(xiàn)根本就執(zhí)行不了调限,后來才發(fā)現(xiàn)舟陆,在SAE部署的python程序,都要通過wsgi去執(zhí)行耻矮。所以只好把程序一骨腦兒的都寫在index.wsgi文件里了秦躯,通過調用時帶不帶index.wsgi來判斷是計劃任務還是用戶訪問。說實話裆装,low是low了點兒踱承,但好歹能用了。
寫在后面
然后經常在網上看到諸如“我多少多少歲了哨免,現(xiàn)在學編程會不會太晚茎活?”,還有“我應該怎么入手學習Python琢唾?”之類的問題载荔,好像有句話大意是說,學編程最好的時間是十年前采桃,其次是現(xiàn)在懒熙。我是幾個月前開始學Python的,38歲的生日過了都半年多了普办。所以工扎,不用問晚不晚的問題,有這問的功夫泌豆,直接用來學多好定庵。
對于怎樣入手學的問題,我覺得最好是從解決自己學習、工作蔬浙、甚至生活上的實際問題著手猪落,不要為了學而學,要為了用而學畴博,隨用隨學笨忌,這樣才能最快的見效。而見效俱病,是繼續(xù)堅持學習最好的動力官疲。