news 2026/6/19 19:14:07

Python爬取科目一题库1685道并生成Word文档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python爬取科目一题库1685道并生成Word文档

Python爬取科目一题库1685道并生成Word文档

在准备机动车驾驶人理论考试(科目一)的过程中,很多人会遇到这样一个痛点:题库分散在网页上,每次只能手动点击“下一题”查看,复习效率低,打印也不方便。有没有办法一次性把全部题目抓下来,整理成一份结构清晰、可编辑的 Word 文档?答案是肯定的——通过 Python 编写一个轻量级爬虫,就能高效完成这个任务。

本文将带你从零开始,完整实现对某驾驶员考试网站科目一题库的自动化采集,并最终导出为.docx文件。整个过程不依赖 Selenium 模拟浏览器操作,而是直接分析其数据接口,精准构造请求,大幅提升爬取效率与稳定性。


环境准备与技术选型

我们优先选择简洁高效的工具链,避免过度工程化。开发环境建议使用Python 3.7+,推荐配合 Anaconda 创建独立虚拟环境以隔离依赖:

conda create -n crawler-env python=3.8 conda activate crawler-env

核心依赖如下:

pip install requests python-docx lxml urllib3
包名用途说明
requests发起 HTTP 请求获取 JSON 数据
python-docx创建和写入.docx格式文档
urllib3/requests下载图片资源
lxml可用于后续扩展 HTML 解析功能

开发工具推荐VS Code + Python 插件PyCharm,调试体验更流畅。


接口逆向:找到题库的真实数据源

打开目标页面 https://m.jsyks.com/km1_sxlx,你会发现每点一次“下一题”,题目就刷新一次。表面上看像是前端动态加载,但其实背后有规律可循。

利用 Chrome 浏览器开发者工具(F12),切换到Network面板,观察网络请求行为。很快就能发现,每当翻页时,浏览器会向类似以下格式的 URL 发起请求:

https://tkdata.mnks.cn/ExamData/{code}.json?CALL=?{version}.json

其中{code}是每道题的唯一编码,而{version}是当前题库版本号。这些信息并非随机生成,而是内嵌在页面源码或加载的 JS 脚本中。

进一步查看Sources面板中的 JavaScript 文件(如lianxiti.js2020_lianxi.js),可以定位到关键变量:

var ExamVersion = "20201231143735"; // 题库版本 var ExamCount = 1685; // 总题数 var ExamCodes = "02dec,0d977,..."; // 所有题目的编码列表

这意味着我们不需要模拟用户点击,只需提取这串ExamCodes并循环拼接 URL,即可批量获取所有题目数据。这是一种典型的“静态 API 接口暴露”模式,非常适合用脚本直接调用。


数据结构解析:判断题 vs 选择题

每个请求返回的是一个 JSON 对象,结构非常简洁。例如一道判断题的响应如下:

{ "tkId": 2013, "sortId": 1501, "code": "3fd79", "tx": 1, "tm": "驾驶机动车在道路上违反道路通行规定应当接受相应的处罚。", "da": "对", "tags": "违反道路通行规定" }

字段含义明确:
-tm: 题干文本(部分含 Unicode 转义)
-da: 正确答案(“对”或“错”)
-tv: 图片标识(存在则表示该题附带配图)

对于选择题,tm字段通常包含<br/>分隔符来表示换行选项,例如:

"tm": "夜间驾驶机动车在照明条件良好的路段行驶时,应使用什么灯光?<br/>近光灯<br/>远光灯<br/>危险报警闪光灯<br/>雾灯"

我们可以用.split('<br/>')将其拆分为问题描述和多个选项,处理起来也很直观。

实际传输中某些字符串可能经过 Unicode 编码(如\u9a7e\u9a8f),Python 的requests.get().json()方法能自动解码,无需额外处理。


图片资源提取策略

如果某道题包含图片,其字段tv值形如/SU/od50vqgFW8x。去掉前缀/SU/后,拼接到固定域名即可得到真实图片地址:

