爬虫实战3-js逆向入门:以黑猫投诉平台为例

news2024/11/15 8:41:30

目录

引言

逆向过程

步骤一:找到参数对应js代码位置

步骤二:分析参数值的生成逻辑

步骤三:确定函数u的具体内容

步骤四:使用python实现请求参数的生成

投诉信息爬取


引言

下面是一张主流网页加密方法的思维导图,本文将介绍的黑猫投诉平台网站使用的即是请求头加密。

从开发者工具中抓包的结果来看,该网页的json数据包的请求参数中rs和signature两个参数在下拉后得到的新数据包中是动态变化的,而ts参数过一段时间会发生变化(推测应该是和时间戳相关的参数)。接下来就通过js逆向获取这几个参数的生成方法,并实现爬取投诉信息。

逆向过程

步骤一:找到参数对应js代码位置

由于用rs搜索容易重复,这里搜索signature参数,其中只有一个js文件中包含该变量名。

在js代码中再次搜索该变量名,发现共找到14个,为了找到真正的signature参数位置,对可能是该参数的位置打上断点,挨个尝试后确定获得signature参数值的位置在下图所示位置,实际是变量g的值。同时也可以清楚的看到ts和rs的值分别等于l和p两个变量的值。

步骤二:分析参数值的生成逻辑

从代码中很清楚的看到g的值通过这段代码赋予:var g = u([l, p, b, h, c, d["type" + e]].sort().join("")),也就是将这几个变量l, p, b, h, c, d["type" + e]排序后组成一个新的字符串,并将该字符串传入函数u,得到返回值即为g的值。

再往上找寻找上面几个变量的值的生成方式,可以发现在下图所示代码中,这些变量被创建和赋值。首先l变量确实是当前时间戳得到的值(l的值也是ts参数的值,印证了一开始的猜想);b是一个常数,值为"$d6eb7ff91ee257475%";h的值是PAGE_CONFIG对象的keywords属性的值,实际上从右边作用域可以看到就是我们的搜索关键字,值为"外卖 食品安全";c的值为10,它其实就是请求参数中的page_size的值;e的值从右边作用域也可以看到值为1,刷新网页该值不变,因此d["type" + e]的值可以确定为1;

最后是p的值,也是请求参数rs的值,它是一个函数的返回值,不需要管这个函数是干什么的,用chatgpt把这段代码转为python代码即可,转换之前还需找到e和t的值是什么,也从右边发现两者值不变,分别是1和4,但e在代码中用于判断,因此转为python值其实是True,如下得到p值得生成方法,实质就是生成16位得随机字符串:

def generate_random_string(e=True, t=4, r=16):
    chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    length = t if not e else random.randint(t, r)
    return ''.join(random.choice(chars) for _ in range(length))

步骤三:确定函数u的具体内容

将断点打到u函数的位置,跳到函数定义的位置

通过反复地打断点跟进,最终确定其执行的实际上是如下两个函数,其实质是执行了一次SHA-256 哈希算法。

知道他执行的是SHA-256 哈希算法后直接使用python对应的hashlib库中的方法即可。

步骤四:使用python实现请求参数的生成

直接放出代码

def generate_random_string(e=True, t=4, r=16):
    chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    length = t if not e else random.randint(t, r)
    return ''.join(random.choice(chars) for _ in range(length))

def get_sha256(value):
    """
    sha256加密
    :param value: 加密字符串
    :return: 加密结果转换为16进制字符串,并大写
    """
    hsobj = hashlib.sha256()
    hsobj.update(value.encode("utf-8"))
    return hsobj.hexdigest()
ts=str(int(time.time() * 1000))#ts,时间戳
l=ts
rs=generate_random_string(True, 4, 16)
p=rs#rs
b = '$d6eb7ff91ee257475%'
h='外卖 食品安全'#keywords
c='10'#page_size
d=str(i)#d["type" + e]=page
signature=''.join(sorted([l, p, b, h, c, d]))
signature=get_sha256(signature)
params = {
        'ts': ts,
        'rs': rs,
        'signature': signature,
        'keywords': h,
        'page_size': c,
        'page': d,
        }

到这里请求参数就构造完成了。

投诉信息爬取

下面是投诉信息的爬取,把cookies和headers复制下来,使用get方法获得每条投诉对应的具体信息页面的url,然后从该url中爬取需要的信息,我这里只需要投诉时间、结束时间和投诉编号,完整代码如下:

import requests
import random
import hashlib
import time
import json
from bs4 import BeautifulSoup


cookies = {
    #自己复制
}

