websocket--hook

  1. 代码不全,大致思路
  2. 原理:
  3. 浏览器(客户端):在浏览器中注入一段JS代码,与服务端建立连接。调用浏览器中的js方法,把返回的数据发送给服务端
  4. node启动js代码,监听某端口(客户端):服务端把参数(python发过来的)发送给客户端处理,并接收处理结果,再次把接收的结果返回给python处理
  5. python(调用者):把参数发送给node,接收node传回来的数据
  6. 优点:
  7. 1.对于js混淆加密较深的,可以采用此方法。
  8. 2.不用扣js加密代码,直接调用浏览器环境
  9. 缺点:
  10. 1.如果有selenium监测,要想使用此方法,必须先绕过selenium监测,否则只能使用真机进行js注入
  11. 2.需要node环境,写一个websocket服务端和客户端
  12. 3.速度没有直接破解js

服务端--WebSocketServer.js

  1. let iconv = require('iconv-lite')
  2. var ws = require("nodejs-websocket");
  3. console.log("开始建立连接...")
  4. var server = ws.createServer(function(conn){
  5. let cached = {};
  6. conn.on("text", function (msg) {
  7. if (!msg) return;
  8. // console.log("msg", msg);
  9. var key = conn.key;
  10. if ((msg === "Browser") || (msg === "Python")){
  11. // browser或者python第一次连接
  12. cached[msg] = key;
  13. // console.log("cached",cached);
  14. return;
  15. }
  16. if (Object.values(cached).includes(key)){
  17. // console.log(server.connections.forEach(conn=>conn.key));
  18. var targetConn = server.connections.filter(function(conn){
  19. return conn.key !== key;
  20. })
  21. // console.log("将要发送的实参:",msg);
  22. targetConn.forEach(conn=>{
  23. conn.send(msg);
  24. })
  25. }
  26. })
  27. conn.on("close", function (code, reason) {
  28. // console.log("关闭连接")
  29. });
  30. conn.on("error", function (code, reason) {
  31. console.log("异常关闭")
  32. });
  33. conn.on("connection", function (conn) {
  34. console.log(conn)
  35. });
  36. }).listen(10512)
  37. console.log("WebSocket建立完毕")

客户端注入JS代码

  1. createSocket();
  2. function createSocket() {
  3. window.ws = new WebSocket('ws://127.0.0.1:10512/');
  4. window.ws.onopen = function (e) {
  5. console.log("连接服务器成功");
  6. window.ws.send("Browser");
  7. }
  8. window.ws.onclose = function (e) {
  9. console.log("服务器关闭");
  10. setTimeout(createSocket, 60000);
  11. }
  12. window.ws.onerror = function () {
  13. console.log("连接出错");
  14. }
  15. window.ws.onmessage = function (e) {
  16. var xmlhttp = new glb.XMLHttpRequest();
  17. function state_Change() {
  18. if (xmlhttp.readyState == 4) {
  19. if (xmlhttp.status == 200) {
  20. let result = xmlhttp.responseText
  21. result = JSON.parse(result)
  22. result = JSON.stringify(result)
  23. // result = String.fromCharCode(result)
  24. //发送给Python
  25. // console.log(result);
  26. window.ws.send(result);
  27. } else {
  28. alert("Problem retrieving XML data");
  29. }
  30. }
  31. }
  32. xmlhttp.onreadystatechange = state_Change;
  33. xmlhttp.open('GET', e.data, true);
  34. xmlhttp.send(null);
  35. }
  36. }

python开端口

  1. # -*- coding: utf-8 -*-
  2. from sanic import Sanic
  3. from sanic.response import json
  4. import os
  5. import urllib3
  6. from toutiao2_文件方式.get_data import get_data
  7. from toutiao2_文件方式.get_user_id import get_user
  8. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  9. app = Sanic(__name__)
  10. @app.route("/get_user_id", methods=["GET"])
  11. def captcha_server(request):
  12. try:
  13. data = request.args
  14. media_id = data['media_id'][0]
  15. return get_user_id(media_id)
  16. except Exception as e:
  17. pass
  18. @app.route("/get_data", methods=["GET"])
  19. def captcha_server(request):
  20. try:
  21. data = request.args
  22. user_id = data['user_id'][0]
  23. offset = data['offset'][0]
  24. return get_res(user_id, offset)
  25. except Exception as e:
  26. pass
  27. def get_user_id(media_id):
  28. html = get_user(media_id)
  29. return html
  30. def get_res(user_id, offset):
  31. html = get_data(user_id,offset)
  32. return html
  33. if __name__ == "__main__":
  34. app.run(host="127.0.0.1", port=4007)

