使用Python爬取小红书笔记与评论(js注入方式获取x-s)

文章目录

  • 1. 写在前面
  • 2. 分析加密入口
  • 3. 使用JS注入
  • 4. 爬虫工程化

【作者主页】:吴秋霖
【作者介绍】:Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作!
【作者推荐】:对JS逆向感兴趣的朋友可以关注《爬虫JS逆向实战》,对分布式爬虫平台感兴趣的朋友可以关注《分布式爬虫平台搭建与开发实战》
还有未来会持续更新的验证码突防、APP逆向、Python领域等一系列文章

1. 写在前面

  除了对x-s、x-s-common进行分析实现加密算法,还有之前文章中提到的通过JS注入免扣加密算法的方式获取加密参数

加密分析及算法文章请阅读这篇文章:小红书x-s、x-s-common加密分析(2024-01-10更新)

x-s的加密算法为JS实现、x-s-common的加密算法为Python实现

2. 分析加密入口

在这里插入图片描述

可以看到上图断点处l包含x-s跟x-t的返回,看下面这行代码:

l = (a && void 0 !== window._webmsxyw ? window._webmsxyw : encrypt_sign)(s, i) || {};

window._webmsxyw函数内即加密逻辑,在自执行函数内部并添加在了window属性中

该函数接受两个参数,s是api接口的路径,i是请求提交的参数

3. 使用JS注入

可以使用Playwright或者pyppeteer实现,通过浏览器的JavaScript注入来获取加密参数,代码实现分别如下

Playwright方式:

import asyncio
from playwright.async_api import async_playwrightasync def main():async with async_playwright() as playwright:browser = await playwright.chromium.launch(headless=True)page = await browser.new_page()# 注入stealth.min.js脚本await page.add_init_script(path="stealth.min.js")url = "" # 请求apidata = "" # 请求参数# 执行JavaScriptencrypt_params = await page.evaluate('([url, data]) => window._webmsxyw(url, data)', [url, data])local_storage = await page.evaluate('() => window.localStorage')print(encrypt_params)print(local_storage)await browser.close()asyncio.run(main())

pyppeteer方式:

import asyncio
from pyppeteer import launchasync def main():browser = await launch(headless=True)page = await browser.newPage()# 注入stealth.min.js脚本stealth_script = open("stealth.min.js", "r").read()await page.evaluateOnNewDocument(stealth_script)url = ""  # 请求apidata = ""  # 请求参数# 执行JavaScriptencrypt_params = await page.evaluate('([url, data]) => window._webmsxyw(url, data)', [url, data])local_storage = await page.evaluate('() => window.localStorage')print(encrypt_params)print(local_storage)await browser.close()asyncio.get_event_loop().run_until_complete(main())

上面的stealth.min.js脚本注入的作用是为了防止被检测的,另外cookie参数需要设置属性来避免Web端出现滑动验证码

当然,这个都是爬虫最终工程化需要考虑的事情,这里主要还是通过非逆向分析的方式去解决加密参数问题!

window.localStorage在之前加密分析的文章中已经详细介绍了,localStorage是一个在浏览器中存储键值对的API,通常用于持久化地存储数据,所需的b1参数就在其中

JS注入方式运行结果如下所示:
在这里插入图片描述

x-s跟x-t的加密参数通过注入的方式能够直接拿到,但是x-s-common的参数仍需要通过sign的方法加密计算生成!

Python版本的sign加密算法在之前的加密分析文章中已提供!JS注入的方式主要为了获取这些个参数:x-s、x-t、b1

JS注入的方式对于有前端基础及经验的小伙伴,就很简单了。通过上面的方式获取到所有的加密参数后,接下来就是爬虫的工程化

4. 爬虫工程化

以笔记搜索为例,爬虫代码实现如下:

