爬虫最重要的就是多练多实践

反爬手段

常见的基础反爬手段有

  • User-Agent 最常见也最简单
  • referer
  • cookie
  • origin

这些是最常见也是最简单 的反爬手段

当这些拦不住的你的时候,爬虫应付简单的网站就没有什么问题了

推荐我常用的工具:

https://curlconverter.com/

被禁止右键查看源码

常用应对手段

  • 你可以通过f12直接查看文档来查看当前页面的页面源代码。
  • 在输入窗口前加上 view-source: 可以直接查看当前页面的页面源代码(通常都是用来快速查看想要爬取的信息是否是动态加载的)
以下涉及到js,不懂js的可以溜了不是

F12 debugger

这里面涉及的地方就很多了,具体情况要具体分析,不同网站的反调试策略也不一样。当然最重要的就是搞清楚它是什么类型的debugger,也就是如何产生的。
我来讲述几个我常遇到的debugger

  • 直接标出
  • 检测DevTools是否打开
  • 定时检测
  • 异常抛出
  • 通过js的构造器讲字符构造成debugger达到效果
  • 临时产生匿名函数像什么VM123,函数主体就一个debugger

一般遇到反调试的网站,那么这个爬虫将会变得很困难。没有办法调试网站,分析就无从下手了。当然,如果你只是想定位某些元素,你可以设置你的开发者模式跳过一切断点就行。如果你是要就行js逆向的话,这是必须要过的一步。

常用应对手段

  • 禁用一切debugger,这个方法不推荐使用,当我们需要使用到断点调试的时候还是需要去解决网站设置的无限调试的关卡。
  • 一般遇到简单的debugger吓唬新手的,你只需要在这个debugger下设置逻辑跳过就行。当然也可以直接删除保存并替换调该页面,但是我不推荐删代码的形式,除非你知道这段代码只有产生debugger的作用。
  • 查询法,这种方法适用于你找不到debugger这个字符串时使用。你可以去寻找字符数组是否有类似于['d','e','b','u','g','g','e','r']这样的数组。你可以将里面的字符全部替换为空
  • js注入,开发者模式是支持你自己写js代码并执行的。当然这种方法适用于对前端十分了解的大佬身为菜鸡我会抄啊,常见的注入网上都有代码,可以去看看Hook注入。
  • 分析法,通过堆栈的追踪去查询这个debugger是如何产生的,是由谁产生的。这种方法我是很推荐的,如果你有前端的知识不妨一步步看看,很锻炼个人水平的,你学会了还可以用在自己的网站。但是这个是很耗费时间的爬虫本来就是费力活。学会跟堆栈这个很重要,在b站的w_rid有很大的体现虽然那个是解参数

混淆加密 傻孩子们,快跑啊

常见的代码混淆加密有:

  • 变量混淆(base64编码,unicode)一般看到结尾有两个等号就要注意了
  • eval混淆,这个我见过好几次了,这个只需要把代码输出到控制台就行貌似很常用
  • AAEncode混淆(表情包加密)
  • JJEncode混淆
  • jsfuck混淆
  • ob混淆 这个是真的难
  • 代码压缩
  • md5 哈希 这个不是加密!md5是不可还原的
  • 字符串混淆
  • 属性加密
  • 控制流平坦化
  • 僵尸代码注入
  • 反调试
  • 多态变异
  • 锁定域名
  • 反格式化
  • 特殊编码

无论是哪种方法,它的出发点都是为了最大程度的降低你的阅读代码的体验,看不懂或者没耐心,就达到它所要的结果。不过当你知道并清楚这些代码是什么混淆的时候,你就可以通过工具来还原阅读。当然还原之后的代码也仍然是一坨,别问我怎么知道的。
这里分析一下我常用的工具

https://lelinhtinh.github.io/de4js/

Console 的基本方法

  • console.info - 向控制台输出提示信息
  • console.error - 向控制台输出错误信息
  • console.warn - 向控制台输出警示信息
  • console.assert - 断言
  • console.log - 输出日志
  • console.count - 输出调用次 数
  • console.table - 以表格形式展现数据
  • copy() - 复制元素到粘贴板
  • $_ - 调用最后一次函数执行结果
  • $ - document.querySelector 可配合xpath使用
  • $$ - document.querySelectorAll

hook方法

JSON.stringify()方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

JSON.parse() 方法用来解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。提供可选的 reviver 函数用以在返回之前对所得到的对象执行变换 (操作)。

  • JSON.stringify(obj) 被调用时,控制台输出 "dp", { key: "value" }
  • JSON.parse(jsonString) 被调用时,控制台输出 "dp", '{"key":"value"}'
1
2
3
4
5
6
7
8
9
10
11
var my_stringify = JSON.stringify;
JSON.stringify = function(params){
console.log("dp",params);
return my_stringif(params);
};

var my_parse = JSON.parse;
JSON.parse = function(params){
console.log("dp",params);
return my_parse(params);
};

hook方法的书写基本都是一样的,先创建拦截对象,确保你改写之后还可以返回原先方法,之后书写你想要查看的属性,最后返回原方法。

Base64 实现原理

Base64编码的核心原理是将二进制数据进行分组,每24Bit(3字节)为一个大组,再把一个大组的数据分成4个6Bit的小分组。
由于6Bit数据只能表示64个不同的字符$2^6=64$,所以这也是Base64的名字由来。