headers = {
    #自己复制
}

#[l, p, b, h, c, d["type" + e]].sort().join("")
def generate_random_string(e=True, t=4, r=16):
    chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    length = t if not e else random.randint(t, r)
    return ''.join(random.choice(chars) for _ in range(length))

def get_sha256(value):
    """
    sha256加密
    :param value: 加密字符串
    :return: 加密结果转换为16进制字符串,并大写
    """
    hsobj = hashlib.sha256()
    hsobj.update(value.encode("utf-8"))
    return hsobj.hexdigest()

requests.packages.urllib3.disable_warnings()
sessions=requests.session()
data=[]
number=0
for i in range(1,101):#1524
    print(i)
    url_list=[]
    if len(data)%50==0 and len(data)!=0:
        time.sleep(60)
    while True:
        ts=str(int(time.time() * 1000))#ts,时间戳
        l=ts
        rs=generate_random_string(True, 4, 16)
        p=rs#rs
        b = '$d6eb7ff91ee257475%'
        h='外卖 食品安全'#keywords
        c='10'#page_size
        d=str(i)#d["type" + e]=page
        signature=''.join(sorted([l, p, b, h, c, d]))
        signature=get_sha256(signature)
        params = {
        'ts': ts,
        'rs': rs,
        'signature': signature,
        'keywords': h,
        'page_size': c,
        'page': d,
        }
        try:
            response = sessions.get('https://tousu.sina.com.cn/api/index/s',cookies=cookies,
                                      headers=headers,params=params,verify=False,allow_redirects=False)
            response=json.loads(response.text)['result']['data']['lists']
            #print(response)
            for n in range(len(response)):
                if response[n]['main']['evaluate_u']==None:
                    number+=1
                    continue
                else:
                    url=response[n]['main']['url']
                    url_list.append(url)
                number+=1
            break
        except Exception as e:
            print(e,response.text,i)
            time.sleep(300)
            continue
    for url in url_list:
        while True:
            try:
                response = sessions.get('https:'+url,cookies=cookies,headers=headers,verify=False,allow_redirects=False)
                soup = BeautifulSoup(response.text, 'html.parser')
                u_date_elements = soup.find_all(class_='u-date')
                u_list=soup.find('ul', class_='ts-q-list')
                c_num=u_list.find_all('li')[0].text
                endtime=u_date_elements[2].text
                starttime=u_date_elements[6].text
                data.append([starttime,endtime,c_num])
                break
            except Exception as e:
                print(e,response.text,i)
                time.sleep(60)
                continue
data=pd.DataFrame(data,columns=['starttime','endtime','c_num'])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364741.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行