import json
import httpx
from typing import Dict, Optionalasync def request(self, method, url, **kwargs) -> Dict:async with httpx.AsyncClient(proxies=self.proxies) as client:response = await client.request(method, url, timeout=self.timeout,**kwargs)   data: Dict = response.json()if data["success"]:return data.get("data", data.get("success", {}))elif data["code"] == self.IP_ERROR_CODE:raise IPBlockError(self.IP_ERROR_STR)else:raise DataFetchError(data.get("msg", None))async def unified_request(self, uri: Optional[str] = None, data: Optional[dict] = None,keyword: Optional[str] = None,page: Optional[int] = 1, page_size: Optional[int] = 20,sort: Optional[SearchSortType] = SearchSortType.GENERAL,note_type: Optional[SearchNoteType] = SearchNoteType.ALL) -> Dict:if keyword:_host = "https://edith.xiaohongshu.com"uri = "/api/sns/web/v1/search/notes"data = {"keyword": keyword,"page": page,"page_size": page_size,"search_id": get_search_id(),"sort": sort.value,"note_type": note_type.value}elif uri and data:headers = await self._pre_headers(uri, data)json_str = json.dumps(data, separators=(',', ':'), ensure_ascii=False)return await self.request(method="POST", url=f"{self._host}{uri}",data=json_str, headers=headers)else:raise ValueError("Either 'uri' and 'data' or 'keyword' must be provided.")return await request(method="POST", url=f"{_host}{uri}", data=json.dumps(data), headers=await self._pre_headers(uri, data))

最后,订阅的小伙伴可找作者获取开箱即用的完整爬虫项目代码,如下:

JS注入方式笔记搜索:

在这里插入图片描述

JS注入方式笔记评论:

在这里插入图片描述

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

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

相关文章

Cesium 实战 - 模型亮度调整,自定义着色器(CustomShader)完美解决模型太暗的问题

Cesium 实战 - 自定义视频标签展示视频 模型变暗问题以往通过光线解决问题模型变暗原理解决问题完整代码在线示例在 Cesium 项目中,添加模型是比较基础的功能,Cesium 支持 glTF(GBL) 格式。 在实际应用中,经常会遇到模型特别暗的情况,对比而言,其他三维环境添加是正常的…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-5稳定性stability-李雅普诺夫Lyapunov

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-5稳定性stability-李雅普诺夫Lyapunov Stability in the sense of Lyapunov Assympototic Stability

怎么做微信秒活动_掀起购物狂潮,引爆品牌影响力

微信秒杀活动:掀起购物狂潮,引爆品牌影响力 在数字化时代,微信已经成为人们日常生活中不可或缺的一部分。作为中国最大的社交媒体平台,微信不仅为人们提供了便捷的通讯方式,还为商家提供了一个广阔的营销舞台。其中&a…

基于SpringBoot的医护人员排班系统(代码+数据库+文档)

🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目 希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅一、研究背景 1.1 研究背景 随…

Visual Studio 2017 “无法查找或打开PDB文件“ 解决方法

运行的时候提示无法查找或打开PDB文件 解决办法(注意:必须使用管理员身份运行VS) 第一步 打开调试窗口的选项 第二步 调试——>常规——>勾选启用源服务器支持 它会弹出警告窗口,点“是”即可 第三步 调试——>符号——…

记录误删除docker中极狐gitlab容器恢复过程

如题一次误操作导致删除了docker中极狐gitlab容器恢复过程 情况说明 创建容器时,我是用的是极狐官网推荐安装的步骤,具体按照官网步骤走就行 sudo docker run --detach \--hostname gitlab.example.com \--publish 443:443 --publish 80:80 --publish …

华为OD机试 - 反射计数(Java JS Python C)

题目描述 给定一个包含 0 和 1 的二维矩阵。 给定一个初始位置和速度,一个物体从给定的初始位置出发,在给定的速度下进行移动,遇到矩阵的边缘则发生镜面发射。 无论物体经过 0 还是 1,都不影响其速度。 请计算并给出经过 t 时间单位后,物体经过 1 点的次数。 矩阵以左…

web网页首页布局

效果展示&#xff1a; html代码&#xff1a; <!doctype html> <html> <head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <meta name"viewport" content&qu…

【C语言题解】 | 144. 二叉树的前序遍历

144. 二叉树的前序遍历 144. 二叉树的前序遍历代码 144. 二叉树的前序遍历 提示&#xff1a; 树中节点数目在范围 [0, 100] 内 函数原型&#xff1a; int* preorderTraversal(struct TreeNode* root, int* returnSize) {首先先观察一下这个函数原型&#xff0c;TreeNode* roo…

亿胜盈科HT4822 160mW免输出电容立体声耳机放大器

