百木园-与人分享,
就是让自己快乐。

django小项目 ----- 创建错题集

构思

整体思路

通过API调用获取错题信息,将数据存入数据库(保证可长期查看),通过python+django将数据库数据在前端呈现。

实施思路

1、通过抓包获取到小程序相对应的错题集API信息(url、path、参数、请求方法),分析响应信息,分析获取API之间的关联关系,输出API文档。
2、通过数据关系,搭建数据库结构,创建数据库表。
3、设计方法类:
  1)调用API,获取响应数据
  2)将响应数据存入数据库
  3)后端读取数据库数据,并返回前端界面。
  4)前端设计错题以卡片的形式展示错题集。

实施过程

调用API获取响应数据

  抓包获取API信息

  使用charles进行抓包,因为小程序使用的是HTTPS请求,此处代理需要开启HTTPS代理请求,建议开启全局代理(即计算机代理),其实在开始charles时会默认开启。在此需要设置HTTPS的代理端口。
 
  0
 
【问题】
  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         <style type=\"text/css\">
11             .cardBox {
12                 width: 200px;
13                 box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
14                 text-align: center;
15                 float: left;
16                 margin-right: 10px;
17                 padding: 5px;
18                 padding-top: 15px;
19             }
20 
21             .headerBox {
22                 color: #fff;
23                 padding: 10px;
24                 font-size: 15px;
25                 height: 60px;
26             }
27 
28             .bodyBox {
29                 padding: 10px;
30             }
31 
32             .bodyBox p {
33                 margin-left: 5px;
34             }
35         </style>
36     <script>
37         function GetOpt(data) {
38             var subjectId = data;
39             $.get(\'/GetOpt/\',{
40                 \'subjectId\': subjectId
41             },function (ret){
42                 var a = \"\";
43                 opt = ret;
44                 console.log(opt)
45                 for(var i = ret.length -1; i >=0 ; i--) {
46                     a = ret[i][\'label\']+\":\"+ret[i][\'content\']+\'<br>\'+a;
47                 document.getElementById(subjectId).innerHTML=a;
48             }
49             }
50             )
51         }
52     </script>
53     </head>
54 </head>
55 <body>
56 <div style=\"text-align: center;width: 90%\">
57     <div hidden=\'1000\'>
58         <h1 style=\"text-align: center\">错题集 </h1>
59     </div>
60 
61     <div style=\"text-align: center;width: 100%\">
62         <div style=\"text-align: center\">
63             {% for List in data %}
64             <div class=\"cardBox\" style=\"text-align:center;width: 22%;height: 600px\">
65 
66             <!--卡片头部标签-->
67                 <div class=\"headerBox\" style=\"background-color: #3c5bc2;height: 40px\">
68                     <p>
69                         <a title=\"查看详情\" style=\"cursor: pointer; color:white\">第{{ List.Id }}题({{ List.type_name }})</a>
70                     </p>
71                 </div>
72                 <!--题目-->
73                 <div class=\"bodyBox\">
74                     <p style=\"text-align: left\">{{ List.content }}</p>
75                 </div>
76                 <!--选项-->
77                 <div class=\"bodyBox\">
78                     <script>
79                     window.onload=GetOpt({{ List.subjectId }});
80                     </script>
81                     <p id=\"{{ List.subjectId }}\" style=\"text-align: left\">
82                     </p>
83                 </div>
84                 <!--答案 分析-->
85                 <div class=\"bodyBox\">
86                     <p style=\"text-align: left\">{{ List.correct_answer }}</p>
87                     <br>
88                     <p style=\"text-align: left\">{{ List.analysis }}</p>
89                 </div>
90             </div>
91             {% endfor %}
92         </div>
93     </div>
94 </div>
95 
96 </body>
97 </html>

 


来源:https://www.cnblogs.com/yunxike/p/16575040.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » django小项目 ----- 创建错题集

相关推荐

  • 暂无文章