md5 - 信息指纹

MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,用于生成128位(16字节)的哈希值(通常称为“摘要”),它通常表示为32位的十六进制数。

控制流平坦化

通过引入状态机与循环,破坏代码上下文之间的阅读连续性和代码块之间的关联性,将若干个分散的小整体整合成一个巨大的循环体。

无法还原成原来具体的函数,无法以函数为单位的调试方式,大幅度增加调试难度。降低代码运行效率,提高爬虫执行时执行js的资源成本。可根据js运行时检测到某些因素自由跳到蜜罐或者跳出代码执行。

常见样例:

  1. 多维数组
  2. 数值计算比较
  3. 循环啊,swtich

处理方法:

  1. 在每个分支开始前输出日志
  2. 借助AST语法分析树分析代码逻辑

对称加密

对称加密(Symmetric Encryption)使用相同的密钥进行加密和解密。主要特点如下:

同一密钥:加密和解密使用相同的密钥,这意味着密钥需要在通信双方之间安全地共享和管理。
速度快:对称加密算法通常计算速度快,适合大数据量的加密。
应用场景:常用于数据的传输和存储,比如文件加密、数据库加密、VPN、HTTPS中的数据加密(对称加密部分)。
常见对称加密算法
AES(Advanced Encryption Standard):现代加密标准,安全性高,支持128位、192位和256位密钥。
DES(Data Encryption Standard):较早的加密标准,密钥长度为56位,现已被认为不够安全。
3DES(Triple DES):DES的增强版,通过三次加密提高安全性,但速度较慢。
Blowfish:速度快,灵活的密钥长度,但逐渐被AES取代。

非对称加密

非对称加密(Asymmetric Encryption),也称为公钥加密,使用一对密钥:公钥(Public Key)和私钥(Private Key)。主要特点如下:

密钥对:加密和解密使用不同的密钥。公钥用于加密,私钥用于解密。公钥可以公开,私钥必须保密。
安全性高:即使公钥被泄露,数据仍然安全,因为私钥无法从公钥中轻易推导出来。
速度慢:计算复杂度高,适合小数据量的加密和密钥交换,不适合大数据量加密。
应用场景:常用于密钥交换、数字签名、证书、SSL/TLS协议中的握手阶段。
常见非对称加密算法
RSA(Rivest-Shamir-Adleman):最常用的非对称加密算法,支持各种密钥长度,安全性高。
ECC(Elliptic Curve Cryptography):基于椭圆曲线数学,密钥长度较短但安全性高。
DSA(Digital Signature Algorithm):用于数字签名。

AES 加密

AES(Advanced Encryption Standard,先进加密标准)是一种对称密钥加密算法,被广泛应用于数据加密保护。AES 由美国国家标准与技术研究院(NIST)于2001年制定,是替代旧的DES(Data Encryption Standard)的标准算法。AES 算法安全性高,速度快,适用于各种环境下的数据加密需求。

AES的基本特点

  1. 对称加密:AES 使用同一个密钥进行加密和解密操作,这意味着加密和解密双方必须共享同一个密钥。
  2. 密钥长度:AES 支持三种密钥长度:128位、192位和256位。密钥长度越长,加密强度越高,但处理速度会稍慢。
  3. 分组加密:AES 是一种分组加密算法,它将数据分成固定大小的块进行加密。每个块的大小是128位(16字节)。

工作模式

AES 可以在多种工作模式下操作,不同的模式决定了如何处理多个块的数据。常见的工作模式有:

  1. ECB(Electronic Codebook)模式:每个块独立加密。优点是简单,但容易受到模式攻击,不推荐使用。
  2. CBC(Cipher Block Chaining)模式:每个块与前一个块的密文进行XOR后再加密。安全性高,但需要初始化向量(IV)
  3. CFB(Cipher Feedback)模式:类似于流模式,将密文反馈到加密过程。适合小数据加密。
  4. OFB(Output Feedback)模式:类似于CFB,但不直接将密文反馈,避免错误传播。
  5. CTR(Counter)模式:将计数器和密钥加密生成密钥流,然后与明文XOR。并行处理性能好,常用在高性能需求场景。

常见的填充方式

  1. PKCS#7 填充:
    PKCS#7 是最常见的填充方式。它会在每个数据块末尾添加若干个字节,每个字节的值是填充字节的数量。
    例如,若块大小为16字节,数据 0x01 0x02 0x03 需要填充13个字节,每个字节的值为 0x0D(13的十六进制表示)。

  2. Zero Padding:
    在末尾添加0字节,适用于明文的最后一个字节不为零的情况,否则在解密时无法确定填充长度。

  3. ISO/IEC 7816-4 Padding:
    在填充开始的第一个字节填入 0x80,其余填入 0x00。

css反爬

  • 字体反爬

利用font-family这个属性,设置不可读的Unicode,让css的字体映射到常见的字体,使得爬虫只能抓到Unicode,而不是真实的数据
下载woff字体,转化为tff文件,查找其映射关系

  • 背景反爬

查看偏移量和真实值的关系

  • 伪类反爬(:名)

使用自动化工具采集

  • 元素定位

计算出替换的元素的偏移量,与被替换元素相对比,还原实际值