为了能够模拟登陆QQ,并获取信息。对扫码登录微信进行了分析。简单的用了一下Django将获取的信息映射到页面上。(python3+pycharm)

主要过程就是:

1、获取二维码

2、扫码登录(有三种状态)

3、获取联系人信息(index页面获取的是个人信息、最近联系人信息、公众号)

4、获取所有的联系人

5、发送和接收消息(接收消息打印到了后台)

创建Django项目、导入JQuery(发送AJax请求)、创建APP、创建模板(简单的弄一下,能合理显示得到的数据就好)

url.py

from django.contrib import admin
# from django.urls import path
from django.conf.urls import url
from app01 import views
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^$', views.login), # 显示登录二维码
url(r'^polling/$', views.long_polling), # 长轮询
url(r'^index/$', views.index), #
url(r'^contact_list/$', views.contact_list),# 获取全部的联系人
url(r'^send_msg/$', views.send_msg), # 发送消息
url(r'^get_msg/$', views.get_msg), # 接收消息
]

templates

login.html(对应的是views中函数login和long_polling)

扫码前

扫码后、没有点击登录按钮,显示的你的头像

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <div style="margin: 0 auto;width: 300px">
<img id="qcode" style="width: 300px;height: 300px" src="https://login.weixin.qq.com/qrcode/{{ code }}" alt="扫码登录">
</div> <script src="/static/jquery-1.12.4.js"></script>
<script>
$(function () { polling();
});
function polling(){
$.ajax({
url: '/polling/',
type: 'GET',
dataType: 'json',
success: function (arg) {
if(arg.status==408){
console.log(1); polling();
}else if(arg.status==201){
$('#qcode').attr('src',arg.data);
polling(); }else if(arg.status==200) {
window.location.href ='/index/';
} } })
}
</script>
</body>
</html>

index.html(个人信息、最近联系人、公众号页面)

