构思
整体思路
通过API调用获取错题信息,将数据存入数据库(保证可长期查看),通过python+django将数据库数据在前端呈现。实施思路
1、通过抓包获取到小程序相对应的错题集API信息(url、path、参数、请求方法),分析响应信息,分析获取API之间的关联关系,输出API文档。2、通过数据关系,搭建数据库结构,创建数据库表。3、设计方法类: 1)调用API,获取响应数据 2)将响应数据存入数据库 3)后端读取数据库数据,并返回前端界面。 4)前端设计错题以卡片的形式展示错题集。实施过程
调用API获取响应数据
抓包获取API信息
使用charles进行抓包,因为小程序使用的是HTTPS请求,此处代理需要开启HTTPS代理请求,建议开启全局代理(即计算机代理),其实在开始charles时会默认开启。在此需要设置HTTPS的代理端口。 【问题】 1、抓包小程序需要清理小程序缓存,查询WMPFRuntime文件夹所在位置,删除该文件夹即可。 2、抓包小程序过程中,总提示小程序认证失败,再次登录却提示“设备参数缺失”,此时可以先退出charles,登陆后再打开charles,即可正常获取认证信息。 3、获取的API信息,其中的token,在python设置参数时需要进行url解码,再进行请求。 python发送HTTPS请求
- 1 def GetExercisebook():
- 2 # SQL集
- 3
- 4 pmpExerciseManualInsertSQL = "INSERT INTO `mysql_python`.`pmp_exercise_manual` (`id`, `history_id`, `subject`, `name`, `exam_type_id`) VALUES (%s, %s, %s, %s, %s);"
- 5 pmpManualSubjectInsertSQL = "INSERT INTO `mysql_python`.`pmp_manual_subject` (`manual`, `subject`) VALUES (%s, %s);"
- 6 pmpSubjectInsertSQL = "INSERT INTO `mysql_python`.`pmp_subject` (`subjectId`, `type_name`, `content`, `opt`, `correct_answer`, `analysis`, `label_text`) VALUES (%s, %s, %s, %s, %s, %s, %s);"
- 7
- 8 # token 值(不同设备登陆后需要更新此部分)
- 9 TOKEN_NEW = '********'
- 10
- 11 # 获取问题集---请求参数params
- 12 VALUE = {"clienttype": "2",
- 13 "exam_type": "****",
- 14 "isBusy": "true",
- 15 "isOver": "false",
- 16 "loadingTips": "*******",
- 17 "login_status": "2",
- 18 "page": "0",
- 19 "pageSize": "100",
- 20 "login_status": "2",
- 21 "token": TOKEN_NEW
- 22 }
- 23 url = "https://*******/api/v2/****/****/history/exercise"
- 24 payload = ""
- 25 headers = {
- 26 }
- 27 print("*********************开始发送请求********************")
- 28 ResponseProblemBook = requests.request("GET", url, headers=headers, data=payload, params=VALUE)
- 29 print(ResponseProblemBook.request)
- 30 ProblemBook = ResponseProblemBook.json()
- 31 subjectDetailList = ProblemBook['data']
- 32 print("*********************获取响应成功********************")
- 33
- 34 # 遍历获取习题信息
- 35 num = 0
- 36 pmpExerciseManualInsertVal = []
- 37 for num in range(len(subjectDetailList)):
- 38 pmpManualSubjectInsertVal = []
- 39 pmpSubjectInsertVal = []
- 40 id = subjectDetailList[num]['id']
- 41 history_id = subjectDetailList[num]['history_id']
- 42 name = subjectDetailList[num]['name']
- 43 exam_type_id = subjectDetailList[num]['exam_type_id']
- 44 subject = subjectDetailList[num]['subject']
- 45 bSubject = qieString(subject)
- 46 for subjectId in bSubject:
- 47 pmpManualSubjectInsertResult = (id, subjectId)
- 48 pmpManualSubjectInsertVal.append(pmpManualSubjectInsertResult)
- 49 url_2 = "https://*******/api/v2/****/****/" + subjectId + "/analysis"
- 50 VALUE_2 = {"id": subjectId,
- 51 "exam_type": "****",
- 52 "clienttype": "2",
- 53 "login_status": "2",
- 54 "token": TOKEN_NEW
- 55 }
- 56 response_2 = requests.request("GET", url_2, headers=headers, data=payload, params=VALUE_2)
- 57 response_b = response_2.json()
- 58 subjectDetailList_b = response_b['data']
- 59 type_name_b = subjectDetailList_b['type_name'] # 题目类型
- 60 correct_answer_b = subjectDetailList_b['correct_answer'] # 答案
- 61 content_b = subjectDetailList_b['content'] # 问题
- 62 analysis_b = subjectDetailList_b['analysis'] # 分析
- 63 opt_b = subjectDetailList_b['opt'] # 选项
- 64 label_text_b = subjectDetailList_b['label_text'] # 分类标准
- 65 pmpSubjectInsertResult = (
- 66 subjectId, type_name_b, content_b, opt_b, correct_answer_b, analysis_b, label_text_b)
- 67 pmpSubjectInsertVal.append(pmpSubjectInsertResult)
- 68 Save_Mysql(pmpManualSubjectInsertSQL, pmpManualSubjectInsertVal)
- 69 Save_Mysql(pmpSubjectInsertSQL, pmpSubjectInsertVal)
- 70 print('获取关联表成功:', pmpManualSubjectInsertVal)
- 71 pmpExerciseManualInsertResult = (id, history_id, subject, name, exam_type_id)
- 72 pmpExerciseManualInsertVal.append(pmpExerciseManualInsertResult)
- 73 # print('获取习题集成功:', name)
- 74 num = num + 1
- 75 Save_Mysql(pmpExerciseManualInsertSQL, pmpExerciseManualInsertVal)
复制代码
将响应值存入数据库
- 1 # 将题目存入数据库,无返回值
- 2 def Save_Mysql(sql, val):
- 3 HOST = 'localhost'
- 4 PORT = 3306
- 5 USER = 'root'
- 6 PASSWORD = 'XF950701.'
- 7
- 8 connection = pymysql.connect(host=HOST, port=PORT, user=USER, password=PASSWORD, db='mysql_python', charset='utf8')
- 9 try:
- 10 cursor = connection.cursor()
- 11
- 12 cursor.executemany(sql, val)
- 13 connection.commit()
- 14 print("插入成功数据:", cursor.rowcount)
- 15 except Exception:
- 16 print("插入失败")
- 17 finally:
- 18 cursor.close() # 关闭游标连接
- 19 connection.close()
- 20
- 21
- 22 # 读取数据库数据输出表格
- 23 def qieString(subject):
- 24 aString = subject
- 25 bString = re.sub(u"\\[|\\]", '', aString)
- 26 cString = bString.split(',')
- 27 return cString
复制代码
获取数据库数据
- 1 def GetPnP(sql):
- 2 HOST = 'localhost'
- 3 PORT = 3306
- 4 USER = 'root'
- 5 PASSWORD = 'XF950701.'
- 6
- 7 conn = pymysql.connect(host=HOST, port=PORT, user=USER, password=PASSWORD,
- 8 db='mysql_python',
- 9 charset='utf8')
- 10 # 生成sql语句 利用传入的BankConsentId进行条件查询
- 11 authorize_sql = sql
- 12 cursor = conn.cursor()
- 13 try:
- 14 cursor.execute(authorize_sql)
- 15 desc = cursor.description # 获取字段的描述
- 16 data = [dict(zip([col[0] for col in desc], row)) for row in
- 17 cursor.fetchall()]
- 18 except:
- 19 conn.rollback()
- 20 cursor.close()
- 21 conn.close()
- 22 return data
复制代码
将数据格式化后返回前端页面
- 1 def GetExercisebook(request):
- 2 p1 = "<p>|</p>"
- 3 from Myapp.Dao.HttpsRequest.getpnp import GetPnP
- 4
- 5 authorize_sql = "SELECT Id,subjectId,type_name,content,correct_answer,analysis FROM pmp_subject"
- 6 data = GetPnP(authorize_sql)
- 7 context = {"code": 200, "data": data}
- 8 JsonDupsContext = json.dumps(context)
- 9 opt_demo = re.sub(p1, '', JsonDupsContext)
- 10 JsonLoadsContext = json.loads(opt_demo)
- 11 return render(request, 'Exercisebook.html', JsonLoadsContext)
- 12
- 13
- 14 def GetOpt(request):
- 15 p1 = "<p>|</p>"
- 16 from Myapp.Dao.HttpsRequest.getpnp import GetPnP
- 17 subjectId = request.GET['subjectId']
- 18 authorize_sql = "SELECT opt FROM pmp_subject where subjectId = "+subjectId
- 19 opt =GetPnP(authorize_sql)
- 20 opt_demo = re.sub(p1, "", opt[0]['opt'])
- 21 context = json.loads(opt_demo)
- 22 return JsonResponse(context, safe=False)
复制代码
前端呈现
- 1 <!DOCTYPE html>
- 2 <html lang="en">
- 3 <head>
- 4 <meta charset="UTF-8">
- 5
- 6
- 7 <title>Exercisebook</title>
- 8 <meta charset="UTF-8">
- 9 <title>卡片效果</title>
- 10
- 36
- 53 </head>
- 54 </head>
- 55 <body>
- 56
- 57
- 58 <h1 style="text-align: center">错题集 </h1>
- 59
- 60
- 61
- 62
- 63 {% for List in data %}
- 64
- 65
- 66
- 67
- 68 <p>
- 69 <a title="查看详情" style="cursor: pointer; color:white">第{{ List.Id }}题({{ List.type_name }})</a>
- 70 </p>
- 71
- 72
- 73
- 74 <p style="text-align: left">{{ List.content }}</p>
- 75
- 76
- 77
- 78
- 81 <p id="{{ List.subjectId }}" style="text-align: left">
- 82 </p>
- 83
- 84
- 85
- 86 <p style="text-align: left">{{ List.correct_answer }}</p>
- 87 <br>
- 88 <p style="text-align: left">{{ List.analysis }}</p>
- 89
- 90
- 91 {% endfor %}
- 92
- 93
- 94
- 95
- 96 </body>
- 97 </html>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |