爬虫案例:建设库JS逆向

爬虫流程

1. 确定目标网址和所需内容

https://www.jiansheku.com/search/enterprise/

只是个学习案例,所以目标就有我自己来选择,企业名称,法定代表人,注册资本,成立日期
在这里插入图片描述

2. 对目标网站,进行分析

  • 动态内容分析:

    JS和Ajax请求:确定页面是否使用JavaScript动态加载内容,如果是,需要分析Ajax请求以获取数据的API。
    在这里插入图片描述进行页面切换,抓去Ajax,发现page里面的response携带这我们所需要的数据

    找到动态变化值,一般在headers,或者payload中,动态变化值,可能就是影响批量爬虫的关键
    例中的payload是明文数据,headerssigntimestamp是动态变化值

3 .找到加密的入口

靠经验,运气,猜测,分析代码,观察数据,调试代码,逆向分析,等等。
使用关键字搜索,断点,调用堆栈等方法。

这里我使用关键字搜索
使用正则表达式搜索缩小搜索范围,勾选“Use Regular Expression”或.*并输入正则表达式,如\bSign\b—\b确定搜索边界
像Math.sign这种是js的数学库文件,可以直接排除,就10几个,慢慢排查,使用断点调试
在这里插入图片描述
这里就是目标,注意这里使用了js的逗号表达式,想要查看结果悬浮,或者在控制台中查看,注意你要在断点的作用域内,函数是有生命周期的
在这里插入图片描述

4. 扣js代码

复制js代码,模拟浏览器加密过程

这里我发现一个好用的小技巧,使用单步调试,从断点开始出发查看经过的函数基本都是我们所需的js代码,途中会跳转到其他的js文件(webpack)然后回来就可一看见MD5加密的算法了
在这里插入图片描述

5. 写代码

  1. 请求模拟
  2. 获取js逆向值
  3. py调用js
  4. 数据清洗
  5. 数据存储
  6. 处理反爬机制(ip封禁)

注意事项

  1. 下载packages的时候过慢,pip和node我都会给出镜像源
  2. 我使用的是Linux:pip install PyExecJS2,Windows:pip install PyExecJS,不行就两个都试一遍
  3. google在浏览器开发者工具中不让粘贴,可在控制台输入allow pasting
  4. 本来打算以csv文件保存,但是爬取页数一多,就打不开csv文件,所以就保存为txt
  5. 最好不要使用异步模块,这个爬取的速度不会太慢,爬取的太快服务区可能不会响应
  6. 不要大量爬去,该网站会封IP(使用代理池就可以了)

packages

  • pip
# 模拟浏览器发送请求
pip install requests -i https://mirrors.aliyun.com/pypi/simple/# 在py中调用js
pip install PyExecJS2 -i https://mirrors.aliyun.com/pypi/simple/# 方便实时预览进度
pip install requests -i https://mirrors.aliyun.com/pypi/simple/
  • npm
# 使用淘宝源
npm config set registry https://registry.npm.taobao.org# 我遇到了证书过期(可能是我设置的是外国时区,使用的是国内的源),设置 npm 忽略 SSL 证书错误
npm config set strict-ssl falsenpm install crypto-js

python code

import requests
import time
import execjs
import json
from tqdm import tqdmdef fetch_data(page, timer):json_data = {'eid': '','achievementQueryType': 'and','achievementQueryDto': [],'personnelQueryDto': {'queryType': 'and',},'aptitudeQueryDto': {'queryType': 'and','nameStr': '','aptitudeQueryType': 'and','businessScopeQueryType': 'or','filePlaceType': '1','aptitudeDtoList': [{'codeStr': '','queryType': 'and','aptitudeType': 'qualification',},],'aptitudeSource': 'new',},'page': {'page': page,'limit': 20,'field': '','order': '',},}get_sign = execjs.compile(open('jiansheku.js').read()).call('get_sign', json_data, timer)cookies = {'Hm_lvt_03b8714a30a2e110b8a13db120eb6774': '1718020163','Hm_lpvt_03b8714a30a2e110b8a13db120eb6774': '1718020163','HWWAFSESTIME': '1718020163509','HWWAFSESID': '228fb8efd82b43680e',}headers = {'accept': 'application/json, text/plain, */*','accept-language': 'en-US,en;q=0.9','content-type': 'application/json;charset=UTF-8','devicetype': 'PC','origin': 'https://www.jiansheku.com','page': 'search-enterprise','priority': 'u=1, i','referer': 'https://www.jiansheku.com/','sec-ch-ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Linux"','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-site','sign': get_sign,'timestamp': str(timer),'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',}try:response = requests.post('https://capi.jiansheku.com/nationzj/enterprice/page', cookies=cookies, headers=headers, json=json_data)response.raise_for_status()  # 检查请求是否成功print(f"Page {page} fetched successfully")print(response.text)  # 打印响应内容以检查数据格式return response.json()except requests.RequestException as e:print(f"Request failed for page {page}: {e}")return Nonedef save_to_txt(all_records, filename='enterprise_data.txt'):with open(filename, 'w', encoding='utf-8') as file:headers = ['Name', 'Legal Person', 'Registered Capital', 'LiceValidity Date']file.write('\t'.join(headers) + '\n')for record in all_records:line = f"{record['name']}\t{record['legalPerson']}\t{record['registeredCapital']}\t{record['liceValidityDate']}\n"file.write(line)print(f"数据已保存到 {filename} 文件中")def main():timer = time.time() * 1000max_pages = 5  # 设置要遍历的最大页数all_records = []for page in tqdm(range(1, max_pages + 1)):data = fetch_data(page, timer)if data and 'data' in data and 'list' in data['data']:records = [{'name': item['name'],'legalPerson': item.get('legalPerson', ''),'registeredCapital': item.get('registeredCapital', ''),'liceValidityDate': item.get('liceValidityDate', '')} for item in data['data']['list']]all_records.extend(records)else:print(f"No data found for page {page}")if all_records:# 将记录保存到txt文件save_to_txt(all_records)else:print("No records to save.")if __name__ == "__main__":main()