get_data.py 文件方式

  1. # -*- coding: utf-8 -*-
  2. import time
  3. from ws4py.client.threadedclient import WebSocketClient
  4. import _locale
  5. _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
  6. import urllib3
  7. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  8. class CG_Client(WebSocketClient):
  9. def opened(self):
  10. self.max_cursor = 0
  11. self.send("Python")
  12. def closed(self, code, reason=None):
  13. # print("Closed down:", code, reason)
  14. pass
  15. def received_message(self, resp):
  16. data = resp.data.decode("utf-8")
  17. write_data(data)
  18. ws.close()
  19. def write_data(data):
  20. with open('./data.txt', 'w', encoding='utf-8') as f:
  21. f.write(data)
  22. f.close()
  23. def get_data(user_id, offset):
  24. ws = CG_Client('ws://127.0.0.1:10512/')
  25. ws.connect()
  26. try:
  27. real_arg = f"/api/feed_backflow/profile_share/v1/?category=profile_article&visited_uid={user_id}&stream_api_version=82&request_source=1&offset={offset}&user_id={user_id}&appId=1286&appType=mobile_detail_web&isAndroid=true&isIOS=false&isMobile=true&cookie_enabled=true&screen_width=288&screen_height=511&browser_language=zh-CN&browser_platform=MacIntel&browser_name=firefox&browser_version=85.0.4183.83&browser_online=true&timezone_name=Asia%2FShanghai"
  28. time.sleep(0.1)
  29. ws.send(real_arg)
  30. ws.run_forever()
  31. except KeyboardInterrupt:
  32. print('异常关闭')
  33. ws.close()

get_user_id.py 文件方式

  1. # -*- coding: utf-8 -*-
  2. import time
  3. from ws4py.client.threadedclient import WebSocketClient
  4. import _locale
  5. _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
  6. import io
  7. import sys
  8. import urllib3
  9. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  10. # sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
  11. # media_id = sys.argv[1].split(',', 1)[0] # sys.argv--> [get_attention.py,user_id,cursor]
  12. class CG_Client(WebSocketClient):
  13. def opened(self):
  14. self.max_cursor = 0
  15. self.send("Python")
  16. def closed(self, code, reason=None):
  17. # print("Closed down:", code, reason)
  18. pass
  19. def received_message(self, resp):
  20. data = resp.data.decode("utf-8")
  21. write_user(data)
  22. ws.close()
  23. def write_user(data):
  24. with open('./user.txt', 'w', encoding='utf-8') as f:
  25. f.write(data)
  26. f.close()
  27. def get_user(media_id):
  28. ws = CG_Client('ws://127.0.0.1:10512/')
  29. ws.connect()
  30. try:
  31. real_arg = f"/user/profile/homepage/share/v7/?media_id={media_id}&request_source=1&appId=1286&appType=mobile_detail_web&isAndroid=true&isIOS=false&isMobile=true&cookie_enabled=true&screen_width=393&screen_height=882&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=85.0.4183.83&browser_online=true&timezone_name=Asia%2FShanghai"
  32. time.sleep(0.1)
  33. ws.send(real_arg)
  34. ws.run_forever()
  35. except KeyboardInterrupt:
  36. print('异常关闭')
  37. ws.close()

get_data.py 终端方式

  1. # -*- coding: utf-8 -*-
  2. import time
  3. from ws4py.client.threadedclient import WebSocketClient
  4. import _locale
  5. _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
  6. import io
  7. import sys
  8. import urllib3
  9. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  10. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
  11. user_id = sys.argv[1].split(',', 1)[0] # sys.argv--> [get_attention.py,user_id,cursor]
  12. offset = str(sys.argv[2])
  13. class CG_Client(WebSocketClient):
  14. def opened(self):
  15. print("连接成功")
  16. self.max_cursor = 0
  17. self.send("Python")
  18. def closed(self, code, reason=None):
  19. print("Closed down:", code, reason)
  20. def received_message(self, resp):
  21. data = resp.data.decode("utf-8")
  22. print(data)
  23. ws.close()
  24. try:
  25. ws = CG_Client('ws://127.0.0.1:10512/')
  26. ws.connect()
  27. real_arg = f"/api/feed_backflow/profile_share/v1/?category=profile_article&visited_uid={user_id}&stream_api_version=82&request_source=1&offset={offset}&user_id={user_id}&appId=1286&appType=mobile_detail_web&isAndroid=true&isIOS=false&isMobile=true&cookie_enabled=true&screen_width=288&screen_height=511&browser_language=zh-CN&browser_platform=MacIntel&browser_name=firefox&browser_version=85.0.4183.83&browser_online=true&timezone_name=Asia%2FShanghai"
  28. time.sleep(0.1)
  29. ws.send(real_arg)
  30. ws.run_forever()
  31. except KeyboardInterrupt:
  32. ws.close()

