将医师定考模拟测评试题批量导出为 PDF

给朋友帮忙,想把某市医师服务协会网站上的定考模拟测评试题导出成 PDF,方便在手机上学习。

第一步:从网页抓取试题 JSON

经过操作分析,网页上每道试题都是一条 JSON 数据。代码没有混淆和加密,可以直接在浏览器 Console 里调用已有接口批量拉取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var bbresult = [];
for (var i = 0; i < ordersortArray.length; i++) {
var nextItemID = itemidArray[i];
var nextItemType = itemtypeArray[i];
var nextOrderSort = ordersortArray[i];
$.ajax({
url: '/Service/Web/GetItemSingleByPaperCodeAndItemCode',
type: 'POST',
async: false,
data: {
'paperCode': '1758ae61-7dc2-43b5-a726-2c81cc9fec9b',
'itemCode': nextItemID,
'itemType': nextItemType,
},
dataType: 'json',
success: function (data) {
bbresult.push(data);
console.log("题号:" + nextOrderSort + ", 长度:" + bbresult.length);
}
});
}

执行完毕后,bbresult 里就是全部试题数据。取到的结果示例(节选):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[
{
"DataCount": 0,
"total": 0,
"Status": 1,
"Msg": "试题加载成功!",
"DataList": {
"PaperID": "1758ae61-7dc2-43b5-a726-2c81cc9fec9b",
"ItemID": "00abcc70-5f06-4b6d-a821-dd93af2d97c1",
"Caption": "<p>患者女,68岁,风湿性心脏病史,牙龈出血1年。检查见牙石,牙龈红肿,探诊出血。对其进行治疗时应注意以下内容,除外:()</p>",
"ItemType": "A2型",
"Remark": "心脑血管疾病患者的牙周治疗时病史询问和收集要尽量全……",
"OrderSort": 0,
"AnswerSortNum": 3,
"OptionList": [
{ "OptionContent": "接受治疗当天服用抗生素", "OrderSort": 1, "IsAnswer": false },
{ "OptionContent": "治疗前可用氯己定含漱液含漱", "OrderSort": 2, "IsAnswer": false },
{ "OptionContent": "避免进行手术治疗", "OrderSort": 3, "IsAnswer": true },
{ "OptionContent": "口腔卫生宣教", "OrderSort": 4, "IsAnswer": false },
{ "OptionContent": "详细询问病史", "OrderSort": 5, "IsAnswer": false }
]
}
}
]

把约 500 条数据存成 data.json

第二步:用 ReportLab 生成 PDF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import json
import re

from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer


def remove_html_tags(text):
"""过滤字符串中的 HTML 标签"""
clean = re.compile('<.*?>')
return re.sub(clean, '', text)


if __name__ == '__main__':
with open('data.json', 'r', encoding='utf-8') as file:
data = json.load(file)

pdfmetrics.registerFont(TTFont('MicrosoftYaHei', 'msyh.ttc'))

doc = SimpleDocTemplate("paper.pdf", pagesize=A4)

styles = getSampleStyleSheet()
question_style = styles["Normal"]
question_style.fontName = 'MicrosoftYaHei'
question_style.leading = 18

option_style = ParagraphStyle(
"OptionStyle", parent=styles["Normal"], leftIndent=15, bulletIndent=20
)

elements = []

for index, value in enumerate(data):
d = value['DataList']
ccc = str(index + 1) + ". " + remove_html_tags(d['Caption'])
question_style.fontSize = 14
caption = Paragraph(ccc, question_style)
elements.append(caption)

for o in d['OptionList']:
question_style.fontSize = 12
item = str(chr(ord('A') + int(o["OrderSort"]) - 1)) + ": " + remove_html_tags(o['OptionContent'])
option_paragraph = Paragraph(item, option_style)
elements.append(Spacer(18, 8))
elements.append(option_paragraph)

answer = Paragraph(
"答案:" + str(chr(ord('A') + int(d["AnswerSortNum"]) - 1)), option_style
)
elements.append(answer)
remark = Paragraph("解析:" + remove_html_tags(str(d["Remark"])), option_style)
elements.append(remark)
elements.append(Spacer(1, 20))

doc.build(elements)

效果

PDF 效果非常不错,放在手机上查看清晰可读,收获范主任稀有的赞一次!

声明:代码不会对任何系统产生危害,所有操作均在正规注册付费账号里合规合法完成,未传播任何带有版权的数据。如有侵权,请联系删除。

Notice: 正常情况下,这里会有一个基于utteranc.es的留言系统,如果看不到,可能要想想办法才能看到。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2012 - 2026 tiaobug.com All Rights Reserved.

鲁ICP备2024124237号-1