视频加载失败

Python 爬虫实战:随机下发路径的资源怎么下载(CH-003)

1060 字
5 分钟
Python 爬虫实战:随机下发路径的资源怎么下载(CH-003)

本文是 LearnSpider 第 3 关的解密教程。这一关要把图片下载下来,答案是这张图片的字节数。真正的考点是:拿到接口给的 image_id / image_url 之后,别把「字节」和「字符」搞混,也别拖太久(图片是随机下发的)。

现象:图片地址在页面源码里找不到#

在挑战广场点开 CH-003,抽屉里有一个「获取图片」按钮。点一下,页面会请求:

GET /api/challenges/CH-003/image

响应:

{
"challenge_id": "CH-003",
"image_id": "e33a1790898939fa",
"image_url": "https://spider.jsnote.top/api/challenges/CH-003/image/e33a1790898939fa"
}

图片本体在 image_url 上,但它不是磁盘文件名:

  • 磁盘上图片一直叫 challenge-01.jpg、challenge-02.jpg(稳定名字,方便维护);
  • 对外暴露的是随机的 image_id,接口用它反查磁盘文件再 send_file。

所以「猜路径下载」这条路是堵死的:每次都要先调一次接口拿 image_id + image_url。

目标是「字节数」不是「字符数」#

图片是二进制,正确姿势是 len(response.content):

写法结果
len(response.content)✅ 图片真实字节数
len(response.text)❌ 二进制被当文本解码,乱码 + 长度不对
len(response.text.encode("utf-8"))❌ 双重编码,更长,而且可能报错

而且这次提交不只是填一个数字:还要带上 image_id,服务端要靠它找到你这一张图去核对大小。

完整脚本#

"""CH-003:答案 = 随机下发那张图片的字节数(提交时带 image_id)"""
import requests
BASE = "https://spider.jsnote.top"
PICK_URL = f"{BASE}/api/challenges/CH-003/image"
session = requests.Session()
session.headers.update({
"Accept": "*/*",
"Referer": f"{BASE}/",
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"
),
})
# 图片是按「当前会话」下发的,并且提交要带登录态 —— 整个流程用一个 Session + 登录 cookie
session.cookies.set("session", "<把浏览器里的 session cookie 粘到这里>",
domain="spider.jsnote.top")
def main():
# 1) 先让服务端发一张图
pick = session.get(PICK_URL, timeout=10)
pick.raise_for_status()
data = pick.json()
image_id = data["image_id"]
image_url = data["image_url"]
print("拿到图片:", image_id)
# 2) 用返回的地址下载本体(别自己拼路径:路径就是随机 image_id)
image = session.get(image_url, timeout=20)
image.raise_for_status()
size = len(image.content) # ⚠️ content(字节),不是 text(字符)
print("Content-Type:", image.headers.get("Content-Type"))
print("Content-Length(服务端声明的):", image.headers.get("Content-Length"))
print("实际字节数:", size)
# 存的文件是个 JPEG:开头 FFD8
print("文件头:", image.content[:4].hex())
print(f"\n答案:{size} (提交时 body 带上 image_id = {image_id})")
print("提交示例:POST /api/challenges/CH-003/submit "
f'{{"answer": {size}, "image_id": "{image_id}"}}')
if __name__ == "__main__":
main()

为什么每一步都要在同一个 Session 里#

GET /api/challenges/CH-003/image 会把这张图片记进当前会话(session["ch003_image_id"]):

  • 如果你提交时没带 image_id,服务端会退回用会话里最近下发的那张 —— 换个 Session 就对不上了;
  • 图片是随机下发的,再点一次「获取图片」就是另一张、另一个大小。

所以正确顺序是:拿图 → 立刻下载 → 立刻算大小 → 立刻提交。跨天再提交,很可能「图片对不上」。

排查清单#

  1. 别猜图片路径,先调 GET /api/challenges/CH-003/image。
  2. 用返回的 image_url 原样请求(它是绝对地址,服务端按当前请求算出来的)。
  3. 大小用 len(response.content)。
  4. 顺手打一下 Content-Length,和实际字节数对不上就先怀疑传输被截断。
  5. 检查文件头(JPEG 是 ffd8,PNG 是 89504e47),确认下下来的真是图片而不是错误页。
  6. 全流程放在一个 Session 里,别中途换 Cookie。
  7. 提交时带上 image_id。

常见问题#

为什么我下载下来的字节数和浏览器看到的文件大小不一样?#

先看是不是被 gzip 了(图片一般不会)。再看是不是拿 .text 数了字符 —— 二进制文件用文本方式读,长度必然不对。

同一张图片能反复下载吗?#

能,只要 image_id 还有效(challenge_images 表里登记着)。但大小是固定的,重复下载不会让答案变化;换个 image_id 才会变。

接口返回的 image_url 为什么是完整域名?#

服务端用 url_for(..., _external=True) 生成的,这样你在任何页面上都能直接拿去请求,不用自己拼域名。

最后提醒#

下载资源类接口在真实站点上通常带鉴权与防盗链(Referer 校验、临时签名 URL)。练习里只在自己的靶场跑;真实站点的图片请遵守版权与使用条款。

去挑战广场提交,然后进 CH-004:这次的伪装不在数据里,而在你的网络握手上。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Python 爬虫实战:随机下发路径的资源怎么下载(CH-003)
https://jsnote.top/posts/ls-ch3/
作者
xiajiao
发布于
2026-10-02
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
Python 爬虫 TLS 指纹实战:requests 被挂住时怎么查(CH-004)
爬虫靶场本文是 LearnSpider 第 4 关的解密教程。这一关的接口数据本身是明文 JSON,难点在你根本连不上:requests 会一直卡到超时,服务端什么都不返回。答案是 5 页共 50 条关键词的 CPC 之和(保留 2 位小数)。
2
Python 爬虫入门实战:服务端渲染页面怎么取数(CH-001)
爬虫靶场本文是 LearnSpider 第 1 关的解密教程。它练的不是「怎么破加密」,而是先判断数据到底在哪:这一关的数据只在服务端渲染出来的 HTML 里,源码里没有接口。答案是第一页 HTML 源码的字符数。
3
Python 爬虫接口签名实战:参数签名 + 会话绑定(CH-005)
爬虫靶场本文是 LearnSpider 第 5 关的解密教程。这一关的接口参数要签名,而且取数只认一个「会话标识」(uuid)—— 这个 uuid 是页面自己生成的、并且已经在后端和你的账号绑定过。答案是 5 页共 50 个数字的总和。
4
Python 爬虫接口实战:翻页取完再累加(CH-002)
爬虫靶场本文是 LearnSpider 第 2 关的解密教程。这一关的数据不在 HTML 里,只能从分页接口拿;答案是全部电影「评分总人数」的累加值。重点是:怎么找到接口、怎么确认它没把总量直接给你、以及怎么把 21 页稳稳翻完。
5
Python 爬虫字体映射实战:HTML 里一个字都没有(CH-007)
爬虫靶场本文是 LearnSpider 第 7 关的解密教程。这一关把大众点评那套「字体库 + 坐标」搬了过来:页面 HTML 里只有随机类名,文字全在字体库(SVG 文字地图)里,而「每个类名要把图挪多少像素」是接口加密下发的。目标是拿到 5 段…
随机文章随机推荐

评论区

Profile Image of the Author
xiajiao
写爬虫,也写防爬虫的靶场。
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
站点统计
文章
15
分类
1
标签
33
总字数
22,317
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录