雨课堂模拟登陆_获取websocket数据

2021年09月16日 阅读数:2
这篇文章主要向大家介绍雨课堂模拟登陆_获取websocket数据,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

写在最前:互联网并不是法外之地,爬虫仅供技术交流python

运行环境web

  • python 3.7.4
  • requests 2.10.0
  • numpy 1.17.2
  • opencv-python 4.2.0.34

爬取目标json

  • 模拟登陆雨课堂

雨课堂目前的登陆流程

此次想跟你们分享一下websocket协议的爬虫怎么作。咱们以雨课堂的扫码登陆为例。api

雨课堂扫码登陆的流程是微信

  1. https://www.yuketang.cn/web?next=/v2/web/index&type=3页面加载完毕后,客户端与服务端创建websocket连接。
  2. 随即客户端发送一段数据,用于请求微信二维码。
  3. 服务端拿到数据后反馈二维码相关信息。
  4. 并每隔一段时间从新发送一次二维码信息(我记得以前测试的时候是这样的,可是最近好像都须要客户端重发,服务端才回馈啊,那这样用websocket的意义何在)。
  5. 客户端根据信息去请求二维码图片。
  6. 用户扫码,由移动客户端发送信息至服务端确认用户正在登陆。
  7. 服务端再经过websocket发送登陆的相关信息回客户端。
  8. 客户端拿到登陆的相关信息后post到login接口进行登陆,至此登陆成功。

具体步骤

1、找到websocket接口

雨课堂的websocket接口为wss://www.yuketang.cn/wsapp/websocket

headers其实能够不带,雨课堂好像没有作相关鉴权。以前好像看到网上有说要带Sec-WebSocket相关属性的headers,其实不用啊,这个使用websocket就会自动生成。session

2、查看websocket数据交流状况

数据 时间
WebSocket 链接已创建 1602385999.188397
{"op":"requestlogin","role":"web","version":1.4,"type":"qrcode","from":"web"} 1602385999.4041245
{"op":"requestlogin","loginid":19xxx22,"expire_seconds":60,"ticket":"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=xxxxxxxxx","qrcode":"http://weixin.qq.com/q/xxxxxxxxx"} 1602385999.4143353

第二行(不包含表头)的数据就是咱们须要发给客户端的。app

第三行就是他会反馈的数据,隐私信息已经打码。less

ticket就是登陆二维码的连接啦。socket

能够下载到本地而后用PIL这个库显示出来,用手机扫码,服务端就会经过websocket连接发送以下数据给咱们。

{"subscribe_status":true,
 "AppOpenID":"打码",
 "profile_edit_status":true,
 "UserID":"打码",
 "DateJoined":"2019-04-30T13:31:55",
 "Role":2,
 "LastLogin":"2019-04-30T13:34:18",
 "Department":"",
 "WeixinUnionID":"打码",
 "LastLoginIP":"打码",
 "noRecArticle":true,
 "Auth":"打码",
 "ppt_config_data":{},
 /*姓名、性别、年龄、头像、位置等相关信息已经所有删除*/
 "Language":"zh-cn",
 "is_self_set":false,
 "MinaOpenID":"",
 "isBind":true,
 "user_on_lessons":[],
 "AndroidOpenID":"",
 "op":"loginsuccess",
 "loginid":"打码"}

关键信息就是里面的UserID和Auth,是接下来登陆的关键。

3、登陆

咱们要先去GET这个连接https://www.yuketang.cn/v/course_meta/user_info获取一个csrftoken。

接着就能够将以前得到的UserID和Auth POST到https://www.yuketang.cn/pc/web_login获取sessionid,至此登陆成功。

具体的代码

import requests
import websocket
import json
import cv2 as cv
import numpy as np

userinfo = {}
session = requests.session()

def on_message(ws, message):
    global userinfo
    userinfo = json.loads(message)
    if 'subscribe_status' in userinfo:
        ws.close()
        return
    req = session.get(userinfo['ticket'])
    cv.namedWindow('input_image', cv.WINDOW_AUTOSIZE)
    cv.imshow('input_image', cv.imdecode(np.array(bytearray(req.content), dtype='uint8'), cv.IMREAD_UNCHANGED))
    cv.waitKey(0)
    cv.destroyAllWindows()
def on_error(ws, error):
    print(error)
def on_open(ws):
    ws.send(data=json.dumps({"op":"requestlogin","role":"web","version":1.4,"type":"qrcode","from":"web"}))
		print("open")

# websocket数据交互
ws = websocket.WebSocketApp("wss://www.yuketang.cn/wsapp/",
                                on_message = on_message,
                                on_error = on_error)
ws.on_open = on_open
ws.run_forever()

# 登陆
req = session.get("https://www.yuketang.cn/v/course_meta/user_info")
session.post("https://www.yuketang.cn/pc/web_login",data=json.dumps({'UserID':userinfo['UserID'],'Auth':userinfo['Auth']}))

# 获取本身的课程列表
req = session.get("https://www.yuketang.cn/v2/api/web/courses/list?identity=2")
print(json.loads(req.content))