#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Last Modified time: 2016-03-03 22:45:18
# @Description: 获取腾讯企业邮箱通讯录
import requests
import re
import rsa
import sys
import base64
import time
import argparse
reload(sys) sys.setdefaultencoding('utf8') # 打印部门人员信息
def print_tree(id, department_infos, level, staff_infors, f):
    prefix = '----' * level
    text = prefix + department_infos[id]['name'] + prefix
    print text
    f.write(text + '\n')
    for key, value in department_infos.items():
        if value['pid'] == id:
            print_tree(
                value['id'], department_infos, level + 1, staff_infors, f)
    prefix = '    ' * level
    for staff in staff_infors:
        if staff['pid'] == id:
            text = prefix + staff['name'] + '  ' + staff['alias']
            print text
            f.write(text + '\n') # 提取RSA算法的公钥
def get_public_key(content):
    regexp = r'var\s*PublicKey\s*=\s*"(\w+?)";'
    results = re.findall(regexp, content)
    if results:
        return results[0] # 获取ts参数
def get_ts(content):
    regexp = r'PublicTs\s*=\s*"([0-9]+)"'
    results = re.findall(regexp, content)
    if results:
        return results[0] # 计算p参数
def get_p(public_key, password, ts):
    public_key = rsa.PublicKey(int(public_key, 16), 65537)
    res_tmp = rsa.encrypt(
        '{password}\n{ts}\n'.format(password=password, ts=ts), public_key)
    return base64.b64encode(res_tmp) def msg():
    return 'python get_tencent_exmail_contacts.py -u name@domain.com -p passw0rd' if __name__ == "__main__":
    description = "获取腾讯企业邮箱通讯录"
    parser = argparse.ArgumentParser(description=description, usage=msg())
    parser.add_argument(
        "-u", "--email", required=True, dest="email", help="邮箱名")
    parser.add_argument(
        "-p", "--password", required=True, dest="password", help="邮箱密码")
    parser.add_argument(
        "-l", "--limit", required=False, dest="limit", default=10000, help="通讯录条数")
    parser.add_argument(
        "-e", "--efile", required=False, dest="emailfile", default="emails.txt", help="邮箱保存文件")
    parser.add_argument(
        "-d", "--dfile", required=False, dest="departfile", default="departments.txt", help="部门信息保存文件")
    args = parser.parse_args()
    email = args.email
    password = args.password
    limit = args.limit
    emailfile = args.emailfile
    departfile = args.departfile
    session = requests.Session()     headers = {'Connection': 'keep-alive',
               'Cache-Control': 'max-age=0',
               'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
               'Upgrade-Insecure-Requests': 1,
               'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
               'DNT': 1,
               'Accept-Encoding': 'gzip, deflate, sdch',
               'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4',
               }
    resp = session.get('http://exmail.qq.com/login', headers=headers)
    content = resp.content     public_key = get_public_key(content)     ts = get_ts(content)     p = get_p(public_key, password, ts)     # print ts
    # print public_key
    # print p     uin = email.split('@')[0]
    domain = email.split('@')[1]
    # print uin
    # print domain     post_data = {}
    post_data['sid'] = ''
    post_data['firstlogin'] = False
    post_data['domain'] = domain
    post_data['aliastype'] = 'other'
    post_data['errtemplate'] = 'dm_loginpage'
    post_data['first_step'] = ''
    post_data['buy_amount'] = ''
    post_data['year'] = ''
    post_data['company_name'] = ''
    post_data['is_get_dp_coupon'] = ''
    post_data['starttime'] = int(time.time() * 1000)
    post_data['redirecturl'] = ''
    post_data['f'] = 'biz'
    post_data['uin'] = uin
    post_data['p'] = p
    post_data['delegate_url'] = ''
    post_data['ts'] = ts
    post_data['from'] = ''
    post_data['ppp'] = ''
    post_data['chg'] = 0
    post_data['loginentry'] = 3
    post_data['s'] = ''
    post_data['dmtype'] = 'bizmail'
    post_data['fun'] = ''
    post_data['inputuin'] = email
    post_data['verifycode'] = ''     headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    url = 'https://exmail.qq.com/cgi-bin/login'
    resp = session.post(url, headers=headers, data=post_data)     regexp = r'sid=(.*?)"'     sid = re.findall(regexp, resp.content)[0]
    url = 'http://exmail.qq.com/cgi-bin/laddr_biz?action=show_party_list&sid={sid}&t=contact&view=biz'
    resp = session.get(url.format(sid=sid))     text = resp.text
    regexp = r'{id:"(\S*?)", pid:"(\S*?)", name:"(\S*?)", order:"(\S*?)"}'
    results = re.findall(regexp, text)
    department_ids = []
    department_infor = dict()
    root_department = None
    for item in results:
        department_ids.append(item[0])
        department = dict(id=item[0], pid=item[1], name=item[2], order=item[3])
        department_infor[item[0]] = department
        if item[1] == 0 or item[1] == '':
            root_department = department     regexp = r'{uin:"(\S*?)",pid:"(\S*?)",name:"(\S*?)",alias:"(\S*?)",sex:"(\S*?)",pos:"(\S*?)",tel:"(\S*?)",birth:"(\S*?)",slave_alias:"(\S*?)",department:"(\S*?)",mobile:"(\S*?)"}'     all_emails = []
    staff_infors = []
    for department_id in department_ids:
        url = 'http://exmail.qq.com/cgi-bin/laddr_biz?t=memtree&limit={limit}&partyid={partyid}&action=show_party&sid={sid}'
        resp = session.get(
            url.format(limit=limit, sid=sid, partyid=department_id))
        text = resp.text
        results = re.findall(regexp, text)         for item in results:
            all_emails.append(item[3])
            print item[3]
            staff = dict(uin=item[0], pid=item[1], name=item[2], alias=item[3], sex=item[4], pos=item[
                         5], tel=item[6], birth=item[7], slave_alias=item[8], department=item[9], mobile=item[10])
            staff_infors.append(staff)     with open(emailfile, 'w') as f:
        for item in all_emails:
            f.write(item + '\n')     with open(departfile, 'w') as f:
        print_tree(root_department['id'], department_infor, 0, staff_infors, f)     print("total email count: %i" % len(all_emails))
    print("total department count: %i" % len(department_ids))

