python实现的登录和操作开心网脚本分享


Posted in Python onJuly 09, 2014

SNS什么的我是一直无爱的,这次蛋疼写了个登录开心网(kaixin001)并向所有好友发送站内消息的脚本。

开心网在登录的时候做了一些处理,并不传原始密码,从js分析到的结果是:登录时会生成一个随机的key,然后用这个key和原始密码进行xxtea加密,把加密后的结果再进行sha1加密。之后post这个key以及加密后的密码进行登录验证。

以下是很简陋的脚本内容:

#coding: utf-8
"""
开心网操作脚本

Author: piglei2007@gmail.com
Version: 1.0
"""
import re
import urllib
import urllib2
import random
import hashlib
import binascii
import cookielib
import simplejson

from xxtea import encrypt

LOGIN_URL = "http://www.kaixin001.com/login/login_api.php"
LOGIN_KEY_URL = "http://www.kaixin001.com/"
FRIEND_LIST_URL = "http://www.kaixin001.com/interface/suggestfriend.php"
MESSAGE_SEND_URL = "http://www.kaixin001.com/msg/post.php"

LOGIN_KEY_RE = re.compile(r"new\sEnLogin\('(.*?)'")

class LoginError(Exception):
  """
  登录失败抛出异常
  """

class Kaixin001User(object):
  """
  操作kaixin001,现有方法:
  
    get_login_key - 获得用户访问登录页面时分配的加密key
    
    get_rpassword - 获得经过xxtea以及sha1加密后的密码
    
    login - 登录
    
    get_friends_list - 获得所有好友,返回字典格式
    
    send_messages_to_all - 给所有好友发消息
  """
  
  def __init__(self, username, password):
    self.username = username
    self.password = password
    self.cj = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
    opener.addheaders = [
      ("User-agent", "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.1) Gecko/20090704 Firefox/3.5"),
      ("Accept", "*/*"),
      ("Host", "www.kaixin001.com")
    ]
    urllib2.install_opener(opener)
    
  def get_login_key(self):
    """
    获得登录时候的加密key
    """
    _temp = urllib2.urlopen(LOGIN_KEY_URL).read()
    key = LOGIN_KEY_RE.search(_temp).group(1)
    return key
    
  def login(self):
    """
    登录
    """
    login_key = self.get_login_key()
    rpassword = self.get_rpassword(self.password, login_key)
    login_params = {
      'email': self.username,
      'encypt': login_key,
      'rpasswd': rpassword,
      'url': '/home/',
      'ver': '1'      
    }
    req = urllib2.Request(LOGIN_URL, urllib.urlencode(login_params), {
      "Referer": "http://www.kaixin001.com/"
    })
    result = urllib2.urlopen(req).read()
    
    # 登录失败
    if "errno" in result:
      raise LoginError("登录失败,请检查用户名或密码")
    
    print "用户 %s 登录成功!" % self.username
    
    return 'ok'
  
  def get_friends_list(self):
    """
    获得所有好友列表
    """
    get_friends_params = {
      't': str(random.random()),
      'type': 'all',    
    }
    result = urllib2.urlopen(FRIEND_LIST_URL, urllib.urlencode(get_friends_params)).read()
    friends = simplejson.loads(result)
    
    print "你一共有 %s 位好友" % (len(friends) - 1)
    return friends
  
  def send_messages_to_all(self, message=''):
    """
    给所有好友发消息
    """
    friends = self.get_friends_list()
    send_params = {
      'attachment_cancel': '',
      'attachment_forwarding': '',	
      'attachment_random': '',
      'code': '',
      'content': message,
      'forward_thread': '',
      'rcode': '',
      'service': '0',
      'texttype': 'html',
      'uids': ",".join([str(f['uid']) for f in friends])   
    }
    result = urllib2.urlopen(MESSAGE_SEND_URL, urllib.urlencode(send_params))
    print result.geturl()
    print "消息发送成功"
    return 'ok'
    
  
  def get_rpassword(self, password, key):
    """
    获得加密后的密码
    """
    xxtea_pw = binascii.b2a_hex( encrypt(password, key) )
    r_password = hashlib.sha1(xxtea_pw).hexdigest()
    return r_password
  
if __name__ == '__main__':
  kxu = Kaixin001User(
    username = 'your_username',
    password = 'your_password'
  )
  kxu.login()
  kxu.send_messages_to_all("This message is send by Python.")

这是脚本中需要用到的xxtea算法的python实现(xxtea.py):

import struct
 
_DELTA = 0x9E3779B9 
 
def _long2str(v, w): 
  n = (len(v) - 1) << 2 
  if w: 
    m = v[-1] 
    if (m < n - 3) or (m > n): return '' 
    n = m 
  s = struct.pack('<%iL' % len(v), *v) 
  return s[0:n] if w else s 
 
def _str2long(s, w): 
  n = len(s) 
  m = (4 - (n & 3) & 3) + n 
  s = s.ljust(m, "\0") 
  v = list(struct.unpack('<%iL' % (m >> 2), s)) 
  if w: v.append(n) 
  return v 
 
