JS爬虫实战之Fastmoss

Fastmoss参数逆向

    • 逆向前准备
    • 思路
      • [1- 确认接口](#1- 确认接口)
      • [2- 参数确认](#2- 参数确认)
      • [3- 重试校验参数逻辑](#3- 重试校验参数逻辑)
      • [4- 寻找逆向入口](#4- 寻找逆向入口)
          • [1- 方式一(search搜索):](#1- 方式一(search搜索):)
          • [2- 方式二(堆栈搜索):](#2- 方式二(堆栈搜索):)
      • [5- 获取加密算法](#5- 获取加密算法)
          • [1- fm-sign字段是有zn来的,我们查看zn是如何得到的。](#1- fm-sign字段是有zn来的,我们查看zn是如何得到的。)
          • [2- zn是由kt对象中的encryptParams方法,以qe.Z为原始函数,生成的函数中,分别调用了Rn和da来的。](#2- zn是由kt对象中的encryptParams方法,以qe.Z为原始函数,生成的函数中,分别调用了Rn和da来的。)
          • [3- 那我们就需要看下Rn和da参数。](#3- 那我们就需要看下Rn和da参数。)
      • [6- 爬虫代码编辑](#6- 爬虫代码编辑)
    • 结语

逆向前准备

首先我们得有Fastmoss账号,否则是无法抓取到数据的。拥有账号后,我们直接进入达人选项。

思路

逆向步骤一般分为:

  1. 接口确认: 找到我们需要的接口进行分析;
  2. 参数确认: 在接口中提炼出我们需要处理的参数;
  3. 重试校验参数逻辑: 查看参数之间关系;
  4. 寻找逆向入口: 找到参数生成位置 ;
  5. 获取加密算法: 实现参数逻辑;
  6. 爬虫代码编辑: 爬虫代码编写;

1- 确认接口

多次请求,很容易就能插到数据接口

2- 参数确认

1- 对不同页进行多次请求

2- 对同一页进行多次请求

对照每个接口进行数据比较,payload中发现两个随机参数,其中 _time 为时间戳。cnonce需要查看从哪里来的。

3- 重试校验参数逻辑

为了校验是否有其他参数。我们需要对每一个参数均进行校验。通过复制curl校验出必要参数如下(具体校验步骤见往期爬虫文章)。

params中:

page: 页数

region: 地区

order: 类目(达人,商品等)

pagesize: 一页多少数据

_time: 时间戳

cnonce: 校验参数

params = {
        "page": page,				# 页数
        "region": "US",				# 地区
        "order": "2,2",				# 类目(达人,商品等)
        "pagesize": "10",			# 一页多少数据
        "_time": _time,				# 时间戳
        "cnonce": cnonce		# 校验参数
    }

headers = {
        "fm-sign": fm_sign			# 根据 "_time" 和 "cnonce"生成的参数
    }

cookie= {} 			# cookie中为登录信息

4- 寻找逆向入口

这里有两种方法。一种取巧, 一种耗时。大家可以自行选择。

1- 方式一(search搜索):

先说说第一种。 直接搜索 "_time" 和 "cnonce"。 有且仅找到一条数据,仔细一看,参数的生成逻辑就在这里。

2- 方式二(堆栈搜索):

我们从接口堆栈中进入。内容较多,后续更新,也会跟到dn["fm-sign"]生成的地方。

5- 获取加密算法

读代码可知:

1- fm-sign字段是有zn来的,我们查看zn是如何得到的。
dn["fm-sign"] = zn
2- zn是由kt对象中的encryptParams方法,以qe.Z为原始函数,生成的函数中,分别调用了Rn和da来的。
zn = kt.encryptParams((0, qe.Z)({}, Rn), da)
3- 那我们就需要看下Rn和da参数。

da的生成逻辑如下

da = g != null && g.data ? JSON.stringify(g == null ? void 0 : g.data) : "", zn = ""

Rn的生成逻辑如下

Rn = ht((0, qe.Z)((0, qe.Z)({}, g.params), {}, { _time: Math.floor(Date.now() / 1e3),
                    cnonce: Math.floor(1e7 + Math.random() * 9e7)}))

经过校验,Rn就是我们的params参数。da为空字符串。 qe.z是一个大的存储对象。那剩下的就是kt.encryptParams函数了。经过跟进,发现该函数就是加密逻辑。

看下加密逻辑,解读代码:

g为接口中的params参数。
代码逻辑如下:
	1- 依次获取params中的参数和值。与o.salt(固定值)进行拼接。生成me
	2- 用函数Mo对me参数进行处理,形成一个加密字符串。
	3- 对加密字符串进行for循环体中的计算拼接。生成返回值dn。此dn就是header中的fm-sign

6- 爬虫代码编辑

我们知道参数生成逻辑之后,就需要构建爬虫代码了。以上分析中还有一个点需要处理,那就是Mo()函数。

在我们持续对Mo进行跟进时,我们会越来越熟悉

如果上面还不够明显,到了reset函数,我们应该有所怀疑了。这是个加密算法。

直到我们跟到了这个地方。识字的都能看到,这是个MD5算法。

一步步走完,并未发现异常,或者很离谱的魔改。那遵循一切从简原则,我们直接使用python中的MD5包去试试。

经过校验,MD5确实没有魔改。那就简单很多了。直接调用python中的md5方法。

结语

ok,以上就是全部内容。回过头来是个很简单的网站。难度初级,快则15分钟搞定,慢则一天。我们重新回顾一下思路。

1- 校验参数。发现header中的"fm-sign",params中的 "_time" 和 "cnonce" 三个参数是不可或缺的。
2- 查找加密入口。直接搜索关键词:发现header中的"fm-sign"参数是通过params中的 "_time" 和 "cnonce"生成而来。
3- 进入加密入口,找到加密函数。解析后,可以知道Mo是个加密算法。其余均正常。
4- 解决。我们选择了简单的python导包MD5,或者也可以直接扣代码将MD5抠出。

因为本网站可以直接通过搜索找到加密入口。而加密算法MD5未魔改。所以很快就能搞定。如果模糊了搜索关键词,MD5进行简单魔改后。改网站可能就会难度翻倍。

最后,需要源码,关注留言博主。
相关推荐
m0_7482478013 分钟前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
数据小爬虫@38 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
ZJ_.40 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
joan_851 小时前
layui表格templet图片渲染--模板字符串和字符串拼接
前端·javascript·layui
袁袁袁袁满2 小时前
100天精通Python(爬虫篇)——第113天:‌爬虫基础模块之urllib详细教程大全
开发语言·爬虫·python·网络爬虫·爬虫实战·urllib·urllib模块教程
还是大剑师兰特2 小时前
什么是尾调用,使用尾调用有什么好处?
javascript·大剑师·尾调用
Watermelo6172 小时前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
LucianaiB4 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
一个处女座的程序猿O(∩_∩)O4 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
燃先生._.10 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js