first commit
This commit is contained in:
+175
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"from datetime import datetime\n",
|
||||
"ip = 'https://band.hxzhxy.cn'\n",
|
||||
"param = {\n",
|
||||
" \"username\": \"xiatianle\",\n",
|
||||
" \"password\": \"123456\",\n",
|
||||
" \"client_id\": \"client\",\n",
|
||||
" \"grant_type\": \"password\",\n",
|
||||
" \"client_secret\": \"123456\",\n",
|
||||
"}\n",
|
||||
"data = requests.get(url=f\"{ip}/oauth/token\", params=param).json()\n",
|
||||
"token = data[\"access_token\"]\n",
|
||||
"header = {\n",
|
||||
" \"content-type\": \"application/json\",\n",
|
||||
" \"authorization\": f\"Bearer {token}\",\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'success': True,\n",
|
||||
" 'msg': '操作成功',\n",
|
||||
" 'code': 0,\n",
|
||||
" 'data': {'imgUrl': None,\n",
|
||||
" 'gradeId': None,\n",
|
||||
" 'classId': None,\n",
|
||||
" 'teaName': '夏天乐',\n",
|
||||
" 'nickName': None,\n",
|
||||
" 'teamId': 19,\n",
|
||||
" 'teaId': None,\n",
|
||||
" 'userName': 'xiatianle'}}"
|
||||
]
|
||||
},
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"requests.get(f'{ip}/uc/account/getInfo',params={\"access_token\": token}).json()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'success': True, 'msg': '操作成功', 'code': 0, 'data': [{'refundFee': 0.0, 'refundNum': 0, 'payFee': 23115000.0, 'totalNum': 609, 'totalFee': 23115000.0, 'payNum': 609, 'payName': '晚自习延时'}, {'refundFee': 0.0, 'refundNum': 0, 'payNum': 3462, 'payFee': 37168400.0, 'totalFee': 37168400.0, 'payName': '餐费充值', 'totalNum': 3462}, {'refundFee': 0.0, 'refundNum': 0, 'totalNum': 953, 'payNum': 953, 'totalFee': 25735500.0, 'payName': '延时服务费', 'payFee': 25735500.0}, {'refundFee': 0.0, 'refundNum': 0, 'payNum': 143, 'payFee': 3170000.0, 'totalNum': 143, 'totalFee': 3170000.0, 'payName': '周末托管报名'}]}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"startDate = int(datetime.strptime(\"2023-06-01\", \"%Y-%m-%d\").timestamp()*1000)\n",
|
||||
"endDate = int(datetime.strptime(\"2023-07-15\", \"%Y-%m-%d\").timestamp()*1000)\n",
|
||||
"res = requests.get(f\"{ip}/pay/stu/total\",params={\n",
|
||||
" \"access_token\": token,\n",
|
||||
" \"teamId\": \"19\",\n",
|
||||
" \"startDate\":startDate,\n",
|
||||
" \"endDate\":endDate\n",
|
||||
"}).json()\n",
|
||||
"print(res)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1685548800000"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"startDate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "javascript"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "SyntaxError",
|
||||
"evalue": "invalid syntax (14025782.py, line 1)",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;36m Cell \u001b[1;32mIn[12], line 1\u001b[1;36m\u001b[0m\n\u001b[1;33m function formatAmount(amount) {\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"function formatAmount(amount) {\n",
|
||||
" return amount.toLocaleString('en-US', { style: 'currency', currency: 'CNY' });\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" let amount = 72538000;\n",
|
||||
" console.log(formatAmount(amount)); "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1720972800000"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"refundFee tuikuan\n",
|
||||
"totalFee shenyu\n",
|
||||
"payFee\n",
|
||||
"payNum shoufeibishu\n",
|
||||
"refundNum tuikuanbishu"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
+736
@@ -0,0 +1,736 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "07a56b94",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import threading\n",
|
||||
"import requests\n",
|
||||
"from queue import Queue\n",
|
||||
"from time import time,sleep\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# 配置信息\n",
|
||||
"ip = \"http://localhost:8080\"\n",
|
||||
"resource_paths = [\n",
|
||||
" \"/static/index.2da1efab.css\",\n",
|
||||
" \"/static/js/chunk-vendors.js\",\n",
|
||||
" \"/static/js/index.js\",\n",
|
||||
" \"/static/js/pages-login-index.js\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 创建下载结果队列\n",
|
||||
"download_results = Queue()\n",
|
||||
"\n",
|
||||
"def download_resource(path, thread_name):\n",
|
||||
" \"\"\"下载单个资源的线程函数\"\"\"\n",
|
||||
" try:\n",
|
||||
" url = ip + path\n",
|
||||
" start_time = time()\n",
|
||||
" response = requests.get(url)\n",
|
||||
" \n",
|
||||
" # 模拟浏览器行为:检查状态码和内容类型\n",
|
||||
" if response.status_code != 200:\n",
|
||||
" result = f\"线程 {thread_name}: {path} 下载失败, 状态码 {response.status_code}\"\n",
|
||||
" else:\n",
|
||||
" # 简略显示内容(实际应用中应保存文件)\n",
|
||||
" content_preview = response.text[:50].replace('\\n', ' ') + \"...\" if len(response.text) > 50 else response.text\n",
|
||||
" \n",
|
||||
" # 模拟浏览器解析CSS/JS的时间延迟\n",
|
||||
" process_time = 0.1 if any(ext in path for ext in ['.css', '.js']) else 0.0\n",
|
||||
" \n",
|
||||
" result = (\n",
|
||||
" f\"线程 {thread_name}: 成功下载 {path}\\n\"\n",
|
||||
" f\"类型: {'CSS' if '.css' in path else 'JS' if '.js' in path else '其他'}\\n\"\n",
|
||||
" f\"大小: {len(response.text)/1024:.1f} KB\\n\"\n",
|
||||
" f\"耗时: {time()-start_time:.3f}秒\\n\"\n",
|
||||
" f\"内容预览: {content_preview}\"\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" # 添加处理延迟,模拟浏览器执行\n",
|
||||
" sleep(process_time)\n",
|
||||
" \n",
|
||||
" except Exception as e:\n",
|
||||
" result = f\"线程 {thread_name}: {path} 下载异常 - {str(e)}\"\n",
|
||||
" \n",
|
||||
" download_results.put(result)\n",
|
||||
"\n",
|
||||
"def simulate_browser_download(max_workers=6):\n",
|
||||
" \"\"\"模拟浏览器并发下载行为\"\"\"\n",
|
||||
" print(f\"模拟浏览器行为 - 并发下载线程数: {max_workers}\")\n",
|
||||
" print(\"=\" * 60)\n",
|
||||
" \n",
|
||||
" threads = []\n",
|
||||
" for i, path in enumerate(resource_paths):\n",
|
||||
" # 使用线程名标识资源类型\n",
|
||||
" thread_name = f\"资源#{i+1}\"\n",
|
||||
" \n",
|
||||
" # 创建并启动线程\n",
|
||||
" t = threading.Thread(\n",
|
||||
" target=download_resource,\n",
|
||||
" args=(path, thread_name),\n",
|
||||
" name=thread_name\n",
|
||||
" )\n",
|
||||
" t.start()\n",
|
||||
" threads.append(t)\n",
|
||||
" \n",
|
||||
" # 控制最大并发数,模拟浏览器的连接限制\n",
|
||||
" if len(threads) >= max_workers:\n",
|
||||
" for t in threads:\n",
|
||||
" t.join()\n",
|
||||
" threads = []\n",
|
||||
" \n",
|
||||
" # 等待剩余的线程完成\n",
|
||||
" for t in threads:\n",
|
||||
" t.join()\n",
|
||||
" \n",
|
||||
" # 打印结果\n",
|
||||
" while not download_results.empty():\n",
|
||||
" print(download_results.get())\n",
|
||||
" print(\"-\" * 60)\n",
|
||||
"\n",
|
||||
" print(\"完成\")\n",
|
||||
"if __name__ == \"__main__\":\n",
|
||||
" print(\"浏览器静态资源请求模拟器\")\n",
|
||||
" print(\"=\" * 60)\n",
|
||||
" simulate_browser_download()\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "73d41e7d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from faker import Faker\n",
|
||||
"import random\n",
|
||||
"import json\n",
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"# 初始化Faker生成器(简体中文)\n",
|
||||
"fake = Faker('zh_CN')\n",
|
||||
"\n",
|
||||
"# 定义固定值\n",
|
||||
"TEAM_ID = 106\n",
|
||||
"PLAN_ID = 131\n",
|
||||
"\n",
|
||||
"# 常见民族列表\n",
|
||||
"ETHNIC_GROUPS = [\"汉\", \"壮\", \"满\", \"回\", \"苗\", \"维吾尔\", \"土家\", \"彝\", \"蒙古\", \"藏\", \"布依\", \n",
|
||||
" \"侗\", \"瑶\", \"朝鲜\", \"白\", \"哈尼\", \"哈萨克\", \"黎\", \"傣\", \"畲\", \"傈僳\", \"仡佬\",\n",
|
||||
" \"东乡\", \"高山\", \"拉祜\", \"水\", \"佤\", \"纳西\", \"羌\", \"土\", \"仫佬\", \"锡伯\", \"柯尔克孜\",\n",
|
||||
" \"达斡尔\", \"景颇\", \"毛南\", \"撒拉\", \"布朗\", \"塔吉克\", \"阿昌\", \"普米\", \"鄂温克\", \"怒\",\n",
|
||||
" \"京\", \"基诺\", \"德昂\", \"保安\", \"俄罗斯\", \"裕固\", \"乌兹别克\", \"门巴\", \"鄂伦春\", \"独龙\",\n",
|
||||
" \"塔塔尔\", \"赫哲\", \"珞巴\"]\n",
|
||||
"\n",
|
||||
"# 疾病列表(健康状态)\n",
|
||||
"HEALTH_CONDITIONS = [\n",
|
||||
" \"无\", \"近视\", \"弱视\", \"鼻炎\", \"哮喘\", \"过敏体质\", \"蛀牙\", \n",
|
||||
" \"肥胖\", \"发育迟缓\", \"ADHD\", \"缺铁性贫血\", \"维生素缺乏\",\n",
|
||||
" \"易感冒体质\", \"偏瘦\", \"过敏(花粉)\", \"过敏(尘螨)\", \"过敏(牛奶)\", \n",
|
||||
" \"消化不良\", \"多动症\", \"抽动症\", \"癫痫\", \"小儿麻痹\", \"乙肝病毒携带\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 艺术特长\n",
|
||||
"ART_TALENTS = [\"无\", \"钢琴\", \"小提琴\", \"绘画\", \"书法\", \"舞蹈\", \"声乐\", \"戏剧表演\", \n",
|
||||
" \"摄影\", \"编程\", \"动画制作\", \"模型制作\", \"手工艺术\"]\n",
|
||||
"\n",
|
||||
"# 体育特长\n",
|
||||
"SPORTS_TALENTS = [\"无\", \"游泳\", \"篮球\", \"足球\", \"乒乓球\", \"羽毛球\", \"田径\", \n",
|
||||
" \"武术\", \"跆拳道\", \"空手道\", \"轮滑\", \"滑板\", \"自行车\", \"健美操\"]\n",
|
||||
"\n",
|
||||
"# 科技特长\n",
|
||||
"TECH_TALENTS = [\"无\", \"机器人编程\", \"电子制作\", \"3D打印\", \"人工智能\", \"网页设计\", \n",
|
||||
" \"科学实验\", \"天文观测\", \"植物培养\", \"动物观察\", \"航模制作\"]\n",
|
||||
"\n",
|
||||
"# 职业列表\n",
|
||||
"OCCUPATIONS = [\"医生\", \"教师\", \"工程师\", \"程序员\", \"设计师\", \"建筑师\", \"销售经理\",\n",
|
||||
" \"会计\", \"律师\", \"公务员\", \"记者\", \"警察\", \"消防员\", \"厨师\", \"商人\",\n",
|
||||
" \"自由职业\", \"个体经营者\", \"银行职员\", \"人力资源\", \"市场营销\"]\n",
|
||||
"\n",
|
||||
"# 公司类型\n",
|
||||
"WORKPLACES = [\n",
|
||||
" \"国有企业\", \"民营企业\", \"外资企业\", \"合资企业\", \"政府机关\", \n",
|
||||
" \"事业单位\", \"学校\", \"医院\", \"设计事务所\", \"律师事务所\",\n",
|
||||
" \"科技公司\", \"互联网公司\", \"金融机构\", \"建筑公司\", \"零售企业\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 小学名称\n",
|
||||
"PRIMARY_SCHOOLS = [\n",
|
||||
" \"第一实验小学\", \"第二实验小学\", \"育才小学\", \"阳光小学\", \"希望小学\", \"和平小学\", \n",
|
||||
" \"实验小学分校\", \"新世纪小学\", \"东方小学\", \"先锋小学\", \"星光小学\", \"明德小学\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"def generate_id_num(birthday):\n",
|
||||
" \"\"\"生成符合规则的身份证号\"\"\"\n",
|
||||
" # 生成前6位(地区码,使用真实的地区码)\n",
|
||||
" region_codes = [\"110101\", \"110105\", \"110106\", \"110107\", \"310112\", \"330102\", \"440106\", \"440304\"]\n",
|
||||
" \n",
|
||||
" # 出生日期码(8位)\n",
|
||||
" birth_code = birthday.replace(\"-\", \"\")\n",
|
||||
" \n",
|
||||
" # 顺序码(3位)\n",
|
||||
" sequence_code = str(random.randint(101, 998))\n",
|
||||
" \n",
|
||||
" # 生成校验码(1位)\n",
|
||||
" base = region_codes[random.randint(0, len(region_codes)-1)] + birth_code + sequence_code\n",
|
||||
" weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]\n",
|
||||
" checksum_map = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}\n",
|
||||
" \n",
|
||||
" total = 0\n",
|
||||
" for i in range(17):\n",
|
||||
" total += int(base[i]) * weight[i]\n",
|
||||
" checksum = checksum_map[total % 11]\n",
|
||||
" \n",
|
||||
" return base + checksum\n",
|
||||
"\n",
|
||||
"def generate_student_data():\n",
|
||||
" \"\"\"生成单个学生数据\"\"\"\n",
|
||||
" # 基础信息\n",
|
||||
" sex = random.choice([\"男\", \"女\"])\n",
|
||||
" \n",
|
||||
" # 生日 (2010-2015年出生)\n",
|
||||
" birthday = fake.date_between(start_date=\"-15y\", end_date=\"-8y\").strftime(\"%Y-%m-%d\")\n",
|
||||
" \n",
|
||||
" # 生成符合规则的身份证号\n",
|
||||
" id_num = generate_id_num(birthday)\n",
|
||||
" \n",
|
||||
" # 计算年龄(仅用于展示)\n",
|
||||
" birth_year = int(birthday[:4])\n",
|
||||
" current_year = datetime.now().year\n",
|
||||
" age = current_year - birth_year\n",
|
||||
" \n",
|
||||
" # 生成学生信息\n",
|
||||
" data = {\n",
|
||||
" \"teamId\": TEAM_ID,\n",
|
||||
" \"stuName\": fake.name(), # 学生姓名\n",
|
||||
" \"idNum\": id_num, # 身份证号\n",
|
||||
" \"formerName\": random.choices([\"无\", fake.last_name() + fake.first_name()], weights=[0.8, 0.2])[0], # 曾用名\n",
|
||||
" \"sex\": sex, # 性别\n",
|
||||
" \"nation\": random.choice(ETHNIC_GROUPS), # 民族\n",
|
||||
" \"birthday\": birthday, # 生日\n",
|
||||
" \"finishSchool\": random.choice(PRIMARY_SCHOOLS), # 毕业学校\n",
|
||||
" \"file\": None, # 文件\n",
|
||||
" \"hkadr\": fake.province() + \"/\" + fake.city() + \"/\" + fake.district(), # 户口所在地\n",
|
||||
" \"homeAddress\": fake.address(), # 家庭住址\n",
|
||||
" \"health\": random.choice(HEALTH_CONDITIONS), # 健康状况\n",
|
||||
" \"artisticSpecialty\": random.choice(ART_TALENTS), # 艺术特长\n",
|
||||
" \"artisticAchievements\": \"无\", # 艺术成就\n",
|
||||
" \"technologicalSpecialty\": random.choice(TECH_TALENTS), # 科技特长\n",
|
||||
" \"technologicalAchievements\": \"无\", # 科技成就\n",
|
||||
" \"sportsSpecialty\": random.choice(SPORTS_TALENTS), # 体育特长\n",
|
||||
" \"sportsAchievements\": \"无\", # 体育成就\n",
|
||||
" \"planId\": PLAN_ID, # 计划ID\n",
|
||||
" \"imageUrl\": \"\", # 图片URL\n",
|
||||
" \"schoolCode\": \"G\" + id_num[:-1], # 学籍号\n",
|
||||
" \"age\": age, # 年龄(仅用于展示)\n",
|
||||
" \"email\": fake.email() if random.random() > 0.7 else \"\", # 邮箱\n",
|
||||
" \"height\": str(random.randint(130, 170)), # 身高\n",
|
||||
" \"weight\": str(random.randint(25, 60)), # 体重\n",
|
||||
" \"measurements\": f\"{random.randint(60, 90)},{random.randint(60, 90)},{random.randint(60, 90)}\" # 三围\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # 生成监护人信息\n",
|
||||
" guardian_prefix = fake.last_name()\n",
|
||||
" \n",
|
||||
" # 监护人1 - 通常为父母之一\n",
|
||||
" relationship_choices = [\"父亲\", \"母亲\", \"爷爷\", \"奶奶\", \"外公\", \"外婆\"]\n",
|
||||
" relationship = random.choice(relationship_choices[:2]) # 主要选择父母\n",
|
||||
" \n",
|
||||
" data.update({\n",
|
||||
" \"guardian1Name\": guardian_prefix + (\"先生\" if relationship == \"父亲\" else \"女士\"), # 监护人1姓名\n",
|
||||
" \"guardian1Relationship\": relationship, # 关系\n",
|
||||
" \"guardian1IdCardNumber\": generate_id_num(fake.date_between(start_date=\"-55y\", end_date=\"-25y\").strftime(\"%Y-%m-%d\")), # 身份证号\n",
|
||||
" \"guardian1Contact\": fake.phone_number(), # 联系方式\n",
|
||||
" \"guardian1Occupation\": random.choice(OCCUPATIONS), # 职业\n",
|
||||
" \"guardian1Workplace\": random.choice(WORKPLACES) # 工作单位\n",
|
||||
" })\n",
|
||||
" \n",
|
||||
" # 监护人2 - 可能是另一位家长或其他人\n",
|
||||
" if relationship == \"父亲\":\n",
|
||||
" guardian2_relationship = \"母亲\"\n",
|
||||
" else:\n",
|
||||
" guardian2_relationship = random.choices(\n",
|
||||
" [\"父亲\", \"爷爷\", \"奶奶\", \"外公\", \"外婆\", \"其他亲属\"], \n",
|
||||
" weights=[0.7, 0.1, 0.1, 0.05, 0.05, 0.1]\n",
|
||||
" )[0]\n",
|
||||
" \n",
|
||||
" data.update({\n",
|
||||
" \"guardian2Name\": guardian_prefix + (\n",
|
||||
" \"先生\" if guardian2_relationship in [\"父亲\", \"爷爷\", \"外公\"] else \"女士\"\n",
|
||||
" ), # 监护人2姓名\n",
|
||||
" \"guardian2Relationship\": guardian2_relationship, # 关系\n",
|
||||
" \"guardian2IdCardNumber\": generate_id_num(fake.date_between(start_date=\"-55y\", end_date=\"-25y\").strftime(\"%Y-%m-%d\")), # 身份证号\n",
|
||||
" \"guardian2Contact\": fake.phone_number() if guardian2_relationship != \"无\" else \"\", # 联系方式\n",
|
||||
" \"guardian2Occupation\": random.choice(OCCUPATIONS) if guardian2_relationship != \"无\" else \"\", # 职业\n",
|
||||
" \"guardian2Workplace\": random.choice(WORKPLACES) if guardian2_relationship != \"无\" else \"\" # 工作单位\n",
|
||||
" })\n",
|
||||
" \n",
|
||||
" return data\n",
|
||||
"\n",
|
||||
"def generate_students():\n",
|
||||
" student = generate_student_data()\n",
|
||||
" return student"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "018a3c24",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"🎬 开始模拟 10 个用户并发访问...\n",
|
||||
"======================================================================\n",
|
||||
"👤 用户 1 开始会话, Session ID: 679e3877-56ac-4791-a1e5-880468dc1d87\n",
|
||||
"👤 用户 2 开始会话, Session ID: 96acf953-61d0-4499-900e-482f75112453\n",
|
||||
"👤 用户 3 开始会话, Session ID: 588c0b3d-05ec-438e-a327-bc51fbc3927a\n",
|
||||
"👤 用户 4 开始会话, Session ID: 52eb7ae8-d1b7-48ae-a0f2-8b1bd384d5b8\n",
|
||||
"👤 用户 5 开始会话, Session ID: 42561435-6a9c-4eac-8282-ce4dd7d11547\n",
|
||||
"👤 用户 6 开始会话, Session ID: ee1daae1-584b-409c-affe-d14ad170d309\n",
|
||||
"👤 用户 7 开始会话, Session ID: 43901a21-0c91-45a5-9c98-b6fddd2dcb50\n",
|
||||
"👤 用户 8 开始会话, Session ID: e8ad6873-751f-4f81-8409-cf1c34ee50ee\n",
|
||||
"👤 用户 9 开始会话, Session ID: ae1d258d-545e-4c45-8b81-d9a8ba3d94e8\n",
|
||||
"👤 用户 10 开始会话, Session ID: fed2a8aa-a697-4e4b-b433-11a9edbe1640\n",
|
||||
"✅ 用户 5 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.032秒\n",
|
||||
"✅ 用户 2 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒\n",
|
||||
"✅ 用户 4 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.040秒\n",
|
||||
"✅ 用户 2 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.057秒\n",
|
||||
"✅ 用户 9 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.038秒\n",
|
||||
"✅ 用户 4 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.044秒\n",
|
||||
"✅ 用户 6 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.034秒\n",
|
||||
"✅ 用户 1 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.036秒\n",
|
||||
"✅ 用户 9 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.029秒\n",
|
||||
"✅ 用户 10 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.037秒\n",
|
||||
"✅ 用户 1 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.033秒\n",
|
||||
"✅ 用户 6 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒\n",
|
||||
"✅ 用户 4 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.040秒\n",
|
||||
"✅ 用户 10 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.040秒\n",
|
||||
"✅ 用户 8 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.051秒\n",
|
||||
"✅ 用户 8 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.032秒\n",
|
||||
"✅ 用户 2 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.038秒\n",
|
||||
"✅ 用户 10 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.077秒\n",
|
||||
"✅ 用户 7 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.053秒\n",
|
||||
"✅ 用户 10 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.047秒\n",
|
||||
"📊 用户 10 加载所有静态资源耗时: 2.305秒\n",
|
||||
"🚀 用户 10 开始看表单\n",
|
||||
"✅ 用户 5 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.066秒\n",
|
||||
"✅ 用户 6 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.046秒\n",
|
||||
"✅ 用户 4 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.069秒\n",
|
||||
"📊 用户 4 加载所有静态资源耗时: 2.348秒\n",
|
||||
"🚀 用户 4 开始看表单\n",
|
||||
"✅ 用户 7 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.055秒\n",
|
||||
"✅ 用户 7 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.055秒\n",
|
||||
"✅ 用户 6 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.069秒\n",
|
||||
"📊 用户 6 加载所有静态资源耗时: 2.391秒\n",
|
||||
"🚀 用户 6 开始看表单\n",
|
||||
"✅ 用户 3 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.043秒\n",
|
||||
"✅ 用户 9 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.057秒\n",
|
||||
"✅ 用户 1 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.055秒\n",
|
||||
"✅ 用户 8 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.057秒\n",
|
||||
"✅ 用户 3 资源 /static/index.2da1efab.css 加载完成: 文件: index.2da1efab.css | 大小: 93.7KB | 耗时: 2.063秒\n",
|
||||
"✅ 用户 7 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.085秒\n",
|
||||
"📊 用户 7 加载所有静态资源耗时: 2.434秒\n",
|
||||
"🚀 用户 7 开始看表单\n",
|
||||
"✅ 用户 1 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.073秒\n",
|
||||
"📊 用户 1 加载所有静态资源耗时: 2.450秒\n",
|
||||
"🚀 用户 1 开始看表单\n",
|
||||
"✅ 用户 3 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.037秒\n",
|
||||
"✅ 用户 3 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.059秒\n",
|
||||
"📊 用户 3 加载所有静态资源耗时: 2.487秒\n",
|
||||
"🚀 用户 3 开始看表单\n",
|
||||
"✅ 用户 2 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.049秒\n",
|
||||
"📊 用户 2 加载所有静态资源耗时: 2.507秒\n",
|
||||
"🚀 用户 2 开始看表单\n",
|
||||
"✅ 用户 9 资源 /static/js/chunk-vendors.js 加载完成: 文件: chunk-vendors.js | 大小: 2655.9KB | 耗时: 2.051秒\n",
|
||||
"📊 用户 9 加载所有静态资源耗时: 2.519秒\n",
|
||||
"🚀 用户 9 开始看表单\n",
|
||||
"✅ 用户 8 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.040秒\n",
|
||||
"📊 用户 8 加载所有静态资源耗时: 2.527秒\n",
|
||||
"🚀 用户 8 开始看表单\n",
|
||||
"✅ 用户 5 资源 /static/js/index.js 加载完成: 文件: index.js | 大小: 100.2KB | 耗时: 2.043秒\n",
|
||||
"✅ 用户 5 资源 /static/js/pages-login-index.js 加载完成: 文件: pages-login-index.js | 大小: 79.8KB | 耗时: 2.035秒\n",
|
||||
"📊 用户 5 加载所有静态资源耗时: 2.542秒\n",
|
||||
"🚀 用户 5 开始看表单\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from faker import Faker\n",
|
||||
"import random\n",
|
||||
"import json\n",
|
||||
"from datetime import datetime\n",
|
||||
"import threading\n",
|
||||
"import requests\n",
|
||||
"from time import time, sleep\n",
|
||||
"import uuid\n",
|
||||
"from concurrent.futures import ThreadPoolExecutor, as_completed\n",
|
||||
"# 初始化Faker生成器(简体中文)\n",
|
||||
"fake = Faker('zh_CN')\n",
|
||||
"\n",
|
||||
"# 定义固定值\n",
|
||||
"TEAM_ID = 106\n",
|
||||
"PLAN_ID = 131\n",
|
||||
"\n",
|
||||
"# 常见民族列表\n",
|
||||
"ETHNIC_GROUPS = [\"汉\", \"壮\", \"满\", \"回\", \"苗\", \"维吾尔\", \"土家\", \"彝\", \"蒙古\", \"藏\", \"布依\", \n",
|
||||
" \"侗\", \"瑶\", \"朝鲜\", \"白\", \"哈尼\", \"哈萨克\", \"黎\", \"傣\", \"畲\", \"傈僳\", \"仡佬\",\n",
|
||||
" \"东乡\", \"高山\", \"拉祜\", \"水\", \"佤\", \"纳西\", \"羌\", \"土\", \"仫佬\", \"锡伯\", \"柯尔克孜\",\n",
|
||||
" \"达斡尔\", \"景颇\", \"毛南\", \"撒拉\", \"布朗\", \"塔吉克\", \"阿昌\", \"普米\", \"鄂温克\", \"怒\",\n",
|
||||
" \"京\", \"基诺\", \"德昂\", \"保安\", \"俄罗斯\", \"裕固\", \"乌兹别克\", \"门巴\", \"鄂伦春\", \"独龙\",\n",
|
||||
" \"塔塔尔\", \"赫哲\", \"珞巴\"]\n",
|
||||
"\n",
|
||||
"# 疾病列表(健康状态)\n",
|
||||
"HEALTH_CONDITIONS = [\n",
|
||||
" \"无\", \"近视\", \"弱视\", \"鼻炎\", \"哮喘\", \"过敏体质\", \"蛀牙\", \n",
|
||||
" \"肥胖\", \"发育迟缓\", \"ADHD\", \"缺铁性贫血\", \"维生素缺乏\",\n",
|
||||
" \"易感冒体质\", \"偏瘦\", \"过敏(花粉)\", \"过敏(尘螨)\", \"过敏(牛奶)\", \n",
|
||||
" \"消化不良\", \"多动症\", \"抽动症\", \"癫痫\", \"小儿麻痹\", \"乙肝病毒携带\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 艺术特长\n",
|
||||
"ART_TALENTS = [\"无\", \"钢琴\", \"小提琴\", \"绘画\", \"书法\", \"舞蹈\", \"声乐\", \"戏剧表演\", \n",
|
||||
" \"摄影\", \"编程\", \"动画制作\", \"模型制作\", \"手工艺术\"]\n",
|
||||
"\n",
|
||||
"# 体育特长\n",
|
||||
"SPORTS_TALENTS = [\"无\", \"游泳\", \"篮球\", \"足球\", \"乒乓球\", \"羽毛球\", \"田径\", \n",
|
||||
" \"武术\", \"跆拳道\", \"空手道\", \"轮滑\", \"滑板\", \"自行车\", \"健美操\"]\n",
|
||||
"\n",
|
||||
"# 科技特长\n",
|
||||
"TECH_TALENTS = [\"无\", \"机器人编程\", \"电子制作\", \"3D打印\", \"人工智能\", \"网页设计\", \n",
|
||||
" \"科学实验\", \"天文观测\", \"植物培养\", \"动物观察\", \"航模制作\"]\n",
|
||||
"\n",
|
||||
"# 职业列表\n",
|
||||
"OCCUPATIONS = [\"医生\", \"教师\", \"工程师\", \"程序员\", \"设计师\", \"建筑师\", \"销售经理\",\n",
|
||||
" \"会计\", \"律师\", \"公务员\", \"记者\", \"警察\", \"消防员\", \"厨师\", \"商人\",\n",
|
||||
" \"自由职业\", \"个体经营者\", \"银行职员\", \"人力资源\", \"市场营销\"]\n",
|
||||
"\n",
|
||||
"# 公司类型\n",
|
||||
"WORKPLACES = [\n",
|
||||
" \"国有企业\", \"民营企业\", \"外资企业\", \"合资企业\", \"政府机关\", \n",
|
||||
" \"事业单位\", \"学校\", \"医院\", \"设计事务所\", \"律师事务所\",\n",
|
||||
" \"科技公司\", \"互联网公司\", \"金融机构\", \"建筑公司\", \"零售企业\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 小学名称\n",
|
||||
"PRIMARY_SCHOOLS = [\n",
|
||||
" \"第一实验小学\", \"第二实验小学\", \"育才小学\", \"阳光小学\", \"希望小学\", \"和平小学\", \n",
|
||||
" \"实验小学分校\", \"新世纪小学\", \"东方小学\", \"先锋小学\", \"星光小学\", \"明德小学\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"def generate_id_num(birthday):\n",
|
||||
" \"\"\"生成符合规则的身份证号\"\"\"\n",
|
||||
" # 生成前6位(地区码,使用真实的地区码)\n",
|
||||
" region_codes = [\"110101\", \"110105\", \"110106\", \"110107\", \"310112\", \"330102\", \"440106\", \"440304\"]\n",
|
||||
" \n",
|
||||
" # 出生日期码(8位)\n",
|
||||
" birth_code = birthday.replace(\"-\", \"\")\n",
|
||||
" \n",
|
||||
" # 顺序码(3位)\n",
|
||||
" sequence_code = str(random.randint(101, 998))\n",
|
||||
" \n",
|
||||
" # 生成校验码(1位)\n",
|
||||
" base = region_codes[random.randint(0, len(region_codes)-1)] + birth_code + sequence_code\n",
|
||||
" weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]\n",
|
||||
" checksum_map = {0: '1', 1: '0', 2: 'X', 3: '9', 4: '8', 5: '7', 6: '6', 7: '5', 8: '4', 9: '3', 10: '2'}\n",
|
||||
" \n",
|
||||
" total = 0\n",
|
||||
" for i in range(17):\n",
|
||||
" total += int(base[i]) * weight[i]\n",
|
||||
" checksum = checksum_map[total % 11]\n",
|
||||
" \n",
|
||||
" return base + checksum\n",
|
||||
"\n",
|
||||
"def generate_student_data():\n",
|
||||
" \"\"\"生成单个学生数据\"\"\"\n",
|
||||
" # 基础信息\n",
|
||||
" sex = random.choice([\"男\", \"女\"])\n",
|
||||
" \n",
|
||||
" # 生日 (2010-2015年出生)\n",
|
||||
" birthday = fake.date_between(start_date=\"-15y\", end_date=\"-8y\").strftime(\"%Y-%m-%d\")\n",
|
||||
" \n",
|
||||
" # 生成符合规则的身份证号\n",
|
||||
" id_num = generate_id_num(birthday)\n",
|
||||
" \n",
|
||||
" # 计算年龄(仅用于展示)\n",
|
||||
" birth_year = int(birthday[:4])\n",
|
||||
" current_year = datetime.now().year\n",
|
||||
" age = current_year - birth_year\n",
|
||||
" \n",
|
||||
" # 生成学生信息\n",
|
||||
" data = {\n",
|
||||
" \"teamId\": TEAM_ID,\n",
|
||||
" \"stuName\": fake.name(), # 学生姓名\n",
|
||||
" \"idNum\": id_num, # 身份证号\n",
|
||||
" \"formerName\": random.choices([\"无\", fake.last_name() + fake.first_name()], weights=[0.8, 0.2])[0], # 曾用名\n",
|
||||
" \"sex\": sex, # 性别\n",
|
||||
" \"nation\": random.choice(ETHNIC_GROUPS), # 民族\n",
|
||||
" \"birthday\": birthday, # 生日\n",
|
||||
" \"finishSchool\": random.choice(PRIMARY_SCHOOLS), # 毕业学校\n",
|
||||
" \"file\": None, # 文件\n",
|
||||
" \"hkadr\": fake.province() + \"/\" + fake.city() + \"/\" + fake.district(), # 户口所在地\n",
|
||||
" \"homeAddress\": fake.address(), # 家庭住址\n",
|
||||
" \"health\": random.choice(HEALTH_CONDITIONS), # 健康状况\n",
|
||||
" \"artisticSpecialty\": random.choice(ART_TALENTS), # 艺术特长\n",
|
||||
" \"artisticAchievements\": \"无\", # 艺术成就\n",
|
||||
" \"technologicalSpecialty\": random.choice(TECH_TALENTS), # 科技特长\n",
|
||||
" \"technologicalAchievements\": \"无\", # 科技成就\n",
|
||||
" \"sportsSpecialty\": random.choice(SPORTS_TALENTS), # 体育特长\n",
|
||||
" \"sportsAchievements\": \"无\", # 体育成就\n",
|
||||
" \"planId\": PLAN_ID, # 计划ID\n",
|
||||
" \"imageUrl\": \"\", # 图片URL\n",
|
||||
" \"schoolCode\": \"G\" + id_num[:-1], # 学籍号\n",
|
||||
" \"age\": age, # 年龄(仅用于展示)\n",
|
||||
" \"email\": fake.email() if random.random() > 0.7 else \"\", # 邮箱\n",
|
||||
" \"height\": str(random.randint(130, 170)), # 身高\n",
|
||||
" \"weight\": str(random.randint(25, 60)), # 体重\n",
|
||||
" \"measurements\": f\"{random.randint(60, 90)},{random.randint(60, 90)},{random.randint(60, 90)}\" # 三围\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # 生成监护人信息\n",
|
||||
" guardian_prefix = fake.last_name()\n",
|
||||
" \n",
|
||||
" # 监护人1 - 通常为父母之一\n",
|
||||
" relationship_choices = [\"父亲\", \"母亲\", \"爷爷\", \"奶奶\", \"外公\", \"外婆\"]\n",
|
||||
" relationship = random.choice(relationship_choices[:2]) # 主要选择父母\n",
|
||||
" \n",
|
||||
" data.update({\n",
|
||||
" \"guardian1Name\": guardian_prefix + (\"先生\" if relationship == \"父亲\" else \"女士\"), # 监护人1姓名\n",
|
||||
" \"guardian1Relationship\": relationship, # 关系\n",
|
||||
" \"guardian1IdCardNumber\": generate_id_num(fake.date_between(start_date=\"-55y\", end_date=\"-25y\").strftime(\"%Y-%m-%d\")), # 身份证号\n",
|
||||
" \"guardian1Contact\": fake.phone_number(), # 联系方式\n",
|
||||
" \"guardian1Occupation\": random.choice(OCCUPATIONS), # 职业\n",
|
||||
" \"guardian1Workplace\": random.choice(WORKPLACES) # 工作单位\n",
|
||||
" })\n",
|
||||
" \n",
|
||||
" # 监护人2 - 可能是另一位家长或其他人\n",
|
||||
" if relationship == \"父亲\":\n",
|
||||
" guardian2_relationship = \"母亲\"\n",
|
||||
" else:\n",
|
||||
" guardian2_relationship = random.choices(\n",
|
||||
" [\"父亲\", \"爷爷\", \"奶奶\", \"外公\", \"外婆\", \"其他亲属\"], \n",
|
||||
" weights=[0.7, 0.1, 0.1, 0.05, 0.05, 0.1]\n",
|
||||
" )[0]\n",
|
||||
" \n",
|
||||
" data.update({\n",
|
||||
" \"guardian2Name\": guardian_prefix + (\n",
|
||||
" \"先生\" if guardian2_relationship in [\"父亲\", \"爷爷\", \"外公\"] else \"女士\"\n",
|
||||
" ), # 监护人2姓名\n",
|
||||
" \"guardian2Relationship\": guardian2_relationship, # 关系\n",
|
||||
" \"guardian2IdCardNumber\": generate_id_num(fake.date_between(start_date=\"-55y\", end_date=\"-25y\").strftime(\"%Y-%m-%d\")), # 身份证号\n",
|
||||
" \"guardian2Contact\": fake.phone_number() if guardian2_relationship != \"无\" else \"\", # 联系方式\n",
|
||||
" \"guardian2Occupation\": random.choice(OCCUPATIONS) if guardian2_relationship != \"无\" else \"\", # 职业\n",
|
||||
" \"guardian2Workplace\": random.choice(WORKPLACES) if guardian2_relationship != \"无\" else \"\" # 工作单位\n",
|
||||
" })\n",
|
||||
" \n",
|
||||
" return data\n",
|
||||
"\n",
|
||||
"def generate_students():\n",
|
||||
" student = generate_student_data()\n",
|
||||
" return student\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# 配置信息\n",
|
||||
"BASE_URL = \"http://localhost:8080\"\n",
|
||||
"STATIC_PATHS = [\n",
|
||||
" \"/static/index.2da1efab.css\",\n",
|
||||
" \"/static/js/chunk-vendors.js\",\n",
|
||||
" \"/static/js/index.js\",\n",
|
||||
" \"/static/js/pages-login-index.js\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 用户数据生成\n",
|
||||
"USER_AGENTS = [\n",
|
||||
" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n",
|
||||
" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15\",\n",
|
||||
" \"Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15\",\n",
|
||||
" \"Mozilla/5.0 (Linux; Android 12; SM-G991B) AppleWebKit/537.36\",\n",
|
||||
" \"Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"def generate_user_data(user_id):\n",
|
||||
" \"\"\"生成模拟用户数据\"\"\"\n",
|
||||
" return {\n",
|
||||
" \"id\": user_id,\n",
|
||||
" \"session_id\": str(uuid.uuid4()),\n",
|
||||
" \"user_agent\": random.choice(USER_AGENTS),\n",
|
||||
" \"request_count\": 0,\n",
|
||||
" \"start_time\": time()\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"def simulate_user_session(user_id):\n",
|
||||
" \"\"\"模拟一个用户的完整会话\"\"\"\n",
|
||||
" user_data = generate_user_data(user_id)\n",
|
||||
" print(f\"👤 用户 {user_id} 开始会话, Session ID: {user_data['session_id']}\")\n",
|
||||
" start = time()\n",
|
||||
" # 使用线程池请求所有静态资源\n",
|
||||
" with ThreadPoolExecutor(max_workers=len(STATIC_PATHS)) as executor:\n",
|
||||
" futures = {}\n",
|
||||
" \n",
|
||||
" # 提交所有静态资源请求任务\n",
|
||||
" for path in STATIC_PATHS:\n",
|
||||
" url = BASE_URL + path\n",
|
||||
" future = executor.submit(\n",
|
||||
" fetch_resource, \n",
|
||||
" url, \n",
|
||||
" user_data\n",
|
||||
" )\n",
|
||||
" futures[future] = path\n",
|
||||
" \n",
|
||||
" # 等待所有静态资源加载完成\n",
|
||||
" for future in as_completed(futures):\n",
|
||||
" path = futures[future]\n",
|
||||
" try:\n",
|
||||
" result = future.result()\n",
|
||||
" print(f\"✅ 用户 {user_id} 资源 {path} 加载完成: {result}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"❌ 用户 {user_id} 资源加载失败: {str(e)}\")\n",
|
||||
" end = time()\n",
|
||||
" # 所有静态资源加载完成后访问百度提交数据\n",
|
||||
" print(f\"📊 用户 {user_id} 加载所有静态资源耗时: {end - start:.3f}秒\")\n",
|
||||
" print(f\"🚀 用户 {user_id} 开始看表单\")\n",
|
||||
" submit_to_baidu(user_data)\n",
|
||||
" \n",
|
||||
" return user_data\n",
|
||||
"\n",
|
||||
"def fetch_resource(url, user_data):\n",
|
||||
" \"\"\"模拟用户获取单个资源\"\"\"\n",
|
||||
" # 更新用户请求计数\n",
|
||||
" user_data[\"request_count\"] += 1\n",
|
||||
" \n",
|
||||
" # 生成请求头\n",
|
||||
" headers = {\n",
|
||||
" \"User-Agent\": user_data[\"user_agent\"],\n",
|
||||
" \"X-Session-Id\": user_data[\"session_id\"],\n",
|
||||
" \"X-Request-Count\": str(user_data[\"request_count\"]),\n",
|
||||
" \"Accept-Encoding\": \"gzip, deflate\"\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
" # 添加随机延迟(0.1-0.5秒)模拟网络波动\n",
|
||||
" sleep(random.uniform(0.1, 0.5))\n",
|
||||
" \n",
|
||||
" try:\n",
|
||||
" # 执行资源请求\n",
|
||||
" start_time = time()\n",
|
||||
" response = requests.get(url, headers=headers)\n",
|
||||
" elapsed_time = time() - start_time\n",
|
||||
" \n",
|
||||
" if response.status_code != 200:\n",
|
||||
" return f\"错误状态码: {response.status_code} | 耗时: {elapsed_time:.3f}秒\"\n",
|
||||
" \n",
|
||||
" # 提取文件名\n",
|
||||
" file_name = url.split('/')[-1]\n",
|
||||
" \n",
|
||||
" return f\"文件: {file_name} | 大小: {len(response.text)/1024:.1f}KB | 耗时: {elapsed_time:.3f}秒\"\n",
|
||||
" \n",
|
||||
" except Exception as e:\n",
|
||||
" return f\"请求异常: {str(e)}\"\n",
|
||||
"\n",
|
||||
"def submit_to_baidu(user_data):\n",
|
||||
" \"\"\"提交数据到百度\"\"\"\n",
|
||||
" # 构造提交数据\n",
|
||||
" payload = generate_students()\n",
|
||||
" sleep(random.uniform(5, 20))\n",
|
||||
" print(f\"🎉 用户 {user_data['id']} 提交数据 \")\n",
|
||||
" try:\n",
|
||||
" # 提交到百度\n",
|
||||
" start_time = time()\n",
|
||||
" response = requests.post(\n",
|
||||
" \"http://band.hxzhxy.cn/register/student/add\", # 模拟的百度提交API\n",
|
||||
" json=payload,\n",
|
||||
" headers={\n",
|
||||
" \"User-Agent\": user_data[\"user_agent\"],\n",
|
||||
" \"X-Session-Id\": user_data[\"session_id\"],\n",
|
||||
" \"Content-Type\": \"application/json\"\n",
|
||||
" }\n",
|
||||
" )\n",
|
||||
" elapsed_time = time() - start_time\n",
|
||||
" \n",
|
||||
" # 记录用户总用时\n",
|
||||
" total_time = time() - user_data[\"start_time\"]\n",
|
||||
" \n",
|
||||
" if response.status_code == 200:\n",
|
||||
" print(f\"🎉 用户 {user_data['id']} 数据提交成功! | 提交耗时: {elapsed_time:.3f}秒 | 总用时: {total_time:.3f}秒\")\n",
|
||||
" return True\n",
|
||||
" else:\n",
|
||||
" print(f\"⚠️ 用户 {user_data['id']} 提交失败: 状态码 {response.status_code} | 总用时: {total_time:.3f}秒\")\n",
|
||||
" return False\n",
|
||||
" \n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"‼️ 用户 {user_data['id']} 提交异常: {str(e)}\")\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
"def simulate_multiple_users(num_users=10):\n",
|
||||
" \"\"\"模拟多个用户并发访问\"\"\"\n",
|
||||
" print(f\"🎬 开始模拟 {num_users} 个用户并发访问...\")\n",
|
||||
" print(\"=\" * 70)\n",
|
||||
" \n",
|
||||
" with ThreadPoolExecutor(max_workers=num_users) as executor:\n",
|
||||
" # 提交所有用户会话任务\n",
|
||||
" futures = [executor.submit(simulate_user_session, i+1) for i in range(5)]\n",
|
||||
" \n",
|
||||
" # 等待所有用户完成并收集结果\n",
|
||||
" results = []\n",
|
||||
" for future in as_completed(futures):\n",
|
||||
" try:\n",
|
||||
" user_data = future.result()\n",
|
||||
" results.append(user_data)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"用户会话异常: {str(e)}\")\n",
|
||||
" \n",
|
||||
" # 生成性能报告\n",
|
||||
" print(\"\\n\" + \"=\" * 70)\n",
|
||||
" print(\"🏁 所有用户已完成操作! 性能摘要:\")\n",
|
||||
" print(\"-\" * 70)\n",
|
||||
" \n",
|
||||
" total_time = 0\n",
|
||||
" total_requests = 0\n",
|
||||
" completed_submissions = 0\n",
|
||||
" \n",
|
||||
" for user in results:\n",
|
||||
" session_time = time() - user[\"start_time\"]\n",
|
||||
" total_time += session_time\n",
|
||||
" total_requests += user[\"request_count\"]\n",
|
||||
" \n",
|
||||
" print(f\"用户 {user['id']:2d} | 用时: {session_time:.3f}秒 | 请求数: {user['request_count']}\")\n",
|
||||
" \n",
|
||||
" print(\"\\n汇总统计:\")\n",
|
||||
" print(f\"- 平均用时: {total_time/len(results):.3f}秒/用户\")\n",
|
||||
" print(f\"- 总请求数: {total_requests}次\")\n",
|
||||
" print(f\"- 用户提交率: {completed_submissions}/{len(results)}\")\n",
|
||||
" print(\"=\" * 70)\n",
|
||||
"\n",
|
||||
"if __name__ == \"__main__\":\n",
|
||||
" simulate_multiple_users(num_users=10)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user