Feb
13
用GAE同步twitter到人人网状态
学习笔记 Popularity: 11%
yegle做过一个同步twitter到人人网状态的PHP脚本,但要求有点高——必须有php-cli组件,估计大多数虚拟主机都没有。Shellex又做了一个用GAE实现的版本,这个可用性高一点,不过他的原版需要webpy和simplejson,需要上传很多东西,而且拼写有错。我改了一下,直接引用django里面的simplejson,再用webapp替换webpy,这样只需要一个文件就能实现了。
更新记录:
纪念冯正虎成功回国特别更新:Retweet一并同步。
2010-4-10:跟随校内网更新。
2010-4-25:跟随校内网更新。
2010-5-16:跟随校内网更新。
使用指南:
请避免使用“记事本/notepad“编辑twitter2renren.py。
允许同步以"@"开头的tweet:注释掉第46行,同时将第47行的缩进减小一格。
取消同步retweet:注释掉第38, 39, 42, 43, 48, 49行。
脚本文件twitter2renren.py:
?Download twitter2renren.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #!/usr/bin/env python2.6 #coding=utf8 import Cookie import urllib import re from django.utils import simplejson from google.appengine.api import urlfetch from google.appengine.ext import db from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app renren_usr = '你的人人网用户名' renren_passwd = '人人网密码' twitter_usr = '推特用户名' twitter_passwd = '推特密码' last_non_sync_tweet = '最后一条不需要同步的tweet的id,比如:8726641859' last_non_sync_retweet = '8883341324' cookie_buf = Cookie.SimpleCookie(); class Record(db.Model): #key is twitter_usr last_tweet = db.StringProperty(required=True) last_retweet = db.StringProperty(required=True) def make_cookie_header(cookie): ret = '' for v in cookie.values(): ret += '%s=%s;' % (v.key, v.value) return ret def get_tweets (usr, passwd): record = Record.get_or_insert(twitter_usr, last_tweet=last_non_sync_tweet, last_retweet=last_non_sync_retweet) new_timeline = [] timeline_uri = 'http://%s:%s@twitter.com/statuses/user_timeline.json?count=10&since_id=%s' % (usr, passwd, record.last_tweet) timeline = simplejson.loads(urllib.urlopen(timeline_uri).read()) retweets_uri = 'http://%s:%s@api.twitter.com/1/statuses/retweeted_by_me.json?count=10&since_id=%s' % (usr, passwd, record.last_retweet) retweets = simplejson.loads(urllib.urlopen(retweets_uri).read()) if len(timeline) != 0: record.last_tweet = str(timeline[0]['id']) if len(retweets) != 0: record.last_retweet = str(retweets[0]['id']) record.put() for tweet in timeline: if tweet['text'][0] != '@' : new_timeline.append(tweet['text'].encode('utf8')) for tweet in retweets: new_timeline.append(tweet['text'].encode('utf8')) return new_timeline def login2renren(): verify_url = 'http://passport.renren.com/PLogin.do' verify_data= urllib.urlencode({ 'email': renren_usr, 'password': renren_passwd, 'origURL': 'http://home.renren.com/Home.do', 'domain': 'renren.com', 'formName': '', 'method': '', 'isplogin': 'true', 'submit': '登录' }) result = urlfetch.fetch( url=verify_url, headers={ 'Cookie':make_cookie_header(cookie_buf), 'Content-Type': 'application/x-www-form-urlencoded', 'user-agent':'Mozilla/5.0 (Linux; U; Linux i686; en-US) Gecko/20100115 Firefox/3.6', }, method=urlfetch.POST, payload=verify_data, follow_redirects = False, ) return result def do_redirect(url, cookie): result = urlfetch.fetch( url=url, headers={ 'Cookie':make_cookie_header(cookie), 'Content-Type': 'application/x-www-form-urlencoded', 'user-agent':'Mozilla/5.0 (Linux; U; Linux i686; en-US) Gecko/20100115 Firefox/3.6', }, method=urlfetch.GET, follow_redirects = False, ) return result def send_status(status, cookie): status_url = 'http://status.renren.com/' result = urlfetch.fetch( url=status_url, headers={ 'Cookie':make_cookie_header(cookie), 'Content-Type': 'application/x-www-form-urlencoded', 'user-agent':'Mozilla/5.0 (Linux; U; Linux i686; en-US) Gecko/20100115 Firefox/3.6', }, method=urlfetch.GET, ) cookie_buf = Cookie.SimpleCookie(result.headers.get('set-cookie', '')) ticket = re.search('<input type="hidden" value="(-?\d+)" class="submit" id="publisher_form_ticket"/>', result.content) status_url = 'http://status.renren.com/doing/update.do?' status_data = urllib.urlencode({ 'c': status, 'raw': status, 'statusPage': 1, 'publisher_form_ticket': ticket.group(1), }) result = urlfetch.fetch( url=status_url, headers={ 'Cookie':make_cookie_header(cookie), 'Content-Type': 'application/x-www-form-urlencoded', 'user-agent':'Mozilla/5.0 (Linux; U; Linux i686; en-US) Gecko/20100115 Firefox/3.6', 'Referer': 'http://status.renren.com/' }, method=urlfetch.POST, payload=status_data, ) return True class sync(webapp.RequestHandler): def get(self): global cookie_buf #get timeline timeline = get_tweets(twitter_usr, twitter_passwd) if len(timeline) == 0: return 'no tweets to sync.' #login to renren result = login2renren() cookie_buf = Cookie.SimpleCookie(result.headers.get('set-cookie', '')); callback_url = result.headers.get('location','xx'); result = do_redirect(callback_url, cookie_buf) cookie_buf = Cookie.SimpleCookie(result.headers.get('set-cookie', '')) #post status for tweet in timeline: result = send_status(tweet, cookie_buf) return 'ok' application = webapp.WSGIApplication([('/twitter2renren', sync)]) if __name__ == "__main__": run_wsgi_app(application) |
配置文件cron.yaml,每5分钟触发一次:
1 2 3 4 | cron:
- description: twitter2renren
url: /twitter2renren
schedule: every 5 minutes |
配置文件app.yaml,限制只有管理员才能访问/twitter2renren:
1 2 3 4 5 6 7 8 9 | application: 你的app名字 version: 8 runtime: python api_version: 1 handlers: - url: /twitter2renren script: twitter2renren.py login: admin |
另:前天刚拿到一个SAE的帐号,不知道能干点什么用……有谁知道的,请悄悄告诉我……
July 21st, 2010 at 23:51 pm
谢谢,搭建成功了。刚开始我用twitter的username附给twitter_usr,GAE一直报错,后来改成email,然后就OK了。
Reply
July 19th, 2010 at 0:02 am
咨询,publisher_form_ticket有虾米用,我没有从html读这个参数,每次虽然http返回值是200,但都没有同步成功。
Reply
July 19th, 2010 at 0:15 am
有虾米用得问人人网做UI的,为啥写这么一堆乱七八糟的参数。
Reply
July 19th, 2010 at 15:27 pm
那我再试试看,这个杯具的参数。。。
Reply
June 25th, 2010 at 1:59 am
[...] 使用方法:http://d.ream.at/sync-twitter-timeline-to-renren-status-via-google-app-engine/ 这个忘记是谁写的了,用来同步推特到人人网的gae程序。 首先在自己的gae上面建立好程序,将上面twitter-feed和twitter2renren中的代码中相应内容修改了。另外还要注意看看文件夹下面是否还有文件夹,如果有,就只要一层文件夹。(比如:twitter2renren文件夹下面又有个twitter2renren文件夹,其里面才是yaml,py等这些文件。) 之后使用sdupload这个工具上传,方法是首先将twitter-feed和twitter2renren这两个文件夹,放到sdupload文件夹下面,我们以sdupload文件夹放在d盘根目录为例。 在命令行里,进入d:sdupload文件夹: (命令行) [...]
May 27th, 2010 at 13:09 pm
那我再试试,弄了半天也没弄好。谢谢你写了这个东西。
Reply
May 27th, 2010 at 12:31 pm
结果发现自己一下写了三个.......无语了,这是第四个了
Reply
May 27th, 2010 at 12:30 pm
为了留言专门注册了,呵呵
我是Google过来的,对于这个文章的技术不是很了解。能不能写一下流程呢?很迷惑现在。谢谢博主啊!已经下了Python和GAE还是一头雾水
Reply
May 27th, 2010 at 12:23 pm
请问一下,能不能写个教程,或者至少流程也可以,我Google过来的,看来是没有必须的知识,下了python,GAE结果还是干瞪眼...
Reply
May 27th, 2010 at 12:33 pm
不能。
Reply
April 24th, 2010 at 2:54 am
[...] GAE同步Twitter轟炸某SNS [...]
April 18th, 2010 at 1:01 am
弱问一下,twitter2renren.py的第17 18行有什么用?不会填哎......
Reply
April 18th, 2010 at 11:28 am
每条tweet都有一个id,这两处填的是最后一条不需要同步的tweet,如果不填,第一次运行时会把你历史上所有的tweet都同步过去,造成刷屏。
Reply
April 18th, 2010 at 11:50 am
是一上传就生效吗?如何查看tweet和retweet的id啊....我是菜鸟,啥都不懂....
Reply
April 18th, 2010 at 12:17 pm
上传生效,只有第一次运行时有效,以后会被写在数据库里,从数据库读出。twitter官方网站显示一条tweet时,在下方有一个"about xx mins/hours ago"的连接,地址如http://twitter.com/littlelittlejia/status/12352041116,其中status/之后的"12352041116"就是tweet id,retweet同理。
Reply
April 18th, 2010 at 12:35 pm
如果实在是搞不清楚,就把17 18行那两个数字留在那,最多会同步10条历史tweet过去。另,你的twitter页面背景很赞。
Reply
April 1st, 2010 at 9:28 am
代码盲弱问下如何关闭RT的同步?觉得该从第40或46行下手,可就是不会改 - -
Reply
March 26th, 2010 at 10:35 am
难道不能自动同步?
每次同步都是手动刷新.../twitter2renren页面后实现的,去掉“ login: admin”后问题依旧,求解??
Reply
March 26th, 2010 at 10:39 am
cron脚本是负责自动同步的。login: admin的作用是防止手动刷新。
Reply
March 20th, 2010 at 17:09 pm
直接用了你上面提供的脚本,GAE给出的Error信息是: unexpected indent (twitter2renren.py, line 145)那个代码根本没有145行,求解
Reply
March 6th, 2010 at 1:25 am
铁通打开你站都很快啊·不错哦
Reply
February 23rd, 2010 at 17:18 pm
博主高手,学习了!
Reply
February 22nd, 2010 at 11:59 am
我找到原因了,原来“tinyurl.com”在人人网是敏感词,在状态中发不出去,我说怎么我的某些推同步不了,我还以为是这个同步程序的原因
Reply
February 22nd, 2010 at 6:38 am
另外,你的网址中的缩略名也太长了吧...
Reply
February 22nd, 2010 at 6:36 am
请问一下,符合什么条件的twit不会被同步,怎样才能取消这些条件,谢谢。
Reply
February 24th, 2010 at 12:44 pm
以"@"开头的tweet不会被同步,注释第44行取消该条件。
Reply
February 17th, 2010 at 22:53 pm
[...] 脚本同时参考了梦.:如此短暂的用GAE同步twitter到人人网状态 [...]
February 8th, 2010 at 18:59 pm
SAE? 我也想要。
Reply
February 8th, 2010 at 19:01 pm
我只有个帐号,没有邀请码┐〈┘.└〉┌
Reply
February 8th, 2010 at 2:46 am
其实php-cli倒是基本都有…关键是shell不一定有,有的只有cpanel里的crontab,那个东西用得很头疼…
Reply