js code

const Cryptojs = require("crypto-js")ku = function(e, t, time) {var n = t + e + time;// 这里的MD5是加密算法,加密后的字符串就是签名return n = Cryptojs.MD5(n).toString()    // 经过单点调试,发现这里是加密算法构成的位置
}Lu = function e(t) {var n;if (Array.isArray(t)) {for (var r in n = new Array,t) {var o = t[r];for (var i in o)null == o[i] ? delete t[r][i] : Array.isArray(t[r][i]) && e(t[r][i])}return n = t,JSON.stringify(n).replace(/^(\s|")+|(\s|")+$/g, "")}return n = t && t.constructor === Object ? JSON.stringify(t) : t
}Tu = function(e) {var t = new Array, n = 0;for (var i in e)t[n] = i,n++;return t.sort()
}Ou = function(e) {var t = Tu(e), n = "";for (var i in t) {var r = Lu(e[t[i]]);null != r && "" != r.toString() && (n += t[i] + "=" + r + "&")}return n
}function get_sign(param, time) {
//     param = {
//     'eid': '',
//     'achievementQueryType': 'and',
//     'achievementQueryDto': [],
//     'personnelQueryDto': {
//         'queryType': 'and',
//     },
//     'aptitudeQueryDto': {
//         'queryType': 'and',
//         'nameStr': '',
//         'aptitudeQueryType': 'and',
//         'businessScopeQueryType': 'or',
//         'filePlaceType': '1',
//         'aptitudeDtoList': [
//             {
//                 'codeStr': '',
//                 'queryType': 'and',
//                 'aptitudeType': 'qualification',
//             },
//         ],
//         'aptitudeSource': 'new',
//     },
//     'page': {
//         'page': 3,
//         'limit': 20,
//         'field': '',
//         'order': '',
//     },
// };
//     time = (new Date).getTime();t = Ou(param);return ku("ghaepVf6IhcHmgnk4NCTXLApxQkBcvh1", ku("mwMlWOdyM7OXbjzQPulT1ndRZIAjShDB", ku("ZuSj0gwgsKXP4fTEz55oAG2q2p1SVGKK", t, time), time), time);
}// console.log(get_sign());

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

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

相关文章

认识Spring 中的BeanPostProcessor

关于BeanPostProcessor和BeanFactoryPostProcessors,将分2篇文章来写,这篇文章是对Spring 中BeanPostProcessor进行了总结 先看下大模型对这个类的介绍,随后再看下这两个类的示例,最后看下这两个类的实现。 这两个类从名字看都很类…