点击登录后的页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>个人信息</h1>
<div>
{# <img src="https://wx.qq.com{{ data.User.HeadImgUrl }}">#}
<img style="width: 40px;height: 40px" src={{ code }}>
</div>
<div>
{{ data.User.NickName }} - {{ data.User.UserName }}
</div>
<h1>最近联系人列表</h1>
<ul>
{% for row in data.ContactList%}
<li>{{ row.UserName }} - {{ row.NickName }}</li>
{% endfor %}
<li><a href="/contact_list/">获取更多联系人</a></li>
</ul> <h1>公众号</h1>
{% for row in data.MPSubscribeMsgList%}
<div style="font-weight: bolder">{{ row.NickName }}</div>
{% for i in row.MPArticleList %}
<div>
<div><a href="{{ i.Url }}">{{ i.Title }}</a></div>
<div style="color: #dddddd">{{ i.Digest }}</div>
</div> {% endfor %} {% endfor %} </body>
</html>

contac_list(全部联系人、发送接收页面)

页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>发送消息</h1>
<div> <p><input id="user_id" type="text" placeholder="请输入用户唯一ID" /></p>
<p><input id='user_msg' type="text" placeholder="请输入内容" /></p>
<input id="sendMsg" type="button" value="提交" />
</div>
<ul>
{% for row in obj.MemberList %}
<li>{{ row.NickName }} - {{ row.UserName }} -{{ row.Province }}</li>
{% endfor %}
</ul>
<script src="/static/jquery-1.12.4.js"></script>
<script>
$(function () {
bindSendMessage();
fetchMessage();
});
function bindSendMessage() {
$('#sendMsg').click(function () {
$.ajax({
url: '/send_msg/',
type: 'POST',
data: {'user_id': $('#user_id').val(), 'user_msg': $('#user_msg').val()},
success:function () { }
})
});
} function fetchMessage(){
$.ajax({
url: '/get_msg/',
type: 'GET',
success:function (arg) {
fetchMessage();
}
})
}
</script>
</body>
</html>

views.py(逻辑层)

import re
import time
import json
import requests
from bs4 import BeautifulSoup
from django.shortcuts import render, HttpResponse
# Create your views here. # 一些全局变量
# 当前时间戳
CURRENT_TIME = None
# 验证码
QCODE = None
#图片
PICTURE = None
# tip
TIP = 1
# LOGININ cookies
# all_cookie_dict = {}
# 保存cookies
LOGIN_COOLIES_DICT = {}
TICKET_COOKIES_DICT = {}
TICKET_DICT = {}
# 用户信息
USER_INIT_DATA = {} def login(request):
'''
获取登录二维码
:param request:
:return:
'''
global QCODE
global CURRENT_TIME 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&_={0}'
CURRENT_TIME = str(time.time())
q_code_url = url.format(CURRENT_TIME)
response = requests.get(q_code_url)
# 打印返回值
# window.QRLogin.code = 200; window.QRLogin.uuid = "4c5VeLH00g==";
# print(response.text)
code = re.findall('uuid = "(.*)";', response.text)[0]
QCODE = code
# print(code)
return render(request, 'login.html', {'code': code}) def long_polling(request):
'''
长轮询,有408、201、200三种状态
:param request:
:return:
''' global TIP
global PICTURE
print('polling') # 默认返回Ajax状态为408
ret = {'status': 408, 'data': None}
base_login_url = 'https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip={1}&r=970980966&_={1}'
login_url = base_login_url.format(QCODE, TIP, CURRENT_TIME)
response = requests.get(login_url)
# print(response.text) # 判断
if 'window.code=201' in response.text:
TIP = 0
# 图片地址
avatar = re.findall("userAvatar = '(.*)';", response.text)[0]
# print(avatar)
ret['data'] = avatar
ret['status'] = 201
# 获得个人信息头像使用(index函数中,直接在函数返回值中提取链接获取不到图片)
PICTURE = avatar elif 'window.code=200' in response.text:
# 获取登录时的cookie值,存到全局变量中
LOGIN_COOLIES_DICT.update(response.cookies.get_dict())
# 提取返回值中的url地址
redirect_uri = re.findall('redirect_uri="(.*)";', response.text)[0]
redirect_uri += '&fun=new&version=v2' # 获取以后要用到的ticket等数据
response_ticket = requests.get(redirect_uri, cookies=LOGIN_COOLIES_DICT)
TICKET_COOKIES_DICT.update(response_ticket.cookies.get_dict())
# print(response_ticket.text)
# soup1 = BeautifulSoup(response_ticket.text, 'lxml')
soup2 = BeautifulSoup(response_ticket.text, 'html.parser')
# print(soup1)
# print(soup2)
for tag in soup2.find():
TICKET_DICT[tag.name] = tag.string
# print(TICKET_DICT)
ret['status'] = 200
return HttpResponse(json.dumps(ret)) def index(request):
'''
获取个人信息、最近联系人、公众号
:param request:
:return:
'''
# 用户初始化
user_init_url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=855409185&pass_ticket=%s' % TICKET_DICT['pass_ticket']
form_data = {
'BaseRequest': {
'DeviceID': 'e531777446530354',
'Sid': TICKET_DICT['wxsid'],
'Skey': TICKET_DICT['skey'],
'Uin': TICKET_DICT['wxuin']
}
} # 带上所有的coolkie
all_cookie_dict = {}
all_cookie_dict.update(LOGIN_COOLIES_DICT)
all_cookie_dict.update(TICKET_COOKIES_DICT)
# json= 发送过去会自动带一个请求头,用json解析
response_init = requests.post(user_init_url, json=form_data, cookies=all_cookie_dict)
# print(response_init.text)
response_init.encoding = 'utf-8'
# print(response_init.text)
user_init_data = json.loads(response_init.text)
USER_INIT_DATA.update(user_init_data) return render(request, 'index.html', {'data': user_init_data, 'code':PICTURE}) def contact_list(request):
'''
获取所有联系人列表
:param request:
:return:
'''
# print(all_cookie_dict)
# print(TICKET_DICT)
# print(LOGIN_COOLIES_DICT)
# print(TICKET_COOKIES_DICT) url = ("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=%s&r=%s&seq=0&skey=%s" % \
(TICKET_DICT['pass_ticket'], str(time.time()), TICKET_DICT['skey']))
# base_url = '{0} {1} {2}'
# url = base_url.format(TICKET_DICT['pass_ticket'], str(time.time()), TICKET_DICT['skey'])
# print(base_url)
all_cookie_dict = {}
all_cookie_dict.update(LOGIN_COOLIES_DICT)
all_cookie_dict.update(TICKET_COOKIES_DICT)
response = requests.get(url, cookies=all_cookie_dict)
response.encoding = 'utf-8'
contact_list_dict = json.loads(response.text)
# print(contact_list_dict)
return render(request, 'contact_list.html', {'obj': contact_list_dict})
# return HttpResponse("ok") def send_msg(request):
'''
发送消息
:param request:
:return:
'''
# print(USER_INIT_DATA)
# print(TICKET_DICT)
# print(LOGIN_COOLIES_DICT)
# print(TICKET_COOKIES_DICT)
from_user_id = USER_INIT_DATA['User']['UserName']
to_user_id = request.POST.get('user_id')
msg = request.POST.get('user_msg')
send_url = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg'
form_data = {
'BaseRequest': {
'DeviceID': 'e531777446530354',
'Sid': TICKET_DICT['wxsid'],
'Skey': TICKET_DICT['skey'],
'Uin': TICKET_DICT['wxuin']
},
'Msg': {
"ClientMsgId": str(time.time()),
#"Content": msg,
"Content": '%(content)s',
"FromUserName": from_user_id,
"LocalID": str(time.time()),
"ToUserName": to_user_id,
"Type": 1
},
'Scene': 0
}
import json
# 字符串
form_data_str = json.dumps(form_data)
# 进行格式化
form_data_str = form_data_str % {'content': msg} # 转换成字节
form_data_bytes = bytes(form_data_str, encoding='utf-8') all_cookie_dict = {}
all_cookie_dict.update(LOGIN_COOLIES_DICT)
all_cookie_dict.update(TICKET_COOKIES_DICT) # response = requests.post(send_url, json=form_data, cookies=all_cookie_dict)
response = requests.post(send_url, data=form_data_bytes, cookies=all_cookie_dict, headers={
'Content-Type': 'application/json'})
print(response.text)
return HttpResponse('OK') def get_msg(request):
sync_url = 'https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck' sync_data_list = []
for item in USER_INIT_DATA['SyncKey']['List']:
temp = "%s_%s" % (item['Key'], item['Val'])
sync_data_list.append(temp)
sync_data_str = "|".join(sync_data_list)
nid = int(time.time())
sync_dict = {
"r": nid,
"skey": TICKET_DICT['skey'],
"sid": TICKET_DICT['wxsid'],
"uin": TICKET_DICT['wxuin'],
"deviceid": "e531777446530354",
"synckey": sync_data_str
}
all_cookie = {}
all_cookie.update(LOGIN_COOLIES_DICT)
all_cookie.update(TICKET_COOKIES_DICT)
response_sync = requests.get(sync_url, params=sync_dict, cookies=all_cookie)
print(response_sync.text)
if 'selector:"2"' in response_sync.text:
fetch_msg_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=%s&skey=%s&lang=zh_CN&pass_ticket=%s" % (
TICKET_DICT['wxsid'], TICKET_DICT['skey'], TICKET_DICT['pass_ticket']) form_data = {
'BaseRequest': {
'DeviceID': 'e531777446530354',
'Sid': TICKET_DICT['wxsid'],
'Skey': TICKET_DICT['skey'],
'Uin': TICKET_DICT['wxuin']
},
'SyncKey': USER_INIT_DATA['SyncKey'],
'rr': str(time.time())
}
response_fetch_msg = requests.post(fetch_msg_url, json=form_data)
response_fetch_msg.encoding = 'utf-8'
res_fetch_msg_dict = json.loads(response_fetch_msg.text)
USER_INIT_DATA['SyncKey'] = res_fetch_msg_dict['SyncKey']
for item in res_fetch_msg_dict['AddMsgList']:
print(item['Content'], ":::::", item['FromUserName'], "---->", item['ToUserName'],)
return HttpResponse('ok')

