西儿马 | 我这样入手学习Python

为什么要学Python

对我来说学习Python完全是一种偶然,就职在杭州,因为工作的缘故,经常会关注浙江省内的高速公路路况信息。
当然,现在这种路况事件信息可以很轻松的随时查询到,渠道也挺多,电话、网站、APP、微信等等。但我的需求比较特别。
首先,目前已有的查询渠道基本上都是定向查询,需要用户先指定要查询的路名,然后它会把这条高速的路况信息一条一条的列出来。但我希望是页面一打开,就告诉我全部的路况事件信息。
然后,不要无关紧要的信息。比如今天几点到几点,哪里到哪里有施工。这种信息其实很无聊。开车上高速前,你会因为这么个施工信息而考虑改变今天的行程么?
最后,总结合自己的需求,我关注是应该是拥堵、缓行、排队、及交通管制等等这些路况信息。

为什么选择了Python

找来找去,没找到符合我需求的,所以想着就只有自己动手了。目标是一个简单的网页,专门用来实现以上两个需求。
交待一下自己的背景,交通工程专业,2000年毕业,大学里学过C和Foxpro,这是仅有的一点编程实践。
本来应该交待一下选Python的前因后果,可是写不出来,因为根本就没有原因,也许只是因为看着Python这个单词比较顺眼吧。现在看看上边的三个需求,似乎很简单,但对于我来说,过程其实相当折腾,毕竟有毛20年没写过哪怕一行的代码,一切几乎都是从零开始。虽然全程碰到的问题用搜索引擎都解决了,但反反复复在所难免。记忆最深刻的是编码问题,一度想放弃算了,搁置了将近三个星期,还是不甘心,又硬着头皮到处寻找问题原因,总算解决了。可是总结下来,Python确实让我非常惊喜。

大致的步骤

如下:
一、先写个爬虫,每5分钟去指定网站把高速公路路况事件信息抓下来。
二、把满足前提条件的事件信息保存下来。
三、展示。

简单的成果

最后的成果是一个非常简单的网页:
六耳高速网
为什么要在高速前面加62这个数字呢?因为在杭州话里, 62这个数字有着相当的含义,表示的是呆子、傻的意思,所以就是想表达不用动脑筋,打开就能用的意思。
程序部署在新浪的SAE,没有用数据库,用Memcached保存事件信息,反正每5分钟更新,也没作长期保存的打算。在手机上打开的效果是这样的:

六耳高速网

原代码

贴上原代码,因为没有系统性的学习过,纯粹为了解决自己的特定需求而现查现改现写,莫名其妙之处,请一笑了之。为减少不必要的麻烦,将爬虫目标网址用星号代替了去。

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="六耳高速网实时发布浙江高速公路路况,为开车上高速的车友提供最简单的高速路况与高速出行信息服务。">
        </head>
        <body>
            %s<br>
        </body>
        <footer>浙ICP备16003482号`</footer>
    </html>
    '''
    
    #如果访问的地址中含有spider,则判断是cron计划任务,执行zhgsspider
    if "index.wsgi" in Request(environ).url:
        gsspider()
    
    #否则认为是用户在浏览器端发起的访问,输出结果
    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去周期性调用,然后把路况信息保存下来,却发现根本就执行不了,后来才发现,在SAE部署的python程序,都要通过wsgi去执行。所以只好把程序一骨脑儿的都写在index.wsgi文件里了,通过调用时带不带index.wsgi来判断是计划任务还是用户访问。说实话,low是low了点儿,但好歹能用了。

写在后面

然后经常在网上看到诸如“我多少多少岁了,现在学编程会不会太晚?”,还有“我应该怎么入手学习Python?”之类的问题,好像有句话大意是说,学编程最好的时间是十年前,其次是现在。我是几个月前开始学Python的,38岁的生日过了都半年多了。所以,不用问晚不晚的问题,有这问的功夫,直接用来学多好。
对于怎样入手学的问题,我觉得最好是从解决自己学习、工作、甚至生活上的实际问题着手,不要为了学而学,要为了用而学,随用随学,这样才能最快的见效。而见效,是继续坚持学习最好的动力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容