HTML静态网页成品作业(HTML+CSS)—— 兰蔻化妆品网页(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

网卡聚合链路配置

创建名为mybond0的绑定,使用示例如下: # nmcli con add type bond con-name mybond0 ifname mybond0 mode active-backup添加从属接口,使用示例如下: # nmcli con add type bond-slave ifname enp3s0 master mybond0要添加其他从…

反射...

一、反射的定义 二、获取Class对象三种方式 全类名:包名类名。 public class test {public static void main(String [] args) throws ClassNotFoundException {//第一种方式Class class1Class.forName("test02.Student");//第二种方法Class class2Stud…

【区块链】深入解析Proof of Work (PoW): 区块链技术的核心驱动力

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 深入解析 Proof of Work (PoW): 区块链技术的核心驱动力引言一、PoW基本概念1.1…

C++ 判断目标文件是否被占用(独占)(附源码)

在IM软件中发起文件发送时,如果要发送的是某word文件,并且该word文件被office打开,则会提示文件正在被占用无法发送,如下所示: 那文件被占用到底是如何判断出来的呢?其实很简单,调用系统API函数CreateFile,打开该文件(OPEN_EXISTING),传入FILE_SHARE_READ共享读标记…

探索Chrome DevTools的高级技巧与隐藏功能

Chrome DevTools是网页开发者不可或缺的调试工具,它提供了丰富的功能,帮助开发者快速诊断和解决问题。然而,除了常见的功能,如元素检查、网络监控和JavaScript调试之外,DevTools还有许多不为人知的强大功能和技巧。本文…

SAP乘云而上

上周四参加了SAP原厂组织的“SAP乘云而上私享会”,由德勤赞助。活动主要的内容是介绍了RISE with SAP的上云服务包并且参观了SAP Labs。 现阶段对于大中型企业客户,SAP力推的是S/4HANA PCE(Private Cloud Edition)私有云版本,这个版本我在之…

Androidstudio项目加载不出来,显示Connect timed out

Android studio加载不出来所需要的环境依赖,99%的问题都是网络原因 解决办法有两个: 1.科学上网 2.使用国内的镜像 方法一自行解决,下面重点介绍方法二 在项目目录下找到gradle->wrapper->gradle-wrapper.properties 将项目的distributionUrl改为https://mirrors.cl…

从零到发布:npm插件包终极指南

在JavaScript和Node.js的生态系统中,npm(Node Package Manager)是最重要的包管理工具之一。通过npm,开发者可以共享代码、复用他人的工作成果以及协作开发。本指南将详细介绍如何通过npm发布自己的插件包,以便其他开发…

平安养老险陕西分公司荣获“2021-2023年乡村振兴‘三村工程’先进机构”

5月27日,中国平安成立36周年司庆暨三省推广启动大会顺利召开。会上,平安养老险陕西分公司获“2021-2023年乡村振兴‘三村工程’先进机构”荣誉表彰。 过去三年间,平安养老险陕西分公司始终坚持金融为民,在平安集团、平安养老险的指…

MFC上下文菜单与定时器学习笔记

本博文简单介绍了上下文菜单以及定时器的知识内容,作为笔记发表在csdn上面。 在这里插入图片描述 菜单资源的使用 添加菜单资源加载菜单资源: 注册窗口类时设置菜单创建窗口传参设置菜单在主窗口WM_CREATE消息中利用SetMenu函数设置 加载菜单资…

Python编写和管理装饰器库之wrapt使用详解

概要 在 Python 编程中,装饰器(decorator)是一个非常强大的工具,可以在不修改原函数代码的情况下,增强函数的功能。然而,编写装饰器有时会遇到一些复杂的问题,比如保持被装饰函数的元信息、正确传递参数等。wrapt 库提供了一组工具,帮助开发者更容易地编写和管理装饰器…

深圳比创达电子|EMI电磁干扰行业:挑战到突破,电子产业新未来

随着电子技术的飞速发展,电磁干扰(EMI)问题日益凸显,成为影响电子设备性能和稳定性的重要因素。EMI电磁干扰行业作为解决这一问题的关键领域,正面临着前所未有的机遇与挑战。 一、引言:EMI电磁干扰行业的崛…

分布式事务AP控制方案(下)

分布式事务控制方案 本篇文章给出一种要求高可用性(AP思想)的分布式事务控制方案 上篇回顾:点我查看 分布式事务控制方案1、前景回顾2、数据库和缓存的操作3、分布式文件系统1)页面静态化2)远程调用3)调用…

10秒钟docker 安装Acunetix

1、拉取镜像: 2、查看镜像: [rootdns-server ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE quay.io/hiepnv/acunetix latest f8415551b8f4 2 months ago 1.98GB 3、运行镜像: …

优思学院|用ChatGPT快速完成数据分析图表【柏累托图法】

数据分析是很多行业的人不可少的一部分,尤其是质量工程师更是日常的工作。然而,随着科技的进步,人工智能(AI)将逐渐承担起数据计算的工作,这意味着未来的质量工程师需要具备的不仅仅是计算能力,…

ISO 19115-3:2023 基本概念的 XML模式实现

前言 ISO(国际标准化组织)是由各国标准化机构(ISO 成员机构)组成的全球性联合会。制定国际标准的工作通常由 ISO 技术委员会完成。对某一技术委员会所关注的主题感兴趣的每个成员机构都有权在该委员会中派代表。与 ISO 联络的国际组织、政府和非政府组织也参与工作。ISO 与…

运营商大模型进化之路:策略分野与AI未来的璀璨展望

运营商大模型的进化路线“分野”与AI大模型的璀璨前景 随着人工智能技术的飞速发展,AI大模型已成为推动科技进步和产业变革的重要力量。在这个浪潮中,运营商作为通信行业的巨头,也纷纷投入大模型的研发与应用,探索出各自独特的进化…

性能测试2【搬代码】

1.性能测试脚本完善以及增强 2.jmeter插件安装以及监控使用 3.性能压测场景设置(基准、负载、压力、稳定性) 4. 无界面压测场景详解 一、性能测试脚本完善以及增强 使用控制器的目的是使我们的脚本更加接近真实的场景 1.逻辑控制器: 【事务控制器】&…