HT4822是一款无需输出隔直电容的立体声耳机放大器。支持差分和单端的模拟信号输入。 在3.6V供电下&#xff0c;THDN 1%&#xff0c;32ohm负载时能提供80mW的输出。其具有低至0.007%的THDN。 HT4822能在2.5V-6.0V电源条件下工作&#xff0c;具有过热保护和欠压保护等功能。 …

记录一次数据中包含转义字符\引发的bug

后端返回给前端的数据是: { "bizObj": { "current": 1, "orders": [ ], "pages": 2, "records": [ { "from": "1d85b8a4bd33aaf99adc2e71ef02960e", …

deepin安装protobuf(3.22前版本可以使用此方法安装)

deepin安装protobuf 下载protobuf编译安装 下载protobuf protobuf版本&#xff1a;https://github.com/protocolbuffers/protobuf/releases 选择你要下载的版本我这里使用的是这个URL&#xff1a;https://github.com/protocolbuffers/protobuf/releases/v21.12 点击下载的版…

多协议数据库Navicat Premium中文

Navicat Premium是一款强大的数据库管理和开发工具&#xff0c;支持多种数据库系统&#xff0c;如MySQL、Oracle、SQL Server、PostgreSQL等。它提供了一个直观的图形用户界面&#xff0c;使开发者可以轻松地创建、管理和维护数据库。Navicat Premium具有强大的数据建模、查询、…

java JDBC 连接数据库(增删查改)

必须先插入工具包 代码 public static void main(String[] args) {DataSource ds JdbcHelper.getDs();System.out.println(ds);JdbcTemplate jdbcTemplatenew JdbcTemplate(ds);System.out.println(jdbcTemplate);//新增String sql1"insert into biao values(null,?,?,…

高阶智驾,开打「硬核」战

一直以来&#xff0c;高阶智驾的「规模化普及」何时到来&#xff0c;硬件的「军备竞赛」和系统「降本增效」长期处于博弈状态。 其中&#xff0c;作为关键环节之一&#xff0c;传感器配置以及相应的感知算法技术迭代升级是最具看点的部分。以特斯拉、百度Apollo为代表的纯视觉技…

初识Ubuntu

其实还是linux操作系统 命令都一样 但是在学习初级阶段&#xff0c;我还是将其分开有便于我的学习和稳固。 cat 查看文件 命令 Ubuntu工作中经常是用普通用户&#xff0c;在需要时才进行登录管理员用户 sudn -i 切换成管理用户 我们远程连接时 如果出现 hostname -I没有出现…

【GO语言依赖】Go语言依赖管理简述

在运行环境中&#xff0c;遭遇报错&#xff0c;显示找不到函数 经过研究后发现需要进行依赖管理&#xff0c;进行如下操作后解决&#xff1a; 起源 最早的时候&#xff0c;Go所依赖的所有的第三方库都放在GOPATH这个目录下面。这就导致了同一个库只能保存一个版本的代码。如…

轴承滚珠故障的理论推导与计算(修订中...)

1.缘起 轴承故障故障位置在高频&#xff0c;如果不即时处理&#xff0c;恶化后&#xff0c;滚珠会有单颗故障迅速恶化到多颗&#xff0c;如果此时电机承载较大负载&#xff0c;轴承的恶化&#xff0c;会牵连到相关的动力轴。是一个不可不进行监测的项目。 2.频谱特征 轴承的…

VF04写入表VKDFS增强

需求&#xff1a;FPLT表中&#xff0c;存在部分期初出具发票计划数据&#xff0c;需要排除掉&#xff0c;不参与VF04后续运算 实现&#xff1a;跟程序发现调用位置LV05IFAP->AP_01 在调用的时候&#xff0c;满足条件&#xff0c;进入form&#xff1a;index_vkdfs_aufbauen参…

Prepar3D设置全屏显示设置方法

一、 基础设置 当视景软件显示的屏幕超过一个的时候&#xff0c;需要将多个显示屏幕在设置->屏幕设置->多显示器这里设置为扩展这些显示器。 二、全屏方法说明 一般情况只需要设置了多屏显示扩展并设置了P3D软件全屏设置&#xff08;即下面的步骤一&#xff09;保存后…