get_user_id.py 终端方式

  1. # -*- coding: utf-8 -*-
  2. import time
  3. from ws4py.client.threadedclient import WebSocketClient
  4. import _locale
  5. _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
  6. import io
  7. import sys
  8. import urllib3
  9. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  10. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
  11. media_id = sys.argv[1].split(',', 1)[0] # sys.argv--> [get_attention.py,user_id,cursor]
  12. class CG_Client(WebSocketClient):
  13. def opened(self):
  14. print("连接成功")
  15. self.max_cursor = 0
  16. self.send("Python")
  17. def closed(self, code, reason=None):
  18. print("Closed down:", code, reason)
  19. def received_message(self, resp):
  20. data = resp.data.decode("utf-8")
  21. # data = resp.data.decode("gbk")
  22. print(data)
  23. ws.close()
  24. try:
  25. ws = CG_Client('ws://127.0.0.1:10512/')
  26. ws.connect()
  27. real_arg = f"/user/profile/homepage/share/v7/?media_id={media_id}&request_source=1&appId=1286&appType=mobile_detail_web&isAndroid=true&isIOS=false&isMobile=true&cookie_enabled=true&screen_width=393&screen_height=882&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=85.0.4183.83&browser_online=true&timezone_name=Asia%2FShanghai"
  28. time.sleep(0.1)
  29. ws.send(real_arg)
  30. ws.run_forever()
  31. except KeyboardInterrupt:
  32. ws.close()

爬虫调用者

  1. import time
  2. import requests
  3. import json
  4. import urllib3
  5. from toutiao2_文件方式.get_user_id import get_user, CG_Client
  6. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  7. def open_user():
  8. with open('./user.txt', 'r', encoding='utf-8') as f:
  9. user = json.loads(f.read())
  10. f.close()
  11. return user
  12. def open_data():
  13. with open('./data.txt', 'r', encoding='utf-8') as f:
  14. data = json.loads(f.read())
  15. f.close()
  16. return data
  17. # media_id换user_id
  18. def start_ocean_toutiao_user_id(media_id):
  19. data = {
  20. 'media_id': media_id,
  21. }
  22. requests.get('http://127.0.0.1:4007/get_user_id', params=data, timeout=3)
  23. time.sleep(2)
  24. response = open_user()
  25. res_media_id = response.get('data').get('media_id')
  26. if int(res_media_id) == int(media_id):
  27. user_id = response.get('data').get('user_id')
  28. return user_id
  29. else:
  30. print('media不对应,请检查')
  31. return None
  32. # 通过websocket获取数据
  33. def start_ocean_toutiao_data(user_id, offset):
  34. if user_id == None:
  35. print('没有获取到user_id,请检查原因。可能消息堆积错误')
  36. return None
  37. data = {
  38. 'user_id': user_id,
  39. 'offset': offset
  40. }
  41. requests.get('http://127.0.0.1:4007/get_data', params=data, timeout=3)
  42. response = open_data()
  43. return response
  44. def get_response(media_id,offset):
  45. user_id = start_ocean_toutiao_user_id(media_id)
  46. print(user_id)
  47. data = start_ocean_toutiao_data(user_id, offset)
  48. print(data)
  49. return data
  50. if __name__ == '__main__':
  51. for i in range(1):
  52. offset = 1587744000
  53. # media_id = 6860767764
  54. media_id = 6989633739
  55. user_id = start_ocean_toutiao_user_id(media_id)
  56. print(user_id)
  57. # user_id = 6860406890
  58. data = start_ocean_toutiao_data(user_id, offset)
  59. print(data)
  60. get_response(media_id, offset)
  61. pass

