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()
運行結果:
發送信息
發送成功后的響應結果