
简介这份PDF为液压工考试题及答案面向液压设备操作、维修人员以及职业院校相关专业考生可用于日常复习、上岗前自测与理论考核前的查漏补缺。内容覆盖液压泵分类、溢流阀与减压阀作用、流量控制阀、蓄能器结构、V型密封圈、过滤器安装位置、润滑油特性及帕斯卡定律等基础考点并延伸至同轴度误差、系统故障判断和维护保养等实操判断题型包括填空、选择、判断与简答题干与答案对照清晰。资源为单个PDF文件压缩包约37KB篇幅精简便于打印随身携带或手机上随时翻阅。目前已有63人学习下载可作为液压工理论考核前的快速过题清单也能帮助初学者建立对液压元件功能与常见故障排查思路的整体认识。1. 液压工考试题及答案.pdf 真正的麻烦不在 PDF在题目睡着了手里有一份几百页的液压工考试题及答案.pdf多数人的用法是打印出来发给学员。问题很快出现学员想按章节刷题教练想随机组卷质量部门想统计知识点覆盖率而 PDF 里只有排好版的文字没有一条能查询的数据。复制到 Word 会出现选项错行、页眉混进题干、答案与题目分居文末搜索「溢流阀」只能跳到页码数不清题库里到底有多少道溢流阀的题。换个定位就顺了把这份 PDF 当数据源而不是终端成品。先把题干、选项、答案、解析、知识点、难度落成结构化题库存进 JSON 或 SQLite再由题库渲染出任意题量、任意版本的试卷。这条链路适合维护企业技能题库的开发与运维也适合被 PDF 反复折磨的内训师。2. 拆解液压工考试题及答案.pdf找准题干、选项、答案、解析的锚点切题这件事本质是在文字流里找四类锚点题号、选项字母、答案标签、解析标签。锚点找对了正则就能干活锚点找错了后面所有工作都是徒劳。2.1 液压题库 PDF 的四种典型排版与对应切题策略排版类型明显特征切题策略处理成本规整式题号独占行首选项 A. B. C. D. 各自成行按行正则逐行状态机低段落式题干与选项挤在同一段选项用「A、」分隔先按行拆再用选项正则二次切分中双栏式同一行的左右两侧属于不同题按词坐标 x0 分栏后再拼行中高扫描件选中文字复制不出来OCR 后再走规整式流程高判断属于哪一种不用肉眼翻两百页跑一遍坐标统计就够。双栏排版的典型特征是词的 x0 集中在两个区间比如 55 到 70 一批、320 到 340 一批如果 x0 连续分布那就是单栏。2.2 用 pdfplumber 读坐标先判分栏再判锚点import pdfplumber with pdfplumber.open(液压工考试题及答案.pdf) as pdf: for i, page in enumerate(pdf.pages[:3], 1): print(f--- 第{i}页 {page.width:.0f}x{page.height:.0f}) # extra_attrs 把字号一起带出来用于识别章节标题 for w in page.extract_words(extra_attrs[size])[:20]: print(fx0{w[x0]:6.1f} top{w[top]:6.1f} fsize{w[size]:4.1f} {w[text]})三个字段各有用途。x0判断分栏两个聚集区间就是双栏此时直接extract_text()会把左右栏串成一行必须先用page.crop()按 x 切开。size用来识别章节标题正文通常 10 到 11 号14 号以上多半是「第二章 液压泵」这类分节标题可以作为知识点归属的天然分隔。top用来定页眉页脚top小于 40 或大于页高减 50 的内容基本都是书名和页码先裁掉再解析能省掉一半噪声。2.3 最小可跑的切题脚本状态机加四组正则import re, json, pdfplumber RE_ITEM re.compile(r^\s*(\d{1,3})\s*[.、]\s*(?\S)) # 题号 1. / 12、 RE_OPT re.compile(r^\s*([A-F])\s*[.、]\s*(.*)$) # 选项 A. / B、 RE_ANS re.compile(r答案\s*[:]\s*([A-F√×对错])) # 答案A RE_NOISE re.compile(r^[-—\s]*\d{1,4}[-—\s]*$) # 纯页码行 def load_lines(path): lines [] with pdfplumber.open(path) as pdf: for pno, page in enumerate(pdf.pages, 1): # 裁掉页眉页脚再抽文本 body page.crop((0, 40, page.width, page.height - 50)) for ln in (body.extract_text(x_tolerance2, y_tolerance3) or ).split(\n): s ln.strip() if s and not RE_NOISE.match(s): lines.append((pno, s)) return lines def slice_items(lines): items, cur [], None for pno, s in lines: m RE_ITEM.match(s) # 排除 A. 泵 这类被误判成题号的行 if m and not RE_OPT.match(s): if cur: items.append(cur) cur {no: int(m.group(1)), page: pno, stem: [s[m.end():].strip()], options: {}, answer: None} continue if cur is None: continue if (ma : RE_ANS.search(s)): cur[answer] ma.group(1) continue if (mo : RE_OPT.match(s)): cur[options][mo.group(1)] mo.group(2).strip() continue # 续行归属已有选项就续到最后一个选项否则续到题干 if cur[options]: k list(cur[options])[-1] cur[options][k] s else: cur[stem].append(s) if cur: items.append(cur) return itemsx_tolerance控制横向字距容差中文字体字距偏大时给到 2 到 3太大反而会把相邻两栏的字并成一个词双栏排版建议先分栏再抽。y_tolerance是行合并容差超过这个纵向距离才算新行设成 3 比较稳。跨页断题的处理藏在「不重置 cur」这一句翻页时当前题目对象继续沿用下一页的续行自然接到同一道题上。有一个坑必须提前拆开很多试卷把参考答案统一放在文末文末答案区的编号和题目区完全一样都是「1. A」。如果答案区和题目区一起喂给切片函数第 100 题的答案会被挂到第 1 题上。稳妥做法是先按位置或「参考答案」「答案与解析」标题行把文档切成两段题目段落只跑题干与选项答案段落单独解析成{题号: 答案}字典最后再回填。2.4 切题失败的五个高频原因题干里混进页眉通常是书名重复出现在每个题号之前靠crop裁页眉解决。选项和题干同行段落式排版里极常见需要在题干文本上再跑一次选项正则做二次切分。全角半角混用「」「A、」「A.」三种写法并存正则里的字符类要把它们都列进去。括号答案没有解析很多老题库只给「A」不给解析这时answer要从题干括号里回捞。判断题没有选项答案直接是「对」「错」或「√」「×」字段设计上不能假设每道题都有 options。3. 题库建表与答案校验让同一道题只剩一个正确答案切出来的原始数据一定有脏东西同一道题被抽了两遍、多选题答案写成「AB」和「A、B」两种格式、判断题答案是「正确」和「√」混用。这些在纸面上无所谓进了数据库就会让统计和判分全乱。3.1 液压工题库的字段设计与建表 SQLCREATE TABLE IF NOT EXISTS question ( id INTEGER PRIMARY KEY AUTOINCREMENT, src_no INTEGER, -- 原 PDF 题号便于回溯 qtype TEXT NOT NULL, -- single/multi/judge/short/calc stem TEXT NOT NULL, options TEXT, -- JSON, 如 {A:...,B:...}判断题留空 answer TEXT NOT NULL, -- 单选 A多选 A,C判断 对简答存要点 analysis TEXT, kp_code TEXT, -- 知识点编码如 HYD-VALVE-03 difficulty INTEGER DEFAULT 3, -- 1~5 src_page INTEGER, fingerprint TEXT, -- 题干指纹用于精确去重 UNIQUE(fingerprint) ); CREATE INDEX idx_kp ON question(kp_code); CREATE INDEX idx_type ON question(qtype);qtype单独建字段而不是从内容推断是因为组卷时要按题型配额抽题靠正则现推既慢又容易出错。answer统一存标准形态多选一律逗号分隔并按字母升序判断题一律存「对」或「错」格式统一放在入库前做不要留到渲染层。3.2 知识点标签按液压系统五大模块打 kp_code模块kp 前缀典型考点动力元件HYD-PUMP齿轮泵、叶片泵、柱塞泵、变量机构、泵的困油执行元件HYD-ACT液压缸、液压马达、差动连接、缓冲与排气控制元件HYD-VALVE方向阀、溢流阀、减压阀、节流阀、比例阀辅助元件HYD-AUX油箱、滤油器、蓄能器、管路与管接头介质与维护HYD-OIL粘度、污染度等级、油温、泄漏与故障诊断回路与系统HYD-CIRC节流调速、容积调速、保压、卸荷、同步回路打标不必全靠人工先按章节标题位置做粗分解析结果保留src_page同时记录每个章节标题所在的页码区间落在区间内的题先给定默认前缀再对题干做关键词匹配做二次修正。比如题干出现「粘度」「污染度」「ISO 4406」就往 HYD-OIL 归出现「节流调速」「背压」就往 HYD-CIRC 归。3.3 规则校验四类题型各自的硬约束import json, re ALLOWED_JUDGE {对, 错, 正确, 错误, √, ×} def validate(q): errs [] opts json.loads(q[options]) if q[options] else {} ans (q[answer] or ).strip().upper() if q[qtype] single: if len(ans) ! 1 or ans not in opts: errs.append(单选答案必须是唯一且已存在的选项) elif q[qtype] multi: picked [c for c in re.split(r[,、], ans) if c] if len(picked) 2 or not set(picked) set(opts): errs.append(多选至少两个选项且都要存在) if len(picked) ! len(set(picked)): errs.append(多选答案存在重复字母) elif q[qtype] judge: if ans not in ALLOWED_JUDGE: errs.append(判断题答案不在允许集合内) elif q[qtype] in (short, calc): if len(q[answer].strip()) 5: errs.append(简答或计算题答案过短疑似抽取失败) return errs这套校验只做静态检查不判断答案对不对但能挡掉九成的抽取事故选项只有三个却出现答案 D、多选题答案只有一个字母、判断题答案是「是」这种方言。跑完把带错的题导出成待修清单人工只看这几十条比从头核对几百道题省得多。3.4 查重指纹做精确去重编辑距离只出候选import re, hashlib from difflib import SequenceMatcher def norm(stem: str) - str: s re.sub(r^\s*\d{1,3}\s*[.、]\s*, , stem) # 去题号 s re.sub(r[\s。、()\.\,\;\:], , s) # 去空白与标点 return s.strip() def fingerprint(stem: str) - str: return hashlib.md5(norm(stem).encode(utf-8)).hexdigest()[:16] def near_dup(a: str, b: str, th: float 0.9) - bool: return SequenceMatcher(None, norm(a), norm(b)).ratio() th指纹走 UNIQUE 约束能挡掉完全重复的录入。近似重复的关键是把阈值卡在 0.9 以上并且只输出候选对交人工确认绝对不要自动删。液压题里「溢流阀进口压力增大」和「溢流阀进口压力减小」只差一个字相似度极高而答案相反自动删除会直接毁掉题库。4. 按知识点权重自动组卷从题库到一份液压工考卷题库建好之后最有价值的动作不是导出而是按考纲配额抽题。手工挑题容易出现某个模块扎堆、某个模块一道没有这在技能鉴定和质量评估里都是硬伤。4.1 考纲权重表怎么落到题量模块目标占比100 题卷题量难度分布1~5HYD-PUMP15%15易 5 / 中 7 / 难 3HYD-ACT15%15易 5 / 中 7 / 难 3HYD-VALVE25%25易 8 / 中 12 / 难 5HYD-AUX10%10易 5 / 中 4 / 难 1HYD-OIL15%15易 6 / 中 7 / 难 2HYD-CIRC20%20易 4 / 中 10 / 难 6合计100%100—权重不是拍脑袋定的控制元件和回路系统在实操故障排查里出现频率最高占比自然要压过辅助元件。这张表放在代码外面用 JSON 或 YAML 存考纲调整时改配置不改逻辑。4.2 分层加权抽题的实现import random from collections import defaultdict def draw_paper(pool, plan, seed20240501): pool: 题目 dict 列表; plan: [(前缀, 总题量, {难度:题量}), ...] rng random.Random(seed) # 固定种子同一场考试可复现 by_kp defaultdict(list) for q in pool: by_kp[q[kp_code][:9]].append(q) # 如 HYD-VALVE picked, used [], set() for prefix, quota, diff_plan in plan: cand [q for q in by_kp.get(prefix, []) if q[id] not in used] for diff, n in diff_plan.items(): # 先按难度精确配额 bucket [q for q in cand if q[difficulty] diff and q[id] not in used] rng.shuffle(bucket) for q in bucket[:n]: picked.append(q); used.add(q[id]) # 难度题量不足时从同模块其余难度回退补齐 got sum(1 for q in picked if q[kp_code].startswith(prefix)) rest [q for q in cand if q[id] not in used] rng.shuffle(rest) picked.extend(rest[:max(0, quota - got)]) return pickedseed是整个函数里最该被认真对待的参数。固定种子意味着同一份配置跑出来的卷子是确定的便于复核和归档换个种子就是一套新卷适合做 A、B 卷。quota是该模块的总题量下限diff_plan是难度细分两段逻辑拆开写是为了让难度配不齐时有明确的回退路径而不是直接抛异常。回退规则建议限定在同模块内实在不够再跨模块补跨模块补的时候在卷子里做标记后续人工调。4.3 难度分布与题型结构的配合单选题适合覆盖广、判分快通常占 60% 左右多选题最容易拉开区分度但数量不宜超过 15%而且必须保证每个选项的表述都站得住判断题用来兜底基础概念占 20%简答和计算题占 5% 到 10%主要考压力计算、流量计算和故障分析。计算题要单独校验一遍单位MPa 与 Pa、L/min 与 m³/s 混用是液压题最常见的答案错误来源。4.4 组卷结果自检权重偏差和重复率def audit(paper, plan): total len(paper) want sum(p[1] for p in plan) for prefix, quota, _ in plan: got sum(1 for q in paper if q[kp_code].startswith(prefix)) flag OK if abs(got / total - quota / want) 0.03 else 偏差超限 print(f{prefix:10s} {got:3d}/{quota:3d} f实际{got/total:6.1%} 目标{quota/want:6.1%} {flag}) ids [q[id] for q in paper] print(重复题数:, len(ids) - len(set(ids))) print(难度分布:, {d: sum(1 for q in paper if q[difficulty] d) for d in range(1, 6)})偏差阈值设 3 个百分点比较合适超过就说明某个模块题量不足需要回题库补题或者调整权重。重复题数必须为 0这一条比权重更重要出现重复说明used集合的过滤逻辑有漏洞。5. 用 ReportLab 把题库渲染回液压工考试题及答案.pdf渲染这条路上最常翻车的不是排版是中文。字体没注册对出来的全是方框而且报错信息往往要翻到最后一页才看得到。5.1 中文字体注册与样式定义from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import ParagraphStyle from reportlab.lib.units import mm from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.platypus import SimpleDocTemplate, Paragraph # .ttc 需要指定 subfontIndex或用 .otf/.ttf 单字体文件更省事 pdfmetrics.registerFont(TTFont(CN, NotoSansCJK-Regular.ttf)) pdfmetrics.registerFont(TTFont(CNB, NotoSansCJK-Bold.ttf)) body ParagraphStyle(body, fontNameCN, fontSize10.5, leading17, spaceAfter2) # leading 约 1.6 倍字号 stem ParagraphStyle(stem, parentbody, fontNameCNB, leading18) opt ParagraphStyle(opt, parentbody, leftIndent8*mm, leading16) doc SimpleDocTemplate(液压工考试题及答案.pdf, pagesizeA4, leftMargin20*mm, rightMargin20*mm, topMargin18*mm, bottomMargin18*mm, title液压工考试题及答案)leading别低于 1.5 倍字号中文行密了非常难读。leftIndent给选项做视觉缩进比空格可靠得多。title参数会写进 PDF 元数据回读校验时可以顺手核对是不是渲染了错误版本的文件。5.2 试卷页与答案解析页分开排排版顺序建议是试卷部分只印题干和选项答案与解析统一放到后面中间强制分页。这样同一份题库可以一次渲染出「学员版」和「讲师版」两个文件靠一个include_answer开关控制是否追加答案段。def render(bank, out_path, include_answerTrue): story [] for q in bank: story.append(Paragraph(f{q[src_no]}. {q[stem]}, stem)) for k, v in sorted(q[options].items()): story.append(Paragraph(f{k}. {v}, opt)) story.append(Spacer(1, 4)) if include_answer: story.append(PageBreak()) story.append(Paragraph(参考答案与解析, stem)) for q in bank: story.append(Paragraph( f{q[src_no]}. {q[answer]}, body)) if q.get(analysis): story.append(Paragraph(q[analysis], opt)) doc.build(story)PageBreak放在答案段之前而不是每题之后避免出现半页空白。答案页的题号直接从题库带出不重新编号学员对照时不会串行。5.3 上下标、单位与公式的排法ReportLab 的Paragraph支持有限标签上下标用super和subΔp、η、°C、L/min、MPa这些直接用 Unicode 字符写进文本就行。麻烦的是p₁、q₂这类带下标的变量能写成psub1/sub就不要用图片。用图片代替文字会直接导致第 6 章的文本回读校验测不到这道题等于自己给自己挖坑。长公式建议单独一段、等宽字体、居中别塞在题干里。5.4 渲染层需要固定的几个参数参数建议值影响字号 / leading10.5 / 17阅读舒适度页边距左右 20mm上下 18mmA4 单栏约排 30 行选项缩进8mm视觉层级题目间距4pt过大会导致大量翻页元数据 title与文件名一致回读时核对版本6. 生成的 PDF 做回读质检以及一个批量修题的技巧渲染完直接发出去是有风险的字号、缩进、特殊字符任何一处出问题都会让某几道题在成品里变样甚至消失。成本最低的质检方式是把成品 PDF 的文本重新读一遍和题库做比对。import re, json, fitz doc fitz.open(液压工考试题及答案.pdf) plain \n.join(p.get_text(text) for p in doc) def norm(s): return re.sub(r\s, , s) # 去掉换行与空格消除排版差异 bank [json.loads(l) for l in open(bank.jsonl, encodingutf-8)] missing [] for q in bank: key norm(q[stem])[:12] # 题干前 12 字做锚短且不易被换行打断 if key not in norm(plain): missing.append((q[id], q[src_no], q[stem][:30])) print(f题库 {len(bank)} 题回读缺失 {len(missing)} 题) for row in missing[:20]: print(row)选前 12 个字当锚点是有讲究的太长容易被行首行尾的空格和分页打断太短又容易撞车。归一化空白这一步不能省PDF 里的文本提取结果和题库原文在换行位置几乎不可能一致。实测中缺失通常集中在三种情况题干里含、这类被当成 XML 标签吞掉公式被替换成了图片以及题目被分页从中间切开导致首行文字跑到了下一页。对应地入库或渲染前统一做一次转义把、、换成实体from xml.sax.saxutils import escape def safe_text(s: str) - str: return escape(s).replace(Δ, Δ) # 保留希腊字母只转义语法字符另一条要一起跑的是答案页覆盖率把答案页提取出的题号集合和试卷题号集合做差集两边必须完全一致。差集不为空说明有题目的答案丢了多半是渲染时PageBreak位置算错或者某道题在组卷阶段就已经被过滤掉了。把转义放在入库前而不是渲染前回读脚本就能和题库共用同一份文本缺字问题基本不会再出现。本文还有配套的精品资源点击获取