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的time模块中的常用方法整理
Jun 18 Python
简单实现python收发邮件功能
Jan 05 Python
tensorflow建立一个简单的神经网络的方法
Feb 10 Python
Python统计单词出现的次数
Apr 04 Python
Python采集代理ip并判断是否可用和定时更新的方法
May 07 Python
Python利用sqlacodegen自动生成ORM实体类示例
Jun 04 Python
python学生管理系统的实现
Apr 05 Python
Django如何使用jwt获取用户信息
Apr 21 Python
Python如何获取文件指定行的内容
May 27 Python
Java如何基于wsimport调用wcf接口
Jun 17 Python
OpenCV Python实现图像指定区域裁剪
Mar 12 Python
详解python内置模块urllib
Sep 09 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+Html+缓存
2006/11/25 PHP
关于js和php对url编码的处理方法
2014/03/04 PHP
php取出数组单个值的方法
2018/03/12 PHP
JS判断是否为数字,是否为整数,是否为浮点数的代码
2010/04/24 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
2010/07/04 Javascript
js的匿名函数使用介绍
2013/12/11 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
一款简单的jQuery图片标注效果附源码下载
2016/03/22 Javascript
jQuery代码实现表格中点击相应行变色功能
2016/05/09 Javascript
jQuery的each循环用法简单示例
2016/06/12 Javascript
JavaScript实现垂直滚动条效果
2017/01/18 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
详解Angular5 路由传参的3种方法
2018/04/28 Javascript
vue路由组件按需加载的几种方法小结
2018/07/12 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
jQuery弹框插件使用方法详解
2020/05/26 jQuery
JS实现网站楼层导航效果代码实例
2020/06/16 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
2020/08/25 Javascript
python根据给定文件返回文件名和扩展名的方法
2015/03/27 Python
python将文本转换成图片输出的方法
2015/04/28 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
在notepad++中实现直接运行python代码
2019/12/18 Python
tensorflow保持每次训练结果一致的简单实现
2020/02/17 Python
AmazeUI折叠式卡片布局,整合内容列表、表格组件实现
2020/08/20 HTML / CSS
欧缇丽英国官方网站:Caudalie英国
2016/08/17 全球购物
Expedia韩国官网:亚洲发展最快的在线旅游门户网站
2018/02/26 全球购物
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
硅酸盐工业控制专业应届生求职信
2013/11/02 职场文书
会计出纳岗位职责
2013/12/25 职场文书
新学期家长寄语
2014/01/19 职场文书
民族学专业大学生职业规划范文:清晰未来的构想
2014/09/20 职场文书
小学生思想品德评语
2014/12/31 职场文书
2015年学校图书室工作总结
2015/05/19 职场文书
为什么mysql字段要使用NOT NULL
2021/05/13 MySQL
一些让Python代码简洁的实用技巧总结
2021/08/23 Python