成信钟楼定时微博报时的设计与实现
喜歡玩新浪微博的同學應該都知道最近有個叫“古城鐘樓”微博因為其一到整點就發條微博報時而爆紅網絡,網友都感嘆其是史上最無聊又最有毅力的微博。作為一個微博控的我,看著“古城鐘樓”和“big_ben_clock”這種機器人微博竟然也能火起來,就想自己也來玩玩,琢磨了下花了一天時間把它實現了,于是“成信鐘樓”整點報時微博就誕生了。目前“成信鐘樓”可以24小時整點報時,并上傳當前時間圖片和顯示鐘樓所在地圖位置,圍觀地址:http://weibo.com/CUITClock 。
網上說“古城鐘樓”的程序至少有3萬行,其中使用了AmazonEC2 和 MicrosoftAzure云服務, Redis, RabbitMQ, JSON, WebService,還專門做了個網站支持鐘樓的運行。“成信鐘樓”沒有用到這么多高深的技術,僅用了Python + SAE。本來是用的OpenShift的,但OpenShift 被墻,22端口經常連不上,所以還是放棄了。
Python是一門面向對象的編程語言。OpenShift是紅帽公司推出的,一個面向開源開發人員開放的平臺即服務(PaaS)。紅帽OpenShift提供比任何PaaS更多的靈活性,它支持用于Java、Python、PHP、Perl和Ruby的更多的開發框架,包括 Spring、Seam、Weld、CDI、Rails、Rack、Symfony、Zend Framework、Twisted、Django和Java E。它包含SQL和NoSQL數據存儲和一個分布式文件系統,很強大,作為免費云平臺空間確實很好,推薦給大家,官網地址:https://openshift.redhat.com/app/ 。
__實現原理__:
當然一切都是調用微博開放平臺的API接口(http://open.weibo.com/wiki/API%E6%96%87%E6%A1%A3_V2 ),平臺還提供了各平臺和語言的SDK。“成信鐘樓”沒有用到SDK,采用自己編碼調用API接口。
發微博很簡單,請求https://api.weibo.com/2/statuses/update.json 或者https://upload.api.weibo.com/2/statuses/upload.json ,前者是直接發布微博文字信息,后者是上傳一張圖片的同時發布一條微博,給出對應要求的參數發起HTTP請求即可。調用前需要進行微博授權,據說現在微博對于開發者的帳號是永久不過期,但是為了以防萬一,我仍然讓他每次報時都去授權,而要24小時報時僅在自己電腦上是不現實的,總會到關機睡覺的時候,所以就要借助SAE做服務器了。用Python發微博,采用Django部署一個網站,通過請求特定url來調用發微博函數。而整點報時則采用Cron實現。其中顯示地理位置只需在Google地圖上找出鐘樓具體位置,然后作為API的參數傳遞給請求函數即可顯示。而來自與YiBo.MX是使用了YiBo的app_key和app_secret。使用自己申請的app_key在沒有經過Sina審核通過時顯示的時來自未審核的應用。
__使用Python實現時需要注意的地方__:
1.授權時自動獲取瀏覽器URL必須指明Content-Type為application/x-www-form-urlencoded
要調用api必須先創建微博應用,然后得到app_key和app_secret。經過授權然后獲得access_token作為請求參數的一部分,而要得到它必須先得到授權碼。授權時可以抓下post到https://api.weibo.com/oauth2/authorize 的包,然后用程序模擬這個授權過程。在自動獲取回調頁面的code值時,請求授權url時必須要在http頭信息中寫明Content-Type為application/x-www-form-urlencoded,不然無法跟蹤到頁面跳轉后的url,就無法通過代碼自動得到code,在SAE上必須設置environ['disable_fetchurl'] = "1"才能正確獲取。有了code后請求https://api.weibo.com/oauth2/access_token 獲取access_token,返回的是json數據,從json數據中拿出access_token即可。具體操作可查看微博開放平臺的API文檔,這里不詳細介紹。
請求代碼:
headers = {'Referer':auth_url,'Content-Type': 'application/x-www-form-urlencoded'} r = urllib2.Request(url, data, headers)2.模擬表單上傳圖片要細心構造Content-Type的值
上傳圖片時,API規定只能使用表單方式上傳,所以http頭的Content-Type要為multipart/form-data。post的數據不能直接寫,必須按照格式加boundary,multipart/form-data boundary說明:http://yefeng.iteye.com/blog/315847 在抓包是可以看到上傳時request payload里面有詳細格式,boundary和格式非常重要,其中的換行是\r\n,有的地方是兩個換行要注意,只要構造出這個字符串作為request的data參數即可。
有表單如下:
表單代碼如下:
Content-Type示例如下:
? ?------WebKitFormBoundaryxD3EeLtCYnk3hHkY
? ?Content-Disposition: form-data; name="status"
? ?hello myclover
? ?------WebKitFormBoundaryxD3EeLtCYnk3hHkY
? ?Content-Disposition: form-data; name="pic"; filename="20100620083829213.jpg"
? ?Content-Type: p_w_picpath/jpeg
? ?圖片二進制信息
? ?------WebKitFormBoundaryxD3EeLtCYnk3hHkY
? ?Content-Disposition: form-data; name="source"
? ?------WebKitFormBoundaryxD3EeLtCYnk3hHkY--
用Python構造以上內容結構即可作為請求參數上傳圖片
boundary = 'cuitclockweibopostdata%s'%(int(time.time())) post_data = [] for k,v in values.iteritems():post_data.append('--%s'%boundary)post_data.append('Content-Disposition: form-data; name="%s"\r\n'%k)post_data.append(v) post_data.append('--%s'%boundary) post_data.append('Content-Disposition: form-data; name="pic"; filename="pic.png"') post_data.append('Content-Type: p_w_picpath/png\r\n') post_data.append(pic) post_data.append('--%s--\r\n'%boundary) data = '\r\n'.join(post_data) headers = {'Content-Type':'multipart/form-data; boundary=%s'%boundary} r = urllib2.Request(url, data, headers)關于生成圖片使用Python的PIL,在SAE和OpenShift上由于安全原因,都不允許對本地進行文件寫操作,所以要把生成的圖片放到內存中,在內存中進行讀寫,StringIO就是拿來做這事的。
buf_img = StringIO.StringIO() img.save(buf_img, 'png') output = buf_img.getvalue() buf_img.close()3.Cron整點調用函數
在SAE上使用cron服務,是Unix和類Unix的操作系統之中常見crontab 命令,用于設置周期性被執行的指令。
配置時在sae環境的配置文件config.yaml中寫上腳本就可以了,如下:
? ?name: cuitclock
? ?version: 1
? ?cron:
? ?- url: /url_update_weibo/
? ? ?schedule: every 1 hour, offset 0
即每隔1小時,會自動請求url_update_weibo這個地址,然后后臺得到請求后立即調用發微博函數。
最后,千萬別關注成信鐘樓新浪微博 http://weibo.com/CUITClock 這顯然就是個坑嘛
文章為阿小信的個人筆記,轉載請注明出處。
轉載于:https://blog.51cto.com/ashin/1200991
總結
以上是生活随笔為你收集整理的成信钟楼定时微博报时的设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bigdecimal 保留两位小数_一律
- 下一篇: docker构建oracle集群,doc