前言
對於很少玩微博@張行之_的我來說,微博內容少的可憐。所以本人就想:能不能寫個成功程序來幫我發微博。這個程序要滿足以下要求:
- 自動化,自動登錄微博,自動發微博。
- 微博內容要有意義,不能是隨機生成的字符。
- 可以設置每隔一段時間發一條微博,頻率不能太快,當然也不能太慢。
於是,就誕生了這個程序,代碼使用純Python實現,沒有使用微博SDK,主要是模擬HTTP操作。程序運行后會先登錄微博,然后啟動一個定時器,每隔一段時間爬取秒拍、cnBeta、博客園、TechWeb、推酷最新的內容,再轉發到微博。
代碼托管在GitHub上,項目地址:https://github.com/zchlong/sinaWeibo.git
試用了幾天,效果可以查看我的微博:@張行之_。
整體結構
程序分為3個模塊:微博登錄、定時發微博、微博內容生產。代碼結構如下:
sinaWeibo
|----main.py
|----sinaWeiboLogin.py
|----config.py
|----logger.py
|----sendWeibo.py
|----TextFactory.py
|spider
|----__init__.py
|----utility.py
|----http.py
|----spider.py
|----cnbeta.py //解析cbbeta
|----cnblog.py //解析博客園
|----techweb.py /解析techweb
|----tuicool.py //解析推酷
|----..... //更多解析
使用
如果你只想使用該代碼來發微博,並不關心代碼是怎么實現的,那么你只需要讀這一節內容。
- 下載,項目地址:https://github.com/zchlong/sinaWeibo.git。
- 修改配置文件
config.py
,把微博賬號和密碼改為你自己的,還可以設置發送時間(默認是30分鍾一次)。 - 在
TextFactory.py
可以設置微博內容生成規則,也可以使用默認的規則。 - 運行
main.py
,python main.py
。
注意:
pip install rsa
pip install requests
- 如果你的微博登錄時要輸入驗證碼,該代碼是登錄不成功的,可以在賬號安全的登錄保護中設置不輸入驗證碼。
登錄
登錄網上有很多現成的方法,在GitHub上找到一個登錄新浪微博的Python代碼,使用requests,比urllib2更方便。代碼依賴requests和rsa。代碼有點舊,需要做一點修改。
WBCLIENT = 'ssologin.js(v1.4.5)' => WBCLIENT = 'ssologin.js(v1.4.18)'
兩個正則表達式也需要修改下:
login_url = re.search(r'replace\([\"\']([^\'\"]+)[\"\']', resp.text).group(1)
改為:
login_url = re.search('replace\\(\'([^\']+)\'\\)', resp.text).group(1)
login_str = re.match(r'[^{]+({.+?}})', resp.text).group(1)
改為:
login_str = login_str = re.search('\((\{.*\})\)', resp.text).group(1)
登錄時要注意,如果需要輸入驗證碼,這段代碼是會登錄失敗的,可以在賬號安全的登錄保護中設置不輸入驗證碼。
定時自動發微博
新浪微博發微博的接口是:
http://www.weibo.com/aj/mblog/add?ajwvr=6&__rnd=時間戳
時間戳使用 int(time.time() * 1000
即可設置。
Post提交數據:
"location" : "v6_content_home",
"appkey" : "",
"style_type" : "1",
"pic_id" : "",
"text" : 微博內容,
"pdetail" : "",
"rank" : "0",
"rankid" : "",
"module" : "stissue",
"pub_type" : "dialog",
"_t" : "0",
提交數據時需要設置Headers:
self.http.headers["Referer"] = "http://www.weibo.com/u/%s/home?wvr=5" % str(self.uid)
uid在登錄時會返回。
在Python中啟動一個定時器(Timer),每當定時器觸發的時候向這個接口Post數據就能實現自動發微博了。
def newTimer(self):
self.timer = Timer(TIME_SLOG, self.main, ()).start()
def stop(self):
log("結束任務")
self.timer.cancel()
pass
def main(self):
self.sendWeibo()
if TIMER_REPEAT:
self.newTimer()
def sendWeibo(self):
text = TextFactory.getText()
self.update(text)
log(u"發送微博:" + text)
微博內容生產
要產生有意義的微博內容,一般需要從網站上爬取。當然,也可以把內容寫入文本再定時發送。內容都是從網上爬取的,因此需要實現一個爬蟲,用Python的requests爬取網頁非常方便,幾行代碼搞定。使用SGMLParser
解析網頁也是非常方便的。爬蟲部分在爬取網頁都是一樣的,解析時不同,所以只需要分別對每一個網站實現一個SGMLParser
子類就能實現多個網站的爬取了。
為了從不同網站爬取數據,代碼實現一個輪詢機制,用一個容器保存各個網站的爬蟲對象,在每次獲取微博內容時使用不同的爬蟲對象。
spiders = [
Spider(miaopai.HOME_URL, miaopai.MiaopaParser()),
Spider(cnbeta.HOME_URL, cnbeta.CnbetaParser()),
Spider(cnblog.HOME_URL, cnblog.CnblogParser()),
Spider(techweb.HOME_URL, techweb.TechwebParser()),
Spider(tuicool.HOME_URL, tuicool.TuicoolParser()),
Spider(miaopai.HOME_URL, miaopai.MiaopaParser()),
]
currentIndex = 0
count = len(spiders)
def getText():
spider = nextSpider()
text = spider.getAMessage()
return text
def nextSpider():
global currentIndex
spider = spiders[currentIndex]
currentIndex = (currentIndex + 1) % count
return spider
添加爬蟲
代碼設計具有較好地擴展性,在爬蟲類spder.py
中定義一個解析屬性
class Spider(object):
def __init__(self, homeUrl, parser):
super(Spider, self).__init__()
self.homeUrl = homeUrl
self.parser = parser
def getAMessage(self):
html = http.get(self.homeUrl)
self.parser.feed(html)
return self.parser.getMsg()
在創建Spider
對象時,只需要注入不同的解析對象,就能解析不同的網站內容了,甚至還可實現從其他渠道獲取內容。
在TextFactory.py
中實現了輪詢機制,當有新的解析類時,只需在TextFactory.py
中的spiders
添加一個就行。
結語
該代碼已經基本滿足了前言的3點要求,不過還存在一些問題:
- 爬蟲部分還存在很多冗余,可以進一步優化。
- 產生微博內容時可能會生成相同的內容,尤其是目標網站更新頻率不高時。
代碼托管在碼托管在GitHub上,項目地址:https://github.com/zchlong/sinaWeibo.git。
本文最早發表於: http://blog.5long.me
原文鏈接: http://blog.5long.me/2015/code-login-sina-weibo-update-weibo/
版權聲明:自由轉載-非商用-保持署名 | Creative Commons BY-NC 4.0