img_url = "https://sucimg.itc.cn/sblog/" + tv.split('/')[-1] # 示例结果:https://sucimg.itc.cn/sblog/od50vqgFW8x

该链接可以直接通过requests.get()获取二进制内容并保存为本地文件。考虑到图片数量较多,建议统一存入./images/目录,并按唯一 key 命名。

值得注意的是,这类图片服务器一般无强反爬机制,短间隔请求基本不会被封 IP,但仍建议加入轻微延时(如 0.5 秒)以降低风险。


完整爬虫实现:从前端分析到文档输出

有了上述分析,就可以动手写代码了。以下是完整的实现逻辑,分为三步:参数初始化 → 遍历请求 → 写入 Word。

参数定义与文档创建

import requests import time import os from docx import Document from docx.shared import Pt from docx.enum.text import WD_PARAGRAPH_ALIGNMENT # 固定参数(来自JS脚本) ExamVersion = "20201231143735" ExamCount = 1685 ExamCodes_str = "02dec,0d977,02567,..." # 此处省略完整列表 ExamCodes = ExamCodes_str.split(',') # 创建Word文档 doc = Document() doc.add_heading('机动车驾驶人理论考试科目一题库(共1685题)', level=1) headers = {'Connection': 'close'} # 减少连接占用

图片下载函数

def download_image(img_url, img_name): try: resp = requests.get(img_url, timeout=30) if resp.status_code == 200: path = f"./images/{img_name}.png" os.makedirs("./images", exist_ok=True) with open(path, 'wb') as f: f.write(resp.content) return path return None except Exception as e: print(f"图片下载失败: {e}") return None

主循环:请求 + 解析 + 写入

for idx in range(ExamCount): code = ExamCodes[idx] url = f"https://tkdata.mnks.cn/ExamData/{code}.json?CALL=?{ExamVersion}.json" try: resp = requests.get(url, headers=headers, timeout=40) data = resp.json() # 处理题干与答案 tm = data['tm'].replace('\u3002', '。').replace('<br/>', '\n') da = data['da'] # 添加题目 p = doc.add_paragraph() p.add_run(f"{idx+1}. {tm}\n").font.size = Pt(12) # 加粗显示答案 ans_para = doc.add_paragraph() ans_para.add_run(f"答案: {da}").font.bold = True # 插入图片(如有) if data.get('tv'): tv = data['tv'] img_key = tv.split('/')[-1] img_url = f"https://sucimg.itc.cn/sblog/{img_key}" img_path = download_image(img_url, img_key) if img_path: pic_para = doc.add_paragraph() pic_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run = pic_para.add_run() run.add_picture(img_path, width=Pt(300)) print(f"已处理第 {idx+1} 题: {tm[:30]}...") time.sleep(0.5) # 控制频率,防IP限制 except Exception as e: print(f"第 {idx+1} 题抓取失败: {e}") continue # 保存最终文档 output_path = "科目一题库1685道.docx" doc.save(output_path) print(f"\n✅ 全部题目已成功导出至: {output_path}")

运行完成后,你会得到一个包含全部题目、答案及配图的 Word 文档,支持搜索、打印、划重点,极大提升备考效率。


提升健壮性:引入AI辅助优化逻辑

虽然本次任务本身并不复杂,但在实际项目中,经常会遇到字段缺失、接口变动、异常重试等问题。这时候可以借助大模型进行智能补全。

例如使用VibeThinker-1.5B这类擅长代码推理的模型,输入提示:

How to safely extract fields from JSON when some keys may be missing?

它可能会返回一段符合 PEP8 规范的健壮代码:

def safe_get(data, key, default=""): return data.get(key, default) or ""

然后你可以将其应用到主流程中:

tm = safe_get(data, 'tm', '未知题目').replace('<br/>', '\n') da = safe_get(data, 'da', '无答案')

这种“人类设计框架 + AI 补充细节”的协作模式,正逐渐成为现代开发的新常态。尤其在处理边缘情况、错误处理、日志记录等非核心但重要的模块时,AI 能显著减少样板代码编写时间。


