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自定义scrapy中间模块避免重复采集的方法
Apr 07 Python
Python字符串中查找子串小技巧
Apr 10 Python
一些Python中的二维数组的操作方法
May 02 Python
在Python的Django框架中生成CSV文件的方法
Jul 22 Python
Python Socket实现简单TCP Server/client功能示例
Aug 05 Python
Python3爬虫学习之爬虫利器Beautiful Soup用法分析
Dec 12 Python
关于numpy中eye和identity的区别详解
Nov 29 Python
pytorch实现对输入超过三通道的数据进行训练
Jan 15 Python
python GUI库图形界面开发之PyQt5 MDI(多文档窗口)QMidArea详细使用方法与实例
Mar 05 Python
安装Anaconda3及使用Jupyter的方法
Oct 27 Python
详解python os.path.exists判断文件或文件夹是否存在
Nov 16 Python
Python3.9.1中使用match方法详解
Feb 08 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 将逗号、空格、回车分隔的字符串转换为数组的函数
2012/06/07 PHP
php去除换行(回车换行)的三种方法
2014/03/26 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
2018/10/31 PHP
说明你的Javascript技术很烂的五个原因
2011/04/26 Javascript
JavaScript数值数组排序示例分享
2014/05/27 Javascript
JavaScript利用HTML DOM进行文档操作的方法
2016/03/28 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
2016/07/09 Javascript
js完整倒计时代码分享
2016/09/18 Javascript
JS限定手机版中图片大小随分辨率自动调整的方法
2016/12/05 Javascript
实例解析Array和String方法
2016/12/14 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
2017/02/05 Javascript
vue-resourse将json数据输出实例
2017/03/08 Javascript
Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程
2017/05/07 Javascript
了解VUE的render函数的使用
2017/06/08 Javascript
Vue.2.0.5实现Class 与 Style 绑定的实例
2017/06/20 Javascript
js实现本地时间同步功能
2017/08/26 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
微信小程序防止多次点击跳转(函数节流)
2019/09/19 Javascript
vue之延时刷新实例
2019/11/14 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
2020/04/09 Javascript
JavaScript原生数组函数实例汇总
2020/10/14 Javascript
[01:18:33]Secret vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[01:47]2018年度DOTA2最具人气解说-完美盛典
2018/12/16 DOTA
Python的Django框架中settings文件的部署建议
2015/05/30 Python
在Lighttpd服务器中运行Django应用的方法
2015/07/22 Python
PyQt编程之如何在屏幕中央显示窗体的实例
2019/06/18 Python
python脚本监控logstash进程并邮件告警实例
2020/04/28 Python
利用Python如何实时检测自身内存占用
2020/05/09 Python
详解KMP算法以及python如何实现
2020/09/18 Python
欧洲最大的拼图游戏商店:JigsawPuzzle.co.uk
2018/07/04 全球购物
学年自我鉴定
2014/01/16 职场文书
大学生饮食连锁店创业计划书
2014/01/17 职场文书
小学领导班子对照材料
2014/08/23 职场文书
老人院义工活动感想
2015/08/07 职场文书