爬虫入门简单,想要深入果然很难。继续努力,加油!

十一、模拟扫码登录微信(用Django简单的布置了下页面)发送接收消息的更多相关文章

  1. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  2. 第三方登录:微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  3. php微信开放平台--第三方网页微信扫码登录(OAuth2.0)

    第一.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提 ...

  4. Web应用多账号系统设计及微信扫码登录实现

    Web应用多账号系统设计及微信扫码登录实现 1   前言概述 公司对功能测试,性能测试,安全测试等等都做了比较好的自动化后,急需要一个MIS系统来统一管理这些结果及报表. 此MIS系统特点如下: 仅内 ...

  5. C#开发微信门户及应用(45)--微信扫码登录

    在前面随笔<C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理>介绍了基于微信开放平台接口实现的微信扫码直接登录的过程.本篇介绍对扫码登录的一些改进和处理,以便更方便应用在实 ...

  6. C#开发微信门户及应用(41)--基于微信开放平台的扫码登录处理

    在现今很多网站里面,都使用了微信开放平台的扫码登录认证处理,这样做相当于把身份认证交给较为权威的第三方进行认证,在应用网站里面可以不需要存储用户的密码了.本篇介绍如何基于微信开放平台的扫码进行网站的登 ...

  7. 微信小程序使用场景延伸:扫码登录、扫码支付

    微信小程序使用场景延伸:扫码登录.扫码支付 小程序最适合的使用场景有哪些?相比大家能列举出来很多,但这个场景,大家可能多数没想到_^ 笔者团队近期接到了一个PC项目:转转游戏租号PC官网,该项目要求在 ...

  8. Vue+abp微信扫码登录

    最近系统中要使用微信扫码登录,根据微信官方文档和网络搜索相关文献实现了.分享给需要的人,也作为自己的一个笔记.后端系统是基于ABP的,所以部分代码直接使用了abp的接口,直接拷贝代码编译不通过. 注册 ...

  9. Java实现微信客户端扫码登录

    此篇文章记录自己开发中的微信客户端扫码登录的实例以及步骤,便于以后自行学习记起的关键,看到的网友有借鉴的地方就借鉴,看不懂的也请别吐槽,毕竟每个人的思维和思路以及记录东西的方式不一样: 1.首先需要一 ...

