微博多了的人总是在想办法来简化自己的消息发布流程,在这之前我是使用月光博客的 一个架设在GAE上的程序来实现部分微博客之间的消息同步。不过稳定性并不是太好,经常性的一天过去了却一条消息都没有同步,而某个时间再一次性全部发到 其他服务上势必造成严重的刷屏效果。加之我还有一些额外的同步需求,此程序无法满足我了,所以最终还是打算自己动手......折腾......
目前已经可以较好地实现一次发布消息,并同步地向以下1415个服务发送:Twitter、人人、开心、嘀咕、人间、新浪、163、滴、雷猴、搜狐、做啥、Follow5、9911、纸飞机(UChome)、叽歪。每个链接都是我的个人页面,没有链接的说明目前不可访问或者由于隐私需要特地而为。
好吧,最主要的还是要讲讲主要的实现方法,着重的分享要点,而不会直接给出我的程序-.-
准备工具:给各个 API 发送数据的最佳命令行工具 Curl,可以从这里下载到 for windows 的版本,当然要支持 SSL 的。Ubuntu 等 Linux 用户直接 sudo aptitude install curl 即可。另外我为了更加稳定地向人人网发送信息而用了 Python。
我想这些服务主要地分为两类,即开放 API 的和不开放 API 的,对于开放API的服务,一般情况下直接使用如下命令:
curl -u user:password -d "status=message" "API Address"
最具代表性的 Twitter API 示例
curl -k -u user:password -d "status=message" https://api.twitter.com/statuses/update.json
而对于不开放 API 的或者 API 使用要求严格的,则可能需要使用 curl 来模拟登录并发布消息了,这个过程通常需要分析网页源代码,举两个例子,第一个是新浪微博的消息发布(新浪微博虽然开放 API 不过其使用过程中需要 appkey,我申请不到)
- curl -k -c sina.txt "https://login.sina.com.cn/sso/login.php?username=user_sina&password=psw_sina&returntype=TEXT"
- curl -e "http://t.sina.com.cn/" -b sina.txt -d "content=message" "http://t.sina.com.cn/mblog/publish.php"
第一句模拟登录新浪微博,并将cookie文件保存为 sina.txt,第二步是带上 cookie 发布消息,参数中 -k 避免因 https 连接时证书不匹配导致的错误,-c 指定保存 cookie 文件,-e 指定 referer,-b 带上 cookie 文件,-d 以 post 方式提交数据,最后则为目的地址了。
再附向163发布消息的代码,这里的 -L 参数可以应对一些页面重定向的情况
- curl -k -L -e "http://t.163.com" -c 163.txt "https://reg.163.com/logins.jsp?username=user_163&password=psw_163&product=t&type=1"
- curl -b 163.txt -e "http://t.163.com" -d "status=message" "http://t.163.com/statuses/update.do"
第二个例子为向开心001或者纸飞机这类 UChome社区发布状态,主要为登录问题,因为他们在登录的时候需要带上一串验证数字verify或者formhash。如果打算用批处理的话可能会稍微烦一点,因为获取该字符串要几个步骤,先以登录纸飞机社区为例
- curl "http://my.nuaa.edu.cn/home/do.php?ac=a4d30c424df67e23cdefc40e489f82c2&&ref" >home_enuaa.txt
- findstr formhash home_enuaa.txt > home_enua.txt
- for /f "tokens=4 delims==/" %%i in ('type home_enua.txt') do (
- set formha=%%i
- set formha=!formha:~1,8!
- )
- curl -c enuaa.txt -d "username=user_enuaa&password=psw_enuaa&cookietime=315360000& amp;refer=space.php?do\=home&loginsubmit=登录&formhash=!formha!" "http://my.nuaa.edu.cn/home/do.php?ac=a4d30c424df67e23cdefc40e489f82c2&&ref"
- curl -b enuaa.txt -c enuaa.txt "http://my.nuaa.edu.cn/home/space.php?do=home" >home_enuaa.txt
- findstr formhash home_enuaa.txt > home_enua.txt
- for /f "tokens=4 delims==/" %%i in ('type home_enua.txt') do (
- set formhash=%%i
- set formhash=!formhash:~1,8!
- )
- curl -L -b enuaa.txt -d "message=message" -d "addsubmit=true&spacenote=true&formhash=!formhash!&add=更新" "http://my.nuaa.edu.cn/home/cp.php?ac=doing"
原则上就是首先访问一遍网页,然后查找字符串,得到相应的验证值之后再登录,发送,并且可能登录的 formhash 和发送时的 formhash 值并不相同。这么复杂的事情交给 Python 来办就好多了,向 开心001 发送消息的例子(片段)
- import os,re,urllib
- from BeautifulSoup import BeautifulSoup
- curl = r'g:\curl\curl.exe'
- def UpdateKaixin( user , password , message ):
- print u'更新开心消息...'
- os.system(curl+' -L -c kaixin_cookie.txt -d \"email='+ user +'&password='+ password +'&remember=1&from=&refuid=0&refcode=&bind=&gotourl=&submit=true\" \"http://wml.kaixin001.com/login/login.php\" >kaixin_temp.txt 2>nul')
- kaixin_web=BeautifulSoup(file(r'kaixin_temp.txt').read())
- verify = kaixin_web.find('postfield',attrs={'name':'verify'})['value']
- os.system(curl +' -b kaixin_cookie.txt -d \"state='+ message + '&verify='+ verify +'\" \"http://wml.kaixin001.com/home/state_submit.php\" >nul' )
- os.system('del /q kaixin_temp.txt')
- os.system('del /q kaixin_cookie.txt')
其中的 verify 就是要获取的字符串,我使用了 BeautifulSoup 这个模块来提取网页数据,并且用 os.system 命令来调用 curl,为了简单,这里是模拟登录开心的手机版页面发送消息,因此在消息后会出现手机的标志。这里又有个问题,人人网的登录验证字符串长度可能变化,使 用批处理时不好弄,并且人人网模拟登录时可能不大稳定,liancheng 给出了利用 PyXMPP 的方法
- from pyxmpp import streamtls
- from pyxmpp.jabber.client import JabberClient
- from pyxmpp.jid import JID
- from pyxmpp.presence import Presence
- from sys import argv
- def UpdateR2( user, password, message ):
- class R2Client( JabberClient ):
- def __init__( self, jid, password ):
- tls = streamtls.TLSSettings( require=True, verify_peer=False )
- auth = ['sasl:PLAIN']
- JabberClient.__init__( self, jid, password, tls_settings=tls,
- auth_methods=auth )
- def session_started( self ):
- self.stream.send( Presence( status=message ) )
- self.stream.disconnect()
- self.stream = None
- client = R2Client( JID( user + '@talk.xiaonei.com/r2' ), password )
- client.connect()
- client.loop( 1 )
很好很强大,需要注意的是这里的 user 是在自己个人主页地址中的那一串数字。
发送消息中还需要注意的是可能需要使用 UTF-8 字符并 URLEncode 编码,而 Windows 中文默认使用 GBK 进行编码,这就需要转换一下了,如果使用 Python,那么可以在 import urllib 后使用类似如下语句转换为 UTF-8 编码并 URLEncode
- message_ut=message_gb.decode('gbk').encode('utf-8')
- message=urllib.quote(message_ut)
若是为了简便只用批处理,可以访问 “http://m.isouth.org/ded/urlencode.php?zh=中文字符” 这个地址获得转换后的结果,但是我不保证这个地址长期有效。
归类起来也就这么几种情况,稍微熟悉一下就可以组织起来自己编写脚本,只是因为批处理不好处理空格和特殊字符的问题,所以我又转向了 Python 。除了腾讯微博现在不知该怎么处理为好,目前我使用自己编写的脚本来同时给1415个服务更新状态感觉很好,虽然简陋,限制较多,但是安全,快速。
没有评论:
发表评论