爬虫|强智系统爬虫分析


强智系统爬虫分析

  • 一、登录分析
  • 二、其他分析

一、登录分析 我校使用的教务管理系统是叫做强智系统,有一天我就突发奇想想要搞一个爬虫去给他搞一搞。
1.刚开始我以为是非常简单的一个post请求就解决的事情,我就post了一个
data = https://www.it610.com/article/{ username:'xxxx', password: 'xxxx', RANDOMCODE: 'XXXX', }

【爬虫|强智系统爬虫分析】由于我还是太年轻,没有经历过反爬虫的毒打,果然返回了登陆失败。然后我就看了下网页源代码
爬虫|强智系统爬虫分析
文章图片

咋回事?这玩意就提交了一个encoded和RANDOMCODE,竟然没有提交username和password。根据我多年的后端经验(假的,ε=ε=ε=┏(゜ロ゜; )┛)肯定这个encoded就是password和username进行加密编码后的产物。果然当我阅读他后面的一段js代码我发现了隐秘。
爬虫|强智系统爬虫分析
文章图片

从中我们可以看到它通过一个叫encodeInp的函数进行加密(转码)然后把这两个通过%%%进行连接(好智障的一个设定)。然后我再一个叫做conwork.js的js文件中发现了这个函数。
爬虫|强智系统爬虫分析
文章图片

爬虫|强智系统爬虫分析
文章图片

找到这个文件就好解决了,我通过PyExecJs来调用这个js文件里面的函数。
登录代码如下
'''简单解析验证码''' def parse_verity_code(session, img_url): img_content = session.get(img_url) img = Image.open(BytesIO(img_content.content)) img.save('a.png') verify_image = Image.open('a.png') code = pytesseract.image_to_string(verify_image) time.sleep(2) return code''' 对账号密码进行编码 '''def make_user_token(username, password): with open('conwork.js') as f: ctx = execjs.compile(f.read()) username_encode = ctx.call('encodeInp', username) password_encode = ctx.call('encodeInp', password) token = username_encode + '%%%' + password_encode print(token) return token

二、其他分析 其实在登录之后事情就变的简单多了,这管理系统没有那么多的反爬机制,所以你想干啥就能干啥。下面完整代码展示下,我这里隐去我们学校的网站
# encode: utf-8 import re from io import BytesIO import requests from lxml import etree from PIL import Image# 用于显示图片 import pymongo import pytesseract import time import execjs# # MONGO_CLIENT = pymongo.MongoClient("mongodb://127.0.0.1:27017") # mydb = MONGO_CLIENT['xxu_jwxt'] # mycol = mydb['score_list']BASE_URL = "https://jwxt.xx大学.edu.cn"SCORE_FOR_USER = []USERNAME = '2017xxxxxx' PASSWORD = 'xxxxxxxxxx'def parse_verity_code(session, img_url): img_content = session.get(img_url) img = Image.open(BytesIO(img_content.content)) img.save('a.png') verify_image = Image.open('a.png') code = pytesseract.image_to_string(verify_image) time.sleep(2) return code''' 对账号密码进行编码 '''def make_user_token(username, password): with open('conwork.js') as f: ctx = execjs.compile(f.read()) username_encode = ctx.call('encodeInp', username) password_encode = ctx.call('encodeInp', password) token = username_encode + '%%%' + password_encode print(token) return token''' 解析登录页面 '''def parse_login(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' } session = requests.session() resp = session.get(url, headers=headers) text = resp.texthtml = etree.HTML(text) img = html.xpath("//img/@src")[1] img_url = BASE_URL + img while True: try: code = parse_verity_code(session, img_url) code = re.sub("[^\d\w]", '', code) print("验证码:" + code) login_url = BASE_URL + "/jsxsd/xk/LoginToXk" print(login_url) ''' 用户名和密码会加密后以%%%连接 ''' encoded = make_user_token(USERNAME, PASSWORD) data = https://www.it610.com/article/{'encoded': encoded, 'RANDOMCODE': code, } print(data)rs = session.post(login_url, data)# 进行登录操作# 成绩列表 score_page_url = 'https://jwxt.xxu.edu.cn/jsxsd/kscj/cjcx_list'resp = session.get(score_page_url, headers=headers) score_list = etree.HTML(resp.text) data_list = score_list.xpath('//table[@id="dataList"]')[0] scores = data_list.xpath(".//tr")[1:] for score in scores: tds = score.xpath(".//td") goal_data = https://www.it610.com/article/{'id': tds[0].text, 'term': tds[1].text, 'cno': tds[2].text, 'cname': tds[3].text, 'score':tds[4].xpath('.//a/text()')[0], 'point': tds[5].text, 'total_point': tds[6].text, 'GPA': tds[7].text, } SCORE_FOR_USER.append(goal_data) # mycol.save(goal_data) #保存到mongo数据库中 print(goal_data) if SCORE_FOR_USER:# 验证码正确 跳出循环结束程序 break except: print("验证码错误")def main(): url = "https://jwxt.xxu.edu.cn/jsxsd/" parse_login(url)if __name__ == '__main__': main()

    推荐阅读