構思
整體思路
通過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 = https://www.cnblogs.com/yunxike/p/{"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=https://www.cnblogs.com/yunxike/p/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=https://www.cnblogs.com/yunxike/p/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 = https://www.cnblogs.com/yunxike/p/[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 =https://www.cnblogs.com/yunxike/p/ 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.uj5u.com/houduan/501477.html
標籤:Python
