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函数编程的一些特性
Apr 13 Python
python requests post多层字典的方法
Dec 27 Python
python实现转盘效果 python实现轮盘抽奖游戏
Jan 22 Python
在python里从协程返回一个值的示例
Feb 19 Python
python实现几种归一化方法(Normalization Method)
Jul 31 Python
python虚拟环境完美部署教程
Aug 06 Python
django+echart数据动态显示的例子
Aug 12 Python
Python 如何查找特定类型文件
Aug 17 Python
python 根据列表批量下载网易云音乐的免费音乐
Dec 03 Python
python 图像增强算法实现详解
Jan 24 Python
python爬虫scrapy基本使用超详细教程
Feb 20 Python
python热力图实现的完整实例
Jun 25 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
第四节 构造函数和析构函数 [4]
2006/10/09 PHP
逆序二维数组插入一元素的php代码
2012/06/08 PHP
Linux中用PHP判断程序运行状态的2个方法
2014/05/04 PHP
THINKPHP在添加数据的时候获取主键id的值方法
2017/04/03 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
用js实现键盘方向键翻页功能的代码
2007/06/03 Javascript
JS查看对象功能代码
2008/04/25 Javascript
Javascript Memoizer浅析
2014/10/16 Javascript
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
Javascript实现可旋转的圆圈实例代码
2015/08/04 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
微信小程序 数组中的push与concat的区别
2017/01/05 Javascript
vue双向绑定简要分析
2017/03/23 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
vue2.0开发入门笔记之.vue文件的生成和使用
2017/09/19 Javascript
详解使用React全家桶搭建一个后台管理系统
2017/11/04 Javascript
vue中使用codemirror的实例详解
2018/11/01 Javascript
JavaScript十大取整方法实例教程
2020/12/03 Javascript
Python迭代器和生成器定义与用法示例
2018/02/10 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
Django接收自定义http header过程详解
2019/08/23 Python
Mac 使用python3的matplot画图不显示的解决
2019/11/23 Python
如何让python的运行速度得到提升
2020/07/08 Python
django序列化时使用外键的真实值操作
2020/07/15 Python
在Python3.74+PyCharm2020.1 x64中安装使用Kivy的详细教程
2020/08/07 Python
利用canvas实现图片下载功能来实现浏览器兼容问题
2019/05/31 HTML / CSS
StubHub希腊:购买体育赛事、音乐会和剧院门票
2019/08/03 全球购物
学习自我鉴定
2014/02/01 职场文书
领导干部遵守党的政治纪律情况思想汇报
2014/09/14 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
领导干部贪图享乐整改措施
2014/09/21 职场文书
设备收款委托书范本
2014/10/02 职场文书
销售口号霸气押韵
2015/12/24 职场文书
《我在为谁工作》:工作的质量往往决定生活的质量
2019/12/27 职场文书
Python标准库pathlib操作目录和文件
2021/11/20 Python
MySQL之MyISAM存储引擎的非聚簇索引详解
2022/03/03 MySQL