随机推荐

  1. 【Webpack】NodeJS + Webpack

    目的:想要通过npm命令按照我们的规则生成静态资源(webpack4以后还能做到很多性能优化的配置,我所知道的只有css.js分包,以达到资源快速加载快速呈现的效果). 一.安装webpack npm ...

  2. java初探(1)之防止库存为负以及防超买

    在秒杀业务中,会出现当只剩一个库存时,但有多个人仍然秒杀成功,且都减库存成功,因此,在减库存,更新数据库的时候,需要在sql语句上进行判断,是否库存大于0. @Update("update ...

  3. 深入了解Redis【一】源码下载与参考资料准备

    引言 一直在使用redis,但是却没有系统的了解过它的底层实现,准备边学习边记录,深入了解redis. 打算分析以下几个方面: redis的基本类型及底层原理与java对比,每种数据类型的使用场景 r ...

  4. Jmeter逻辑控制器,简单操作

    1. 2. 循环控制器可以设置请求的循环次数或永久循环, .  作用:改控制器下的取样器请求可以循环运行. 3. 请求需要拖拽到循环控制器里, 4.循环次数乘以线程数 得到如下图: 成功了 二. 事务 ...

  5. css动画实现吃豆豆

    话不多说,直接上代码:(作为一个初学者写的代码,多么0基础都能看的懂吧.) HTML部分 <!DOCTYPE html> <html lang=en> <head> ...

  6. DVWA_sql injection(low)

    这里主要记录下做题时的思路以及步骤,不查看源码也不对源码进行分析.(我这个dvwa是一个在线靶场,所以我也不确定是否与本地靶场有些许出入) 1.Low 将难度调为Low级别后,来到如下界面 首先输入一 ...

  7. JVM学习第三天(JVM的执行子系统)之类加载机制补充

    昨晚没看完,今天继续 系统的类加载器 对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间.这句话可以表达得更通俗一些: ...

  8. 用Maven给一个Maven工程打包,使用阿里云镜像解决mvn clean package出错的问题,使用plugin解决没有主清单属性的问题

    本来在STS里做了一个极简Maven工程,内中只有一个Main方法的Java类,然后用新装的Maven3.6.3给它打包. 结果,Maven罢工,输出如下: C:\personal\programs\ ...

  9. win10家庭版启用远程桌面

    此电脑右键属性->远程设置->允许远程协助连接这台计算机 勾选 下载RDP Wrapper 地址:https://github.com/stascorp/rdpwrap/releases ...

  10. matlab中矩阵的表示与简单操作

    原文地址为:matlab矩阵的表示和简单操作 一.矩阵的表示在MATLAB中创建矩阵有以下规则: a.矩阵元素必须在”[ ]”内: b.矩阵的同行元素之间用空格(或”,”)隔开: c.矩阵的行与行之间 ...