用Python requests库搞定CF武器图鉴:从接口分析到图片批量下载的保姆级教程

刚学完Python基础语法的新手开发者,往往面临"学完就忘"的困境。而通过一个完整的实战项目,不仅能巩固requests库的核心用法,更能掌握接口分析→数据处理→文件操作的完整开发链路。本文将以《穿越火线》武器图鉴爬取为例,带你从零实现一个兼具趣味性和实用性的工具。

1. 逆向工程:从网页展示到接口分析

现代网页普遍采用前后端分离架构,数据通过异步接口动态加载。以《穿越火线》武器库页面为例,打开Chrome开发者工具(F12),切换到Network面板并刷新页面,可以看到名为workList_inc.cgi的请求,其响应正是包含武器数据的JSONP格式。

关键观察点

  • 请求URL中的page参数表明支持分页
  • sDataType=JSON暗示返回数据格式
  • jsoncallback是JSONP跨域的典型特征

处理这类接口时,需要先剥离JSONP包装。原始返回格式如下:

jsonp1619421788694({...})

通过字符串切割提取有效JSON部分:

raw_json = res.text.split('(')[1].split(')')[0]

提示:实际开发中建议使用json.loads()替代eval(),后者存在安全风险

2. 数据解码:处理URL编码的武器信息

接口返回的武器名称和图片URL都经过URL编码,例如:

  • %3A 对应冒号 :
  • %2F 对应斜杠 /
  • %20 对应空格

建立解码映射表并实现替换函数:

DECODE_MAP = {
    '%3A': ':', 
    '%2F': '/',
    '%2D': '-',
    '%2E': '.',
    '%5F': '_',
    '%20': ' '
}

def decode_url(s: str) -> str:
    for encoded, decoded in DECODE_MAP.items():
        s = s.replace(encoded, decoded)
    return s

进阶技巧:Python标准库的urllib.parse模块其实提供了unquote()函数,但手动实现有助于理解编码原理。

3. 文件存储:处理中文路径的Windows兼容方案

将图片保存到本地时,需要考虑两个关键问题:

  1. 目录创建:检查并自动创建存储文件夹
import os

save_dir = 'cf_weapons'
os.makedirs(save_dir, exist_ok=True)
  1. 中文文件名:Windows系统默认编码可能导致乱码
file_path = f"{save_dir}/{name}.jpg"
with open(file_path.encode('utf-8'), 'wb') as f:
    f.write(requests.get(image_url).content)

注意:在非Windows系统上,可能需要移除.encode('utf-8')

4. 工程化改进:构建健壮的爬虫脚本

原始脚本存在若干可优化点:

4.1 请求重试机制

from time import sleep

def safe_request(url, max_retry=3):
    for _ in range(max_retry):
        try:
            res = requests.get(url, timeout=10)
            res.raise_for_status()
            return res
        except Exception as e:
            print(f"Request failed: {e}")
            sleep(2)
    raise Exception("Max retry exceeded")

4.2 进度可视化 使用tqdm库添加进度条:

from tqdm import tqdm

for page in tqdm(range(1, 34), desc="Downloading pages"):
    # 分页请求逻辑

4.3 异常记录 将失败记录写入日志文件:

import logging

logging.basicConfig(
    filename='error.log',
    level=logging.ERROR,
    format='%(asctime)s - %(message)s'
)

5. 扩展思考:项目进阶方向

完成基础功能后,可以考虑以下增强功能:

  • 图片去重:通过MD5校验避免重复下载
  • 元数据存储:将武器属性保存到SQLite数据库
  • 异步加速:改用aiohttp实现并发下载
  • GUI界面:用PySimpleGUI构建可视化工具
# 计算文件MD5示例
import hashlib

def get_file_md5(content):
    return hashlib.md5(content).hexdigest()

在实际项目中,我遇到过服务器限制频繁访问的情况。解决方案是合理设置请求间隔:

import random

# 每页请求后暂停1-3秒
sleep(random.uniform(1, 3))
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