{ "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 }