websocket直接绕过JS加密的方式的更多相关文章

  1. 使用selenium进行密码破解(绕过账号密码JS加密)

    经常碰到网站,账号密码通过js加密后进行提交.通过burp拦截抓到的账号密码是加密后的,所以无法通过burp instruder进行破解.只能模拟浏览器填写表单并点击登录按钮进行破解.于是想到了自动化 ...

  2. AES加密解密——AES在JavaWeb项目中前台JS加密,后台Java解密的使用

    一:前言 在软件开发中,经常要对数据进行传输,数据在传输的过程中可能被拦截,被监听,所以在传输数据的时候使用数据的原始内容进行传输的话,安全隐患是非常大的.因此就要对需要传输的数据进行在客户端进行加密 ...

  3. 爬虫之图片懒加载技术及js加密

    图片懒加载 图片懒加载概念: 图片懒加载是一种网页优化技术.图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间.为了 ...

  4. 爬虫破解js加密(一) 有道词典js加密参数 sign破解

    在爬虫过程中,经常给服务器造成压力(比如耗尽CPU,内存,带宽等),为了减少不必要的访问(比如爬虫),网页开发者就发明了反爬虫技术. 常见的反爬虫技术有封ip,user_agent,字体库,js加密, ...

  5. 当爬虫遇到js加密

    当爬虫遇到js加密 我们在做python爬虫的时候经常会遇到许多的反爬措施,js加密就是其中一种. 破解js加密的方法也有很多种: 1.直接驱动浏览器抓取数据,无视js加密. 2.找到本地加密的js代 ...

  6. post 传递参数中包含 html 代码解决办法,js加密,.net解密

    今天遇到一个问题,就是用post方式传递参数,程序在vs中完美调试,但是在iis中,就无法运行了,显示传递的参数获取不到,报错了,查看浏览器请求情况,错误500,服务器内部错误,当时第一想法是接收方式 ...

  7. js 加密 crypto-js des加密

    js 加密 crypto-js    https://www.npmjs.com/package/crypto-js   DES  举例:   js 引入:   <script src=&quo ...

  8. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  9. python爬虫爬小说网站涉及到(js加密,CSS加密)

    我是对于xxxx小说网进行爬取只讲思路不展示代码请见谅 一.涉及到的反爬 js加密 css加密 请求头中的User-Agent以及 cookie 二.思路 1.对于js加密 对于有js加密信息,我们一 ...

随机推荐

  1. 设置Anaconda启动jupyter的默认目录

    要解决的问题:安装好Anaconda后打开jupyter总是会自动跳到c:下的用户目录,通过以下方法可以修改其默认打开的目录 吐槽:竟然没有设置默认打开目录的选项,只能通过修改配置文件完成,让人不爽. ...

  2. Docker Run Cadvisor failed: inotify_add_watch /sys/fs/cgroup/cpuacct,cpu: no such file or directory

    原文链接:https://blog.csdn.net/poem_2010/article/details/84836816 没有找这个文件, 这是一个bug,在系统中,是cpu,cpuacct 可以去 ...

  3. 作为一个Java程序员连简单的分页功能都会写,你好意思嘛!

    今天想说的就是能够在我们操作数据库的时候更简单的更高效的实现,现成的CRUD接口直接调用,方便快捷,不用再写复杂的sql,带吗简单易懂,话不多说上方法 1.Utils.java工具类中的方法 1 /* ...

  4. go语言之函数及闭包

    一:函数 1 概述: 函数是 Go 程序源代码的基本构造单位,一个函数的定义包括如下几个部分,函数声明关键字 也町. 函数名.参数列表.返回列表和函数体.函数名遵循标识符的命名规则, 首字母的大小写决 ...

  5. 【洛谷日报#26】GCC自带位运算系列函数

    文章转自 洛谷 谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error " ...

  6. Android开发之数据存储——SharedPreferences基础知识详解,饿补学会基本知识,开发者必会它的用法。

    一.数据存储选项:Data Storage --Storage Options[重点] 1.Shared Preferences Store private primitive data in key ...

  7. 【API进阶之路】破圈,用一个API代替10人内容团队

    摘要:我用一个API代替10人内容团队,一年帮老板省了一百万. 自从学习API以后,我用技术手段相继帮助业务部.市场部解决了不少难题,算是从纯研发破圈发展到了业务端.老板召开业务讨论会的时候也会带上我 ...

  8. 长沙做假证u

    长沙做假证[电/薇:187ヘ1184ヘ0909同号]办各类证件-办毕业证-办离婚证,办学位证书,办硕士毕业证,办理文凭学历,办资格证,办房产证不. 这是一个简单的取最大值程序,可以用于处理 i32 数 ...

  9. 初学WebGL引擎-BabylonJS:第4篇-灯光动画与丛林场景

    前几章接触的案例都是接近静态的,由这张开始开始接触大量动态的内容,包括 球体灯光,变动的形体,以及一个虚拟的丛林场景 下章我会试着结合1-9案例的内容做出一个demo出来 [playground]-l ...

  10. ASP导出数据到excel遇到的一些问题

    一直用动易平台的ASP做新闻发布网站,直到现在才接触导出数据到Excel的问题,目的在于公司要统计各部门的投稿量,要做这么个东西,实现起来是挺简单的,但是第一次做,还是费了一些功夫的,特此记录一下 主 ...