热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python爬虫学习python登录微信获取联系人信息,并向联系人发送信息

python登录微信获取联系人信息,并向联系人发送信息 #!usrbinenvpython#-*-coding:utf-8-*-#@Time:20183720:34#@Author

python登录微信获取联系人信息,并向联系人发送信息

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/3/7 20:34
# @Author  : hyang
# @Site    :
# @File    : weixin_test.py
# @Software: PyCharm

import json
import hashlib as hasher
import requests
import random
import time
import ssl
import urllib3
import re
from bs4 import BeautifulSoup
from PIL import Image  # pip install pillow
from urllib import parse

# https://wx.qq.com/
"""
访问首页
https://login.weixin.qq.com/qrcode/gZtXpqySmA==
https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1520439689629
获得uuid
扫描二维码登录后返回一个链接
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ATAjHkeQox2qNj3HcDSIX1lJ@qrticket_0&uuid=gZtXpqySmA==&lang=zh_CN&scan=1520439709";
请求上面返回地址 获取返回的参数
用户初始化
url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-21266882&pass_ticket={}".format(self.pass_ticket)
获取联系人username与nickname字典信息:
url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?pass_ticket={}&r=1520439753654&seq=0&skey={}'.format(
            self.pass_ticket, self.skey)
向联系人发送信息:
url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket={}'.format(self.pass_ticket)
"""
import urllib3

# 解决某些环境下报
ssl._create_default_https_cOntext= ssl._create_unverified_context
urllib3.disable_warnings()  # 关闭警告


class WxBot(object):
    def __init__(self):
        self.session = requests.Session()
        self.session.verify = False  # 忽略证书认证
        self.session.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
        }
        self.contact_dict = {}  # 联系人字典存储UserName和NickName

    def get_clientId(self):
        """
        解析ClientMsgId
        js代码
        e.ClientMsgId = e.LocalID = e.MsgId = (utilFactory.now() + Math.random().toFixed(3)).replace(".", "")
        :return: 
        """
        self.client_id = str(int(time.time()*1000)) + str(random.random())[:5].replace(".","")

    def get_uuid(self):
        """
        获取uuid
        :return:
        """
        url = 'https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1520439689629'
        result = self.session.get(url).text
        print(result)
        self.uuid = re.findall(r'uuid = "(.*?)"', result)[0]
        print(self.uuid, "uuid已获取")

    def get_qcode(self):
        """
         获取扫描二维码
        :return:
        """
        url = "https://login.weixin.qq.com/qrcode/{}".format(self.uuid)
        with open('qcode.jpg', 'wb') as f:
            f.write(self.session.get(url).content)  # 图片内容用content获取
        image = Image.open('qcode.jpg')  # 读取图片对象
        image.show()  # 调用系统默认方式打开图片
        print('已扫描')

    def visit_login(self):
        url = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={}&tip=0&r=-21311978&_=1520439689632".format(
            self.uuid)
        while True:
            result = self.session.get(url).text
            if '200' in result:
                self.redirect_url = re.findall(r'redirect_uri="(.*?)"', result)[0]
                break
        #print(self.redirect_url)
        print('登录成功')

    # 解析重定向的url
    def visit_parse(self):
        result = self.session.get(self.redirect_url, allow_redirects=False)
        soup = BeautifulSoup(result.text, 'lxml')
        self.skey = soup.find('skey').text
        self.wxsid = soup.find('wxsid').text
        self.wxuin = soup.find('wxuin').text
        self.pass_ticket = soup.find('pass_ticket').text
        self.isgrayscale = soup.find('isgrayscale').text

    def visit_init(self):
        """
        初始化
        :return:
        """
        url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-21266882&pass_ticket={}".format(self.pass_ticket)
        data = {"BaseRequest":
                    {"Uin": self.wxuin,
                     "Sid": self.wxsid,
                     "Skey": self.skey,
                     "DeviceID": self.DeviceID}}
        result = self.session.post(url, data=json.dumps(data))
        result.encoding = 'utf-8'
        # print(result.text)

    # 得到js参数DeviceID
    def get_DeviceID(self):
        """
        js代码https://res.wx.qq.com/a/wx_fed/webwx/res/static/js/index_ca360ff.js
        getDeviceID:function(){return"e"+(""+Math.random().toFixed(15)).substring(2,17)},
        :return:
        """
        self.DeviceID = 'e' + str(round(random.random(), 15))[2:17]

    # 获得所有联系人 建立username和nickname对应的字典
    def get_contact(self):
        url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?pass_ticket={}&r=1520439753654&seq=0&skey={}'.format(
            self.pass_ticket, self.skey)
        result = self.session.get(url)
        result.encoding = 'utf-8'
        contact_dict = result.json()
        print('获得联系人数:', contact_dict['MemberCount'])
        for item in contact_dict.get('MemberList'):
            self.contact_dict[item['NickName']] = item['UserName']
        print(self.contact_dict)

    # 发送信息函数
    def send_msg(self):
        url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket={}'.format(self.pass_ticket)
        data = {"BaseRequest":
                 dict(Uin=self.wxuin, Sid=self.wxsid, Skey=self.skey, DeviceID=self.DeviceID),
                "Msg": {"Type": 1, 'Content': "你好,节日快乐",
                "FromUserName": self.contact_dict["杨皓彭"],
                "ToUserName": self.contact_dict["千懿"],
                "LocalID": self.client_id,
                "ClientMsgId": self.client_id}, "Scene": 0}
        """
        我们在post请求数据时,响应的内容是json数据,但是返回的json数据中文显示有问题,
        变成 \\uXXX的形式。这是因为中文以 unicode 编码了,
        而默认是以ASCII解析的,中文不在ASCII编码中,所以无法显示
       """
        print((json.dumps(data, ensure_ascii= False, indent= 4)))  # 加入ensure_ascii= False,可使中文正常转换
        result = self.session.post(url, data=json.dumps(data, ensure_ascii=False, indent=4).encode('utf-8'))  # 转换为utf-8
        result.encoding = 'utf-8'
        print('消息发送成功' if result.json().get('BaseResponse')['Ret'] == 0 else '消息发送失败' )

