话说Ele自从买了Kindle之后,阅读量蹭蹭的上去了。小K有个好处,就是可以摘录一些片段。然而,眼见着摘录越来越多,但是懒惰的Ele却从来没有打开回温一下,这是不对的!!于是乎,Ele决定把其推送到微博上,没事刷一刷。ε(┬┬﹏┬┬)3 为了战胜自己,也是够了!
自动登录微博
虽然新浪微博提供了Python API可以直接接入。但是,本着不想暴露过多个人信息,最后还是决定模拟登录之。 如果要模拟PC端的登录,过程相当复杂。需要根据用户名密码算出多个值,其过程还涉及到各种加密运算。网上已经有很多相关的内容描述这整个过程。但由于Google上找到的大部分相关信息都是比较久远的,对当前不再适用。此时,祭出黑招: > 移动端的登录通常比PC端登录简单很多很多,因此,登录解析可以从移动端入手。
怎么找到移动端呢?有一个简单粗暴的方法:拿出手机,登录到网站上,就会自动跳到移动端啦。这里,新浪微博的移动端是:http://m.weibo.cn/。 模拟的思路可以参考之前写过的沪江部落自动登录打卡。 代码如下:
1 | import requests |
微博发布
因为前面登录是在移动端登录的,所以下面的微博发布也需要在移动端进行。进入微博发布界面,打开Fiddler,随便发送一条微博,可以看到会POST新微博到http://m.weibo.cn/mblogDeal/addAMblog上。 代码如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21def add_new(self, content):
'''
create a new weibo发布新微博方法
'''
addurl = "https://m.weibo.cn/mblogDeal/addAMblog"
st = re.findall(r'"st":"(\w+)"', self.session.get(r"http://m.weibo.cn/mblog").text)
# 如果发送数据中有一些值为数字字母等混合的长得像随机数的参数,
# 建议可以在页面源代码里找找,然后用正则表达式提取出来。就像这里的st
data = {'content':content, 'st':st[0],}
headers = { # headers也是必不可少的,否则会有什么安全问题导致发送失败
"Host": "m.weibo.cn",
"Connection": "keep-alive",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Origin": "http://m.weibo.cn",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": "http://m.weibo.cn/mblog",
"Accept-Language": "zh-CN,zh;q=0.8"
}
respon = self.session.post(addurl, data, headers=headers).json()
return respon.get("msg", "Unknow Error") # 这里的msg是发布结果My Clippings.txt
文件中。之前出于某种目的已经把它们整合到sqlite数据库app.db里的clipping表里了。直接操作此表既可以获得摘录信息。 另外,因为是希望把它加进香蕉派的定时任务中定时发送的,所以每次获得的摘录当然不能重复。因此会把获得的下一个摘录的id保存在clipping_index
文件里。 代码如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class Clipping(object):
'''
片段摘抄
'''
def __init__(self, db=r"/home/ele/lab/myxixi/app.db"):
self.conn = sqlite3.connect(db)
self.conn.isolation_level = None
# 获得下一个摘录的id
tmp = os.popen("cat clipping_index").read()
self.index = int(tmp) if tmp else 1
# 保存最大的id值
self.max_index = int(self.conn.execute("select max(id) from clipping").fetchone()[0])
def get_one(self, topic=u"片段"):
while self.index <= self.max_index : # 避免死循环
result = self.conn.execute("select * from clipping where id=%d"%self.index).fetchone()
self.index += 1
if result: # 若获得的结果不为空,则保存下一个摘录的id,然后返回内容
os.popen("echo %d > clipping_index" % self.index)
return u"#{}##{}#{}".format(topic,result[1],result[2])1
2
3
4
5
6
7if __name__ == "__main__":
username = '*********'
password = '**********'
wb = Weibo(username, password)
cl = Clipping()
content = cl.get_one()
print wb.add_new(content)