总结与延伸思考

本文展示了一个典型的静态 API 数据采集场景:通过分析前端行为,定位真实数据接口,绕过繁琐的 UI 操作,直接对接后端服务。这种方法不仅速度快、成功率高,而且资源消耗极低。

整个方案的核心思想是“最小必要原则”——不用 Selenium,不用 Puppeteer,不搞分布式调度,仅靠requests + python-docx两个轻量库就完成了全部工作。这种极简主义风格更适合个人学习、小规模数据整合等场景。

此外,类似的思路还可拓展至其他领域:
- 抓取在线课程题库生成复习资料
- 批量导出知乎专栏文章为 PDF
- 备份公开 API 提供的新闻/天气/股票数据

只要目标站点存在可预测的数据接口,哪怕没有开放文档,也能通过逆向手段实现自动化采集。

最后提醒一句:请仅将此类技术用于合法合规的学习用途,尊重网站版权与访问规则,合理控制请求频率,做一个有责任感的技术使用者。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/19 4:47:44

解析 ‘PREEMPT_RT’ 补丁:如何将通用 Linux 改造为具备确定性响应的硬实时内核?

各位同仁&#xff0c;各位对系统编程与实时控制充满热情的工程师们&#xff1a;欢迎来到今天的讲座&#xff0c;我们将深入探讨一个在工业控制、航空航天、医疗设备以及高性能计算领域至关重要的技术——如何将我们熟悉的通用 Linux 操作系统改造为具备确定性响应的硬实时内核。…

作者头像 李华
网站建设 2026/6/18 16:30:19

Spark集群搭建与PySpark开发环境配置

Spark集群搭建与PySpark开发环境配置 在大数据处理日益成为企业核心能力的今天&#xff0c;构建一个稳定高效的分布式计算平台是开展数据分析、机器学习乃至大模型工程化的基础。Apache Spark 作为当前最主流的统一分析引擎&#xff0c;其快速、易用和通用的特点让它广泛应用于…

作者头像 李华
网站建设 2026/6/13 12:50:38

JSP+JavaScript 实现验证码登录功能

JSP JavaScript 实现验证码登录功能 在开发一个 Web 应用时&#xff0c;用户登录几乎是每个系统都绕不开的环节。而为了防止恶意程序暴力破解密码&#xff0c;加入图形验证码成了最基础、也最有效的防护手段之一。最近我在做 Java Web 练手项目时&#xff0c;就动手实现了一套…

作者头像 李华
网站建设 2026/6/16 12:40:18

Docker从入门到实践:核心概念与实战指南

Docker从入门到实践&#xff1a;核心概念与实战指南 在现代AI开发中&#xff0c;一个令人头疼的场景再熟悉不过&#xff1a;你在本地调试好的多模态模型&#xff0c;一放到服务器上就“水土不服”——依赖版本冲突、CUDA环境不匹配、Python包缺失……尤其是像 GLM-4.6V-Flash-…

作者头像 李华
网站建设 2026/6/14 4:57:25

CI/CD工具一文纵评,GitLab CI/CD vs Jenkins vs Arbess

面对众多的CI/CD工具&#xff0c;如何根据功能、价格和易用性做出选择&#xff1f;本文旨在通过多款工具的横向对比&#xff0c;为你提供清晰的梳理与参考。1、GitLab CI/CD1.1 产品介绍GitLab CI/CD 是 GitLab 内置的自动化工具链&#xff0c;提供从代码提交到生产部署的全流程…

作者头像 李华
网站建设 2026/6/14 11:59:40

【Open-AutoGLM操作手机安装全攻略】:手把手教你5步完成部署

第一章&#xff1a;Open-AutoGLM操作手机安装全解析Open-AutoGLM 是一款基于大语言模型驱动的移动端自动化工具&#xff0c;支持通过自然语言指令控制手机完成各类操作。其核心优势在于无需编写代码即可实现应用启动、页面跳转、数据填写等自动化流程。以下为在安卓设备上部署并…

作者头像 李华