if __name__ == '__main__':
    wx = WxBot()
    wx.get_clientId()
    wx.get_uuid()
    wx.get_qcode()
    wx.visit_login()
    wx.visit_parse()
    wx.get_DeviceID()
    wx.visit_init()
    wx.get_contact()
    wx.send_msg()

 

运行结果:

python爬虫学习------python登录微信获取联系人信息,并向联系人发送信息

发送信息

python爬虫学习------python登录微信获取联系人信息,并向联系人发送信息

发送成功后的响应结果

python爬虫学习------python登录微信获取联系人信息,并向联系人发送信息

 


推荐阅读
  • 基于SSM框架的在线考试系统:随机组卷功能详解
    本文深入探讨了基于SSM(Spring, Spring MVC, MyBatis)框架构建的在线考试系统中,随机组卷功能的设计与实现方法。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文介绍如何通过Java代码调用阿里云短信服务API来实现短信验证码的发送功能,包括必要的依赖添加和关键代码示例。 ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 本文介绍了两个重要的Node.js库——cache-content-type和mime-types,它们在处理HTTP响应头时非常有用。cache-content-type是基于mime-types构建的,并且实现了缓存机制以提高性能。 ... [详细]
  • 本文详细介绍了Golang中string类型的内部结构及其特性,包括字符串的定义、表示方式、数据结构以及相关的操作方法,如字符串拼接和类型转换等。 ... [详细]
  • 现在的新手程序猿,动不动就是框架,就连外面培训的也是框架,我就问一句,没了框架是不是就啥也不会了 ... [详细]
  • 本文总结了在多人协作开发环境中使用 Git 时常见的问题及其解决方案,包括错误合并分支的处理、使用 SourceTree 查找问题提交、Git 自动生成的提交信息解释、删除远程仓库文件夹而不删除本地文件的方法、合并冲突时的注意事项以及如何将多个提交合并为一个。 ... [详细]
  • 使用jQuery与百度地图API实现地址转经纬度功能
    本文详细介绍了如何利用jQuery和百度地图API将地址转换为经纬度,包括申请API密钥、页面构建及核心代码实现。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • Django与Python及其他Web框架的对比
    本文详细介绍了Django与其他Python Web框架(如Flask和Tornado)的区别,并探讨了Django的基本使用方法及与其他语言(如PHP)的比较。 ... [详细]
author-avatar
hhqblog
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有