def encrypt(str, key): 
  if str == '': return str 
  v = _str2long(str, True) 
  k = _str2long(key.ljust(16, "\0"), False) 
  n = len(v) - 1 
  z = v[n] 
  y = v[0] 
  sum = 0 
  q = 6 + 52 // (n + 1) 
  while q > 0: 
    sum = (sum + _DELTA) & 0xffffffff 
    e = sum >> 2 & 3 
    for p in xrange(n): 
      y = v[p + 1] 
      v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff 
      z = v[p] 
    y = v[0] 
    v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff 
    z = v[n] 
    q -= 1 
  return _long2str(v, False) 
 
def decrypt(str, key): 
  if str == '': return str 
  v = _str2long(str, False) 
  k = _str2long(key.ljust(16, "\0"), False) 
  n = len(v) - 1 
  z = v[n] 
  y = v[0] 
  q = 6 + 52 // (n + 1) 
  sum = (q * _DELTA) & 0xffffffff 
  while (sum != 0): 
    e = sum >> 2 & 3 
    for p in xrange(n, 0, -1): 
      z = v[p - 1] 
      v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff 
      y = v[p] 
    z = v[n] 
    v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff 
    y = v[0] 
    sum = (sum - _DELTA) & 0xffffffff 
  return _long2str(v, True) 
 
if __name__ == "__main__": 
  print decrypt(encrypt('Hello XXTEA!', '16bytelongstring'), '16bytelongstring')
Python 相关文章推荐
Python open读写文件实现脚本
Sep 06 Python
Python中处理字符串的相关的len()方法的使用简介
May 19 Python
python机器学习理论与实战(四)逻辑回归
Jan 19 Python
浅谈Python中的作用域规则和闭包
Mar 20 Python
python  Django中的apps.py的目的是什么
Oct 15 Python
谈谈Python中的while循环语句
Mar 10 Python
Python3获取拉勾网招聘信息的方法实例
Apr 03 Python
python爬虫 爬取超清壁纸代码实例
Aug 16 Python
使用opencv将视频帧转成图片输出
Dec 10 Python
pandas factorize实现将字符串特征转化为数字特征
Dec 19 Python
浅谈keras保存模型中的save()和save_weights()区别
May 21 Python
如何利用python生成MD5并去重
Dec 07 Python
python实现的一个火车票转让信息采集器
Jul 09 #Python
python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 #Python
Python中__init__和__new__的区别详解
Jul 09 #Python
Python中使用logging模块代替print(logging简明指南)
Jul 09 #Python
Python中的魔法方法深入理解
Jul 09 #Python
gearman的安装启动及python API使用实例
Jul 08 #Python
python实现跨文件全局变量的方法
Jul 07 #Python
You might like
php制作的简单验证码识别代码
2016/01/26 PHP
js计算页面刷新的次数
2009/07/20 Javascript
javascript 支持链式调用的异步调用框架Async.Operation
2009/08/04 Javascript
IE与Firefox在JavaScript上的7个不同写法小结
2009/09/14 Javascript
JS实现self的resend
2010/07/22 Javascript
js实现网页自动刷新可制作节日倒计时效果
2014/05/27 Javascript
jquery判断单选按钮radio是否选中的方法
2015/05/05 Javascript
js选择器全面解析
2016/06/27 Javascript
解析微信JS-SDK配置授权,实现分享接口
2016/12/09 Javascript
js 调用百度分享功能
2017/02/27 Javascript
利用node.js实现自动生成前端项目组件的方法详解
2017/07/12 Javascript
js禁止浏览器页面后退功能的实例(推荐)
2017/09/01 Javascript
node.js多个异步过程中判断执行是否完成的解决方案
2017/12/10 Javascript
layui点击按钮添加可编辑的一行方法
2018/08/15 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
vue中组件的过渡动画及实现代码
2018/11/21 Javascript
vue2.0项目集成Cesium的实现方法
2019/07/30 Javascript
Ant Design的Table组件去除
2020/10/24 Javascript
vue3+typescript实现图片懒加载插件
2020/10/26 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
手动实现把python项目发布为exe可执行程序过程分享
2014/10/23 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
2018/02/02 Python
Python下使用Scrapy爬取网页内容的实例
2018/05/21 Python
python 一个figure上显示多个图像的实例
2019/07/08 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
2020/03/30 Python
纯css3实现的竖形无限级导航
2014/12/10 HTML / CSS
Furla官网:意大利著名的皮革品牌
2019/08/06 全球购物
历史学专业毕业生求职信
2013/09/27 职场文书
建材业务员岗位职责
2013/12/08 职场文书
《雨霖铃》教学反思
2014/02/22 职场文书
2014两会优秀的心得体会范文
2014/03/17 职场文书
国庆节活动总结
2014/08/26 职场文书
创先争优宣传标语
2014/10/08 职场文书
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python
浅谈 JavaScript 沙箱Sandbox
2021/11/02 Javascript
Python实现视频中添加音频工具详解
2021/12/06 Python