环境: Rustdesk1.19 问题描述: Rustdesk打开Win10 下客户端下面服务不会自启,显示服务未运行 解决方案: 1.查看源代码 pub async fn start_all() {crate::hbbs_http::sync::start();let mut nat_tested = false;check_zombie()

税法相关的基础知识

文章目录 税法原则1.税法基本原则2.税法适用原则 来和大家聊聊税法相关的基础知识 税法原则 1.税法基本原则 2.税法适用原则

1329:【例8.2】细胞 广度优先搜索

1329:【例8.2】细胞 时间限制: 1000 ms 内存限制: 65536 KB 【题目描述】 一矩形阵列由数字0 到9组成,数字1到9 代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如: 4 10 0234500067 1034560500 2045600671 00000000…

超声波模块的驱动(STM32、51单片机等)

一、前言 本文旨在分享单片机对超声波模块的驱动,测量距离和显示 二、超声波的驱动 1、超声波模块 2、模块性能 (1)TCT40-16T/R1 压电陶瓷超声传感器(通用型) 3、接口定义 Vcc、 Trig(控制端&#xff09…

一款开源的MES系统

随着工业4.0的快速发展,制造执行系统(MES)成为了智能制造的核心。今天,将为大家推荐一款开源的MES系统——iMES工厂管家。 什么是iMES工厂管家 iMES工厂管家是一款专为中小型制造企业打造的开源MES系统。它具备高度的可定制性和灵…

【无线通信专题】NFC通信模式及可能的应用方式

在文章【无线通信专题】NFC基本原理中我们讲到了NFC工作模式。其中NFC工作模式主要有三种,读写模式、卡模拟模式、点对点模式。 NFC通信模式丰富,NFC Forum定义了三种NFC设备:通用NFCForum设备、读写器设备和标签设备。这些NFC设备可以在三种通信模式下运行,并对应用案例进…

docker、docker-compose 离线安装、shell脚本一键安装、卸载

注:二进制包,与脚本在同级目录 docker 离线安装: 包下载:https://download.docker.com/linux/static/stable/x86_64/ docker_install.sh: #!/bin/bash# 指定 Docker 版本和文件名 DOCKER_VERSION"24.0.7" D…

FreeRTOS移植详解

一、前言 本文旨在讲解FreeRTOS在STM32单片机上的移植步骤,对于FreeRTOS在其他单片机上的移植已具有一定的参考意义。相信读者在看完这篇文章后,一定会有所收获! 文末附有相关资料连接,有需要的读者可以自行下载。 二、FreeRTOS源…

【自动驾驶中的SLAM技术】第2讲:基础数学知识回顾

第二讲:基础数学回顾 文章目录 第二讲:基础数学回顾1 几何学1.1 坐标系1.2 坐标变换① 空间向量② 基变换③ 坐标变换④ 总结 1.3 四元数与旋转向量 2 运动学2.1 李群视角2.2 四元数视角2.3 四元数的李代数与旋转向量间的转换2.4 SO(3)t 上的运动学2.5 线…

视频剪辑技巧:添加srt字幕,提升视频品质的方法

在视频制作和剪辑过程中,字幕的添加是一项常见的技巧。通过添加srt字幕,可以提升视频的品质和观感,让观众更好地理解视频内容。下面一起来看云炫AI智剪如何批量添加srt字幕的方法,如何通过这些技巧提升视频品质。 原视频画面与添…

【Docker基础二】Docker安装Mysql8

下载镜像 安装mysql(版本:8.0.35) # 拉取镜像 docker pull mysql:8.0.35 # 查看镜像是否已经下载 docker images 创建挂载目录 # 宿主机上创建挂载目录 (可以不创建,docker run -v配置了挂载目录,docker会自动…

二分查找(一)

算法原理 原理:当一个序列有“二段性”的时候,就可以使用二分查找算法。 适用范围:根据规律找一个点,能将这个数组分成两部分,根据规律能有选择性的舍去一部分,进而在另一个部分继续查找。 除了最普通的…

使用ChatGPT生成项目需求文档模板

前言 我们在工作中需要编写的技术文档有多种形式,包括Word、Excel、PDF及一些在线形式。我们可以借助ChatGPT生成文本,然而,它不能直接生成Word、Excel、PDF等格式的文档。因此,我们需要利用其他工具来帮助我们生成一些模板&…

分布式之任务调度学习二

4 Quartz 集成到 Spring Spring-quartz 工程 Spring 在 spring-context-support.jar 中直接提供了对 Quartz 的支持 可以在配置文件中把 JobDetail、Trigger、Scheduler 定义成 Bean。 4.1 定义 Job <bean name"myJob1" class"org.springframework.sched…

机器学习模型可解释性的结果分析

模型的可解释性是机器学习领域的一个重要分支&#xff0c;随着 AI 应用范围的不断扩大&#xff0c;人们越来越不满足于模型的黑盒特性&#xff0c;与此同时&#xff0c;金融、自动驾驶等领域的法律法规也对模型的可解释性提出了更高的要求&#xff0c;在可解释 AI 一文中我们已…

MySQL复习汇总(图书管理系统)

MySQL图书管理系统&#xff08;49-94&#xff09;源码_71.备份book数据库到e盘的mybook.sql文件(备份文件中要求包含建库命令)-CSDN博客 -- 1、 创建一个名称为book的数据库。 -- 2、 打开book数据库 -- 3、 创建数据表分别如下&#xff08;除外键之外&#xff09;…

2.1.1 预期年化收益率

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率 3、投资实证   [3.1 202…

GPT实战系列-简单聊聊LangChain

GPT实战系列-简单聊聊LangChain LLM大模型相关文章&#xff1a; GPT实战系列-ChatGLM3本地部署CUDA111080Ti显卡24G实战方案 GPT实战系列-Baichuan2本地化部署实战方案 GPT实战系列-大话LLM大模型训练 GPT实战系列-探究GPT等大模型的文本生成 GPT实战系列-Baichuan2等大模…

元数据管理平台对比预研 Atlas VS Datahub VS Openmetadata

大家好&#xff0c;我是独孤风。元数据管理平台层出不穷&#xff0c;但目前主流的还是Atlas、Datahub、Openmetadata三家&#xff0c;那么我们该如何选择呢&#xff1f; 本文就带大家对比一下,这三个平台优势劣势。要了解元数据管理平台&#xff0c;先要从架构说起。 正文共&am…

【算法Hot100系列】合并 K 个升序链表

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…