Files
2026-01-30 11:28:35 +08:00

521 lines
20 KiB
Plaintext

{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "车辆信息",
"id": "7a8707c0ac4733a6"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-06-25T08:46:31.693364Z",
"start_time": "2025-06-25T08:19:15.222863Z"
}
},
"source": [
"import time\n",
"import requests\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Connection': 'keep-alive',\n",
" 'Origin': 'https://cms.carisok.com',\n",
" 'Referer': 'https://cms.carisok.com/',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-site',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"# 添加 retry 装饰器到 request 请求上\n",
"@retry(\n",
" stop=stop_after_attempt(3), # 最多重试 3 次\n",
" wait=wait_exponential(multiplier=1, max=10), # 指数退避,最大等待 10 秒\n",
" retry=retry_if_exception_type((requests.exceptions.RequestException,))\n",
")\n",
"def safe_get_request(url, params, headers):\n",
" response = requests.get(url, params=params, headers=headers, timeout=10)\n",
" response.raise_for_status() # 如果状态码不是 2xx 抛出异常\n",
" return response\n",
"\n",
"\n",
"all_data = []\n",
"\n",
"for i in tqdm(range(1, 227)): # 手动修改页码范围\n",
" params = {\n",
" 'page': str(i),\n",
" 'mobile': '',\n",
" 'car_no': '',\n",
" 'page_size': '10',\n",
" 'api_version': '4.00',\n",
" '__trace_id': '014cc085-97d5-4be2-956b-df7ca4d87821-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
"\n",
" try:\n",
" response = safe_get_request('https://ssapp-api.carisok.com/pc.php/CustomerManage/cars_list', params=params, headers=headers)\n",
" car_list = response.json().get('data', {}).get('car_list', [])\n",
" except Exception as e:\n",
" print(f\"第 {i} 页 cars_list 请求失败:{e}\")\n",
" car_list = []\n",
"\n",
" for car in car_list:\n",
" car_no = car.get('car_no')\n",
"\n",
" new_params = {\n",
" 'car_no': car_no,\n",
" 'api_version': '4.00',\n",
" '__trace_id': '91f56c62-9349-4cdd-97d7-d03e264c8249-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" try:\n",
" response1 = safe_get_request('https://ssapp-api.carisok.com/pc.php/CustomerManage/car_detail', params=new_params, headers=headers)\n",
" base_data = response1.json().get('data')\n",
" car.update(base_data or {})\n",
" except Exception as e:\n",
" print(f\"car_detail 请求失败(car_no={car_no}):{e}\")\n",
"\n",
" params2 = {\n",
" 'page': '1',\n",
" 'pagesize': '5',\n",
" 'car_no': car_no,\n",
" 'api_version': '4.00',\n",
" '__trace_id': '433e8cab-65bb-4ceb-80e0-7fa4eb1a6f8b-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" try:\n",
" response2 = safe_get_request('https://ssapp-api.carisok.com/pc.php/CustomerManage/get_user_list', params=params2, headers=headers)\n",
" user_info = response2.json().get('data', {}).get('user_list', [])\n",
" if user_info:\n",
" for user in user_info:\n",
" car.update(user)\n",
" except Exception as e:\n",
" print(f\"get_user_list 请求失败(car_no={car_no}):{e}\")\n",
"\n",
" all_data.append(car)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\枫车系统车辆信息.csv', index=False, encoding='utf-8-sig')"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 226/226 [27:16<00:00, 7.24s/it]\n"
]
}
],
"execution_count": 36
},
{
"metadata": {},
"cell_type": "markdown",
"source": "",
"id": "f584c584ca1c4664"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 会员卡信息",
"id": "e4ff5eb93d99d851"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-26T02:54:45.667548Z",
"start_time": "2025-06-26T02:32:15.205943Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type\n",
"\n",
"# ================ 重试装饰器 ================\n",
"@retry(\n",
" stop=stop_after_attempt(3), # 最多尝试3次\n",
" wait=wait_fixed(2), # 每次间隔2秒\n",
" retry=retry_if_exception_type((requests.exceptions.RequestException, KeyError)),\n",
")\n",
"def safe_get_request(url, params, headers):\n",
" response = requests.get(url, params=params, headers=headers)\n",
" response.raise_for_status()\n",
" return response.json()\n",
"\n",
"# ================ 请求头 ================\n",
"headers = {\n",
" 'Accept': 'application/json',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Connection': 'keep-alive',\n",
" 'Origin': 'https://cms.carisok.com',\n",
" 'Referer': 'https://cms.carisok.com/',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-site',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"all_data1 = []\n",
"all_data2 = []\n",
"\n",
"# ================ 主循环获取数据 ================\n",
"for i in tqdm(range(1, 78)): # 注意修改\n",
" params = {\n",
" 'pagesize': '20',\n",
" 'page': i,\n",
" 'user_name': '',\n",
" 'custome_level': '0',\n",
" 'user_mobile': '',\n",
" 'car_no': '',\n",
" 'cost1': '',\n",
" 'cost2': '',\n",
" 'api_version': '4.00',\n",
" '__trace_id': 'c5cdb71a-e195-4390-aa70-21d31bd62a63-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
"\n",
" try:\n",
" user_list_response = safe_get_request(\n",
" 'https://ssapp-api.carisok.com/pc.php/CustomerManage/get_user_list',\n",
" params=params,\n",
" headers=headers\n",
" )\n",
" \n",
" user_list = user_list_response.get(\"data\").get('user_list', [])\n",
" \n",
" except Exception as e:\n",
" print(f\"获取用户列表失败: {e}\")\n",
" continue\n",
"\n",
" for user in user_list:\n",
" user_id = user.get('user_id')\n",
" if not user_id:\n",
" print(\"无效的 user_id,跳过该用户\")\n",
" continue\n",
"\n",
" # ================ 获取用户详情 ================\n",
" params1 = {\n",
" 'user_id': user_id,\n",
" 'api_version': '4.00',\n",
" '__trace_id': 'c5cdb71a-e195-4390-aa70-21d31bd62a63-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" try:\n",
" base_data = safe_get_request(\n",
" 'https://ssapp-api.carisok.com/pc.php/CustomerManage/get_user_info',\n",
" params=params1,\n",
" headers=headers\n",
" ).get('data', {})\n",
" except Exception as e:\n",
" print(f\"获取用户详情失败 (user_id={user_id}): {e}\")\n",
" base_data = {}\n",
"\n",
" merged_user = {**user, **base_data}\n",
"\n",
" # ================ 获取储值卡 ================\n",
" params2 = {\n",
" 'user_id': user_id,\n",
" 'pagesize': '20',\n",
" 'page': '1',\n",
" 'startDate': '',\n",
" 'endDate': '',\n",
" 'api_version': '4.00',\n",
" '__trace_id': 'c5cdb71a-e195-4390-aa70-21d31bd62a63-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" try:\n",
" card_data1 = safe_get_request(\n",
" 'https://ssapp-api.carisok.com/pc.php/CustomerManage/recharge_card_list',\n",
" params=params2,\n",
" headers=headers\n",
" )\n",
" cardList1 = card_data1.get('data', {}).get('cardList', [])\n",
" except Exception as e:\n",
" print(f\"获取储值卡失败 (user_id={user_id}): {e}\")\n",
" cardList1 = []\n",
"\n",
" for card1 in cardList1:\n",
" all_data1.append({**merged_user, **card1})\n",
"\n",
" # ================ 获取套餐卡 ================\n",
" params3 = {\n",
" 'user_id': user_id,\n",
" 'pagesize': '20',\n",
" 'page': '1',\n",
" 'keyword': '',\n",
" 'api_version': '4.00',\n",
" '__trace_id': 'c5cdb71a-e195-4390-aa70-21d31bd62a63-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" try:\n",
" card_data2 = safe_get_request(\n",
" 'https://ssapp-api.carisok.com/pc.php/CustomerManage/sstore_card_list',\n",
" params=params3,\n",
" headers=headers\n",
" )\n",
" cardList2 = card_data2.get('data', {}).get('cardList', [])\n",
" except Exception as e:\n",
" print(f\"获取套餐卡失败 (user_id={user_id}): {e}\")\n",
" cardList2 = []\n",
"\n",
" for card2 in cardList2:\n",
" all_data2.append({**merged_user, **card2})\n",
"\n",
"# ================ 写入 CSV 文件 ================\n",
"df1 = pd.DataFrame(all_data1)\n",
"df2 = pd.DataFrame(all_data2)\n",
"\n",
"output_path_1 = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\枫车储值卡.csv'\n",
"output_path_2 = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\枫车套餐卡.csv'\n",
"\n",
"df1.to_csv(output_path_1, index=False)\n",
"df2.to_csv(output_path_2, index=False)\n",
"\n",
"print(\"导出完成!\")"
],
"id": "80536c4cd53d5e48",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 77/77 [22:30<00:00, 17.54s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"导出完成!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
}
],
"execution_count": 64
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 历史维修记录",
"id": "45fa307391e01382"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-26T08:38:32.921361Z",
"start_time": "2025-06-26T06:58:33.455924Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"from retrying import retry\n",
"from tqdm import tqdm\n",
"import logging\n",
"import os\n",
"import json\n",
"\n",
"# 配置日志\n",
"logging.basicConfig(\n",
" filename='fetch_errors.log',\n",
" level=logging.ERROR,\n",
" format='%(asctime)s - %(levelname)s - %(message)s'\n",
")\n",
"\n",
"# 请求头\n",
"headers = {\n",
" 'Accept': 'application/json',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Connection': 'keep-alive',\n",
" 'Origin': 'https://cms.carisok.com',\n",
" 'Referer': 'https://cms.carisok.com/',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-site',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"# 存储数据的列表\n",
"car_data = []\n",
"operate_data = []\n",
"order_data = []\n",
"server_data = []\n",
"settlement_data = []\n",
"\n",
"# 已抓取的订单 ID 文件(用于断点续传)\n",
"PROCESSED_FILE = 'processed_orders.json'\n",
"\n",
"# 如果存在已处理文件则加载,否则初始化为空集合\n",
"processed_orders = set()\n",
"if os.path.exists(PROCESSED_FILE):\n",
" with open(PROCESSED_FILE, 'r', encoding='utf-8') as f:\n",
" processed_orders = set(json.load(f))\n",
"\n",
"# 失败重试装饰器\n",
"@retry(stop_max_attempt_number=3, wait_fixed=2000)\n",
"def fetch_url(url, params=None):\n",
" response = requests.get(url, headers=headers, params=params, timeout=10)\n",
" response.raise_for_status()\n",
" return response.json()\n",
"\n",
"@retry(stop_max_attempt_number=3, wait_fixed=2000)\n",
"def fetch_order_detail(orderId):\n",
" detail_url = 'https://ssapp-api.carisok.com/pc.php/GainRecord/get_order_detail'\n",
" params = {\n",
" 'orderId': orderId,\n",
" 'businessType': '1',\n",
" 'api_version': '4.00',\n",
" '__trace_id': 'c41f197b-ef5c-4813-8d97-8947f4289243-store',\n",
" 'token': '4d62a33aa979d6d242d6b0198afbbf27',\n",
" }\n",
" response = requests.get(detail_url, params=params, headers=headers, timeout=10)\n",
" response.raise_for_status()\n",
" return response.json()\n",
"\n",
"@retry(stop_max_attempt_number=3, wait_fixed=2000)\n",
"def fetch_page(i):\n",
" list_url = f'https://ssapp-api.carisok.com/pc.php/PcPickcarOrder/lists?name=&mobile=&orderState=0&workState=0&businessType=0&page={i}&pagesize=20&carNo=&orderNo=&operate_count=&companyName=&startDate&endDate&api_version=4.00&__trace_id=6f72ab8e-f569-4b5d-aa7b-c890eec6756d-store&token=4d62a33aa979d6d242d6b0198afbbf27'\n",
" return fetch_url(list_url)\n",
"\n",
"# 主循环\n",
"for i in tqdm(range(1, 350), desc=\"正在抓取页面\"):\n",
" try:\n",
" response = fetch_page(i)\n",
" history_list = response.get('data', {}).get(\"listData\", [])\n",
" except Exception as e:\n",
" logging.error(f\"第{i}页抓取失败: {e}\")\n",
" print(f\"⚠️ 第{i}页抓取失败\")\n",
" continue\n",
"\n",
" for history in history_list:\n",
" orderId = history.get('orderId')\n",
"\n",
" # 断点续传:跳过已处理的订单\n",
" if str(orderId) in processed_orders:\n",
" continue\n",
"\n",
" try:\n",
" data = fetch_order_detail(orderId)\n",
" data_content = data.get('data', {})\n",
"\n",
" carInfo = data_content.get('carInfo', [])\n",
" operate = data_content.get('operate', [])\n",
" orderInfo = data_content.get('orderInfo', [])\n",
" serverInfo = data_content.get('serverInfo', [])\n",
" settlementInfo = data_content.get('settlementInfo', [])\n",
"\n",
" # 数据合并到对应表中\n",
" def process_data(data_list, target_list):\n",
" if isinstance(data_list, dict):\n",
" data_list[\"orderid\"] = orderId\n",
" target_list.append(data_list)\n",
" elif isinstance(data_list, list):\n",
" for item in data_list:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" target_list.append(item)\n",
"\n",
" process_data(carInfo, car_data)\n",
" process_data(operate, operate_data)\n",
" process_data(orderInfo, order_data)\n",
" process_data(serverInfo, server_data)\n",
" process_data(settlementInfo, settlement_data)\n",
"\n",
" # 记录已处理的订单ID\n",
" processed_orders.add(str(orderId))\n",
" with open(PROCESSED_FILE, 'w', encoding='utf-8') as f:\n",
" json.dump(list(processed_orders), f)\n",
"\n",
" except requests.exceptions.RequestException as req_err:\n",
" logging.error(f\"请求失败 (orderId={orderId}): {req_err}\")\n",
" print(f\"⚠️ 请求失败 (orderId={orderId}): {req_err}\")\n",
" except Exception as e:\n",
" logging.error(f\"未知错误 (orderId={orderId}): {e}\")\n",
" print(f\"❌ 未知错误 (orderId={orderId}): {e}\")\n",
"\n",
"# 写入 CSV 文件\n",
"output_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\\\'\n",
"\n",
"df1 = pd.DataFrame(car_data)\n",
"df2 = pd.DataFrame(operate_data)\n",
"df3 = pd.DataFrame(order_data)\n",
"df4 = pd.DataFrame(server_data)\n",
"df5 = pd.DataFrame(settlement_data)\n",
"\n",
"df1.to_csv(output_path + 'car.csv', index=False)\n",
"df2.to_csv(output_path + 'operate.csv', index=False)\n",
"df3.to_csv(output_path + 'order.csv', index=False)\n",
"df4.to_csv(output_path + 'server.csv', index=False)\n",
"df5.to_csv(output_path + 'settlement.csv', index=False)\n",
"\n",
"print(\"✅ 数据写入完成\")"
],
"id": "f8b29d309bd85d7b",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"正在抓取页面: 100%|██████████| 349/349 [1:39:59<00:00, 17.19s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ 数据写入完成\n"
]
}
],
"execution_count": 2
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}