获取QQ企业邮箱通讯录PY脚本的更多相关文章

  1. django使用QQ企业邮箱发送邮件

    一.首先申请QQ企业邮箱 免费QQ企业邮箱地址如下:https://exmail.qq.com/signupfree?refer=intro#signup/free 二.配置自己的域名 在域名解析中添 ...

  2. 腾讯QQ企业邮箱在ruby on rails 框架中的mailer配置

    在编写ruby on rails程序时,我们可能会需要用到发送邮件的程序,如果使用gmail进行smtp发送一般问题不大,但很多企业使用的是腾讯QQ企业邮箱.使用该邮箱进行链接时出现各种错误,goog ...

  3. Gitlab使用QQ企业邮箱发送邮件

    注册QQ企业邮箱 地址 https://exmail.qq.com/signupfree?refer=intro#signup/free 注册完成后解析 编辑/etc/gitlab/gitlab.rb ...

  4. Python qq企业邮箱发送邮件

    Python qq企业邮箱发送邮件 进入客户端设置: 下面是代码部分: from email.header import Header from email.mime.text import MIME ...

  5. 配置QQ企业邮箱小结

    https://exmail.qq.com/login 1,注册管理员账号 2,添加域名 3.设置MX记录 记录类型选:MX记录 主机记录(RR):不填(非万网可以填写@) 记录值与MX优先级分别为: ...

  6. 腾讯QQ企业邮箱POP3/SMTP设置

    腾讯企业邮箱支持通过client进行邮件管理. POP3/SMTP协议 收发邮件server地址分别例如以下. 接收邮件server:pop.exmail.qq.com (port 110) 发送邮件 ...

  7. QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)

    原来有个教程是关于Javamail的,但是那个是自己写Javamail的发送过程,这次不同的是:使用Spring的Mail功能,使用了消息队列. 先看一下设想的场景 不过本文重点不是消息队列,而是使用 ...

  8. panabit允许一台代理服务器只能收QQ企业邮箱,和内网ip通讯,限制除了QQ企业邮箱以外的所有内容规则

    环境: 可访公网网的内网网段:192.168.0.0/24(员工网段)  192.168.2.0/24(服务器网段)两个内网网段. 不能访问公网的内网网段:192.168.4.0/24 4网段利用fo ...

  9. C# 发送邮件,QQ企业邮箱测试成功

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

随机推荐

  1. 【Oracle】悲观锁和乐观锁

    悲观锁     如select * for update     悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性.但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样  ...

  2. OSG中的HUD

    OSG中的HUD 所谓HUD节点,说白了就是无论三维场景中的内容怎么改变,它都能在屏幕上固定位置显示的节点. 实现要点: 关闭光照,不受场景光照影响,所有内容以同一亮度显示 关闭深度测试 调整渲染顺序 ...

  3. DBLink创建 ORA-12154: TNS: 无法解析指定的连接标识符

    因为对oracle不了解,这个问题可TM的搞了好久! 走的弯路: 1. 在客服端的PLSQL连接工具上折腾,而不是在服务器的PLSQL解决 2. 配置的tnsnames.org文件在环境变量path( ...

  4. Oracle 数值函数

    上一次整理了一下Oracle字符串中常用的函数,接下来就整理一下Oracle数值方面的一些常用的函数. 1.NVL 空值转换函数,请注意一下,任何包含NULL值的算术运算都会得到NULL,这个函数有点 ...

  5. HDU 2955(0-1背包问题)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#problem/M 题目: Description The aspir ...

  6. jquery插件之拖拽改变元素大小

    该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 此插件旨在实现目前较为流行的拖拽改变元素大小的效果,您可以根据自己的实际需求来设置被 ...

  7. javascript模块化应用

    这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生与变迁,展望ES6模块化标准的未来.经历过这段历史的人或许会感到沧桑,没经历过的人也应该知道这段历史. 无模块时代 在ajax还未提出 ...

  8. 9.20 java继承

    package liu0920; //继承 public class Person { //属性 姓名和年龄 private String name; private int age; //无参构造方 ...

  9. HDU 2546

    饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  10. unity3d插件Daikon Forge GUI 中文教程4-高级控件Checkbox和dropdownlis的使用

    第三节  高级的控件 Checkbox单选和多选.dropdownlis下拉列表.listbox列表框.progressbar进度条.richtextlabel富文本.slider滑块.textbox ...