您当前的位置:首页 > 计算机 > 编程开发 > Python

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

时间:09-16来源:作者:点击数:

python爬虫学习------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

# 解决某些环境下报<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
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()

运行结果:

发送信息

发送成功后的响应结果

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门