This commit is contained in:
2026-01-30 11:28:35 +08:00
commit f1831c31b4
399 changed files with 860978 additions and 0 deletions
@@ -0,0 +1,513 @@
# 竞品系统数据导出脚本说明文档
## 目录说明
本目录包含多个竞品系统的数据导出脚本,用于从不同竞品系统中导出客户信息、车辆信息、会员卡信息、历史维修记录等数据。
---
## 系统列表
### 1. i店系统
- **文件**: `i.py`, `i店.ipynb`, `i店客户车辆导出.ipynb`
- **功能**:
- 材料信息导出
- 客户信息导出
- 客户车辆信息导出
- 根据车牌查询fid
- 根据fid查询卡信息
- 储值卡信息导出
- 套餐卡信息导出
- **接口**: `http://www.idsz.xin:7070/posapi_invoke`
- **主要API**:
- `goodscommon_list`: 材料列表
- `kpi_customerDetailQuery_new`: 客户详情查询
- `member_customer_query_v1`: 根据车牌查询客户
- `member_person_query_by_id_v1`: 根据fid查询客户信息
- `kpi_memberVerifiAndSurplusQuery`: 会员卡信息查询
### 2. 京东云修系统
- **文件**: `京东云修.py`, `京东云修客户信息排序.ipynb`, `京东云修工单子表单.ipynb`, `京东云修系统导出.ipynb`
- **功能**:
- 客户信息导出(支持排序)
- 车辆信息导出
- 工单信息导出
- 工单子表单数据导出(服务项目、配件项目)
- **接口**: `https://www.yunxiu.com`, `https://jch1.yunxiu.com`
- **特点**:
- 支持按时间范围查询(可回溯10年)
- 支持多种排序方式
- 支持子单数据提取
### 3. 优米系统
- **文件**: `优米系统导出.ipynb`
- **功能**: 会员卡明细导出
- **接口**: `https://www.aibiyme.com`
- **特点**: 需要先导出会员表,之后做处理
### 4. 全智通系统
- **文件**: `全智通系统数据导出.ipynb`
- **功能**: 数据导出
### 5. 华胜云系统
- **文件**: `华胜云.py`
- **功能**: 使用Selenium自动化操作导出数据
- **特点**: 需要登录,使用浏览器自动化
### 6. 大唛云系统
- **文件**: `大唛云.py`, `大唛云历史维修记录.ipynb`, `大唛云管理平台.ipynb`, `新大唛云历史维修记录导出.ipynb`
- **功能**:
- 订单明细导出
- 历史维修记录导出
- 销售明细导出
- 库存查询
- **接口**: `http://rp.chezizhu.com`, `http://sp.chezizhu.com`
- **特点**:
- 使用FineReport报表系统
- 需要提取SessionID
- 支持订单明细的消费项目拆分
### 7. 大大汽修系统
- **文件**: `大大汽修token登录(1).ipynb`, `大大汽修点击导出(1).ipynb`
- **功能**:
- Token登录
- 导出维修历史单据里程、备注
- 导出维修历史明细
- 导出客户车辆信息
- 导出套餐卡信息
- **接口**: `https://api-qixiu.dada365.com`
- **特点**: 使用Token认证,支持批量导出
### 8. 好店长系统
- **文件**: `好店长.ipynb`
- **功能**:
- 消费流水导出
- 剩余套餐导出
- **接口**: `https://api.365hdz.com`
- **特点**: 需要配置storeid和authorization
### 9. 客户无忧系统
- **文件**: `客户无忧.ipynb`
- **功能**: 客户信息导出
- **接口**: `https://s19.kehu51.com`
- **特点**: 使用BeautifulSoup解析HTML表格
### 10. 客管家系统
- **文件**: `客管家数据导出(1).ipynb`
- **功能**:
- 客户车辆信息导出
- 储值卡导出
- 套餐卡导出(注意:不能翻页,需要一页导出)
- 库存查询
- 维修历史导出
- **接口**: `https://apicrm.kgjsoft.com`
- **特点**: 使用Bearer Token认证
### 11. 快修哥系统
- **文件**: `快修哥脚本.ipynb`
- **功能**: 客户信息导出
- **接口**: `http://www.kuaixiuge.com`
- **特点**: 使用ASP.NET ViewState机制,需要处理分页
### 12. 快录系统
- **文件**: `快录.ipynb`
- **功能**: 数据导出
### 13. 快维系统
- **文件**: `快维系统导出.ipynb`, `快维辅助程序.ipynb`
- **功能**: 系统数据导出
### 14. 掌上车店系统
- **文件**: `掌上车店.py`
- **功能**: 数据导出
- **接口**: `https://qfy.lycjh.com`
### 15. 财神驾到系统
- **文件**: `接口抓取数据_财神驾到.ipynb`
- **功能**: 通过接口抓取数据
### 16. 普盛系统
- **文件**: `普盛系统导出.ipynb`
- **功能**: 会员卡明细导出
- **接口**: `https://www.600vip.cn`
- **特点**: 需要先导出会员表,对会员卡号进行处理
### 17. 有礼云系统
- **文件**: `有礼云数据导出.ipynb`
- **功能**:
- 车辆信息导出
- 客户信息导出(含详情)
- 历史维修记录导出
- 历史维修记录数据处理(解析PHP序列化数据)
- **接口**: `https://www.4008778515.com`
- **特点**:
- 支持DataTables分页
- 需要处理PHP序列化的OthersList、PartsList、Carmaintainget字段
### 18. 枫车系统
- **文件**: `枫车系统导出.ipynb`
- **功能**:
- 车辆信息导出
- 会员卡信息导出(储值卡、套餐卡)
- 历史维修记录导出
- **接口**: `https://ssapp-api.carisok.com`, `https://cms.carisok.com`
- **特点**:
- 使用Token认证
- 支持重试机制
- 支持断点续传
### 19. 汽服云系统
- **文件**: `汽服云.py`
- **功能**: 车辆信息导出
- **接口**: `https://qfy.lycjh.com/applet.php`
### 20. 瀚都系统
- **文件**: `瀚都系统会员信息导出.ipynb`
- **功能**: 会员信息导出
### 21. 爱车店系统
- **文件**: `爱车店.ipynb`, `爱车店.py`, `爱车店导出数据处理.py`, `爱车店应收账款数据导出.py`, `爱车店新.ipynb`, `爱车店新版.py`
- **功能**:
- 订单数据导出(使用Selenium)
- 应收账款数据导出
- 数据拆分处理(服务项目、销售产品、支付记录)
- **特点**:
- 使用Selenium自动化浏览器操作
- 需要登录和选择门店
- 支持按日期范围查询
- 数据需要拆分处理
### 22. 特价轮胎经销商系统
- **文件**: `特价轮胎经销商系统.ipynb`, `特价轮胎经销商系统1.ipynb`
- **功能**: 经销商系统数据导出
### 23. 百少侠系统
- **文件**: `百少侠.ipynb`
- **功能**: 历史维修记录导出
- **接口**: `https://erp.byjy168.cn`
- **特点**: 请求过于频繁会挂掉,需要控制请求频率
### 24. 神汽链系统
- **文件**: `神汽链导出.ipynb`
- **功能**: 历史维修记录导出
- **接口**: `https://www.sqzone.com`
- **特点**: 支持按月范围查询,可回溯多年数据
### 25. 程浩美车系统
- **文件**: `程浩美车数据导出.ipynb`
- **功能**: 会员卡明细导出
- **接口**: `http://yqhm.vip5968.com`
- **特点**: 需要提取CustCardID,然后逐个查询明细
### 26. 稻田系统
- **文件**: `稻田系统导出.ipynb`
- **功能**:
- 车辆信息导出
- 工单信息导出
- 工单明细导出
- **接口**: `https://api.shuidao.com`
- **特点**: 使用Bearer Token认证
### 27. 米其林驰加系统
- **文件**: `米其林驰加系统导出.ipynb`
- **功能**:
- 车辆信息导出
- 历史维修记录列表(结算单)
- 历史维修记录明细(结算单明细)
- **接口**: `https://teds.tyreplus.com.cn`
- **特点**:
- 支持多门店查询
- 明细数据分为服务明细、产品明细、支付方式
### 28. 美孚(孚创)系统
- **文件**: `美孚(孚创)导出.ipynb`
- **功能**:
- 客户信息导出(含解密手机号)
- 客户明细导出
- **接口**: `https://store.fuchuang.com`
- **特点**: 手机号需要解密
### 29. 谷涂(黑谷前身)系统
- **文件**: `谷涂(黑谷前身)系统数据导出.ipynb`, `谷涂会员卡消费记录导出.py`
- **功能**:
- 有效会员卡导出
- 会员卡消费记录导出
- **接口**: `http://crm.zhongtukj.com`
- **特点**: 使用Playwright进行浏览器自动化
### 30. 车仆系统
- **文件**: `车仆.ipynb`
- **功能**: 数据导出
### 31. 车好了系统
- **文件**: `车好了.ipynb`
- **功能**: 会员信息导出
- **接口**: `http://www.chezhanggui.com:92`
- **特点**: 支持一次性导出大量数据(pageSize=5000
### 32. 车工坊系统
- **文件**: `车工坊.ipynb`
- **功能**: 历史维修记录导出
- **接口**: `https://caremore.saic-gm.com`
- **特点**:
- 按30天间隔下载数据
- 自动下载Excel文件
- 支持合并多个Excel文件
### 33. 车店无忧(车店通)系统
- **文件**: `车店无忧(车店通)会员卡明细.py`, `车店通.ipynb`
- **功能**: 会员卡明细导出
- **接口**: `https://auto.51autoshop.com`, `https://autoexpert.pli-petronas.com.cn`
- **特点**:
- 需要提取CustCardID
- 逐个查询会员卡明细
- 使用lxml解析HTML
### 34. 途虎养车系统
- **文件**: `途虎养车脚本导出.ipynb`
- **功能**:
- 客户信息导出
- 客户手机号解密
- 历史维修记录导出
- 供应商信息导出(含图片下载)
- **接口**: `https://shop-gateway.tuhu.cn`
- **特点**:
- 使用Bearer Token认证
- Token存在过期时间,需要经常更换
- 支持图片下载和超链接生成
- 订单号需要正则处理(TH前缀)
---
## 通用技术栈
### 主要使用的库
- **requests**: HTTP请求
- **pandas**: 数据处理和Excel导出
- **selenium**: 浏览器自动化(部分系统)
- **BeautifulSoup/lxml**: HTML解析
- **tqdm**: 进度条显示
- **openpyxl**: Excel文件操作
- **phpserialize**: PHP序列化数据解析(有礼云系统)
### 常见功能模式
1. **API接口调用**
- 大部分系统通过HTTP API获取数据
- 需要配置cookies、headers、token等认证信息
- 支持分页查询
2. **浏览器自动化**
- 部分系统使用Selenium或Playwright
- 需要处理登录、选择门店等操作
- 适合无法直接调用API的系统
3. **数据导出格式**
- 主要导出为Excel文件(.xlsx
- 部分导出为CSV文件
- 保存路径通常在`文件输出`目录
4. **错误处理**
- 大部分脚本包含重试机制
- 使用try-except处理异常
- 记录失败订单/记录
---
## 使用注意事项
### 1. 认证信息
- **Token/Cookie**: 大部分脚本中的token和cookie会过期,需要定期更新
- **登录状态**: 使用浏览器自动化的脚本需要保持登录状态
- **权限**: 确保账号有相应的数据导出权限
### 2. 请求频率控制
- 大部分脚本包含`time.sleep()`延迟,避免请求过于频繁
- 部分系统(如百少侠)明确标注"请求过于频繁会挂掉"
- 建议根据实际情况调整延迟时间
### 3. 数据量处理
- 大量数据导出时建议分批处理
- 部分脚本支持断点续传(如枫车系统)
- 注意内存占用,及时保存中间结果
### 4. 特殊处理
- **有礼云系统**: 需要解析PHP序列化数据(OthersList、PartsList、Carmaintainget
- **爱车店系统**: 数据需要拆分处理(服务项目、销售产品、支付记录)
- **大唛云系统**: 需要提取SessionID,使用FineReport报表系统
- **车工坊系统**: 按时间段下载多个Excel文件,需要合并
### 5. 文件路径
- 输出文件路径通常使用绝对路径
- 注意路径中的反斜杠需要使用原始字符串(r'')或双反斜杠
---
## 脚本分类
### 按技术实现分类
#### API接口调用类
- i店系统
- 京东云修
- 优米系统
- 客管家
- 有礼云
- 枫车系统
- 稻田系统
- 米其林驰加
- 美孚(孚创)
- 车好了
- 途虎养车
- 等大部分系统
#### 浏览器自动化类
- 华胜云(Selenium
- 大大汽修(部分功能)
- 爱车店(Selenium
- 谷涂系统(Playwright
- 车工坊(部分功能)
#### HTML解析类
- 客户无忧(BeautifulSoup
- 快修哥(BeautifulSoup + ViewState
- 车店无忧(lxml
---
## 数据导出类型
### 1. 客户信息
- 客户姓名、手机号、车牌号、车型等基本信息
- 部分系统支持客户详情导出
### 2. 车辆信息
- 车牌号、品牌、型号、VIN码、里程等
### 3. 会员卡信息
- **储值卡**: 余额、开卡时间、到期时间等
- **套餐卡**: 套餐内容、剩余次数、使用记录等
- **会员卡明细**: 消费记录、充值记录等
### 4. 历史维修记录
- 工单基本信息
- 服务项目明细
- 配件/产品明细
- 支付信息
- 部分系统支持子单数据导出
### 5. 其他数据
- 库存信息
- 销售明细
- 供应商信息
- 材料信息
---
## 常见问题
### 1. Token过期
**解决方案**: 重新登录获取新的token,更新脚本中的authorization字段
### 2. Cookie失效
**解决方案**: 重新登录获取新的cookie,更新脚本中的cookies字典
### 3. 请求失败/超时
**解决方案**:
- 增加重试机制
- 增加请求间隔时间
- 检查网络连接
### 4. 数据不完整
**解决方案**:
- 检查分页逻辑是否正确
- 确认总页数计算
- 检查数据过滤条件
### 5. 编码问题
**解决方案**:
- 使用UTF-8编码
- Excel导出时使用`encoding='utf-8-sig'`CSV文件)
---
## 维护建议
1. **定期更新认证信息**: Token和Cookie会过期,需要定期更新
2. **监控脚本运行**: 大量数据导出时注意监控进度和错误
3. **备份重要数据**: 导出前确认输出路径,避免覆盖重要数据
4. **版本控制**: 系统更新可能导致脚本失效,需要及时调整
5. **文档更新**: 系统变更时及时更新脚本和文档
---
## 文件结构
```
竞品系统数据导出/
├── i.py # i店系统 - 简单测试脚本
├── i店.ipynb # i店系统 - 完整导出脚本
├── i店客户车辆导出.ipynb # i店系统 - 客户车辆导出
├── 京东云修.py # 京东云修 - Python脚本
├── 京东云修客户信息排序.ipynb # 京东云修 - 客户信息排序导出
├── 京东云修工单子表单.ipynb # 京东云修 - 工单子表单导出
├── 京东云修系统导出.ipynb # 京东云修 - 系统导出
├── 优米系统导出.ipynb # 优米系统导出
├── 全智通系统数据导出.ipynb # 全智通系统导出
├── 华胜云.py # 华胜云系统(Selenium
├── 大唛云.py # 大唛云系统
├── 大唛云历史维修记录.ipynb # 大唛云历史维修记录
├── 大唛云管理平台.ipynb # 大唛云管理平台
├── 大大汽修token登录(1).ipynb # 大大汽修Token登录
├── 大大汽修点击导出(1).ipynb # 大大汽修点击导出
├── 好店长.ipynb # 好店长系统
├── 客户无忧.ipynb # 客户无忧系统
├── 客管家数据导出(1).ipynb # 客管家数据导出
├── 快修哥脚本.ipynb # 快修哥脚本
├── 快录.ipynb # 快录系统
├── 快维系统导出.ipynb # 快维系统导出
├── 快维辅助程序.ipynb # 快维辅助程序
├── 掌上车店.py # 掌上车店系统
├── 接口抓取数据_财神驾到.ipynb # 财神驾到接口抓取
├── 新大唛云历史维修记录导出.ipynb # 新大唛云历史维修记录
├── 普盛系统导出.ipynb # 普盛系统导出
├── 有礼云数据导出.ipynb # 有礼云数据导出
├── 枫车系统导出.ipynb # 枫车系统导出
├── 汽服云.py # 汽服云系统
├── 测试.ipynb # 测试脚本
├── 瀚都系统会员信息导出.ipynb # 瀚都系统会员信息
├── 爱车店.ipynb # 爱车店系统(旧版)
├── 爱车店.py # 爱车店系统(Python版)
├── 爱车店导出数据处理.py # 爱车店数据拆分处理
├── 爱车店应收账款数据导出.py # 爱车店应收账款导出
├── 爱车店新.ipynb # 爱车店系统(新版)
├── 爱车店新版.py # 爱车店系统(新版Python)
├── 特价轮胎经销商系统.ipynb # 特价轮胎经销商系统
├── 特价轮胎经销商系统1.ipynb # 特价轮胎经销商系统(版本1)
├── 百少侠.ipynb # 百少侠系统
├── 神汽链导出.ipynb # 神汽链导出
├── 程浩美车数据导出.ipynb # 程浩美车数据导出
├── 稻田系统导出.ipynb # 稻田系统导出
├── 米其林驰加系统导出.ipynb # 米其林驰加系统导出
├── 美孚(孚创)导出.ipynb # 美孚(孚创)导出
├── 谷涂(黑谷前身)系统数据导出.ipynb # 谷涂系统导出
├── 谷涂会员卡消费记录导出.py # 谷涂会员卡消费记录
├── 车仆.ipynb # 车仆系统
├── 车好了.ipynb # 车好了系统
├── 车工坊.ipynb # 车工坊系统
├── 车店无忧(车店通)会员卡明细.py # 车店无忧会员卡明细
├── 车店通.ipynb # 车店通系统
└── 途虎养车脚本导出.ipynb # 途虎养车脚本导出
```
---
## 更新日志
- 2025-01-27: 创建说明文档,整理所有脚本功能
---
## 联系方式
如有问题或需要更新脚本,请联系脚本维护人员。
@@ -0,0 +1,18 @@
import requests
cookies = {
'JSESSIONID': '9C45E1317CD259B2847DFE880A214989',
}
headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Connection': 'keep-alive',
'Referer': 'http://www.idsz.xin:7070/report_member_verifi_list?detailtype=1&key=totalBalance&datafrom=2025-01-01&datato=2025-11-19&sshopId=&type=1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',
'X-Requested-With': 'XMLHttpRequest',
# 'Cookie': 'JSESSIONID=9C45E1317CD259B2847DFE880A214989',
}
response = requests.get('http://www.idsz.xin:7070/posapi_invoke?apiname=kpi_memberVerifiAndSurplusQuery&detailtype=1&startTime=2025-01-01&endTime=2025-11-19&key=totalBalance&sshopId=&timesCardId=&option=&page=0&pageSize=50', cookies=cookies, headers=headers, verify=False)
print(response.text)
@@ -0,0 +1,971 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "获取材料",
"id": "be89024828eeb339"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-06-23T03:52:55.446076Z",
"start_time": "2025-06-23T03:52:49.281182Z"
}
},
"source": [
"import requests\n",
"import pandas as pd\n",
"\n",
"all_data = []\n",
"cookies = {\n",
" 'Hm_lvt_a856165bfa0ce84d1fb04dc98d558ead': '1750648887',\n",
" 'Hm_lpvt_a856165bfa0ce84d1fb04dc98d558ead': '1750648887',\n",
" 'HMACCOUNT': 'ABFCA62083E00432',\n",
" 'JSESSIONID': 'C719B94B2515D8D6582B9D4AE91903FF',\n",
" 'td_cookie': '3361803543',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\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",
" 'Referer': 'http://www.idsz.xin:7070/setting_commodity_information_new',\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",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'Hm_lvt_a856165bfa0ce84d1fb04dc98d558ead=1750648887; Hm_lpvt_a856165bfa0ce84d1fb04dc98d558ead=1750648887; HMACCOUNT=ABFCA62083E00432; JSESSIONID=C719B94B2515D8D6582B9D4AE91903FF; td_cookie=3361803543',\n",
"}\n",
"\n",
"topGroupId_list = [\n",
" '974e032e-0052-42b0-9d98-2d83f9ee7d0a',\n",
" '81f51c1d-f33b-4ec7-ab79-34af0cb4a006',\n",
" 'b17589f3-ad29-429a-9f15-6077d1cbafbb',\n",
" '25eb6487-0bf9-4fa2-8fcf-5c7e1fedf700',\n",
" 'be723274-157e-4da5-a7cd-dae8874a3bf5',\n",
" '29ae4eb1-cd7d-4521-a4cf-6feaae449f2f',\n",
" '96a1f351-ae12-46dd-b6b3-57dd96a316a1',\n",
" \"72278a29-7c9b-4c54-9eec-809542a2327b\"\n",
"] # 手动获取\n",
"\n",
"for topGroupId in topGroupId_list:\n",
" total = 0\n",
" params = {\n",
" 'apiname': 'goodscommon_list',\n",
" 'page': '0',\n",
" 'rows': '50',\n",
" 'topGroupId': topGroupId, # 不同类目需要手动变更\n",
" 'subGroupId': '',\n",
" 'queryStr': '',\n",
" 'goodsType': '',\n",
" }\n",
"\n",
" response = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
" total = response.json().get('total')\n",
"\n",
" rows_list = []\n",
" for i in range(total + 1):\n",
" new_params = {\n",
" 'apiname': 'goodscommon_list',\n",
" 'page': f'{i}',\n",
" 'rows': '50',\n",
" 'topGroupId': topGroupId, # 不同类目需要手动变更\n",
" 'subGroupId': '',\n",
" 'queryStr': '',\n",
" 'goodsType': '',\n",
" }\n",
" rows_list += requests.get('http://www.idsz.xin:7070/posapi_invoke', params=new_params, cookies=cookies,\n",
" headers=headers, verify=False).json().get('rows')\n",
" df = pd.DataFrame(rows_list)\n",
" df.to_excel(f'{topGroupId}data.xlsx', index=False)"
],
"outputs": [],
"execution_count": 16
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 客户信息",
"id": "bcb243b547895096"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T03:39:42.773538Z",
"start_time": "2025-12-05T03:38:31.538614Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm.notebook import tqdm\n",
"import pandas as pd\n",
"USER_AGENT = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36\"\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '621467AB3BF49A8C806B9AA859C05C81',\n",
" 'td_cookie': '438646777',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'Origin': 'http://www.idsz.xin:7070',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/report/memberservicelist?detailtype=3&key=4&startTime=2025-01-01&endTime=2025-12-05&sshopId=&type=1&typeFlag=0',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=621467AB3BF49A8C806B9AA859C05C81; td_cookie=438646777',\n",
"}\n",
"\n",
"all_data = []\n",
"\n",
"params = {\n",
" 'apiname': 'kpi_customerDetailQuery_new',\n",
" 'detailtype': '4',\n",
" 'startTime': '2015-01-01',\n",
" 'endTime': '2025-12-31',\n",
" 'key': 'cus',\n",
" 'sshopId': '',\n",
" 'option': '',\n",
" 'page': 1,\n",
" 'pageSize': '50',\n",
"}\n",
"\n",
"response = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
"\n",
"# print(response.json())\n",
"total = response.json().get('total')\n",
"total = int(total)\n",
"print( total)\n",
"total_pages = total // 50 + 1\n",
"for i in tqdm(range(total_pages)):\n",
" params['page'] = i + 1\n",
" response = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
" cus_list = response.json().get('rows')\n",
" for cus in cus_list:\n",
" all_data.append(cus)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel('customer_data.xlsx', index=False)"
],
"id": "2c30955bd49819cc",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7701\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/155 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "0aa7e0c27bc045c0aeb870544edaa328"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T03:21:40.255194Z",
"start_time": "2025-12-05T03:21:38.345894Z"
}
},
"cell_type": "code",
"source": "df.to_excel('customer_data.xlsx', index=False)",
"id": "1209e7c233e5a37a",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"正在抓取会员卡信息: 18%|█▊ | 1347/7658 [1:30:48<7:05:27, 4.04s/it]\n"
]
}
],
"execution_count": 37
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 根据车牌查询fid",
"id": "f483cb1329585127"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-04T11:06:52.170254Z",
"start_time": "2025-12-04T09:37:05.539650Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '621467AB3BF49A8C806B9AA859C05C81',\n",
" 'td_cookie': '438646777',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'Origin': 'http://www.idsz.xin:7070',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/report/memberservicelist?detailtype=3&key=4&startTime=2025-01-01&endTime=2025-12-05&sshopId=&type=1&typeFlag=0',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=621467AB3BF49A8C806B9AA859C05C81; td_cookie=438646777',\n",
"}\n",
"\n",
"# 定义查询单个车牌信息的函数\n",
"def query_vehicle_info(license_plate):\n",
" params = {\n",
" 'apiname': 'member_customer_query_v1',\n",
" 'option': license_plate,\n",
" 'tagId': '',\n",
" 'page': '0',\n",
" 'pageSize': '50',\n",
" }\n",
" try:\n",
" response = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies,\n",
" headers=headers, verify=False)\n",
" response.raise_for_status() # 如果请求失败(状态码不是200),抛出异常\n",
" data = response.json()\n",
" if 'userObject' in data and 'list' in data['userObject']:\n",
" return data['userObject']['list']\n",
" else:\n",
" return []\n",
" except requests.RequestException as e:\n",
" print(f\"查询车牌 {license_plate} 时出现请求错误: {e}\")\n",
" return []\n",
" except ValueError as e:\n",
" print(f\"查询车牌 {license_plate} 时解析JSON出错: {e}\")\n",
" return []\n",
"\n",
"\n",
"# 读取 Excel 文件\n",
"excel_file = pd.ExcelFile('customer_data.xlsx')\n",
"df = excel_file.parse()\n",
"\n",
"# 假设车牌列名为 '车牌',如果不是请修改\n",
"license_plates = df['carNo'].tolist()\n",
"\n",
"all_results = []\n",
"for plate in tqdm(license_plates):\n",
" result = query_vehicle_info(plate)\n",
" if result:\n",
" all_results.extend(result)\n",
" time.sleep(0.5) # 适当延时,避免给服务器造成过大压力\n",
"\n",
"# 将结果转换为 DataFrame 并保存为 Excel 文件\n",
"result_df = pd.DataFrame(all_results)\n",
"result_df.to_excel(r'车牌查询结果.xlsx', index=False)"
],
"id": "2d27a314d2cc6b40",
"outputs": [
{
"data": {
"text/plain": [
" 0%| | 0/7650 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "f5e0feb761e8432494dec95b0ed6146e"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 1
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 根据fid查询卡信息",
"id": "b31f79d06acb381a"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T01:46:27.497896Z",
"start_time": "2025-12-05T01:46:22.721666Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '32C141F5A7A289491D34C50325D2D5A8',\n",
" 'td_cookie': '431362035',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/x-www-form-urlencoded',\n",
" 'Origin': 'http://www.idsz.xin:7070',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/member_1_info?cusId=001ae236-99ee-4330-88eb-83532e605eab&type=0',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=32C141F5A7A289491D34C50325D2D5A8; td_cookie=431362035',\n",
"}\n",
"\n",
"params = {\n",
" 'apiname': 'member_person_query_by_id_v1',\n",
"}\n",
"\n",
"df = pd.read_excel('车牌查询结果.xlsx', sheet_name='Sheet1')\n",
"all_data = []\n",
"\n",
"for index, item in tqdm(df.iterrows(), total=len(df)):\n",
" data = {\n",
" 'id': item['fid'],\n",
" 'licensePlate': '',\n",
" 'idType': '1',\n",
" }\n",
" retry = 0\n",
" while retry < 5:\n",
" response = requests.post(\n",
" 'http://www.idsz.xin:7070/posapi_invoke',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" data=data,\n",
" verify=False,\n",
" )\n",
" if not json_data.get(\"success\"):\n",
" # 即使 success=False,也视为“成功响应”,不再重试\n",
" return []\n",
" try:\n",
" cus = response.json().get('userObject')\n",
" cus_card_list = cus.get('tiemsItems')\n",
"\n",
" time.sleep(1)\n",
" for card in cus_card_list:\n",
" all_data.append(card)\n",
" break\n",
" except:\n",
" retry += 1\n",
" time.sleep(1)\n",
" continue\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel('会员卡信息1.xlsx', index=False)\n",
"# df2 = pd.merge(df, df1, on='fid', how='left')\n",
"# df2.to_excel('会员卡信息.xlsx', index=False)\n"
],
"id": "c56ad6be942a37b1",
"outputs": [
{
"data": {
"text/plain": [
" 0%| | 0/7658 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "3a8ef6406c414ec2a030c1f30471f262"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'success': False, 'msg': '未找到符合条件的客户!', 'errorCode': -1, 'userObject': None}\n",
"{'success': False, 'msg': '未找到符合条件的客户!', 'errorCode': -1, 'userObject': None}\n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
"\u001B[31mAttributeError\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[32]\u001B[39m\u001B[32m, line 51\u001B[39m\n\u001B[32m 50\u001B[39m cus = response.json().get(\u001B[33m'\u001B[39m\u001B[33muserObject\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m---> \u001B[39m\u001B[32m51\u001B[39m cus_card_list = cus.get(\u001B[33m'\u001B[39m\u001B[33mtiemsItems\u001B[39m\u001B[33m'\u001B[39m)\n\u001B[32m 52\u001B[39m \u001B[38;5;28mprint\u001B[39m(cus)\n",
"\u001B[31mAttributeError\u001B[39m: 'NoneType' object has no attribute 'get'",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[32]\u001B[39m\u001B[32m, line 59\u001B[39m\n\u001B[32m 57\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m:\n\u001B[32m 58\u001B[39m retry += \u001B[32m1\u001B[39m\n\u001B[32m---> \u001B[39m\u001B[32m59\u001B[39m time.sleep(\u001B[32m1\u001B[39m)\n\u001B[32m 60\u001B[39m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[32m 62\u001B[39m df1 = pd.DataFrame(all_data)\n",
"\u001B[31mKeyboardInterrupt\u001B[39m: "
]
}
],
"execution_count": 32
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T02:02:22.985849Z",
"start_time": "2025-12-05T01:54:44.634161Z"
}
},
"cell_type": "code",
"source": [
"import asyncio\n",
"import httpx\n",
"import pandas as pd\n",
"import random\n",
"from tqdm.notebook import tqdm\n",
"\n",
"# ===== 配置 =====\n",
"CONCURRENCY = 5\n",
"RETRY_LIMIT = 3\n",
"TIMEOUT = 10\n",
"MIN_DELAY = 0.2\n",
"MAX_DELAY = 0.8\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '621467AB3BF49A8C806B9AA859C05C81',\n",
" 'td_cookie': '438646777',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'Origin': 'http://www.idsz.xin:7070',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/report/memberservicelist?detailtype=3&key=4&startTime=2025-01-01&endTime=2025-12-05&sshopId=&type=1&typeFlag=0',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=621467AB3BF49A8C806B9AA859C05C81; td_cookie=438646777',\n",
"}\n",
"\n",
"params = {'apiname': 'member_person_query_by_id_v1'}\n",
"\n",
"async def fetch_card_data(client, fid, semaphore):\n",
" async with semaphore:\n",
" await asyncio.sleep(random.uniform(MIN_DELAY, MAX_DELAY))\n",
" data = {'id': fid, 'licensePlate': '', 'idType': '1'}\n",
" for attempt in range(RETRY_LIMIT):\n",
" try:\n",
" response = await client.post(\n",
" 'http://www.idsz.xin:7070/posapi_invoke',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=base_headers,\n",
" data=data,\n",
" timeout=TIMEOUT\n",
" )\n",
" response.raise_for_status()\n",
" json_data = response.json()\n",
" if not json_data.get(\"success\"):\n",
" # 即使 success=False,也视为“成功响应”,不再重试\n",
" return []\n",
" user_obj = json_data.get('userObject', {})\n",
" card_list = user_obj.get('tiemsItems', [])\n",
" return [{'fid': fid, **card} for card in card_list]\n",
" except Exception as e:\n",
" if attempt == RETRY_LIMIT - 1:\n",
" print(f\"❌ 最终失败: fid={fid}, error={str(e)}\")\n",
" return []\n",
" await asyncio.sleep(random.uniform(0.5, 1.5))\n",
" return []\n",
"\n",
"# ===== 改进版:精准进度条 =====\n",
"async def run_main():\n",
" df = pd.read_excel('车牌查询结果.xlsx', sheet_name='Sheet1')\n",
" fids = df['fid'].tolist()\n",
" semaphore = asyncio.Semaphore(CONCURRENCY)\n",
"\n",
" async with httpx.AsyncClient(verify=False) as client:\n",
" # 创建所有任务\n",
" tasks = [fetch_card_data(client, fid, semaphore) for fid in fids]\n",
"\n",
" # 使用 tqdm 手动管理进度\n",
" all_results = []\n",
" pbar = tqdm(total=len(tasks), desc=\"正在抓取会员卡信息\")\n",
"\n",
" # 使用 as_completed 逐个获取完成的任务\n",
" for coro in asyncio.as_completed(tasks):\n",
" result = await coro\n",
" all_results.append(result)\n",
" pbar.update(1) # 每完成一个,进度+1\n",
"\n",
" pbar.close()\n",
"\n",
" # 展平结果\n",
" all_data = [item for sublist in all_results for item in sublist]\n",
" df1 = pd.DataFrame(all_data)\n",
" df1.to_excel('会员卡信息1.xlsx', index=False)\n",
" print(f\"✅ 共获取 {len(all_data)} 条记录,已保存到 '会员卡信息1.xlsx'\")\n",
"\n",
"# 在 Jupyter 中运行\n",
"await run_main()"
],
"id": "ad8733e5b29be5fc",
"outputs": [
{
"data": {
"text/plain": [
"正在抓取会员卡信息: 0%| | 0/7658 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "6125ba241801415a883750b643390f6d"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✅ 共获取 0 条记录,已保存到 '会员卡信息1.xlsx'\n"
]
}
],
"execution_count": 35
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 储值卡信息(快速接口)",
"id": "6344358f85945812"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T07:01:03.797372Z",
"start_time": "2025-12-05T07:00:56.618957Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"\n",
"import requests\n",
"cookies = {\n",
" 'JSESSIONID': '052CB97F817616E954B542F4F7442E54',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Pragma': 'no-cache',\n",
" 'Proxy-Connection': 'keep-alive',\n",
" 'Referer': 'http://www.idsz.xin:7070/report_member_verifi_list?detailtype=1&key=totalBalance&datafrom=2025-01-01&datato=2025-12-05&sshopId=&type=1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=052CB97F817616E954B542F4F7442E54',\n",
"}\n",
"\n",
"\n",
"params = {\n",
" 'apiname': 'kpi_memberVerifiAndSurplusQuery',\n",
" 'detailtype': '1',\n",
" 'startTime': '2015-01-01',\n",
" 'endTime': '2025-12-21',\n",
" 'key': 'totalBalance',\n",
" 'sshopId': '',\n",
" 'timesCardId': '',\n",
" 'option': '',\n",
" 'page': '0',\n",
" 'pageSize': '50',\n",
"}\n",
"\n",
"res = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
"# print(res.json())\n",
"\n",
"total = res.json()['total']\n",
"total = int(total)\n",
"print(total)\n",
"page_num = total // 50 + 1\n",
"all_data = []\n",
"for i in tqdm(range(page_num)):\n",
" params['page'] = i\n",
" res = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
" time.sleep(0.5)\n",
" rows = res.json()['rows']\n",
" for row in rows:\n",
" all_data.append(row)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\储值卡.xlsx', index=False)"
],
"id": "5bdde2efbe9b0390",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"233\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/5 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "fb907a4cfddd4bb09a7a6305204e1ebd"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 12
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 套餐卡",
"id": "93dfefe59f8f6a63"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T05:37:07.706976Z",
"start_time": "2025-12-05T05:36:57.105851Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"\n",
"import requests\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '705CFAA4C504D16F38A0379FD33DF300',\n",
" 'td_cookie': '445761476',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/report_member_verifi_list?detailtype=1&key=totalBalance&datafrom=2025-01-01&datato=2025-12-05&sshopId=&type=1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=705CFAA4C504D16F38A0379FD33DF300; td_cookie=445761476',\n",
"}\n",
"\n",
"\n",
"params = {\n",
" 'apiname': 'kpi_memberVerifiAndSurplusQuery',\n",
" 'detailtype': '4',\n",
" 'startTime': '2015-01-01',\n",
" 'endTime': '2025-12-31',\n",
" 'key': 'totalCount',\n",
" 'sshopId': '',\n",
" 'timesCardId': '',\n",
" 'option': '',\n",
" 'page': '0',\n",
" 'pageSize': '50',\n",
"}\n",
"\n",
"res = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
"# print(res.json())\n",
"\n",
"total = res.json()['total']\n",
"total = int(total)\n",
"page_num = total // 50 + 1\n",
"all_data = []\n",
"for i in tqdm(range(page_num)):\n",
" params['page'] = i\n",
" res = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n",
" time.sleep(0.5)\n",
" rows = res.json()['rows']\n",
" for row in rows:\n",
" all_data.append(row)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\套餐卡.xlsx', index=False)"
],
"id": "b2f7fb71b16faedf",
"outputs": [
{
"data": {
"text/plain": [
" 0%| | 0/14 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "af61f1ef2dca42d195d6bb70d4c93909"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 10
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 两个卡信息合并获取客户信息fid",
"id": "95c8ba6456b099b"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T01:28:45.798092Z",
"start_time": "2025-12-05T01:28:44.780987Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"\n",
"df1 = pd.read_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\储值卡.xlsx\")\n",
"df2 = pd.read_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\套餐卡.xlsx\")\n",
"df3 = pd.concat([df1, df2], ignore_index=True)\n",
"df3.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\全部卡信息.xlsx\", index=False)"
],
"id": "8d7315e912a17884",
"outputs": [],
"execution_count": 19
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 客户信息\n",
"id": "564b68724ffc3cc6"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T01:35:53.740495Z",
"start_time": "2025-12-05T01:34:15.936800Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm.notebook import tqdm\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '052CB97F817616E954B542F4F7442E54',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Pragma': 'no-cache',\n",
" 'Proxy-Connection': 'keep-alive',\n",
" 'Referer': 'http://www.idsz.xin:7070/report_member_verifi_list?detailtype=1&key=totalBalance&datafrom=2025-01-01&datato=2025-12-05&sshopId=&type=1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=052CB97F817616E954B542F4F7442E54',\n",
"}\n",
"\n",
"df = pd.read_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\全部卡信息.xlsx\", sheet_name=\"Sheet1\")\n",
"\n",
"# 去重\n",
"df_dedup = df.drop_duplicates(subset=['fid'], keep='first')\n",
"\n",
"params = {\n",
" 'apiname': 'member_person_query_by_id_v1',\n",
"}\n",
"all_data = []\n",
"for index, row in tqdm(df_dedup.iterrows(), total=len(df_dedup)):\n",
" data = {\n",
" 'id': row[\"fid\"],\n",
" 'licensePlate': '',\n",
" 'idType': '1',\n",
" }\n",
"\n",
" response = requests.post(\n",
" 'http://www.idsz.xin:7070/posapi_invoke',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" data=data,\n",
" verify=False,\n",
" )\n",
"\n",
" # print(response.json())\n",
" all_data.append(response.json().get(\"userObject\", {}))\n",
"\n",
"res_df = pd.DataFrame(all_data)\n",
"res_df.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\有卡客户信息.xlsx\", index=False)"
],
"id": "52074a8276d30ee6",
"outputs": [
{
"data": {
"text/plain": [
" 0%| | 0/339 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "bf2e958e68dc40828eb424acd4e9d1c3"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"ename": "AttributeError",
"evalue": "'NoneType' object has no attribute 'keys'",
"output_type": "error",
"traceback": [
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
"\u001B[31mAttributeError\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[21]\u001B[39m\u001B[32m, line 52\u001B[39m\n\u001B[32m 49\u001B[39m \u001B[38;5;66;03m# print(response.json())\u001B[39;00m\n\u001B[32m 50\u001B[39m all_data.append(response.json().get(\u001B[33m\"\u001B[39m\u001B[33muserObject\u001B[39m\u001B[33m\"\u001B[39m, {}))\n\u001B[32m---> \u001B[39m\u001B[32m52\u001B[39m res_df = pd.DataFrame(all_data)\n\u001B[32m 53\u001B[39m res_df.to_excel(\u001B[33mr\u001B[39m\u001B[33m\"\u001B[39m\u001B[33mD:\u001B[39m\u001B[33m\\\u001B[39m\u001B[33mIdea Project\u001B[39m\u001B[33m\\\u001B[39m\u001B[33mF6+宜搭+其它(1)\u001B[39m\u001B[33m\\\u001B[39m\u001B[33m张阳脚本\u001B[39m\u001B[33m\\\u001B[39m\u001B[33m文件输出\u001B[39m\u001B[33m\\\u001B[39m\u001B[33m有卡客户信息.xlsx\u001B[39m\u001B[33m\"\u001B[39m,index=\u001B[38;5;28;01mFalse\u001B[39;00m)\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\ProgramTools\\anaconda3\\envs\\f6\\Lib\\site-packages\\pandas\\core\\frame.py:851\u001B[39m, in \u001B[36mDataFrame.__init__\u001B[39m\u001B[34m(self, data, index, columns, dtype, copy)\u001B[39m\n\u001B[32m 849\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m columns \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[32m 850\u001B[39m columns = ensure_index(columns)\n\u001B[32m--> \u001B[39m\u001B[32m851\u001B[39m arrays, columns, index = nested_data_to_arrays(\n\u001B[32m 852\u001B[39m \u001B[38;5;66;03m# error: Argument 3 to \"nested_data_to_arrays\" has incompatible\u001B[39;00m\n\u001B[32m 853\u001B[39m \u001B[38;5;66;03m# type \"Optional[Collection[Any]]\"; expected \"Optional[Index]\"\u001B[39;00m\n\u001B[32m 854\u001B[39m data,\n\u001B[32m 855\u001B[39m columns,\n\u001B[32m 856\u001B[39m index, \u001B[38;5;66;03m# type: ignore[arg-type]\u001B[39;00m\n\u001B[32m 857\u001B[39m dtype,\n\u001B[32m 858\u001B[39m )\n\u001B[32m 859\u001B[39m mgr = arrays_to_mgr(\n\u001B[32m 860\u001B[39m arrays,\n\u001B[32m 861\u001B[39m columns,\n\u001B[32m (...)\u001B[39m\u001B[32m 864\u001B[39m typ=manager,\n\u001B[32m 865\u001B[39m )\n\u001B[32m 866\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\ProgramTools\\anaconda3\\envs\\f6\\Lib\\site-packages\\pandas\\core\\internals\\construction.py:520\u001B[39m, in \u001B[36mnested_data_to_arrays\u001B[39m\u001B[34m(data, columns, index, dtype)\u001B[39m\n\u001B[32m 517\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m is_named_tuple(data[\u001B[32m0\u001B[39m]) \u001B[38;5;129;01mand\u001B[39;00m columns \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[32m 518\u001B[39m columns = ensure_index(data[\u001B[32m0\u001B[39m]._fields)\n\u001B[32m--> \u001B[39m\u001B[32m520\u001B[39m arrays, columns = to_arrays(data, columns, dtype=dtype)\n\u001B[32m 521\u001B[39m columns = ensure_index(columns)\n\u001B[32m 523\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m index \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\ProgramTools\\anaconda3\\envs\\f6\\Lib\\site-packages\\pandas\\core\\internals\\construction.py:837\u001B[39m, in \u001B[36mto_arrays\u001B[39m\u001B[34m(data, columns, dtype)\u001B[39m\n\u001B[32m 835\u001B[39m arr = _list_to_arrays(data)\n\u001B[32m 836\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(data[\u001B[32m0\u001B[39m], abc.Mapping):\n\u001B[32m--> \u001B[39m\u001B[32m837\u001B[39m arr, columns = _list_of_dict_to_arrays(data, columns)\n\u001B[32m 838\u001B[39m \u001B[38;5;28;01melif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(data[\u001B[32m0\u001B[39m], ABCSeries):\n\u001B[32m 839\u001B[39m arr, columns = _list_of_series_to_arrays(data, columns)\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\ProgramTools\\anaconda3\\envs\\f6\\Lib\\site-packages\\pandas\\core\\internals\\construction.py:917\u001B[39m, in \u001B[36m_list_of_dict_to_arrays\u001B[39m\u001B[34m(data, columns)\u001B[39m\n\u001B[32m 915\u001B[39m gen = (\u001B[38;5;28mlist\u001B[39m(x.keys()) \u001B[38;5;28;01mfor\u001B[39;00m x \u001B[38;5;129;01min\u001B[39;00m data)\n\u001B[32m 916\u001B[39m sort = \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28many\u001B[39m(\u001B[38;5;28misinstance\u001B[39m(d, \u001B[38;5;28mdict\u001B[39m) \u001B[38;5;28;01mfor\u001B[39;00m d \u001B[38;5;129;01min\u001B[39;00m data)\n\u001B[32m--> \u001B[39m\u001B[32m917\u001B[39m pre_cols = lib.fast_unique_multiple_list_gen(gen, sort=sort)\n\u001B[32m 918\u001B[39m columns = ensure_index(pre_cols)\n\u001B[32m 920\u001B[39m \u001B[38;5;66;03m# assure that they are of the base dict class and not of derived\u001B[39;00m\n\u001B[32m 921\u001B[39m \u001B[38;5;66;03m# classes\u001B[39;00m\n",
"\u001B[36mFile \u001B[39m\u001B[32mpandas/_libs/lib.pyx:367\u001B[39m, in \u001B[36mpandas._libs.lib.fast_unique_multiple_list_gen\u001B[39m\u001B[34m()\u001B[39m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\ProgramTools\\anaconda3\\envs\\f6\\Lib\\site-packages\\pandas\\core\\internals\\construction.py:915\u001B[39m, in \u001B[36m<genexpr>\u001B[39m\u001B[34m(.0)\u001B[39m\n\u001B[32m 895\u001B[39m \u001B[38;5;250m\u001B[39m\u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 896\u001B[39m \u001B[33;03mConvert list of dicts to numpy arrays\u001B[39;00m\n\u001B[32m 897\u001B[39m \n\u001B[32m (...)\u001B[39m\u001B[32m 912\u001B[39m \u001B[33;03mcolumns : Index\u001B[39;00m\n\u001B[32m 913\u001B[39m \u001B[33;03m\"\"\"\u001B[39;00m\n\u001B[32m 914\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m columns \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m915\u001B[39m gen = (\u001B[38;5;28mlist\u001B[39m(x.keys()) \u001B[38;5;28;01mfor\u001B[39;00m x \u001B[38;5;129;01min\u001B[39;00m data)\n\u001B[32m 916\u001B[39m sort = \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28many\u001B[39m(\u001B[38;5;28misinstance\u001B[39m(d, \u001B[38;5;28mdict\u001B[39m) \u001B[38;5;28;01mfor\u001B[39;00m d \u001B[38;5;129;01min\u001B[39;00m data)\n\u001B[32m 917\u001B[39m pre_cols = lib.fast_unique_multiple_list_gen(gen, sort=sort)\n",
"\u001B[31mAttributeError\u001B[39m: 'NoneType' object has no attribute 'keys'"
]
}
],
"execution_count": 21
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-05T01:23:06.186557Z",
"start_time": "2025-12-05T01:23:05.740048Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"\n",
"cookies = {\n",
" 'JSESSIONID': '32C141F5A7A289491D34C50325D2D5A8',\n",
" 'td_cookie': '430509658',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'http://www.idsz.xin:7070/report_member_verifi_list?detailtype=4&key=totalBalance&datafrom=2025-01-01&datato=2025-12-04&sshopId=&type=1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'JSESSIONID=32C141F5A7A289491D34C50325D2D5A8; td_cookie=430509658',\n",
"}\n",
"\n",
"params = {\n",
" 'apiname': 'kpi_memberVerifiAndSurplusQuery',\n",
" 'detailtype': '4',\n",
" 'startTime': '2025-01-01',\n",
" 'endTime': '2025-12-04',\n",
" 'key': 'totalBalance',\n",
" 'sshopId': '',\n",
" 'timesCardId': '',\n",
" 'option': '',\n",
" 'page': '2',\n",
" 'pageSize': '50',\n",
"}\n",
"\n",
"response = requests.get('http://www.idsz.xin:7070/posapi_invoke', params=params, cookies=cookies, headers=headers,\n",
" verify=False)\n"
],
"id": "63713fc278b99d27",
"outputs": [],
"execution_count": 9
}
],
"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
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
import requests
import json
import time
import pandas as pd
from tqdm import tqdm
from datetime import datetime, timedelta
headers = {
"cookie":"__jdv=135409966|direct|-|none|-|1746495871709; flash=3_fmYwX89tb2teRGeQ4SfQL-pKDSmxglqPBgD7qIuZXmReygIf2eagag6hUJes8tPuEqjJP9l1l2qwsJs1XTuyRzJEICXIDkXx6lzysw2bis8pDhQYXP31QXbNPfa5XiJ4K1NeoIjs2jKwQARaXdqu8cg2xJrLj74CClfK1rz_kwOPy__dMtZGSq-S13Lc; pin=jd_gEFaqZlekSYM; unick=jd_28m3wapraiha3z; thor=9ADBD5C0241E6AA7507DB6E6ECED6657690C3A23BC73A7FDFF4C59CFB5DC19D09141D8C81ECE715B83D420382764AC40A51836A77298AA3BA872D825E72E86FB855E24FFB4A3D661C3FF1A5388EB47EECE339286A888E357FCE532D1A8DB26AC4195C7CDF94F989D5EF977BAA810BB8FE80486E89D9A34C4464471AE9CFCDB55975C9092DB060D12120A2A864B48F07D2EF235B6C34DC65D4D9A5CA6CF1AD0B5; light_key=AASBKE7rOxgWQziEhC_QY6ya8T1mkut_nO-Zdj9XQRxIxK-0ug40Vcgbs_HMus6W8doYmG03; JD_UUID=ed02c724-9458-4fef-b74e-ff66090efca9; yunxiupin=jd_gEFaqZlekSYM; UUID=b1715a1a-b8f8-4d6b-b29f-b13da6358062; SESSION_USER_NAME=%E4%BD%95%E4%BA%9A%E5%B3%B0; __jda=154799550.17464958717091671508260.1746495872.1746495872.1746499819.2; __jdc=154799550; __jdb=154799550.8.17464958717091671508260|2.1746499819",
"referer": "https://www.yunxiu.com/legend/account",
"sec-ch-ua": "\"Not(A:Brand\";v=\"99\", \"Microsoft Edge\";v=\"133\", \"Chromium\";v=\"133\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0",
"x-requested-with": "XMLHttpRequest"
}
all_data = []
number = 1746500626772 # 从车辆查询页面中 date参数获取
page = 1
max_retries = 5 # 最大重试次数
backoff_factor = 1 # 指数退避因子
current_date = datetime.now()
years_back = 10
end_date = current_date - timedelta(days=365 * years_back)
start_date = current_date
while start_date >= end_date:
try:
search_startTime = (start_date - timedelta(days=365)).strftime('%Y-%m-%d')
search_endTime = start_date.strftime('%Y-%m-%d')
print(f'search_startTime: {search_startTime}, search_endTime: {search_endTime}')
start_date -= timedelta(days=365) # 每次减去一年
exit_loop = False
for page in tqdm(range(1,1001)):
if exit_loop:
break
url = f"https://www.yunxiu.com/legend/archives/carinfo/locate/list?page={page}&size=12&search_startTime={search_startTime}&search_endTime={search_endTime}&_={number}"
attempt = 0
while attempt < max_retries:
try:
response = requests.get(url=url, headers=headers)
response.raise_for_status() # 如果响应状态码不是200,则抛出HTTPError异常
res = response.json().get("data", {}).get("content", [])
max_len = response.json().get("data", {}).get("totalPages", []) + 1
if page == max_len:
print(max_len)
exit_loop = True
break # 成功后退出重试循环
for item in res:
base_info = {k: v for k, v in item.items() if k != "licenseList"}
all_data.append(base_info)
break # 成功后退出重试循环
except requests.exceptions.RequestException as e:
print(f"{page}页请求失败: {e}")
if attempt < max_retries - 1:
sleep_time = backoff_factor * (2 ** attempt) # 计算等待时间
print(f"准备第{attempt + 1}次重试,等待{sleep_time}秒...")
time.sleep(sleep_time) # 等待一段时间后重试
else:
print(f"达到最大重试次数,跳过第{page}")
attempt += 1
number += 1
time.sleep(1)
except:
pass
df1 = pd.DataFrame(all_data)
df1.to_csv(r"D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\京东云修数据导出-13914209863 -车辆.csv")
@@ -0,0 +1,116 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-05-30T01:21:11.014130Z",
"start_time": "2025-05-30T01:01:24.119875Z"
}
},
"source": [
"import requests\n",
"import json\n",
"import time\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"\n",
"headers = {\n",
" \"Cookie\": \"__jdv=195278372%7Cdirect%7C-%7Cnone%7C-%7C1748480028960; mba_muid=1748480028960904285855; QRCodeKey=AAEAIN1BeBof-i4Zw8hvr-aG7CQu5u87gNXaRTDWEIyObJwJ; wlfstk_smdl=0zlr8a4uh5xi9n7wneoe7f1dtg3gmf4m; flash=3_Ph0N57CFsjJX7qJrf3jFhR2KtGaskdDyz0uaOe7M5cv8HXomGD7XAONhQEW4AdogODQVOMcvo7cAhnCtVRgeA_KEbDojTjBLROXbXXsH4dVDIUml_To2aRXuy7ifznU4E7gFgs6ztENk6VvYDzHM4XM4tzN8JA6ZinxiQEuhb7shI3tgFrbSG3LyTAyh3c1PHbU7; pin=%E5%85%BB%E8%BD%A6%E9%A9%BF%E6%A0%88%E4%B8%87%E6%B1%9F%E5%BA%97; unick=3x31uabda90cvn; thor=5EE400E7603F4FFFA56C15D1CDCE1ED2D696342F9B7D93B6828A585300D929E228AC00481EB0071D930EDA11CE005878BA99AE6501BFB4FCD664ED18C983B851317700EABE9412AAD1B2EFDBEE79D68BA7935E2CFA41531DDA2495DF925EEB38DE0E6D565E0AEA561263D27E127BA1C5A5A265A54FF2134462E28C15625847DAEA9838BA7CC226743C3AF780F4B4B1BD; light_key=AASBKE7rOxgWQziEhC_QY6yatak8Gj94PuPDJNKicqqnLhtyKqgNkVJhNXp4h31u--XoD8uMz5ZWORXUv1A4IKSjEqNTig; JD_UUID=d86ad331-9452-4965-81c4-871c9f622c8b; yunxiupin=%E5%85%BB%E8%BD%A6%E9%A9%BF%E6%A0%88%E4%B8%87%E6%B1%9F%E5%BA%97; bmall_id=8C9AFA76560E12B6116B47CE33B5ADF63E6941F825D9D52F317A543390F95D20700ADD2EE1D0F1C4F46929C1CA9A55D64D024C865A5C48C5E46BAEDB85601A47B4EFD44CB97863068AB4C1C1C9C0E633705B049FDACD382DDB3EA269F0E2D8DA63F3B5C6443C3B2DB12D9130CF7E5685; UUID=3b5708c5-aae1-4b91-83bd-606bb5a4c08d; SESSION_USER_NAME=%E7%8E%8B%E6%AD%A6%E6%96%8C; mba_sid=17485072577312005509178.0; 3AB9D23F7A4B3C9B=U3G6MJASLF6FOBCVPW5GOBPXFAUBK6VWDNALTH6W6EYUEBTPGQXLGP6A4P5CTRP5C6TQMFZLHYTECKB72KSKAPDORM; __jda=241039512.1748480028960904285855.1748480028.1748489963.1748495804.3; __jdc=241039512; __jdb=241039512.135.1748480028960904285855|3.1748495804\",\n",
" \"Referer\": \"https://jch1.yunxiu.com/legend/account?refer=float-menu\",\n",
" \"Sec-Ch-Ua\": '\"Not=A?Brand\";v=\"99\", \"Chromium\";v=\"118\"',\n",
" \"Sec-Ch-Ua-Mobile\": \"?0\",\n",
" \"Sec-Ch-Ua-Platform\": '\"Windows\"',\n",
" \"Sec-Fetch-Dest\": \"empty\",\n",
" \"Sec-Fetch-Mode\": \"cors\",\n",
" \"Sec-Fetch-Site\": \"same-origin\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.1.2 Safari/537.36 JiSu/118.0.1.2\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
"}\n",
"\n",
"all_data = []\n",
"number = 1748507284349\n",
"page = 1\n",
"max_retries = 5 # 最大重试次数\n",
"backoff_factor = 1 # 指数退避因子\n",
"# sort = \"sortByCardNumberType,ASC\"\n",
"# sort = \"sortByCardNumberType,DESC\"\n",
"# sort = \"sortByTotalBalanceType,ASC\"\n",
"sort = \"sortByTotalBalanceType,DESC\"\n",
"for page in tqdm(range(1,1001)):\n",
" url = f\"https://jch1.yunxiu.com/legend/account/search?page={page}&sort={sort}&_={number}\" # 注意url\n",
" data = f'page={page}&_={number}'\n",
"\n",
" attempt = 0\n",
" while attempt < max_retries:\n",
" try:\n",
" response = requests.get(url=url, headers=headers, data=data)\n",
" response.raise_for_status()\n",
" # print(response.json())\n",
" # break# 如果响应状态码不是200,则抛出HTTPError异常\n",
" res = response.json().get(\"data\", {}).get(\"content\", [])\n",
"\n",
" for item in res:\n",
" base_info = {k: v for k, v in item.items() if k != \"licenseList\"}\n",
" if \"licenseList\" in item and isinstance(item[\"licenseList\"], list):\n",
" for new_item in item[\"licenseList\"]:\n",
" row = base_info.copy()\n",
" row.update({\"car\": new_item})\n",
" all_data.append(row)\n",
" else:\n",
" # 如果没有licenseList或者它不是列表,则直接添加基本信息\n",
" all_data.append(base_info)\n",
"\n",
" break # 成功后退出重试循环\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"第{page}页请求失败: {e}\")\n",
" if attempt < max_retries - 1:\n",
" sleep_time = backoff_factor * (2 ** attempt) # 计算等待时间\n",
" print(f\"准备第{attempt + 1}次重试,等待{sleep_time}秒...\")\n",
" time.sleep(sleep_time) # 等待一段时间后重试\n",
" else:\n",
" print(f\"达到最大重试次数,跳过第{page}页\")\n",
" attempt += 1\n",
"\n",
" number += 1\n",
" time.sleep(1)\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(fr\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-养车驿栈万江店{sort}.xlsx\")\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 1000/1000 [19:45<00:00, 1.19s/it]\n"
]
}
],
"execution_count": 4
}
],
"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
}
@@ -0,0 +1,848 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "## 工单子表单",
"id": "88666286230ca491"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-05-23T16:17:14.754376Z",
"start_time": "2025-05-23T11:40:55.999863Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import json\n",
"import time\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"from datetime import datetime, timedelta\n",
"from bs4 import BeautifulSoup\n",
"\n",
"headers = {\n",
" \"cookie\": '__jdv=154799550|direct|-|none|-|1747659054237; flash=3_BN5FlBXqwDExD0Hqb3B70F9P_8Auw1KoNHmmWpbTyc_Zf4ughqhQAf3Dn_SYPn5R1Y6WZAd537CdRMmeauNNAqGU8ZwRu5c78bo-JimpRh71cvcmU2N9aKNNe7-ZXmPzhlMsJQhul_B5V3Y1L1TK42h8C0JKQW3xo4Cmtf20_WfGfvlVIXvuG8FnwxnR; pin=jd_BtxRnLkqczoE; unick=%E7%88%B1%E5%B8%AE%E8%BD%A6%E6%9C%8D; thor=F1C2CE45C3BB0D6AFAD21E4048588D13AA86F90A17A75FB8C125D8BBEBCEA71C7F0A7FCB3C3B6F5CDA534E1EA85BF2093B2A93EEE733A7536F7B9CBB50AE8FDCCBED1C41AF1F7F1EC0E525A306CDF7B50EDFC0972CC51ECA2ADCC74EE79CF0FD5BA3EB3798699E847C3D51F381E0F386C7394AE98B1F408C1454AB21FBF87C9E55E01BBD0EB64221F817191FA238708A35E710FCD7238DC9D7A574F3CF85919E; light_key=AASBKE7rOxgWQziEhC_QY6yabH8n9ROlxsU0CDGt7G7DsmfOcYCIBCjtBcp8f2n2enKriWRO; JD_UUID=7254175f-6a89-4144-ba95-823dd36d0fff; yunxiupin=jd_BtxRnLkqczoE; UUID=1f7f9980-72d3-49b9-85bc-ae8b99f559e0; SESSION_USER_NAME=%E6%AC%A7%E9%98%B3%E8%BF%9B%E9%A3%9E; __jda=154799550.17476590542361552970576.1747659054.1747876397.1748000112.4; __jdc=154799550; __jdb=154799550.4.17476590542361552970576|4.1748000112',\n",
" \"referer\": \"https://www.yunxiu.com/legend/account\",\n",
" \"sec-ch-ua\": \"\\\"Not(A:Brand\\\";v=\\\"99\\\", \\\"Microsoft Edge\\\";v=\\\"133\\\", \\\"Chromium\\\";v=\\\"133\\\"\",\n",
" \"sec-ch-ua-mobile\": \"?0\",\n",
" \"sec-ch-ua-platform\": \"\\\"Windows\\\"\",\n",
" \"sec-fetch-dest\": \"empty\",\n",
" \"sec-fetch-mode\": \"cors\",\n",
" \"sec-fetch-site\": \"same-origin\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0\",\n",
" \"x-requested-with\": \"XMLHttpRequest\"\n",
"}\n",
"\n",
"all_data = []\n",
"all_service_data = []\n",
"all_parts_data = []\n",
"all_base_ddata = []\n",
"\n",
"number = 1743152268544\n",
"page = 1\n",
"max_retries = 5 # 最大重试次数\n",
"backoff_factor = 10 # 指数退避因子\n",
"\n",
"current_date = datetime.now()\n",
"years_back = 20\n",
"\n",
"end_date = current_date - timedelta(days=365 * years_back)\n",
"start_date = current_date\n",
"\n",
"while start_date >= end_date:\n",
" try:\n",
" search_startTime = (start_date - timedelta(days=365)).strftime('%Y-%m-%d')\n",
" search_endTime = start_date.strftime('%Y-%m-%d')\n",
" print(f'查询时间范围: {search_startTime} 至 {search_endTime}')\n",
"\n",
" start_date -= timedelta(days=365)\n",
" should_break = False\n",
"\n",
" for page in tqdm(range(1, 1001)):\n",
" if should_break: # 检查是否需要跳出\n",
" break\n",
" \n",
" url = f\"https://www.yunxiu.com/legend/shop/order/order-list/list?page={page}&size=12&search_startTime={search_startTime}&search_endTime={search_endTime}&_={number}\"\n",
"\n",
" for attempt in range(max_retries):\n",
" try:\n",
" response = requests.get(url=url, headers=headers)\n",
" response.raise_for_status()\n",
"\n",
" data = response.json().get(\"data\", {})\n",
" res = data.get(\"content\", [])\n",
" total_pages = data.get(\"totalPages\", 1)\n",
"\n",
" if page >= total_pages:\n",
" should_break = True\n",
" break\n",
"\n",
" for item in res:\n",
" if not isinstance(item, dict):\n",
" print(f\"跳过非字典项: {item}\")\n",
" continue\n",
"\n",
" base_info = {k: str(v) for k, v in item.items() if k != \"licenseList\"}\n",
" all_data.append(base_info)\n",
" order_id = item.get(\"id\")\n",
" # order_id = 66752497\n",
"\n",
" if not order_id:\n",
" print(\"订单ID缺失,跳过处理\")\n",
" continue\n",
"\n",
" try:\n",
" # 获取订单详情\n",
" detail_url = f\"https://www.yunxiu.com/legend/shop/order/detail?orderId={order_id}&refer=order-list\"\n",
" detail_resp = requests.get(detail_url, headers=headers)\n",
" detail_soup = BeautifulSoup(detail_resp.text, 'html.parser')\n",
"\n",
" # 检查子单\n",
" sub_order_link = detail_soup.find('a', class_='new-order')\n",
" if sub_order_link and \"查看子单\" in sub_order_link.text:\n",
" # print(\"存在子单\")\n",
" base_info[\"子单\"] = \"存在\"\n",
"\n",
" # 获取子单内容\n",
" sub_order_url = \"https://www.yunxiu.com\" + sub_order_link['href']\n",
" sub_resp = requests.get(sub_order_url, headers=headers)\n",
" sub_soup = BeautifulSoup(sub_resp.text, 'html.parser')\n",
"\n",
" # 提取服务项目\n",
" tables = sub_soup.find_all('table', class_='yqx-table')\n",
" if tables:\n",
" service_table = tables[0]\n",
" # 修正选择器:使用实际的tr class\n",
" service_rows = service_table.select('tr.service-datatr')\n",
"\n",
" service_data = []\n",
" # 调整header与实际列数匹配\n",
" service_headers = [\"服务名称\", \"服务类别\", \"工时费\", \"工时\", \"金额\", \"优惠\",\n",
" \"服务备注\"]\n",
"\n",
" for row in service_rows:\n",
" # 从input标签提取数据\n",
" service_item = {\n",
" \"服务名称\": row.find('input', {'name': 'serviceName'}).get('value', ''),\n",
" \"服务类别\": row.find('input', {'name': 'serviceCatName'}).get('value', ''),\n",
" \"工时费\": row.find('input', {'name': 'servicePrice'}).get('value', ''),\n",
" \"工时\": row.find('input', {'name': 'serviceHour'}).get('value', ''),\n",
" \"金额\": row.find('input', {'name': 'serviceAmount'}).get('value', ''),\n",
" \"优惠\": row.find('input', {'name': 'discount'}).get('value', ''),\n",
" \"服务备注\": row.find('input', {'name': 'serviceNote'}).get('value', ''),\n",
" \"id\": order_id\n",
" }\n",
" service_data.append(service_item)\n",
"\n",
" all_service_data.extend(service_data)\n",
"\n",
" # tables = sub_soup.find_all('table', class_='yqx-table')\n",
" # service_table = tables[0]\n",
" # service_rows = service_table.select('tr.form_item')\n",
" # # print(tables[0])\n",
" # print(service_rows)\n",
" # service_data = []\n",
" # service_headers = [\"服务名称\", \"服务类别\", \"工时费\", \"工时\", \"金额\", \"优惠\", \"维修工\", \"服务备注\"]\n",
" #\n",
" # for row in service_rows:\n",
" # print(1)\n",
" # cells = row.find_all('td')\n",
" # if len(cells) == len(service_headers):\n",
" # service_item = {service_headers[i]: cells[i].get_text(strip=True) for i in range(len(service_headers))}\n",
" # service_item[\"id\"] = order_id\n",
" # service_data.append(service_item)\n",
" #\n",
" # all_service_data.extend(service_data)\n",
"\n",
" # 提取配件项目\n",
" parts_table = tables[1]\n",
" parts_rows = parts_table.select('tr.goods-datatr')\n",
" parts_data = []\n",
" parts_headers = [\"零件号\", \"配件名称\", \"售价\", \"数量\", \"单位\", \"金额\", \"优惠\", \"库存\",\n",
" \"销售员\", \"配件备注\"]\n",
"\n",
" for row in parts_rows:\n",
" parts_item = {\n",
" \"零件号\": row.find('input', {'name': 'goodsFormat'}).get('value', ''),\n",
" \"配件名称\": row.find('input', {'name': 'goodsName'}).get('value', ''),\n",
" \"售价\": row.find('input', {'name': 'goodsPrice'}).get('value', ''),\n",
" \"数量\": row.find('input', {'name': 'goodsNumber'}).get('value', ''),\n",
" \"单位\": row.find('input', {'name': 'measureUnit'}).get('value', ''),\n",
" \"金额\": row.find('input', {'name': 'goodsAmount'}).get('value', ''),\n",
" \"优惠\": row.find('input', {'name': 'discount'}).get('value', ''),\n",
" \"库存\": row.find('input', {'name': 'inventoryPrice'}).get('value', ''),\n",
" \"销售员\": row.find('input', {'name': 'saleId'}).get('value', ''),\n",
" \"配件备注\": row.find('input', {'name': 'goodsNote'}).get('value', ''),\n",
" \"id\": order_id\n",
" }\n",
" parts_data.append(parts_item)\n",
"\n",
" all_parts_data.extend(parts_data)\n",
"\n",
" # parts_table = tables[1]\n",
" # parts_rows = parts_table.select('tr.goods-datatr')\n",
" # parts_data = []\n",
" # parts_headers = [\"零件号\", \"配件名称\", \"售价\", \"数量\", \"金额\", \"优惠\", \"库存\", \"销售员\", \"配件备注\"]\n",
" # \n",
" # for row in parts_rows:\n",
" # cells = row.find_all('td')\n",
" # if len(cells) == len(parts_headers):\n",
" # parts_item = {parts_headers[i]: cells[i].get_text(strip=True) for i in range(len(parts_headers))}\n",
" # parts_item[\"id\"] = order_id\n",
" # parts_data.append(parts_item)\n",
" # \n",
" # all_parts_data.extend(parts_data)\n",
"\n",
" # 提取基本信息\n",
" base_info1 = {}\n",
" inputs = sub_soup.find_all('input')\n",
" for input_tag in inputs:\n",
" name = input_tag.get('name')\n",
" value = input_tag.get('value', '').strip()\n",
" if name:\n",
" key = name.replace('orderInfo.', '')\n",
" base_info1[key] = value\n",
"\n",
" base_info1[\"id\"] = order_id\n",
" all_base_ddata.append(base_info1)\n",
"\n",
" else:\n",
" base_info[\"子单\"] = \"不存在\"\n",
"\n",
"\n",
" except Exception as e:\n",
" print(f\"处理订单{order_id}时出错: {str(e)}\")\n",
" continue\n",
" page += 1\n",
"\n",
" break # 请求成功,跳出重试循环\n",
"\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"第{page}页请求失败(尝试{attempt + 1}): {str(e)}\")\n",
" if attempt < max_retries - 1:\n",
" time.sleep(backoff_factor * (2 ** attempt))\n",
" else:\n",
" print(f\"达到最大重试次数,跳过第{page}页\")\n",
" break\n",
"\n",
" number += 1\n",
" time.sleep(1)\n",
"\n",
" except Exception as e:\n",
" print(f\"处理日期范围时出错: {str(e)}\")\n",
" continue\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df2 = pd.DataFrame(all_base_ddata)\n",
"df3 = pd.DataFrame(all_service_data)\n",
"df4 = pd.DataFrame(all_parts_data)\n",
"df1.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-18186751313 -工单.csv\")\n",
"df2.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-18186751313 -工单子单基本信息.csv\")\n",
"df3.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-18186751313 -工单子单服务项目.csv\")\n",
"df4.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-18186751313 -工单子单配件项目.csv\")\n"
],
"id": "8d6f11a2b11f8be4",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2024-05-23 至 2025-05-23\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 15%|█▍ | 148/1000 [14:31<1:24:49, 5.97s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单60248836时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=60248836&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F22A14DE50>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 16%|█▌ | 158/1000 [15:54<1:31:45, 6.54s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"第159页请求失败(尝试1): HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/order-list/list?page=159&size=12&search_startTime=2024-05-23&search_endTime=2025-05-23&_=1743152268702 (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F22C4FDE50>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 16%|█▌ | 159/1000 [16:31<3:42:44, 15.89s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单59683769时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=59683769&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F22AA403E0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 27%|██▋ | 269/1000 [27:45<1:13:13, 6.01s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单55024316时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=55024316&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F22CD4DA60>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 47%|████▋ | 466/1000 [47:50<54:49, 6.16s/it] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2023-05-24 至 2024-05-23\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 30%|██▉ | 299/1000 [29:29<1:09:17, 5.93s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单39527167时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=39527167&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F231231520>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 36%|███▌ | 358/1000 [35:36<1:01:30, 5.75s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单38398035时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=38398035&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F231606D80>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 37%|███▋ | 370/1000 [37:11<1:06:33, 6.34s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单38121509时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=38121509&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F2317D58E0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 37%|███▋ | 374/1000 [37:56<1:27:39, 8.40s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单38000056时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=38000056&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F231817F50>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 49%|████▉ | 492/1000 [49:50<50:05, 5.92s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单35733059时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=35733059&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F232FB2690>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 57%|█████▋ | 570/1000 [57:29<43:22, 6.05s/it] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2022-05-24 至 2023-05-24\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 46%|████▌ | 455/1000 [42:13<51:13, 5.64s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单28770640时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=28770640&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F2373C4260>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 52%|█████▏ | 517/1000 [48:13<43:45, 5.44s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单28203564时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=28203564&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F237AD5790>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 53%|█████▎ | 530/1000 [49:47<43:38, 5.57s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单28025893时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=28025893&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F2378F6BA0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 54%|█████▎ | 536/1000 [50:41<51:26, 6.65s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单27977874时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=27977874&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F237CDBDA0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 66%|██████▌ | 658/1000 [1:02:26<31:20, 5.50s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单26668270时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=26668270&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F22AB0D6D0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 69%|██████▉ | 691/1000 [1:05:48<29:25, 5.71s/it] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2021-05-24 至 2022-05-24\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 56%|█████▌ | 555/1000 [51:49<42:13, 5.69s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单20781414时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=20781414&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F23CAFC200>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 57%|█████▋ | 568/1000 [53:22<40:50, 5.67s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单20614104时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=20614104&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F23CBAE900>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 57%|█████▋ | 572/1000 [54:06<54:52, 7.69s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"处理订单20573201时出错: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/shop/order/detail?orderId=20573201&refer=order-list (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001F23C8D3680>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 68%|██████▊ | 679/1000 [1:04:27<30:28, 5.70s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2020-05-24 至 2021-05-24\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 44%|████▎ | 435/1000 [40:20<52:23, 5.56s/it] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2019-05-25 至 2020-05-24\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:47, 1.19s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2018-05-25 至 2019-05-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:09, 1.15s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2017-05-25 至 2018-05-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:23, 1.17s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2016-05-25 至 2017-05-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<18:42, 1.12s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2015-05-26 至 2016-05-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<18:46, 1.13s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2014-05-26 至 2015-05-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:06, 1.15s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2013-05-26 至 2014-05-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:12, 1.15s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2012-05-26 至 2013-05-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:14, 1.16s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2011-05-27 至 2012-05-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:21, 1.16s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2010-05-27 至 2011-05-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:56, 1.20s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2009-05-27 至 2010-05-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<18:50, 1.13s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2008-05-27 至 2009-05-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:23, 1.16s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2007-05-28 至 2008-05-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:11, 1.15s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2006-05-28 至 2007-05-28\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:21, 1.16s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2005-05-28 至 2006-05-28\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:16, 1.16s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"查询时间范围: 2004-05-28 至 2005-05-28\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:27, 1.17s/it]\n"
]
}
],
"execution_count": 1
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 处理附表(废弃)",
"id": "758592b039b5f41a"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-05-14T02:51:30.881079Z",
"start_time": "2025-05-14T02:51:30.866080Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_data)\n",
"df2 = pd.DataFrame(all_base_ddata)\n",
"df3 = pd.DataFrame(all_service_data)\n",
"df4 = pd.DataFrame(all_parts_data)\n",
"df1.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13986383030 -工单.csv\")\n",
"df2.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13986383030 -工单子单基本信息.csv\")\n",
"df3.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13986383030 -工单子单服务项目.csv\")\n",
"df4.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13986383030 -工单子单配件项目.csv\")\n"
],
"id": "d9dc38b82db31903",
"outputs": [],
"execution_count": 50
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 附表子单总额计算",
"id": "19be0dac78f1a3e"
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "",
"id": "8a1cc6d877124e86"
}
],
"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
}
@@ -0,0 +1,730 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "客户信息导出",
"id": "a10af68ca00de50a"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-28T06:27:39.309261100Z",
"start_time": "2026-01-28T06:27:31.811575700Z"
}
},
"source": [
"import requests\n",
"import json\n",
"import time\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"\n",
"import requests\n",
"\n",
"cookies = {\n",
" '__jdv': '241039512|direct|-|none|-|1769580195196',\n",
" 'mba_muid': '17695801951961847696270',\n",
" 'mba_sid': '1769580378119515622883.0',\n",
" 'QRCodeKey': 'AAEAIGlfy0S9IVwOVAfE3NXgBILRP8R2qpHAikvosD3cyvar',\n",
" 'wlfstk_smdl': 'drd3j1dlvwjz7o96orgqco4keigo6ipj',\n",
" 'pin': '%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8',\n",
" 'unick': 's2v2tk1w4w8eb9',\n",
" 'yunxiupin': '%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8',\n",
" 'bmall_id': '499220987560FEF36C9FB4C092693FFC98D6D74FB85924A6DC3E030ADD3477238C68C7B8E10ED66898B6EBEB4562ED893FBF19E4CD0030FECE3218317F39A2F5FC9FF25A11561368D02C95564D247AC2A151A086B1074D5EE362C7CB1BA34EC79B50B3252535972791A084C5D010158EF4B5C1EADC2808FFF3EB992EF34A9D14',\n",
" 'UUID': '7c069d6f-2724-4008-b308-09f436240035',\n",
" 'SESSION_USER_NAME': '%E6%9F%A5%E4%BA%AE',\n",
" 'flash': '3_bBBCg0-OBy68xAANqduCSaKWV_6DKpxvObl29hEy-5Il0taBIimdGJfimCMZHKH-CUR09cTQwjAyGRKP9z9jHkm9UrWP2nTOg38vb68OEMqiiwdZRg1AqxMtUmDSWBQdVhGg5qQSbO5p1eyeBPlu7Htsgtf_TMouEaoqlijt7PqsLs4yBBM8Alki49TorJwr9E6mcmF96X-2O-E6',\n",
" 'thor': '51C732866E8A756A4ED8B4738163D4C059D9063322E05745BA0D815A80FEBE3D550B447E8BB3C99207EE02D994108998DE070A571A758BED83B7535090CB6C2DF853F8994511D1708463D0C16274A620668FCE84D3B708BA56633C46432FABC8B4DA7688141595BA1C45C419160C151A638E6A118D22DA606EE420BE383B9D53FB842C2C90A6454E4CFED4E3A63A8ED5',\n",
" 'light_key': 'AASBKE7rOxgWQziEhC_QY6yaLIBQgOT1dxVmsPRjRIB9ndtR9Aslstb1iQBYYZyMvLEJNsNDL52e7UA1dFCeHNIVWAseFg',\n",
" 'JD_UUID': 'b9441bd1-a782-4d34-b2af-47b6f1e89bc6',\n",
" '3AB9D23F7A4B3CSS': 'jdd03XH7UJPD6AWWSVFN6XP6T23OSWBA235SAMFFYPEW3JTTJRTT4TQTZLIAKR47DQ26GKGT266NM6WGBCEKT7R6RL2K34IAAAAM4ANDUGQYAAAAACSHCLFATJTAJKMX',\n",
" '_gia_d': '1',\n",
" 'sdtoken': 'AAbEsBpEIOVjqTAKCQtvQu17FLUpUb4CM0QtRGo9_y1DbK8h44YEOS2UiemwosOOgSgqPwHoDiJho0E69o2zgRTqSGouwgzZW2ByDMgJdY2S_IVvi4uyNneMFom6TCFDsAUG_C0BzQYsVWWU',\n",
" '__jda': '200816309.17695801951961847696270.1769580195.1769580195.1769580195.1',\n",
" '__jdc': '200816309',\n",
" '3AB9D23F7A4B3C9B': 'KPOAZ5CBYQXJ25JOSSXGBQDYYOVGX7EMTPWFWDGVZ3KWTLNZU45HHPQ4MXYSIO37IV72PLAND3VYJH2ZOLD6LFWBDA',\n",
" '__jdb': '200816309.53.17695801951961847696270|1.1769580195',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" # 'content-length': '0',\n",
" 'origin': 'https://jch.yunxiu.com',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://jch.yunxiu.com/',\n",
" 'sec-ch-ua': '\"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"144\", \"Microsoft Edge\";v=\"144\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\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/144.0.0.0 Safari/537.36 Edg/144.0.0.0',\n",
" 'x-requested-with': 'XMLHttpRequest',\n",
" # 'cookie': '__jdv=241039512|direct|-|none|-|1769580195196; mba_muid=17695801951961847696270; mba_sid=1769580378119515622883.0; QRCodeKey=AAEAIGlfy0S9IVwOVAfE3NXgBILRP8R2qpHAikvosD3cyvar; wlfstk_smdl=drd3j1dlvwjz7o96orgqco4keigo6ipj; pin=%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; unick=s2v2tk1w4w8eb9; yunxiupin=%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; bmall_id=499220987560FEF36C9FB4C092693FFC98D6D74FB85924A6DC3E030ADD3477238C68C7B8E10ED66898B6EBEB4562ED893FBF19E4CD0030FECE3218317F39A2F5FC9FF25A11561368D02C95564D247AC2A151A086B1074D5EE362C7CB1BA34EC79B50B3252535972791A084C5D010158EF4B5C1EADC2808FFF3EB992EF34A9D14; UUID=7c069d6f-2724-4008-b308-09f436240035; SESSION_USER_NAME=%E6%9F%A5%E4%BA%AE; flash=3_bBBCg0-OBy68xAANqduCSaKWV_6DKpxvObl29hEy-5Il0taBIimdGJfimCMZHKH-CUR09cTQwjAyGRKP9z9jHkm9UrWP2nTOg38vb68OEMqiiwdZRg1AqxMtUmDSWBQdVhGg5qQSbO5p1eyeBPlu7Htsgtf_TMouEaoqlijt7PqsLs4yBBM8Alki49TorJwr9E6mcmF96X-2O-E6; thor=51C732866E8A756A4ED8B4738163D4C059D9063322E05745BA0D815A80FEBE3D550B447E8BB3C99207EE02D994108998DE070A571A758BED83B7535090CB6C2DF853F8994511D1708463D0C16274A620668FCE84D3B708BA56633C46432FABC8B4DA7688141595BA1C45C419160C151A638E6A118D22DA606EE420BE383B9D53FB842C2C90A6454E4CFED4E3A63A8ED5; light_key=AASBKE7rOxgWQziEhC_QY6yaLIBQgOT1dxVmsPRjRIB9ndtR9Aslstb1iQBYYZyMvLEJNsNDL52e7UA1dFCeHNIVWAseFg; JD_UUID=b9441bd1-a782-4d34-b2af-47b6f1e89bc6; 3AB9D23F7A4B3CSS=jdd03XH7UJPD6AWWSVFN6XP6T23OSWBA235SAMFFYPEW3JTTJRTT4TQTZLIAKR47DQ26GKGT266NM6WGBCEKT7R6RL2K34IAAAAM4ANDUGQYAAAAACSHCLFATJTAJKMX; _gia_d=1; sdtoken=AAbEsBpEIOVjqTAKCQtvQu17FLUpUb4CM0QtRGo9_y1DbK8h44YEOS2UiemwosOOgSgqPwHoDiJho0E69o2zgRTqSGouwgzZW2ByDMgJdY2S_IVvi4uyNneMFom6TCFDsAUG_C0BzQYsVWWU; __jda=200816309.17695801951961847696270.1769580195.1769580195.1769580195.1; __jdc=200816309; 3AB9D23F7A4B3C9B=KPOAZ5CBYQXJ25JOSSXGBQDYYOVGX7EMTPWFWDGVZ3KWTLNZU45HHPQ4MXYSIO37IV72PLAND3VYJH2ZOLD6LFWBDA; __jdb=200816309.53.17695801951961847696270|1.1769580195',\n",
"}\n",
"\n",
"\n",
"\n",
"all_data = []\n",
"number = 1748507284349\n",
"page = 1\n",
"max_retries = 5 # 最大重试次数\n",
"backoff_factor = 1 # 指数退避因子\n",
"\n",
"for page in tqdm(range(1,2)):\n",
" url = f\"https://jch1.yunxiu.com/legend/account/search?page={page}&_={number}\" # 注意url\n",
" data = f'page={page}&_={number}'\n",
"\n",
" attempt = 0\n",
" while attempt < max_retries:\n",
" try:\n",
" response = requests.get(url=url, headers=headers, data=data)\n",
" response.raise_for_status() \n",
" # print(response.json())\n",
" # break# 如果响应状态码不是200,则抛出HTTPError异常\n",
" res = response.json().get(\"data\", {}).get(\"content\", [])\n",
" \n",
" for item in res:\n",
" base_info = {k: v for k, v in item.items() if k != \"licenseList\"}\n",
" if \"licenseList\" in item and isinstance(item[\"licenseList\"], list):\n",
" for new_item in item[\"licenseList\"]:\n",
" row = base_info.copy()\n",
" row.update({\"car\": new_item})\n",
" all_data.append(row)\n",
" else:\n",
" # 如果没有licenseList或者它不是列表,则直接添加基本信息\n",
" all_data.append(base_info)\n",
" \n",
" break # 成功后退出重试循环\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"第{page}页请求失败: {e}\")\n",
" if attempt < max_retries - 1:\n",
" sleep_time = backoff_factor * (2 ** attempt) # 计算等待时间\n",
" print(f\"准备第{attempt + 1}次重试,等待{sleep_time}秒...\")\n",
" time.sleep(sleep_time) # 等待一段时间后重试\n",
" else:\n",
" print(f\"达到最大重试次数,跳过第{page}页\")\n",
" attempt += 1\n",
"\n",
" number += 1\n",
" time.sleep(1)\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\京东云修数据导出-养车驿栈万江店.xlsx\")\n"
],
"outputs": [
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001B[31m---------------------------------------------------------------------------\u001B[39m",
"\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)",
"\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[1]\u001B[39m\u001B[32m, line 67\u001B[39m\n\u001B[32m 65\u001B[39m \u001B[38;5;28;01mwhile\u001B[39;00m attempt < max_retries:\n\u001B[32m 66\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m---> \u001B[39m\u001B[32m67\u001B[39m response = \u001B[43mrequests\u001B[49m\u001B[43m.\u001B[49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[43murl\u001B[49m\u001B[43m=\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m=\u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdata\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdata\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 68\u001B[39m response.raise_for_status() \n\u001B[32m 69\u001B[39m \u001B[38;5;66;03m# print(response.json())\u001B[39;00m\n\u001B[32m 70\u001B[39m \u001B[38;5;66;03m# break# 如果响应状态码不是200,则抛出HTTPError异常\u001B[39;00m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\api.py:73\u001B[39m, in \u001B[36mget\u001B[39m\u001B[34m(url, params, **kwargs)\u001B[39m\n\u001B[32m 62\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mget\u001B[39m(url, params=\u001B[38;5;28;01mNone\u001B[39;00m, **kwargs):\n\u001B[32m 63\u001B[39m \u001B[38;5;250m \u001B[39m\u001B[33mr\u001B[39m\u001B[33;03m\"\"\"Sends a GET request.\u001B[39;00m\n\u001B[32m 64\u001B[39m \n\u001B[32m 65\u001B[39m \u001B[33;03m :param url: URL for the new :class:`Request` object.\u001B[39;00m\n\u001B[32m (...)\u001B[39m\u001B[32m 70\u001B[39m \u001B[33;03m :rtype: requests.Response\u001B[39;00m\n\u001B[32m 71\u001B[39m \u001B[33;03m \"\"\"\u001B[39;00m\n\u001B[32m---> \u001B[39m\u001B[32m73\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\u001B[33;43m\"\u001B[39;49m\u001B[33;43mget\u001B[39;49m\u001B[33;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mparams\u001B[49m\u001B[43m=\u001B[49m\u001B[43mparams\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\api.py:59\u001B[39m, in \u001B[36mrequest\u001B[39m\u001B[34m(method, url, **kwargs)\u001B[39m\n\u001B[32m 55\u001B[39m \u001B[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001B[39;00m\n\u001B[32m 56\u001B[39m \u001B[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001B[39;00m\n\u001B[32m 57\u001B[39m \u001B[38;5;66;03m# cases, and look like a memory leak in others.\u001B[39;00m\n\u001B[32m 58\u001B[39m \u001B[38;5;28;01mwith\u001B[39;00m sessions.Session() \u001B[38;5;28;01mas\u001B[39;00m session:\n\u001B[32m---> \u001B[39m\u001B[32m59\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43msession\u001B[49m\u001B[43m.\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m=\u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m=\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\sessions.py:589\u001B[39m, in \u001B[36mSession.request\u001B[39m\u001B[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001B[39m\n\u001B[32m 584\u001B[39m send_kwargs = {\n\u001B[32m 585\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mtimeout\u001B[39m\u001B[33m\"\u001B[39m: timeout,\n\u001B[32m 586\u001B[39m \u001B[33m\"\u001B[39m\u001B[33mallow_redirects\u001B[39m\u001B[33m\"\u001B[39m: allow_redirects,\n\u001B[32m 587\u001B[39m }\n\u001B[32m 588\u001B[39m send_kwargs.update(settings)\n\u001B[32m--> \u001B[39m\u001B[32m589\u001B[39m resp = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43msend\u001B[49m\u001B[43m(\u001B[49m\u001B[43mprep\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43msend_kwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 591\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m resp\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\sessions.py:724\u001B[39m, in \u001B[36mSession.send\u001B[39m\u001B[34m(self, request, **kwargs)\u001B[39m\n\u001B[32m 721\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m allow_redirects:\n\u001B[32m 722\u001B[39m \u001B[38;5;66;03m# Redirect resolving generator.\u001B[39;00m\n\u001B[32m 723\u001B[39m gen = \u001B[38;5;28mself\u001B[39m.resolve_redirects(r, request, **kwargs)\n\u001B[32m--> \u001B[39m\u001B[32m724\u001B[39m history = \u001B[43m[\u001B[49m\u001B[43mresp\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mresp\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mgen\u001B[49m\u001B[43m]\u001B[49m\n\u001B[32m 725\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m 726\u001B[39m history = []\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\sessions.py:265\u001B[39m, in \u001B[36mSessionRedirectMixin.resolve_redirects\u001B[39m\u001B[34m(self, resp, req, stream, timeout, verify, cert, proxies, yield_requests, **adapter_kwargs)\u001B[39m\n\u001B[32m 263\u001B[39m \u001B[38;5;28;01myield\u001B[39;00m req\n\u001B[32m 264\u001B[39m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m265\u001B[39m resp = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43msend\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 266\u001B[39m \u001B[43m \u001B[49m\u001B[43mreq\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 267\u001B[39m \u001B[43m \u001B[49m\u001B[43mstream\u001B[49m\u001B[43m=\u001B[49m\u001B[43mstream\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 268\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 269\u001B[39m \u001B[43m \u001B[49m\u001B[43mverify\u001B[49m\u001B[43m=\u001B[49m\u001B[43mverify\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 270\u001B[39m \u001B[43m \u001B[49m\u001B[43mcert\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcert\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 271\u001B[39m \u001B[43m \u001B[49m\u001B[43mproxies\u001B[49m\u001B[43m=\u001B[49m\u001B[43mproxies\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 272\u001B[39m \u001B[43m \u001B[49m\u001B[43mallow_redirects\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 273\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43madapter_kwargs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 274\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 276\u001B[39m extract_cookies_to_jar(\u001B[38;5;28mself\u001B[39m.cookies, prepared_request, resp.raw)\n\u001B[32m 278\u001B[39m \u001B[38;5;66;03m# extract redirect url, if any, for the next loop\u001B[39;00m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\sessions.py:703\u001B[39m, in \u001B[36mSession.send\u001B[39m\u001B[34m(self, request, **kwargs)\u001B[39m\n\u001B[32m 700\u001B[39m start = preferred_clock()\n\u001B[32m 702\u001B[39m \u001B[38;5;66;03m# Send the request\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m703\u001B[39m r = \u001B[43madapter\u001B[49m\u001B[43m.\u001B[49m\u001B[43msend\u001B[49m\u001B[43m(\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 705\u001B[39m \u001B[38;5;66;03m# Total elapsed time of the request (approximately)\u001B[39;00m\n\u001B[32m 706\u001B[39m elapsed = preferred_clock() - start\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\requests\\adapters.py:644\u001B[39m, in \u001B[36mHTTPAdapter.send\u001B[39m\u001B[34m(self, request, stream, timeout, verify, cert, proxies)\u001B[39m\n\u001B[32m 641\u001B[39m timeout = TimeoutSauce(connect=timeout, read=timeout)\n\u001B[32m 643\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m644\u001B[39m resp = \u001B[43mconn\u001B[49m\u001B[43m.\u001B[49m\u001B[43murlopen\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 645\u001B[39m \u001B[43m \u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m.\u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 646\u001B[39m \u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m=\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 647\u001B[39m \u001B[43m \u001B[49m\u001B[43mbody\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m.\u001B[49m\u001B[43mbody\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 648\u001B[39m \u001B[43m \u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m=\u001B[49m\u001B[43mrequest\u001B[49m\u001B[43m.\u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 649\u001B[39m \u001B[43m \u001B[49m\u001B[43mredirect\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 650\u001B[39m \u001B[43m \u001B[49m\u001B[43massert_same_host\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 651\u001B[39m \u001B[43m \u001B[49m\u001B[43mpreload_content\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 652\u001B[39m \u001B[43m \u001B[49m\u001B[43mdecode_content\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[32m 653\u001B[39m \u001B[43m \u001B[49m\u001B[43mretries\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mmax_retries\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 654\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 655\u001B[39m \u001B[43m \u001B[49m\u001B[43mchunked\u001B[49m\u001B[43m=\u001B[49m\u001B[43mchunked\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 656\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 658\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m (ProtocolError, \u001B[38;5;167;01mOSError\u001B[39;00m) \u001B[38;5;28;01mas\u001B[39;00m err:\n\u001B[32m 659\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mConnectionError\u001B[39;00m(err, request=request)\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\connectionpool.py:787\u001B[39m, in \u001B[36mHTTPConnectionPool.urlopen\u001B[39m\u001B[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001B[39m\n\u001B[32m 784\u001B[39m response_conn = conn \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m release_conn \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[32m 786\u001B[39m \u001B[38;5;66;03m# Make the request on the HTTPConnection object\u001B[39;00m\n\u001B[32m--> \u001B[39m\u001B[32m787\u001B[39m response = \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_make_request\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 788\u001B[39m \u001B[43m \u001B[49m\u001B[43mconn\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 789\u001B[39m \u001B[43m \u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 790\u001B[39m \u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 791\u001B[39m \u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtimeout_obj\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 792\u001B[39m \u001B[43m \u001B[49m\u001B[43mbody\u001B[49m\u001B[43m=\u001B[49m\u001B[43mbody\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 793\u001B[39m \u001B[43m \u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m=\u001B[49m\u001B[43mheaders\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 794\u001B[39m \u001B[43m \u001B[49m\u001B[43mchunked\u001B[49m\u001B[43m=\u001B[49m\u001B[43mchunked\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 795\u001B[39m \u001B[43m \u001B[49m\u001B[43mretries\u001B[49m\u001B[43m=\u001B[49m\u001B[43mretries\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 796\u001B[39m \u001B[43m \u001B[49m\u001B[43mresponse_conn\u001B[49m\u001B[43m=\u001B[49m\u001B[43mresponse_conn\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 797\u001B[39m \u001B[43m \u001B[49m\u001B[43mpreload_content\u001B[49m\u001B[43m=\u001B[49m\u001B[43mpreload_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 798\u001B[39m \u001B[43m \u001B[49m\u001B[43mdecode_content\u001B[49m\u001B[43m=\u001B[49m\u001B[43mdecode_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 799\u001B[39m \u001B[43m \u001B[49m\u001B[43m*\u001B[49m\u001B[43m*\u001B[49m\u001B[43mresponse_kw\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 800\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 802\u001B[39m \u001B[38;5;66;03m# Everything went great!\u001B[39;00m\n\u001B[32m 803\u001B[39m clean_exit = \u001B[38;5;28;01mTrue\u001B[39;00m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\connectionpool.py:464\u001B[39m, in \u001B[36mHTTPConnectionPool._make_request\u001B[39m\u001B[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001B[39m\n\u001B[32m 461\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m 462\u001B[39m \u001B[38;5;66;03m# Trigger any extra validation we need to do.\u001B[39;00m\n\u001B[32m 463\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m464\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43m_validate_conn\u001B[49m\u001B[43m(\u001B[49m\u001B[43mconn\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 465\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m (SocketTimeout, BaseSSLError) \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m 466\u001B[39m \u001B[38;5;28mself\u001B[39m._raise_timeout(err=e, url=url, timeout_value=conn.timeout)\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\connectionpool.py:1093\u001B[39m, in \u001B[36mHTTPSConnectionPool._validate_conn\u001B[39m\u001B[34m(self, conn)\u001B[39m\n\u001B[32m 1091\u001B[39m \u001B[38;5;66;03m# Force connect early to allow us to validate the connection.\u001B[39;00m\n\u001B[32m 1092\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m conn.is_closed:\n\u001B[32m-> \u001B[39m\u001B[32m1093\u001B[39m \u001B[43mconn\u001B[49m\u001B[43m.\u001B[49m\u001B[43mconnect\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 1095\u001B[39m \u001B[38;5;66;03m# TODO revise this, see https://github.com/urllib3/urllib3/issues/2791\u001B[39;00m\n\u001B[32m 1096\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m conn.is_verified \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m conn.proxy_is_verified:\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\connection.py:796\u001B[39m, in \u001B[36mHTTPSConnection.connect\u001B[39m\u001B[34m(self)\u001B[39m\n\u001B[32m 793\u001B[39m \u001B[38;5;66;03m# Remove trailing '.' from fqdn hostnames to allow certificate validation\u001B[39;00m\n\u001B[32m 794\u001B[39m server_hostname_rm_dot = server_hostname.rstrip(\u001B[33m\"\u001B[39m\u001B[33m.\u001B[39m\u001B[33m\"\u001B[39m)\n\u001B[32m--> \u001B[39m\u001B[32m796\u001B[39m sock_and_verified = \u001B[43m_ssl_wrap_socket_and_match_hostname\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 797\u001B[39m \u001B[43m \u001B[49m\u001B[43msock\u001B[49m\u001B[43m=\u001B[49m\u001B[43msock\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 798\u001B[39m \u001B[43m \u001B[49m\u001B[43mcert_reqs\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mcert_reqs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 799\u001B[39m \u001B[43m \u001B[49m\u001B[43mssl_version\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mssl_version\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 800\u001B[39m \u001B[43m \u001B[49m\u001B[43mssl_minimum_version\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mssl_minimum_version\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 801\u001B[39m \u001B[43m \u001B[49m\u001B[43mssl_maximum_version\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mssl_maximum_version\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 802\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_certs\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mca_certs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 803\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_cert_dir\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mca_cert_dir\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 804\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_cert_data\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mca_cert_data\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 805\u001B[39m \u001B[43m \u001B[49m\u001B[43mcert_file\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mcert_file\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 806\u001B[39m \u001B[43m \u001B[49m\u001B[43mkey_file\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mkey_file\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 807\u001B[39m \u001B[43m \u001B[49m\u001B[43mkey_password\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mkey_password\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 808\u001B[39m \u001B[43m \u001B[49m\u001B[43mserver_hostname\u001B[49m\u001B[43m=\u001B[49m\u001B[43mserver_hostname_rm_dot\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 809\u001B[39m \u001B[43m \u001B[49m\u001B[43mssl_context\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43mssl_context\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 810\u001B[39m \u001B[43m \u001B[49m\u001B[43mtls_in_tls\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtls_in_tls\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 811\u001B[39m \u001B[43m \u001B[49m\u001B[43massert_hostname\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43massert_hostname\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 812\u001B[39m \u001B[43m \u001B[49m\u001B[43massert_fingerprint\u001B[49m\u001B[43m=\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m.\u001B[49m\u001B[43massert_fingerprint\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 813\u001B[39m \u001B[43m \u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 814\u001B[39m \u001B[38;5;28mself\u001B[39m.sock = sock_and_verified.socket\n\u001B[32m 816\u001B[39m \u001B[38;5;66;03m# If an error occurs during connection/handshake we may need to release\u001B[39;00m\n\u001B[32m 817\u001B[39m \u001B[38;5;66;03m# our lock so another connection can probe the origin.\u001B[39;00m\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\connection.py:975\u001B[39m, in \u001B[36m_ssl_wrap_socket_and_match_hostname\u001B[39m\u001B[34m(sock, cert_reqs, ssl_version, ssl_minimum_version, ssl_maximum_version, cert_file, key_file, key_password, ca_certs, ca_cert_dir, ca_cert_data, assert_hostname, assert_fingerprint, server_hostname, ssl_context, tls_in_tls)\u001B[39m\n\u001B[32m 972\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m is_ipaddress(normalized):\n\u001B[32m 973\u001B[39m server_hostname = normalized\n\u001B[32m--> \u001B[39m\u001B[32m975\u001B[39m ssl_sock = \u001B[43mssl_wrap_socket\u001B[49m\u001B[43m(\u001B[49m\n\u001B[32m 976\u001B[39m \u001B[43m \u001B[49m\u001B[43msock\u001B[49m\u001B[43m=\u001B[49m\u001B[43msock\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 977\u001B[39m \u001B[43m \u001B[49m\u001B[43mkeyfile\u001B[49m\u001B[43m=\u001B[49m\u001B[43mkey_file\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 978\u001B[39m \u001B[43m \u001B[49m\u001B[43mcertfile\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcert_file\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 979\u001B[39m \u001B[43m \u001B[49m\u001B[43mkey_password\u001B[49m\u001B[43m=\u001B[49m\u001B[43mkey_password\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 980\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_certs\u001B[49m\u001B[43m=\u001B[49m\u001B[43mca_certs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 981\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_cert_dir\u001B[49m\u001B[43m=\u001B[49m\u001B[43mca_cert_dir\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 982\u001B[39m \u001B[43m \u001B[49m\u001B[43mca_cert_data\u001B[49m\u001B[43m=\u001B[49m\u001B[43mca_cert_data\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 983\u001B[39m \u001B[43m \u001B[49m\u001B[43mserver_hostname\u001B[49m\u001B[43m=\u001B[49m\u001B[43mserver_hostname\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 984\u001B[39m \u001B[43m \u001B[49m\u001B[43mssl_context\u001B[49m\u001B[43m=\u001B[49m\u001B[43mcontext\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 985\u001B[39m \u001B[43m \u001B[49m\u001B[43mtls_in_tls\u001B[49m\u001B[43m=\u001B[49m\u001B[43mtls_in_tls\u001B[49m\u001B[43m,\u001B[49m\n\u001B[32m 986\u001B[39m \u001B[43m\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 988\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m 989\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m assert_fingerprint:\n",
"\u001B[36mFile \u001B[39m\u001B[32mD:\\Program Files\\anaconda3\\envs\\F6+宜搭+其它\\Lib\\site-packages\\urllib3\\util\\ssl_.py:461\u001B[39m, in \u001B[36mssl_wrap_socket\u001B[39m\u001B[34m(sock, keyfile, certfile, cert_reqs, ca_certs, server_hostname, ssl_version, ciphers, ssl_context, ca_cert_dir, key_password, ca_cert_data, tls_in_tls)\u001B[39m\n\u001B[32m 459\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m ca_certs \u001B[38;5;129;01mor\u001B[39;00m ca_cert_dir \u001B[38;5;129;01mor\u001B[39;00m ca_cert_data:\n\u001B[32m 460\u001B[39m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[32m--> \u001B[39m\u001B[32m461\u001B[39m \u001B[43mcontext\u001B[49m\u001B[43m.\u001B[49m\u001B[43mload_verify_locations\u001B[49m\u001B[43m(\u001B[49m\u001B[43mca_certs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mca_cert_dir\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mca_cert_data\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 462\u001B[39m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mOSError\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[32m 463\u001B[39m \u001B[38;5;28;01mraise\u001B[39;00m SSLError(e) \u001B[38;5;28;01mfrom\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34;01me\u001B[39;00m\n",
"\u001B[31mKeyboardInterrupt\u001B[39m: "
]
}
],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-17T09:05:23.254492Z",
"start_time": "2025-03-17T09:05:20.198477Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13576939998.xlsx\")"
],
"id": "3ec7e6bfa5d425ee",
"outputs": [],
"execution_count": 2
},
{
"metadata": {},
"cell_type": "markdown",
"source": "车辆信息",
"id": "a405bccb4dfdf949"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-07-25T02:19:42.395112Z",
"start_time": "2025-07-25T01:57:39.563741Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import json\n",
"import time\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"from datetime import datetime, timedelta\n",
"\n",
"headers = {\n",
" \"cookie\":'__jdv=135409966|direct|-|none|-|1753349284245; flash=3_EuI2ojX4uJ6bPhnrd3tKHPKia0BaRB7TCi-gdcbqrSIauxZmkgE_yZJ7WTnzwB4_5G2Tdhdi89A4xE8t1uUvWrpjg5EnWwwrMNKGl8mWCaH1Vlo0VlXNk6Eyv9VrOA_6v-MDACjpO5RN4yGkhYfYFH5968Y9NPLEbK-ARUVmdrTXu6y8_zq-chEIqCSnme**; pin=jd_4d1be17ac64d3; unick=jd_2tnscrz74er69g; thor=884B7391C2AC4631693332E7FA593E284097D0ECACAF2D9BD0A558BB6EB65EAAB7F276B2475E6F7271396EBE3D1C84832247536BA40EB75D5EBF9AF87797FDD41D2AC25CC5C5B8803729EF8374A9C2CCE2D36DB51AB971A07238FDB6EE68D2ADC973BD6F40501EB116A185BEB86917D5C9DA41A03B1E1794D9591D2861EE053015AACDC7C64065615BBCCE428FC7E09AB66E0E5EA6EE69B23323F013536FF8ED; light_key=AASBKE7rOxgWQziEhC_QY6ya_BdQfCqNzo11axkWQXqAq56Qf-aHwELmm75kijsmGBR7FBg2; JD_UUID=d4eef9de-02a9-41c6-85dd-7f656b5c2bac; yunxiupin=jd_4d1be17ac64d3; UUID=b54ae144-a7f5-4000-bcfb-19ac3838a879; SESSION_USER_NAME=%E6%9D%8E%E5%BB%BA%E4%BC%9A; __jda=154799550.17533492842442035336434.1753349284.1753349284.1753408464.2; __jdc=154799550; PUBLIC_NOTICE_TIME105188=\"2022-10-16 10:33:17\"; __jdb=154799550.4.17533492842442035336434|2.1753408464',\n",
" \"referer\": \"https://www.yunxiu.com/legend/account\",\n",
" \"sec-ch-ua\": \"\\\"Not(A:Brand\\\";v=\\\"99\\\", \\\"Microsoft Edge\\\";v=\\\"133\\\", \\\"Chromium\\\";v=\\\"133\\\"\",\n",
" \"sec-ch-ua-mobile\": \"?0\",\n",
" \"sec-ch-ua-platform\": \"\\\"Windows\\\"\",\n",
" \"sec-fetch-dest\": \"empty\",\n",
" \"sec-fetch-mode\": \"cors\",\n",
" \"sec-fetch-site\": \"same-origin\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0\",\n",
" \"x-requested-with\": \"XMLHttpRequest\"\n",
"}\n",
"\n",
"all_data = []\n",
"number = 1746510018148 # 从车辆查询页面中 date参数获取\n",
"page = 1\n",
"max_retries = 5 # 最大重试次数\n",
"backoff_factor = 1 # 指数退避因子\n",
"\n",
"current_date = datetime.now()\n",
"years_back = 10\n",
"\n",
"end_date = current_date - timedelta(days=365 * years_back)\n",
"start_date = current_date\n",
"\n",
"while start_date >= end_date:\n",
" try:\n",
" search_startTime = (start_date - timedelta(days=365)).strftime('%Y-%m-%d')\n",
" search_endTime = start_date.strftime('%Y-%m-%d')\n",
" print(f'search_startTime: {search_startTime}, search_endTime: {search_endTime}')\n",
" start_date -= timedelta(days=365) # 每次减去一年\n",
" exit_loop = False\n",
" for page in tqdm(range(1,1001)):\n",
" if exit_loop:\n",
" break\n",
" url = f\"https://www.yunxiu.com/legend/archives/carinfo/locate/list?page={page}&size=12&search_startTime={search_startTime}&search_endTime={search_endTime}&_={number}\"\n",
" attempt = 0\n",
" while attempt < max_retries:\n",
" try:\n",
" response = requests.get(url=url, headers=headers)\n",
" response.raise_for_status() # 如果响应状态码不是200,则抛出HTTPError异常\n",
" res = response.json().get(\"data\", {}).get(\"content\", [])\n",
" max_len = response.json().get(\"data\", {}).get(\"totalPages\", []) + 1\n",
" if page == max_len:\n",
" print(max_len)\n",
" exit_loop = True\n",
" break # 成功后退出重试循环\n",
" for item in res:\n",
" base_info = {k: v for k, v in item.items() if k != \"licenseList\"}\n",
" all_data.append(base_info)\n",
"\n",
" break # 成功后退出重试循环\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"第{page}页请求失败: {e}\")\n",
" if attempt < max_retries - 1:\n",
" sleep_time = backoff_factor * (2 ** attempt) # 计算等待时间\n",
" print(f\"准备第{attempt + 1}次重试,等待{sleep_time}秒...\")\n",
" time.sleep(sleep_time) # 等待一段时间后重试\n",
" else:\n",
" print(f\"达到最大重试次数,跳过第{page}页\")\n",
" attempt += 1\n",
"\n",
" number += 1\n",
" time.sleep(1)\n",
" except:\n",
" pass\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-15202993999 车辆.csv\")\n"
],
"id": "335a10b919a1f6b5",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2024-07-25, search_endTime: 2025-07-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<25:03, 1.50s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 2/1000 [00:02<22:00, 1.32s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2023-07-26, search_endTime: 2024-07-25\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 2%|▏ | 20/1000 [00:31<24:34, 1.50s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"21\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 2%|▏ | 21/1000 [00:32<25:15, 1.55s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2022-07-26, search_endTime: 2023-07-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 22%|██▏ | 216/1000 [05:25<20:51, 1.60s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"第217页请求失败: HTTPSConnectionPool(host='www.yunxiu.com', port=443): Max retries exceeded with url: /legend/archives/carinfo/locate/list?page=217&size=12&search_startTime=2022-07-26&search_endTime=2023-07-26&_=1746510018387 (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x0000027CA36597C0>, 'Connection to www.yunxiu.com timed out. (connect timeout=None)'))\n",
"准备第1次重试,等待1秒...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 23%|██▎ | 226/1000 [06:02<22:23, 1.74s/it] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"227\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 23%|██▎ | 227/1000 [06:03<20:37, 1.60s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2021-07-26, search_endTime: 2022-07-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 25%|██▍ | 248/1000 [06:09<18:34, 1.48s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"249\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 25%|██▍ | 249/1000 [06:10<18:36, 1.49s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2020-07-26, search_endTime: 2021-07-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 33%|███▎ | 333/1000 [08:16<16:34, 1.49s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"334\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 33%|███▎ | 334/1000 [08:17<16:32, 1.49s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2019-07-27, search_endTime: 2020-07-26\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 3%|▎ | 29/1000 [00:42<23:50, 1.47s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"30\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 3%|▎ | 30/1000 [00:43<23:37, 1.46s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2018-07-27, search_endTime: 2019-07-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 0/1000 [00:00<?, ?it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:02, 1.14s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2017-07-27, search_endTime: 2018-07-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 0/1000 [00:00<?, ?it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<20:22, 1.22s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2016-07-27, search_endTime: 2017-07-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<25:47, 1.55s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 2/1000 [00:02<22:49, 1.37s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2015-07-28, search_endTime: 2016-07-27\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<24:04, 1.45s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 2/1000 [00:02<21:36, 1.30s/it]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"search_startTime: 2014-07-28, search_endTime: 2015-07-28\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 0/1000 [00:00<?, ?it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 1/1000 [00:01<19:09, 1.15s/it]\n"
]
}
],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-05-15T08:31:40.647176Z",
"start_time": "2025-05-15T08:31:40.210149Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_data)\n",
"df1.to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\京东云修数据导出-13032256777 -车辆.csv\")"
],
"id": "e45e8757ed4ca425",
"outputs": [
{
"ename": "NameError",
"evalue": "name 'pd' is not defined",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mNameError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[1], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m df1 \u001B[38;5;241m=\u001B[39m pd\u001B[38;5;241m.\u001B[39mDataFrame(all_data)\n\u001B[0;32m 2\u001B[0m df1\u001B[38;5;241m.\u001B[39mto_csv(\u001B[38;5;124mr\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mD:\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mIdea Project\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mF6+宜搭+其它(1)\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mnew\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m文件输出\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m京东云修数据导出-13032256777 -车辆.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
"\u001B[1;31mNameError\u001B[0m: name 'pd' is not defined"
]
}
],
"execution_count": 1
},
{
"metadata": {},
"cell_type": "markdown",
"source": "",
"id": "bf951aee0e74b1d1"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "新单据信息",
"id": "eb09e38f6613b5e7"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-28T06:31:17.385432200Z",
"start_time": "2026-01-28T06:31:16.760396700Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"\n",
"cookies = {\n",
" '__jdv': '241039512|direct|-|none|-|1769580195196',\n",
" 'mba_muid': '17695801951961847696270',\n",
" 'mba_sid': '1769580378119515622883.0',\n",
" 'QRCodeKey': 'AAEAIGlfy0S9IVwOVAfE3NXgBILRP8R2qpHAikvosD3cyvar',\n",
" 'wlfstk_smdl': 'drd3j1dlvwjz7o96orgqco4keigo6ipj',\n",
" 'pin': '%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8',\n",
" 'unick': 's2v2tk1w4w8eb9',\n",
" 'yunxiupin': '%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8',\n",
" 'bmall_id': '499220987560FEF36C9FB4C092693FFC98D6D74FB85924A6DC3E030ADD3477238C68C7B8E10ED66898B6EBEB4562ED893FBF19E4CD0030FECE3218317F39A2F5FC9FF25A11561368D02C95564D247AC2A151A086B1074D5EE362C7CB1BA34EC79B50B3252535972791A084C5D010158EF4B5C1EADC2808FFF3EB992EF34A9D14',\n",
" 'UUID': '7c069d6f-2724-4008-b308-09f436240035',\n",
" 'SESSION_USER_NAME': '%E6%9F%A5%E4%BA%AE',\n",
" 'flash': '3_bBBCg0-OBy68xAANqduCSaKWV_6DKpxvObl29hEy-5Il0taBIimdGJfimCMZHKH-CUR09cTQwjAyGRKP9z9jHkm9UrWP2nTOg38vb68OEMqiiwdZRg1AqxMtUmDSWBQdVhGg5qQSbO5p1eyeBPlu7Htsgtf_TMouEaoqlijt7PqsLs4yBBM8Alki49TorJwr9E6mcmF96X-2O-E6',\n",
" 'thor': '51C732866E8A756A4ED8B4738163D4C059D9063322E05745BA0D815A80FEBE3D550B447E8BB3C99207EE02D994108998DE070A571A758BED83B7535090CB6C2DF853F8994511D1708463D0C16274A620668FCE84D3B708BA56633C46432FABC8B4DA7688141595BA1C45C419160C151A638E6A118D22DA606EE420BE383B9D53FB842C2C90A6454E4CFED4E3A63A8ED5',\n",
" 'light_key': 'AASBKE7rOxgWQziEhC_QY6yaLIBQgOT1dxVmsPRjRIB9ndtR9Aslstb1iQBYYZyMvLEJNsNDL52e7UA1dFCeHNIVWAseFg',\n",
" 'JD_UUID': 'b9441bd1-a782-4d34-b2af-47b6f1e89bc6',\n",
" '3AB9D23F7A4B3CSS': 'jdd03XH7UJPD6AWWSVFN6XP6T23OSWBA235SAMFFYPEW3JTTJRTT4TQTZLIAKR47DQ26GKGT266NM6WGBCEKT7R6RL2K34IAAAAM4ANDUGQYAAAAACSHCLFATJTAJKMX',\n",
" 'sdtoken': 'AAbEsBpEIOVjqTAKCQtvQu17FLUpUb4CM0QtRGo9_y1DbK8h44YEOS2UiemwosOOgSgqPwHoDiJho0E69o2zgRTqSGouwgzZW2ByDMgJdY2S_IVvi4uyNneMFom6TCFDsAUG_C0BzQYsVWWU',\n",
" '__jda': '200816309.17695801951961847696270.1769580195.1769580195.1769580195.1',\n",
" '__jdc': '200816309',\n",
" '3AB9D23F7A4B3C9B': 'KPOAZ5CBYQXJ25JOSSXGBQDYYOVGX7EMTPWFWDGVZ3KWTLNZU45HHPQ4MXYSIO37IV72PLAND3VYJH2ZOLD6LFWBDA',\n",
" '__jdb': '200816309.56.17695801951961847696270|1.1769580195',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'origin': 'https://jch.yunxiu.com',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://jch.yunxiu.com/',\n",
" 'sec-ch-ua': '\"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"144\", \"Microsoft Edge\";v=\"144\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\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/144.0.0.0 Safari/537.36 Edg/144.0.0.0',\n",
" 'x-requested-with': 'XMLHttpRequest',\n",
" # 'cookie': '__jdv=241039512|direct|-|none|-|1769580195196; mba_muid=17695801951961847696270; mba_sid=1769580378119515622883.0; QRCodeKey=AAEAIGlfy0S9IVwOVAfE3NXgBILRP8R2qpHAikvosD3cyvar; wlfstk_smdl=drd3j1dlvwjz7o96orgqco4keigo6ipj; pin=%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; unick=s2v2tk1w4w8eb9; yunxiupin=%E5%8D%97%E6%98%8C%E4%BD%B3%E4%B9%BE%E8%BD%A6%E6%9C%8D%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; bmall_id=499220987560FEF36C9FB4C092693FFC98D6D74FB85924A6DC3E030ADD3477238C68C7B8E10ED66898B6EBEB4562ED893FBF19E4CD0030FECE3218317F39A2F5FC9FF25A11561368D02C95564D247AC2A151A086B1074D5EE362C7CB1BA34EC79B50B3252535972791A084C5D010158EF4B5C1EADC2808FFF3EB992EF34A9D14; UUID=7c069d6f-2724-4008-b308-09f436240035; SESSION_USER_NAME=%E6%9F%A5%E4%BA%AE; flash=3_bBBCg0-OBy68xAANqduCSaKWV_6DKpxvObl29hEy-5Il0taBIimdGJfimCMZHKH-CUR09cTQwjAyGRKP9z9jHkm9UrWP2nTOg38vb68OEMqiiwdZRg1AqxMtUmDSWBQdVhGg5qQSbO5p1eyeBPlu7Htsgtf_TMouEaoqlijt7PqsLs4yBBM8Alki49TorJwr9E6mcmF96X-2O-E6; thor=51C732866E8A756A4ED8B4738163D4C059D9063322E05745BA0D815A80FEBE3D550B447E8BB3C99207EE02D994108998DE070A571A758BED83B7535090CB6C2DF853F8994511D1708463D0C16274A620668FCE84D3B708BA56633C46432FABC8B4DA7688141595BA1C45C419160C151A638E6A118D22DA606EE420BE383B9D53FB842C2C90A6454E4CFED4E3A63A8ED5; light_key=AASBKE7rOxgWQziEhC_QY6yaLIBQgOT1dxVmsPRjRIB9ndtR9Aslstb1iQBYYZyMvLEJNsNDL52e7UA1dFCeHNIVWAseFg; JD_UUID=b9441bd1-a782-4d34-b2af-47b6f1e89bc6; 3AB9D23F7A4B3CSS=jdd03XH7UJPD6AWWSVFN6XP6T23OSWBA235SAMFFYPEW3JTTJRTT4TQTZLIAKR47DQ26GKGT266NM6WGBCEKT7R6RL2K34IAAAAM4ANDUGQYAAAAACSHCLFATJTAJKMX; sdtoken=AAbEsBpEIOVjqTAKCQtvQu17FLUpUb4CM0QtRGo9_y1DbK8h44YEOS2UiemwosOOgSgqPwHoDiJho0E69o2zgRTqSGouwgzZW2ByDMgJdY2S_IVvi4uyNneMFom6TCFDsAUG_C0BzQYsVWWU; __jda=200816309.17695801951961847696270.1769580195.1769580195.1769580195.1; __jdc=200816309; 3AB9D23F7A4B3C9B=KPOAZ5CBYQXJ25JOSSXGBQDYYOVGX7EMTPWFWDGVZ3KWTLNZU45HHPQ4MXYSIO37IV72PLAND3VYJH2ZOLD6LFWBDA; __jdb=200816309.56.17695801951961847696270|1.1769580195',\n",
"}\n",
"\n",
"params = {\n",
" 'page': '1',\n",
" 'size': '12',\n",
" 'btnType': 'search',\n",
"}\n",
"\n",
"response = requests.get('https://g.yunxiu.com/megatron/api/v1/order/list', params=params, cookies=cookies, headers=headers)\n"
],
"id": "ca85268200bda895",
"outputs": [],
"execution_count": 2
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-28T06:35:23.307514700Z",
"start_time": "2026-01-28T06:35:23.261598100Z"
}
},
"cell_type": "code",
"source": [
"response.json()\n",
"content = response.json()['data'].get(\"content\")\n",
"\n",
"import pandas as pd\n",
"df = pd.DataFrame(content)\n",
"df.to_csv(\"京东云修单据信息demo.csv\")"
],
"id": "b18cdb2c1fb49e75",
"outputs": [],
"execution_count": 5
}
],
"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
}
@@ -0,0 +1,169 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "## 会员卡明细导出",
"id": "1b14f94c5e74163b"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-05-14T06:45:24.475273Z",
"start_time": "2025-05-14T06:44:16.062351Z"
}
},
"source": [
"import requests\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"import time\n",
"\n",
"\n",
"url = f\"https://www.aibiyme.com/base-admin/memberCard/selectUserCardList\"\n",
"\n",
"headers = {\n",
" 'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate, br, zstd',\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",
" 'Content-Length': '21', # 根据实际情况调整Content-Length\n",
" 'Content-Type': 'application/x-www-form-urlencoded',\n",
" 'Cookie': 'sid=e8ca5702-f938-437e-a37b-368088cdaff4',\n",
" 'Host': 'www.aibiyme.com',\n",
" 'Origin': 'https://www.aibiyme.com',\n",
" 'Referer': 'https://www.aibiyme.com/web-admin/erp/procurement.html',\n",
" 'Sec-Ch-Ua': '\"Chromium\";v=\"136\", \"Microsoft Edge\";v=\"136\", \"Not.A/Brand\";v=\"99\"',\n",
" 'Sec-Ch-Ua-Mobile': '?0',\n",
" 'Sec-Ch-Ua-Platform': '\"Windows\"',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest'\n",
"}\n",
"all_data = []\n",
"\n",
"data = \"pageSize=10&pageNum=1\"\n",
"\n",
"# 获取总记录数\n",
"f_res = requests.post(url, data=data, headers=headers)\n",
"f_res.raise_for_status() # 检查请求是否成功\n",
"total = f_res.json().get(\"total\", 0)\n",
"print(total)\n",
"\n",
"for i in tqdm(range(1, total + 1)):\n",
" data = f\"pageSize=10&pageNum={i}\"\n",
" \n",
" res = requests.post(url, data=data, headers=headers)\n",
" res.raise_for_status()\n",
"\n",
" data_list = res.json().get(\"obj\", {}).get(\"pageData\", [])\n",
"\n",
" for item in data_list:\n",
" pk = item.get(\"pk\")\n",
" pk = int(pk)\n",
" if pk:\n",
" # 获取详细信息\n",
" pk_data = f\"cardPk={pk}\"\n",
" \n",
" detail_url = \"https://www.aibiyme.com/base-admin/memberCard/getCardInfoByPk\"\n",
" pk_res = requests.post(detail_url, data=pk_data, headers=headers)\n",
" pk_res.raise_for_status()\n",
"\n",
" detail_data = pk_res.json().get(\"obj\", {})\n",
" item.update(detail_data)\n",
"\n",
" # 处理卡片明细\n",
" card_details = detail_data.get(\"cardItemList\", [])\n",
" for card_detail in card_details:\n",
" item_copy = item.copy() # 创建副本避免修改原始数据\n",
" item_copy.update(card_detail)\n",
" all_data.append(item_copy)\n",
"\n",
"# 保存数据\n",
"if all_data:\n",
" pd.DataFrame(all_data).to_csv(\"./new/文件输出/会员卡明细.csv\", index=False)\n",
"else:\n",
" print(\"没有获取到任何数据\")\n"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"22\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 22/22 [01:06<00:00, 3.04s/it]\n"
]
},
{
"ename": "OSError",
"evalue": "Cannot save file into a non-existent directory: 'new\\文件输出'",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mOSError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[34], line 70\u001B[0m\n\u001B[0;32m 68\u001B[0m \u001B[38;5;66;03m# 保存数据\u001B[39;00m\n\u001B[0;32m 69\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m all_data:\n\u001B[1;32m---> 70\u001B[0m pd\u001B[38;5;241m.\u001B[39mDataFrame(all_data)\u001B[38;5;241m.\u001B[39mto_csv(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m./new/文件输出/会员卡明细.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m, index\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[0;32m 71\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m 72\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m没有获取到任何数据\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\util\\_decorators.py:333\u001B[0m, in \u001B[0;36mdeprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper\u001B[1;34m(*args, **kwargs)\u001B[0m\n\u001B[0;32m 327\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(args) \u001B[38;5;241m>\u001B[39m num_allow_args:\n\u001B[0;32m 328\u001B[0m warnings\u001B[38;5;241m.\u001B[39mwarn(\n\u001B[0;32m 329\u001B[0m msg\u001B[38;5;241m.\u001B[39mformat(arguments\u001B[38;5;241m=\u001B[39m_format_argument_list(allow_args)),\n\u001B[0;32m 330\u001B[0m \u001B[38;5;167;01mFutureWarning\u001B[39;00m,\n\u001B[0;32m 331\u001B[0m stacklevel\u001B[38;5;241m=\u001B[39mfind_stack_level(),\n\u001B[0;32m 332\u001B[0m )\n\u001B[1;32m--> 333\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m func(\u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\core\\generic.py:3967\u001B[0m, in \u001B[0;36mNDFrame.to_csv\u001B[1;34m(self, path_or_buf, sep, na_rep, float_format, columns, header, index, index_label, mode, encoding, compression, quoting, quotechar, lineterminator, chunksize, date_format, doublequote, escapechar, decimal, errors, storage_options)\u001B[0m\n\u001B[0;32m 3956\u001B[0m df \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(\u001B[38;5;28mself\u001B[39m, ABCDataFrame) \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mto_frame()\n\u001B[0;32m 3958\u001B[0m formatter \u001B[38;5;241m=\u001B[39m DataFrameFormatter(\n\u001B[0;32m 3959\u001B[0m frame\u001B[38;5;241m=\u001B[39mdf,\n\u001B[0;32m 3960\u001B[0m header\u001B[38;5;241m=\u001B[39mheader,\n\u001B[1;32m (...)\u001B[0m\n\u001B[0;32m 3964\u001B[0m decimal\u001B[38;5;241m=\u001B[39mdecimal,\n\u001B[0;32m 3965\u001B[0m )\n\u001B[1;32m-> 3967\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m DataFrameRenderer(formatter)\u001B[38;5;241m.\u001B[39mto_csv(\n\u001B[0;32m 3968\u001B[0m path_or_buf,\n\u001B[0;32m 3969\u001B[0m lineterminator\u001B[38;5;241m=\u001B[39mlineterminator,\n\u001B[0;32m 3970\u001B[0m sep\u001B[38;5;241m=\u001B[39msep,\n\u001B[0;32m 3971\u001B[0m encoding\u001B[38;5;241m=\u001B[39mencoding,\n\u001B[0;32m 3972\u001B[0m errors\u001B[38;5;241m=\u001B[39merrors,\n\u001B[0;32m 3973\u001B[0m compression\u001B[38;5;241m=\u001B[39mcompression,\n\u001B[0;32m 3974\u001B[0m quoting\u001B[38;5;241m=\u001B[39mquoting,\n\u001B[0;32m 3975\u001B[0m columns\u001B[38;5;241m=\u001B[39mcolumns,\n\u001B[0;32m 3976\u001B[0m index_label\u001B[38;5;241m=\u001B[39mindex_label,\n\u001B[0;32m 3977\u001B[0m mode\u001B[38;5;241m=\u001B[39mmode,\n\u001B[0;32m 3978\u001B[0m chunksize\u001B[38;5;241m=\u001B[39mchunksize,\n\u001B[0;32m 3979\u001B[0m quotechar\u001B[38;5;241m=\u001B[39mquotechar,\n\u001B[0;32m 3980\u001B[0m date_format\u001B[38;5;241m=\u001B[39mdate_format,\n\u001B[0;32m 3981\u001B[0m doublequote\u001B[38;5;241m=\u001B[39mdoublequote,\n\u001B[0;32m 3982\u001B[0m escapechar\u001B[38;5;241m=\u001B[39mescapechar,\n\u001B[0;32m 3983\u001B[0m storage_options\u001B[38;5;241m=\u001B[39mstorage_options,\n\u001B[0;32m 3984\u001B[0m )\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\formats\\format.py:1014\u001B[0m, in \u001B[0;36mDataFrameRenderer.to_csv\u001B[1;34m(self, path_or_buf, encoding, sep, columns, index_label, mode, compression, quoting, quotechar, lineterminator, chunksize, date_format, doublequote, escapechar, errors, storage_options)\u001B[0m\n\u001B[0;32m 993\u001B[0m created_buffer \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m 995\u001B[0m csv_formatter \u001B[38;5;241m=\u001B[39m CSVFormatter(\n\u001B[0;32m 996\u001B[0m path_or_buf\u001B[38;5;241m=\u001B[39mpath_or_buf,\n\u001B[0;32m 997\u001B[0m lineterminator\u001B[38;5;241m=\u001B[39mlineterminator,\n\u001B[1;32m (...)\u001B[0m\n\u001B[0;32m 1012\u001B[0m formatter\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfmt,\n\u001B[0;32m 1013\u001B[0m )\n\u001B[1;32m-> 1014\u001B[0m csv_formatter\u001B[38;5;241m.\u001B[39msave()\n\u001B[0;32m 1016\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m created_buffer:\n\u001B[0;32m 1017\u001B[0m \u001B[38;5;28;01massert\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(path_or_buf, StringIO)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\formats\\csvs.py:251\u001B[0m, in \u001B[0;36mCSVFormatter.save\u001B[1;34m(self)\u001B[0m\n\u001B[0;32m 247\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m 248\u001B[0m \u001B[38;5;124;03mCreate the writer & save.\u001B[39;00m\n\u001B[0;32m 249\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m 250\u001B[0m \u001B[38;5;66;03m# apply compression and byte/text conversion\u001B[39;00m\n\u001B[1;32m--> 251\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m get_handle(\n\u001B[0;32m 252\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfilepath_or_buffer,\n\u001B[0;32m 253\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmode,\n\u001B[0;32m 254\u001B[0m encoding\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mencoding,\n\u001B[0;32m 255\u001B[0m errors\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39merrors,\n\u001B[0;32m 256\u001B[0m compression\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcompression,\n\u001B[0;32m 257\u001B[0m storage_options\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mstorage_options,\n\u001B[0;32m 258\u001B[0m ) \u001B[38;5;28;01mas\u001B[39;00m handles:\n\u001B[0;32m 259\u001B[0m \u001B[38;5;66;03m# Note: self.encoding is irrelevant here\u001B[39;00m\n\u001B[0;32m 260\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mwriter \u001B[38;5;241m=\u001B[39m csvlib\u001B[38;5;241m.\u001B[39mwriter(\n\u001B[0;32m 261\u001B[0m handles\u001B[38;5;241m.\u001B[39mhandle,\n\u001B[0;32m 262\u001B[0m lineterminator\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mlineterminator,\n\u001B[1;32m (...)\u001B[0m\n\u001B[0;32m 267\u001B[0m quotechar\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mquotechar,\n\u001B[0;32m 268\u001B[0m )\n\u001B[0;32m 270\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_save()\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\common.py:749\u001B[0m, in \u001B[0;36mget_handle\u001B[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001B[0m\n\u001B[0;32m 747\u001B[0m \u001B[38;5;66;03m# Only for write methods\u001B[39;00m\n\u001B[0;32m 748\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mr\u001B[39m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m mode \u001B[38;5;129;01mand\u001B[39;00m is_path:\n\u001B[1;32m--> 749\u001B[0m check_parent_directory(\u001B[38;5;28mstr\u001B[39m(handle))\n\u001B[0;32m 751\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m compression:\n\u001B[0;32m 752\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m compression \u001B[38;5;241m!=\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mzstd\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[0;32m 753\u001B[0m \u001B[38;5;66;03m# compression libraries do not like an explicit text-mode\u001B[39;00m\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\common.py:616\u001B[0m, in \u001B[0;36mcheck_parent_directory\u001B[1;34m(path)\u001B[0m\n\u001B[0;32m 614\u001B[0m parent \u001B[38;5;241m=\u001B[39m Path(path)\u001B[38;5;241m.\u001B[39mparent\n\u001B[0;32m 615\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m parent\u001B[38;5;241m.\u001B[39mis_dir():\n\u001B[1;32m--> 616\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mOSError\u001B[39;00m(\u001B[38;5;124mrf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mCannot save file into a non-existent directory: \u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mparent\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
"\u001B[1;31mOSError\u001B[0m: Cannot save file into a non-existent directory: 'new\\文件输出'"
]
}
],
"execution_count": 34
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-05-14T06:47:28.647625Z",
"start_time": "2025-05-14T06:47:28.625811Z"
}
},
"cell_type": "code",
"source": [
"# 保存数据\n",
"if all_data:\n",
" pd.DataFrame(all_data).to_csv(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\会员卡明细.csv\", index=False)\n",
"else:\n",
" print(\"没有获取到任何数据\")"
],
"id": "584f989c494205d5",
"outputs": [],
"execution_count": 40
}
],
"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
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from urllib.parse import urljoin
import pandas as pd
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service
from datetime import datetime
from selenium.webdriver.chrome.options import Options
from datetime import datetime, timedelta
from selenium.common.exceptions import NoSuchElementException
from tqdm import tqdm
from selenium.common.exceptions import TimeoutException
# 设置Chrome选项
chrome_options = Options()
# 设置为无头模式(不打开浏览器窗口)
# chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
# 指定ChromeDriver路径
service = Service(executable_path='D:\ProgramTools\chromedriver-win64\chromedriver.exe')
# 创建WebDriver对象
driver = webdriver.Chrome(service=service, options=chrome_options)
# 目标网址
url = 'https://ebc.cloud.harsonserver.com/#/user/login?redirect=/'
url1 = ''
username = '193WSX'
password = '193WSX'
# title = 'HGYH -- HGYH'
# 访问网页
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id="login-container"]/div[4]/div[3]/div'))).click()
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "form_item_loginAccount"))
).send_keys(username)
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "form_item_password"))
).send_keys(password)
time.sleep(2)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id="login-container"]/div[4]/div[2]/form/div[5]/div/div/div/button'))).click()
time.sleep(3)
new_url = "https://ebc.cloud.harsonserver.com/#/maintenance/frontManage/maintenanceReport/workOrderReport"
driver.get(new_url)
start_date = "2025-09-22"
end_date = "2025-11-22"
# 等待日期选择器容器出现
date_picker = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".ant-picker-range"))
)
# 定位两个 input(根据 placeholder
start_input = date_picker.find_element(By.XPATH, './/input[@placeholder="开始时间"]')
end_input = date_picker.find_element(By.XPATH, './/input[@placeholder="结束时间"]')
# 使用 JavaScript 设置值并触发事件
driver.execute_script(f"arguments[0].value = '{start_date}'; arguments[0].dispatchEvent(new Event('input'));", start_input)
driver.execute_script(f"arguments[0].value = '{end_date}'; arguments[0].dispatchEvent(new Event('input'));", end_input)
# 可选:再触发 change 事件(某些框架需要)
driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", start_input)
driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", end_input)
@@ -0,0 +1,41 @@
import pandas as pd
import requests
from tqdm import tqdm
from bs4 import BeautifulSoup
all_data_list = []
keys = ["门店","订单编号","产品类型","产品名称","型号","数量","采购单价","销售单价",
"采购金额","销售金额","毛利润","下单人","接单人","车牌号"]
reversed_keys = list(reversed(keys))
for i in tqdm(range(1, 2)):
url = f"http://rp.chezizhu.com/ReportServer?_=1745552902755&__boxModel__=true&op=page_content&sessionID=27200&pn={i}&__fit__=false"
header = {
"Referer": "http://rp.chezizhu.com/ReportServer?reportlet=czz/storage/prod_sale_dtl_jm.cpt&servicer_id=B9GC8C8oZpTAxmUR1YEp9q&hideexport=true&database=chezizhu_14",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0",
"X-Requested-With": "XMLHttpRequest"
}
res = requests.post(url, headers=header)
soup = BeautifulSoup(res.text, "html.parser")
# 定位真正的数据行(跳过标题行)
for tr in soup.select('tr:not(:has(th))'): # 排除包含表头的行
tds = [td.get_text(strip=True) for td in tr.find_all("td")]
reversed_tds = list(reversed(tds))
# 如果 reversed_tds 长度不够,填充空字符串
if len(reversed_tds) < len(reversed_keys):
reversed_tds += [""] * (len(reversed_keys) - len(reversed_tds))
elif len(reversed_tds) > len(reversed_keys):
reversed_tds = reversed_tds[:len(reversed_keys)]
# 构建字典(反转后的 keys 和 tds)
row_data = dict(zip(reversed_keys, reversed_tds))
all_data_list.append(row_data)
# break
print(all_data_list)
df = pd.DataFrame(all_data_list)
df.to_excel(r'D:\Idea Project\F6+宜搭+其它(1)\new\文件输出\大唛云销售明细.xlsx', index=False)
@@ -0,0 +1,410 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-05-15T03:14:27.994103Z",
"start_time": "2025-05-15T02:03:56.503917Z"
}
},
"source": [
"import requests\n",
"import re\n",
"import time\n",
"\n",
"timestamp_ms = int(time.time() * 1000)\n",
"\n",
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"from bs4 import BeautifulSoup\n",
"from urllib.parse import urlencode, quote\n",
"import time\n",
"from requests.exceptions import RequestException\n",
"\n",
"# 读取Excel文件\n",
"df = pd.read_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\大唛云订单明细 (2).xlsx\")\n",
"\n",
"# 定义要提取的基本字段列表\n",
"BASE_FIELDS = [\n",
" '保险公司', '保险到期', '年检日期', '车架号',\n",
" '购车日期', '服务日期', '服务里程',\n",
" '下次服务日期', '下次服务里程'\n",
"]\n",
"\n",
"# 创建两个DataFrame分别存储不同类型的数据\n",
"base_info_df = df.copy() # 存储基本信息\n",
"service_items_df = pd.DataFrame() # 存储消费项目明细\n",
"\n",
"\n",
"def make_request_with_retry(url, headers, max_retries=10, retry_delay=1):\n",
" \"\"\"带重试机制的请求函数\"\"\"\n",
" for attempt in range(max_retries):\n",
" try:\n",
" res = requests.get(url=url, headers=headers, timeout=10)\n",
" res.raise_for_status()\n",
" return res\n",
" except RequestException as e:\n",
" if attempt == max_retries - 1:\n",
" raise\n",
" print(f\"请求失败,第 {attempt + 1} 次重试... 错误: {str(e)}\")\n",
" time.sleep(retry_delay)\n",
" return None\n",
" # print(res.text)\n",
"\n",
"\n",
"def extract_session_id(html_content):\n",
" soup = BeautifulSoup(html_content, \"html.parser\")\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"\n",
" session_ids = set()\n",
" for script in scripts:\n",
" # 匹配注册语句中的sessionid\n",
" register_match = re.search(r\"FR\\.SessionMgr\\.register\\('(\\d+)'\", script.text)\n",
" if register_match:\n",
" session_ids.add(register_match.group(1))\n",
"\n",
" # 匹配变量赋值中的sessionid\n",
" current_match = re.search(r\"currentSessionID\\s*=\\s*'(\\d+)'\", script.text)\n",
" if current_match:\n",
" session_ids.add(current_match.group(1))\n",
"\n",
" return list(session_ids)\n",
"\n",
"\n",
"for index, row in tqdm(list(df.iterrows()), desc=\"处理订单\"):\n",
" order_number = row[\"单号\"]\n",
" success = False\n",
" # print(f\"正在处理订单 {order_number}\")\n",
"\n",
" timestamp_ms = int(time.time() * 1000)\n",
" for attempt in range(10): # 最大重试次数\n",
" try:\n",
" url = (\n",
" \"http://rp.chezizhu.com/ReportServer?reportlet=/czz/order/order.cpt&__parameters__={%22_%22:%22\" + f\"{timestamp_ms}\" + \"%22,%22PINGJIA%22:[5b][5d],%22DISCOUNT_DESC%22:%22%22,%22B%22:%222011-05-01%22,%22LABELPLATE_NUMBER%22:%22%25E8%25BD%25A6%25E7%2589%258C%25E5%258F%25B7%22,%22LABELUSER_NAME%22:%22%25E5%25A7%2593%25E5%2590%258D%22,%22E%22:%222025-05-07%22,%22SERVICER%22:[5b][5d],%22CAR_NAME%22:%22%22,%22ORDER_SERVICE_TYPE%22:%22%22,%22order_number%22:%22\" + order_number + \"%22,%22USER_MOBILE%22:%22%22,%22LABELUSER_STATE%22:%22%25E6%2596%25B0%25E8%2580%2581%25E7%2594%25A8%25E6%2588%25B7%22,%22LABELCAR_NAME%22:%22%25E8%25BD%25A6%25E5%259E%258B%22,%22SERVICER_ID%22:%22683XGWqnyn66mE1oa8Gkzb%22,%22LABELORDER_SOURCE%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E6%259D%25A5%25E6%25BA%2590%22,%22LABELE%22:%22%25E8%2587%25B3%22,%22LABELSERVER%22:%22%25E9%2597%25A8%25E5%25BA%2597%22,%22LABELGONGDAN_STATUS%22:%22%25E5%25B7%25A5%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22LABELORDER_STATUS%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22ORDER_STATUS%22:[5b][5d],%22CMD%22:%22parameters_d%22,%22PAY_METHOD%22:%22%22,%22LABELUSER_MOBILE%22:%22%25E5%25AE%25A2%25E6%2588%25B7%25E7%2594%25B5%25E8%25AF%259D%22,%22LABELPINGJIA%22:%22%25E8%25AF%2584%25E4%25BB%25B7%25E7%258A%25B6%25E6%2580%2581%22,%22USER_STATE%22:[5b][5d],%22LABELRP_TYPE%22:%22%25E6%258A%25A5%25E8%25A1%25A8%25E7%25B1%25BB%25E5%259E%258B%22,%22LABELPAY_METHOD%22:%22%25E7%25BB%2593%25E7%25AE%2597%25E6%2596%25B9%25E5%25BC%258F%22,%22USER_NAME%22:%22%22,%22REPORTNAME%22:%22czz%252Forder%252Forder_detail_md.cpt%22,%22DISCOUNT_TYPE%22:%22%22,%22DATE_TYPE%22:%22%25E5%25AE%258C%25E6%2588%2590%25E6%2597%25A5%25E6%259C%259F%22,%22LABELDISCOUNT_DESC%22:%22%25E6%258A%2598%25E6%2589%25A3%25E5%258E%259F%25E5%259B%25A0%22,%22GONGDAN_STATUS%22:[5b][5d],%22__STREAMCLOSED__%22:%22%22,%22__pi__%22:%22true%22,%22CHANNEL%22:%22%22,%22DATABASE%22:%22chezizhu_14%22,%22ORDER_SOURCE%22:[5b][5d],%22LABELORDER_NUMBER%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E5%258F%25B7%22,%22PLATE_NUMBER%22:%22%22,%22RP_TYPE%22:%22%25E9%25AB%2598%25E7%25BA%25A7%25E6%2590%259C%25E7%25B4%25A2%22}\"\n",
" )\n",
"\n",
" headers = {\n",
" 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',\n",
" 'Accept-Encoding': 'gzip, deflate',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Cache-Control': 'max-age=0',\n",
" 'Connection': 'keep-alive',\n",
" 'Cookie': 'td_cookie=2912605941',\n",
" 'Host': 'rp.chezizhu.com',\n",
" 'Referer': 'http://rp.chezizhu.com/ReportServer?reportlet=czz/order/order_detail_md.cpt&servicer_id=683XGWqnyn66mE1oa8Gkzb&database=chezizhu_14',\n",
" 'Upgrade-Insecure-Requests': '1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0'\n",
" }\n",
"\n",
" res = requests.get(url, headers=headers)\n",
"\n",
" session_ids = extract_session_id(res.text)\n",
" # print(\"提取到的SessionID:\", session_ids[0])\n",
" # ========== 请求部分 ==========\n",
" url = f\"http://rp.chezizhu.com/ReportServer?_={timestamp_ms}&__boxModel__=true&op=page_content&sessionID={session_ids[0]}&pn=1&__fit__=false\"\n",
"\n",
" headers = {\n",
" 'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate',\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",
" 'Cookie': 'td_cookie=2912605941',\n",
" 'Host': 'rp.chezizhu.com',\n",
" \"Referer\": \"http://rp.chezizhu.com/ReportServer?reportlet=/czz/order/order.cpt&__parameters__={%22_%22:%22\" + f\"{timestamp_ms}\" + \"%22,%22PINGJIA%22:[5b][5d],%22DISCOUNT_DESC%22:%22%22,%22B%22:%222021-05-01%22,%22LABELPLATE_NUMBER%22:%22%25E8%25BD%25A6%25E7%2589%258C%25E5%258F%25B7%22,%22LABELUSER_NAME%22:%22%25E5%25A7%2593%25E5%2590%258D%22,%22E%22:%222025-05-06%22,%22SERVICER%22:[5b][5d],%22CAR_NAME%22:%22%22,%22ORDER_SERVICE_TYPE%22:%22%22,%22order_number%22:%22\"\n",
" + order_number +\n",
" \"%22,%22USER_MOBILE%22:%22%22,%22LABELUSER_STATE%22:%22%25E6%2596%25B0%25E8%2580%2581%25E7%2594%25A8%25E6%2588%25B7%22,%22LABELCAR_NAME%22:%22%25E8%25BD%25A6%25E5%259E%258B%22,%22SERVICER_ID%22:%22683XGWqnyn66mE1oa8Gkzb%22,%22LABELORDER_SOURCE%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E6%259D%25A5%25E6%25BA%2590%22,%22LABELE%22:%22%25E8%2587%25B3%22,%22LABELSERVER%22:%22%25E9%2597%25A8%25E5%25BA%2597%22,%22LABELGONGDAN_STATUS%22:%22%25E5%25B7%25A5%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22LABELORDER_STATUS%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22ORDER_STATUS%22:[5b][5d],%22CMD%22:%22parameters_d%22,%22PAY_METHOD%22:%22%22,%22LABELUSER_MOBILE%22:%22%25E5%25AE%25A2%25E6%2588%25B7%25E7%2594%25B5%25E8%25AF%259D%22,%22LABELPINGJIA%22:%22%25E8%25AF%2584%25E4%25BB%25B7%25E7%258A%25B6%25E6%2580%2581%22,%22USER_STATE%22:[5b][5d],%22LABELRP_TYPE%22:%22%25E6%258A%25A5%25E8%25A1%25A8%25E7%25B1%25BB%25E5%259E%258B%22,%22LABELPAY_METHOD%22:%22%25E7%25BB%2593%25E7%25AE%2597%25E6%2596%25B9%25E5%25BC%258F%22,%22USER_NAME%22:%22%22,%22REPORTNAME%22:%22czz%252Forder%252Forder_detail_md.cpt%22,%22DISCOUNT_TYPE%22:%22%22,%22DATE_TYPE%22:%22%25E5%25AE%258C%25E6%2588%2590%25E6%2597%25A5%25E6%259C%259F%22,%22LABELDISCOUNT_DESC%22:%22%25E6%258A%2598%25E6%2589%25A3%25E5%258E%259F%25E5%259B%25A0%22,%22GONGDAN_STATUS%22:[5b][5d],%22__STREAMCLOSED__%22:%22%22,%22__pi__%22:%22true%22,%22CHANNEL%22:%22%22,%22DATABASE%22:%22chezizhu_14%22,%22ORDER_SOURCE%22:[5b][5d],%22LABELORDER_NUMBER%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E5%258F%25B7%22,%22PLATE_NUMBER%22:%22%22,%22RP_TYPE%22:%22%25E9%25AB%2598%25E7%25BA%25A7%25E6%2590%259C%25E7%25B4%25A2%22}\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
" }\n",
"\n",
" # 使用带重试的请求函数\n",
" res = make_request_with_retry(url, headers)\n",
" # print(res.text)\n",
"\n",
" soup = BeautifulSoup(res.text, 'lxml')\n",
"\n",
" # ========== 1. 提取基本信息(单行) ==========\n",
" base_info = {'单号': order_number} # 保留原始订单号\n",
"\n",
" for field in BASE_FIELDS:\n",
" field_td = soup.find('td', string=f'{field}')\n",
" if field_td:\n",
" value_td = field_td.find_next('td')\n",
" base_info[field] = value_td.get_text(strip=True) if value_td else None\n",
" else:\n",
" base_info[field] = None\n",
"\n",
" # 更新基本信息DataFrame\n",
" for col in base_info:\n",
" if col not in base_info_df.columns:\n",
" base_info_df[col] = None\n",
" base_info_df.at[index, col] = base_info[col]\n",
"\n",
" # ========== 2. 提取消费项目(多行) ==========\n",
" # 初始化 last_item 用于保存上一行数据\n",
" last_item = {}\n",
" \n",
" # 定义字段顺序(从后往前)\n",
" field_order = [\n",
" ('合计', 10),\n",
" ('工时', 9),\n",
" ('产品小计', 8),\n",
" ('单价', 7),\n",
" ('单位', 6),\n",
" ('规格', 5),\n",
" ('产品型号', 3),\n",
" ('产品名称', 2),\n",
" ('服务项目', 1),\n",
" ('套餐', 0),\n",
" ]\n",
" \n",
" # 设置不继承的字段集合\n",
" do_not_inherit_fields = {\n",
" '产品小计', '单价',\n",
" '单位', '规格', '产品型号', '产品名称'\n",
" }\n",
" \n",
" consumption_header = soup.find(lambda tag: tag.name == 'td' and '消费项目' in tag.text)\n",
" if consumption_header:\n",
" table = consumption_header.find_parent('table')\n",
" if table:\n",
" rows = table.find_all('tr')[1:] # 跳过表头\n",
" \n",
" for row_idx, row in enumerate(rows, 1):\n",
" cols = row.find_all('td')\n",
" \n",
" if len(cols) < 7:\n",
" continue\n",
" \n",
" # 初始化当前 item\n",
" item = {\n",
" '单号': order_number,\n",
" '行号': row_idx,\n",
" }\n",
" \n",
" # 倒序填充字段\n",
" for field_name, col_index in field_order:\n",
" if col_index < len(cols):\n",
" # 当前列存在,正常提取\n",
" try:\n",
" item[field_name] = cols[col_index].get_text(strip=True)\n",
" except Exception:\n",
" item[field_name] = ''\n",
" else:\n",
" # 列不存在,尝试从上一行继承(除非被禁止)\n",
" if field_name in do_not_inherit_fields:\n",
" item[field_name] = '' # 不允许继承,留空\n",
" else:\n",
" item[field_name] = last_item.get(field_name, '') # 可以继承\n",
" \n",
" # 更新 last_item\n",
" last_item = item.copy()\n",
" \n",
" # 添加到 DataFrame\n",
" service_items_df = pd.concat([\n",
" service_items_df,\n",
" pd.DataFrame([item])\n",
" ], ignore_index=True)\n",
" \n",
" success = True\n",
" break # 成功则跳出重试循环\n",
"\n",
"\n",
" \n",
"\n",
" except Exception as e:\n",
" if attempt == 9: # 最后一次尝试仍然失败\n",
" print(f\"订单 {order_number} 处理失败,已达最大重试次数。错误: {str(e)}\")\n",
" # 记录失败订单(可选)\n",
" with open('failed_orders.txt', 'a') as f:\n",
" f.write(f\"{order_number}\\n\")\n",
" time.sleep(1) # 等待1秒后重试\n",
"\n",
" if not success:\n",
" continue # 跳过处理失败的订单\n",
" # break\n",
"\n",
"# ========== 3. 合并数据并保存 ==========\n",
"# 方法1:保存为两个关联表(推荐)\n",
"base_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\订单基本信息.xlsx'\n",
"items_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\消费项目明细.xlsx'\n",
"base_info_df.to_excel(base_output, index=False)\n",
"service_items_df.to_excel(items_output, index=False)\n",
"\n",
"# 方法2:合并为一个宽表(每行重复基本信息)\n",
"if not service_items_df.empty:\n",
" merged_df = pd.merge(\n",
" base_info_df,\n",
" service_items_df,\n",
" on='单号',\n",
" how='left'\n",
" )\n",
" merged_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\历史维修记录明细-15635606677.xlsx'\n",
" merged_df.to_excel(merged_output, index=False)\n",
"\n",
"print(\"\\n处理完成!\")\n",
"print(f\"- 基本信息保存至: {base_output}\")\n",
"print(f\"- 消费项目保存至: {items_output}\")\n",
"if not service_items_df.empty:\n",
" print(f\"- 合并数据保存至: {merged_output}\") # 输出:['57435']\n",
" "
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 0%| | 0/7946 [00:00<?, ?it/s]C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_12220\\1424788091.py:48: DeprecationWarning: The 'text' argument to find()-type methods is deprecated. Use 'string' instead.\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"处理订单: 0%| | 1/7946 [00:00<24:49, 5.34it/s]C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_12220\\1424788091.py:48: DeprecationWarning: The 'text' argument to find()-type methods is deprecated. Use 'string' instead.\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"处理订单: 31%|███ | 2441/7946 [12:04<34:15, 2.68it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"请求失败,第 1 次重试... 错误: HTTPConnectionPool(host='rp.chezizhu.com', port=80): Max retries exceeded with url: /ReportServer?_=1747275363838&__boxModel__=true&op=page_content&sessionID=7058&pn=1&__fit__=false (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000024EEAFAB080>, 'Connection to rp.chezizhu.com timed out. (connect timeout=10)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 36%|███▌ | 2851/7946 [15:04<36:00, 2.36it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"请求失败,第 1 次重试... 错误: HTTPConnectionPool(host='rp.chezizhu.com', port=80): Max retries exceeded with url: /ReportServer?_=1747275543553&__boxModel__=true&op=page_content&sessionID=55535&pn=1&__fit__=false (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000024EEE97B0E0>, 'Connection to rp.chezizhu.com timed out. (connect timeout=10)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 48%|████▊ | 3824/7946 [22:42<34:53, 1.97it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"请求失败,第 1 次重试... 错误: HTTPConnectionPool(host='rp.chezizhu.com', port=80): Max retries exceeded with url: /ReportServer?_=1747276001354&__boxModel__=true&op=page_content&sessionID=78866&pn=1&__fit__=false (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000024EE97A0A10>, 'Connection to rp.chezizhu.com timed out. (connect timeout=10)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 95%|█████████▌| 7578/7946 [1:03:49<04:32, 1.35it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"请求失败,第 1 次重试... 错误: HTTPConnectionPool(host='rp.chezizhu.com', port=80): Max retries exceeded with url: /ReportServer?_=1747278468348&__boxModel__=true&op=page_content&sessionID=24705&pn=1&__fit__=false (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000024EEE909580>, 'Connection to rp.chezizhu.com timed out. (connect timeout=10)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 100%|██████████| 7946/7946 [1:08:39<00:00, 1.93it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"处理完成!\n",
"- 基本信息保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\订单基本信息.xlsx\n",
"- 消费项目保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\消费项目明细.xlsx\n",
"- 合并数据保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\历史维修记录明细-15635606677.xlsx\n"
]
}
],
"execution_count": 4
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-05-09T02:12:23.607378Z",
"start_time": "2025-05-09T02:12:23.588256Z"
}
},
"cell_type": "code",
"source": [
"# ========== 3. 合并数据并保存 ==========\n",
"# 方法1:保存为两个关联表(推荐)\n",
"base_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\订单基本信息.xlsx'\n",
"items_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\消费项目明细.xlsx'\n",
"base_info_df.to_excel(base_output, index=False)\n",
"service_items_df.to_excel(items_output, index=False)\n",
"\n",
"# 方法2:合并为一个宽表(每行重复基本信息)\n",
"if not service_items_df.empty:\n",
" merged_df = pd.merge(\n",
" base_info_df,\n",
" service_items_df,\n",
" on='单号',\n",
" how='left'\n",
" )\n",
" merged_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\历史维修记录明细-古交腾飞路店13593189858.xlsx'\n",
" merged_df.to_excel(merged_output, index=False)\n",
"\n",
"print(\"\\n处理完成!\")\n",
"print(f\"- 基本信息保存至: {base_output}\")\n",
"print(f\"- 消费项目保存至: {items_output}\")\n",
"if not service_items_df.empty:\n",
" print(f\"- 合并数据保存至: {merged_output}\") # 输出:['57435']\n",
" "
],
"id": "2dad90815fd16898",
"outputs": [
{
"ename": "NameError",
"evalue": "name 'base_info_df' is not defined",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mNameError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[3], line 5\u001B[0m\n\u001B[0;32m 3\u001B[0m base_output \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mr\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mD:\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mIdea Project\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mF6+宜搭+其它(1)\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mnew\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m文件输出\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m订单基本信息.xlsx\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m 4\u001B[0m items_output \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mr\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mD:\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mIdea Project\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mF6+宜搭+其它(1)\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mnew\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m文件输出\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m消费项目明细.xlsx\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[1;32m----> 5\u001B[0m base_info_df\u001B[38;5;241m.\u001B[39mto_excel(base_output, index\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[0;32m 6\u001B[0m service_items_df\u001B[38;5;241m.\u001B[39mto_excel(items_output, index\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n\u001B[0;32m 8\u001B[0m \u001B[38;5;66;03m# 方法2:合并为一个宽表(每行重复基本信息)\u001B[39;00m\n",
"\u001B[1;31mNameError\u001B[0m: name 'base_info_df' is not defined"
]
}
],
"execution_count": 3
}
],
"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
}
@@ -0,0 +1,555 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "## 订单明细",
"id": "8bdaf70d574d1868"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-20T09:45:36.313844400Z",
"start_time": "2026-01-20T09:38:55.425173700Z"
}
},
"source": [
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"from bs4 import BeautifulSoup\n",
"import time\n",
"\n",
"all_data_list = []\n",
"for i in tqdm(range(1, 1303)):\n",
" time.sleep(0.2)\n",
" import requests\n",
"\n",
" headers = {\n",
" 'Accept': 'text/html, */*; q=0.01',\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",
" 'Referer': 'http://rp.chezizhu.com/ReportServer?reportlet=czz/order/order_detail_md.cpt&servicer_id=HyBKFgc2uCNtqs59aDZhc2&database=chezizhu_14',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" }\n",
"\n",
" params = {\n",
" '_': '1768901546535',\n",
" '__boxModel__': 'true',\n",
" 'op': 'page_content',\n",
" 'sessionID': '99282',\n",
" 'pn': i,\n",
" '__fit__': 'false',\n",
" }\n",
"\n",
" res = requests.get('http://rp.chezizhu.com/ReportServer', params=params, headers=headers, verify=False)\n",
"\n",
" # print(res.text)\n",
"\n",
" keys = [\n",
" \"单号\", \"用料\", \"图片\", \"客户姓名\", \"客户电话\", \"车牌号码\", \"车型\",\n",
" \"产品金额\", \"服务费\", \"上门费\", \"折扣金额\", \"折扣原因\", \"实收金额\",\n",
" \"结算方式\", \"新老用户\", \"订单来源\", \"下单方式\", \"服务类型\", \"服务商\",\n",
" \"技师\", \"下单时间\", \"预约时间\", \"完成时间\", \"评价状态\", \"工单状态\",\n",
" \"订单状态\", \"全车检测\", \"备注\"\n",
" ]\n",
" soup = BeautifulSoup(res.text, 'lxml')\n",
" for tr in soup.find_all('tr'):\n",
" tds = tr.find_all('td')\n",
" if \"单号\" in tds[0].text or \"总计\" in tds[0].text or \"订单列表\" in tds[\n",
" 0].text or \"注:红色订单为实收金额有误订单\" in tds[0].text:\n",
" continue\n",
" td_list = []\n",
" for td in tds:\n",
" td_list.append(td.text)\n",
"\n",
" order_dict = dict(zip(keys, td_list))\n",
" # print(order_dict)\n",
" all_data_list.append(order_dict)\n",
"\n",
"df = pd.DataFrame(all_data_list)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\大唛云订单明细-18135844455.xlsx', index=False)\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 1302/1302 [06:34<00:00, 3.30it/s]\n"
]
}
],
"execution_count": 6
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-20T09:34:49.479362100Z",
"start_time": "2026-01-20T09:34:49.180981Z"
}
},
"cell_type": "code",
"source": [
"df = pd.DataFrame(all_data_list)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\大唛云订单明细-18135844455.xlsx', index=False)"
],
"id": "a848bd6b4137743e",
"outputs": [],
"execution_count": 4
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 历史维修记录",
"id": "271853920f6210f"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-07-14T11:44:43.656887Z",
"start_time": "2025-07-14T09:38:43.922512Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import re\n",
"import time\n",
"\n",
"timestamp_ms = int(time.time() * 1000)\n",
"\n",
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"from bs4 import BeautifulSoup\n",
"from urllib.parse import urlencode, quote\n",
"import time\n",
"from requests.exceptions import RequestException\n",
"\n",
"# 读取Excel文件\n",
"df = pd.read_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\大唛云订单明细-18135844455.xlsx\")\n",
"\n",
"# 定义要提取的基本字段列表\n",
"BASE_FIELDS = [\n",
" '保险公司', '保险到期', '年检日期', '车架号',\n",
" '购车日期', '服务日期', '服务里程',\n",
" '下次服务日期', '下次服务里程'\n",
"]\n",
"\n",
"# 创建两个DataFrame分别存储不同类型的数据\n",
"base_info_df = df.copy() # 存储基本信息\n",
"service_items_df = pd.DataFrame() # 存储消费项目明细\n",
"\n",
"\n",
"def make_request_with_retry(url, headers, max_retries=10, retry_delay=1):\n",
" \"\"\"带重试机制的请求函数\"\"\"\n",
" for attempt in range(max_retries):\n",
" try:\n",
" res = requests.get(url=url, headers=headers, timeout=10)\n",
" res.raise_for_status()\n",
" return res\n",
" except RequestException as e:\n",
" if attempt == max_retries - 1:\n",
" raise\n",
" print(f\"请求失败,第 {attempt + 1} 次重试... 错误: {str(e)}\")\n",
" time.sleep(retry_delay)\n",
" return None\n",
" # print(res.text)\n",
"\n",
"\n",
"def extract_session_id(html_content):\n",
" soup = BeautifulSoup(html_content, \"html.parser\")\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"\n",
" session_ids = set()\n",
" for script in scripts:\n",
" # 匹配注册语句中的sessionid\n",
" register_match = re.search(r\"FR\\.SessionMgr\\.register\\('(\\d+)'\", script.text)\n",
" if register_match:\n",
" session_ids.add(register_match.group(1))\n",
"\n",
" # 匹配变量赋值中的sessionid\n",
" current_match = re.search(r\"currentSessionID\\s*=\\s*'(\\d+)'\", script.text)\n",
" if current_match:\n",
" session_ids.add(current_match.group(1))\n",
"\n",
" return list(session_ids)\n",
"\n",
"\n",
"for index, row in tqdm(list(df.iterrows()), desc=\"处理订单\"):\n",
" order_number = row[\"单号\"]\n",
" success = False\n",
" # print(f\"正在处理订单 {order_number}\")\n",
"\n",
" timestamp_ms = int(time.time() * 1000)\n",
" for attempt in range(10): # 最大重试次数\n",
" try:\n",
" url = (\n",
" \"http://rp.chezizhu.com/ReportServer?reportlet=/czz/order/order.cpt&__parameters__={%22_%22:%22\" + f\"{timestamp_ms}\" + \"%22,%22PINGJIA%22:[5b][5d],%22DISCOUNT_DESC%22:%22%22,%22B%22:%222011-05-01%22,%22LABELPLATE_NUMBER%22:%22%25E8%25BD%25A6%25E7%2589%258C%25E5%258F%25B7%22,%22LABELUSER_NAME%22:%22%25E5%25A7%2593%25E5%2590%258D%22,%22E%22:%222025-05-07%22,%22SERVICER%22:[5b][5d],%22CAR_NAME%22:%22%22,%22ORDER_SERVICE_TYPE%22:%22%22,%22order_number%22:%22\" + order_number + \"%22,%22USER_MOBILE%22:%22%22,%22LABELUSER_STATE%22:%22%25E6%2596%25B0%25E8%2580%2581%25E7%2594%25A8%25E6%2588%25B7%22,%22LABELCAR_NAME%22:%22%25E8%25BD%25A6%25E5%259E%258B%22,%22SERVICER_ID%22:%22683XGWqnyn66mE1oa8Gkzb%22,%22LABELORDER_SOURCE%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E6%259D%25A5%25E6%25BA%2590%22,%22LABELE%22:%22%25E8%2587%25B3%22,%22LABELSERVER%22:%22%25E9%2597%25A8%25E5%25BA%2597%22,%22LABELGONGDAN_STATUS%22:%22%25E5%25B7%25A5%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22LABELORDER_STATUS%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22ORDER_STATUS%22:[5b][5d],%22CMD%22:%22parameters_d%22,%22PAY_METHOD%22:%22%22,%22LABELUSER_MOBILE%22:%22%25E5%25AE%25A2%25E6%2588%25B7%25E7%2594%25B5%25E8%25AF%259D%22,%22LABELPINGJIA%22:%22%25E8%25AF%2584%25E4%25BB%25B7%25E7%258A%25B6%25E6%2580%2581%22,%22USER_STATE%22:[5b][5d],%22LABELRP_TYPE%22:%22%25E6%258A%25A5%25E8%25A1%25A8%25E7%25B1%25BB%25E5%259E%258B%22,%22LABELPAY_METHOD%22:%22%25E7%25BB%2593%25E7%25AE%2597%25E6%2596%25B9%25E5%25BC%258F%22,%22USER_NAME%22:%22%22,%22REPORTNAME%22:%22czz%252Forder%252Forder_detail_md.cpt%22,%22DISCOUNT_TYPE%22:%22%22,%22DATE_TYPE%22:%22%25E5%25AE%258C%25E6%2588%2590%25E6%2597%25A5%25E6%259C%259F%22,%22LABELDISCOUNT_DESC%22:%22%25E6%258A%2598%25E6%2589%25A3%25E5%258E%259F%25E5%259B%25A0%22,%22GONGDAN_STATUS%22:[5b][5d],%22__STREAMCLOSED__%22:%22%22,%22__pi__%22:%22true%22,%22CHANNEL%22:%22%22,%22DATABASE%22:%22chezizhu_14%22,%22ORDER_SOURCE%22:[5b][5d],%22LABELORDER_NUMBER%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E5%258F%25B7%22,%22PLATE_NUMBER%22:%22%22,%22RP_TYPE%22:%22%25E9%25AB%2598%25E7%25BA%25A7%25E6%2590%259C%25E7%25B4%25A2%22}\"\n",
" )\n",
"\n",
" headers = {\n",
" 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',\n",
" 'Accept-Encoding': 'gzip, deflate',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Cache-Control': 'max-age=0',\n",
" 'Connection': 'keep-alive',\n",
" 'Cookie': 'td_cookie=2912605941',\n",
" 'Host': 'rp.chezizhu.com',\n",
" 'Referer': 'http://rp.chezizhu.com/ReportServer?reportlet=czz/order/order_detail_md.cpt&servicer_id=CJRuYehLSqLqy4snS5bLoo&database=chezizhu_14',\n",
" 'Upgrade-Insecure-Requests': '1',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0'\n",
" }\n",
"\n",
" res = requests.get(url, headers=headers)\n",
"\n",
" session_ids = extract_session_id(res.text)\n",
" # print(\"提取到的SessionID:\", session_ids[0])\n",
" # ========== 请求部分 ==========\n",
" url = f\"http://rp.chezizhu.com/ReportServer?_={timestamp_ms}&__boxModel__=true&op=page_content&sessionID={session_ids[0]}&pn=1&__fit__=false\"\n",
"\n",
" headers = {\n",
" 'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate',\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",
" 'Cookie': 'td_cookie=2912605941',\n",
" 'Host': 'rp.chezizhu.com',\n",
" \"Referer\": \"http://rp.chezizhu.com/ReportServer?reportlet=/czz/order/order.cpt&__parameters__={%22_%22:%22\" + f\"{timestamp_ms}\" + \"%22,%22PINGJIA%22:[5b][5d],%22DISCOUNT_DESC%22:%22%22,%22B%22:%222010-07-01%22,%22LABELPLATE_NUMBER%22:%22%25E8%25BD%25A6%25E7%2589%258C%25E5%258F%25B7%22,%22LABELUSER_NAME%22:%22%25E5%25A7%2593%25E5%2590%258D%22,%22E%22:%222025-07-14%22,%22SERVICER%22:[5b][5d],%22CAR_NAME%22:%22%22,%22ORDER_SERVICE_TYPE%22:%22%22,%22order_number%22:%22\" + order_number + \"%22,%22USER_MOBILE%22:%22%22,%22LABELUSER_STATE%22:%22%25E6%2596%25B0%25E8%2580%2581%25E7%2594%25A8%25E6%2588%25B7%22,%22LABELCAR_NAME%22:%22%25E8%25BD%25A6%25E5%259E%258B%22,%22SERVICER_ID%22:%22CJRuYehLSqLqy4snS5bLoo%22,%22LABELORDER_SOURCE%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E6%259D%25A5%25E6%25BA%2590%22,%22LABELE%22:%22%25E8%2587%25B3%22,%22LABELSERVER%22:%22%25E9%2597%25A8%25E5%25BA%2597%22,%22LABELGONGDAN_STATUS%22:%22%25E5%25B7%25A5%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22LABELORDER_STATUS%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E7%258A%25B6%25E6%2580%2581%22,%22ORDER_STATUS%22:[5b][5d],%22CMD%22:%22parameters_d%22,%22PAY_METHOD%22:%22%22,%22LABELUSER_MOBILE%22:%22%25E5%25AE%25A2%25E6%2588%25B7%25E7%2594%25B5%25E8%25AF%259D%22,%22LABELPINGJIA%22:%22%25E8%25AF%2584%25E4%25BB%25B7%25E7%258A%25B6%25E6%2580%2581%22,%22USER_STATE%22:[5b][5d],%22LABELRP_TYPE%22:%22%25E6%258A%25A5%25E8%25A1%25A8%25E7%25B1%25BB%25E5%259E%258B%22,%22LABELPAY_METHOD%22:%22%25E7%25BB%2593%25E7%25AE%2597%25E6%2596%25B9%25E5%25BC%258F%22,%22USER_NAME%22:%22%22,%22REPORTNAME%22:%22czz%252Forder%252Forder_detail_md.cpt%22,%22DISCOUNT_TYPE%22:%22%22,%22DATE_TYPE%22:%22%25E5%25AE%258C%25E6%2588%2590%25E6%2597%25A5%25E6%259C%259F%22,%22LABELDISCOUNT_DESC%22:%22%25E6%258A%2598%25E6%2589%25A3%25E5%258E%259F%25E5%259B%25A0%22,%22GONGDAN_STATUS%22:[5b][5d],%22__STREAMCLOSED__%22:%22%22,%22__pi__%22:%22true%22,%22CHANNEL%22:%22%22,%22DATABASE%22:%22chezizhu_14%22,%22ORDER_SOURCE%22:[5b][5d],%22LABELORDER_NUMBER%22:%22%25E8%25AE%25A2%25E5%258D%2595%25E5%258F%25B7%22,%22PLATE_NUMBER%22:%22%22,%22RP_TYPE%22:%22%25E9%25AB%2598%25E7%25BA%25A7%25E6%2590%259C%25E7%25B4%25A2%22}\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
" }\n",
"\n",
" # 使用带重试的请求函数\n",
" res = make_request_with_retry(url, headers)\n",
" # print(res.text)\n",
"\n",
" soup = BeautifulSoup(res.text, 'lxml')\n",
"\n",
" # ========== 1. 提取基本信息(单行) ==========\n",
" base_info = {'单号': order_number} # 保留原始订单号\n",
"\n",
" for field in BASE_FIELDS:\n",
" field_td = soup.find('td', string=f'{field}')\n",
" if field_td:\n",
" value_td = field_td.find_next('td')\n",
" base_info[field] = value_td.get_text(strip=True) if value_td else None\n",
" else:\n",
" base_info[field] = None\n",
"\n",
" # 更新基本信息DataFrame\n",
" for col in base_info:\n",
" if col not in base_info_df.columns:\n",
" base_info_df[col] = None\n",
" base_info_df.at[index, col] = base_info[col]\n",
"\n",
" # ========== 2. 提取消费项目(多行) ==========\n",
" consumption_header = soup.find(lambda tag: tag.name == 'td' and '消费项目' in tag.text)\n",
" if consumption_header:\n",
" table = consumption_header.find_parent('table')\n",
" if table:\n",
" rows = table.find_all('tr')[1:] # 跳过表头\n",
"\n",
" for row_idx, row in enumerate(rows, 1):\n",
" cols = row.find_all('td')\n",
" if len(cols) >= 6:\n",
" item = {\n",
" '单号': order_number,\n",
" '行号': row_idx,\n",
" '套餐': cols[0].get_text(strip=True) if len(cols) > 0 else '',\n",
" '服务项目': cols[1].get_text(strip=True) if len(cols) > 1 else '',\n",
" '产品名称': cols[2].get_text(strip=True) if len(cols) > 2 else '',\n",
" '产品型号': cols[3].get_text(strip=True) if len(cols) > 3 else '',\n",
" '数量': cols[4].get_text(strip=True) if len(cols) > 4 else '',\n",
" '规格': cols[5].get_text(strip=True) if len(cols) > 5 else '',\n",
" '单位': cols[6].get_text(strip=True) if len(cols) > 6 else '',\n",
" '单价': cols[7].get_text(strip=True) if len(cols) > 7 else '',\n",
" '产品小计': cols[8].get_text(strip=True) if len(cols) > 8 else '',\n",
" '工时': cols[9].get_text(strip=True) if len(cols) > 9 else '',\n",
" '合计': cols[10].get_text(strip=True) if len(cols) > 10 else ''\n",
" }\n",
"\n",
" # 添加到消费项目DataFrame\n",
" service_items_df = pd.concat([\n",
" service_items_df,\n",
" pd.DataFrame([item])\n",
" ], ignore_index=True)\n",
" # print(item)\n",
"\n",
" success = True\n",
" break # 成功则跳出重试循环\n",
"\n",
" except Exception as e:\n",
" if attempt == 9: # 最后一次尝试仍然失败\n",
" print(f\"订单 {order_number} 处理失败,已达最大重试次数。错误: {str(e)}\")\n",
" # 记录失败订单(可选)\n",
" with open('failed_orders.txt', 'a') as f:\n",
" f.write(f\"{order_number}\\n\")\n",
" time.sleep(1) # 等待1秒后重试\n",
"\n",
" if not success:\n",
" continue # 跳过处理失败的订单\n",
" # break\n",
"\n",
"# ========== 3. 合并数据并保存 ==========\n",
"# 方法1:保存为两个关联表(推荐)\n",
"base_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\订单基本信息.xlsx'\n",
"items_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\消费项目明细.xlsx'\n",
"base_info_df.to_excel(base_output, index=False)\n",
"service_items_df.to_excel(items_output, index=False)\n",
"\n",
"# 方法2:合并为一个宽表(每行重复基本信息)\n",
"if not service_items_df.empty:\n",
" merged_df = pd.merge(\n",
" base_info_df,\n",
" service_items_df,\n",
" on='单号',\n",
" how='left'\n",
" )\n",
" merged_output = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\历史维修记录明细-古交腾飞路店13593189858.xlsx'\n",
" merged_df.to_excel(merged_output, index=False)\n",
"\n",
"print(\"\\n处理完成!\")\n",
"print(f\"- 基本信息保存至: {base_output}\")\n",
"print(f\"- 消费项目保存至: {items_output}\")\n",
"if not service_items_df.empty:\n",
" print(f\"- 合并数据保存至: {merged_output}\") # 输出:['57435']"
],
"id": "ed2755053dd426c",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 0%| | 0/10868 [00:00<?, ?it/s]C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_4532\\3409432529.py:48: DeprecationWarning: The 'text' argument to find()-type methods is deprecated. Use 'string' instead.\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"处理订单: 0%| | 1/10868 [00:00<28:50, 6.28it/s]C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_4532\\3409432529.py:48: DeprecationWarning: The 'text' argument to find()-type methods is deprecated. Use 'string' instead.\n",
" scripts = soup.find_all(\"script\", text=re.compile(r\"(FR\\.SessionMgr\\.register|currentSessionID)\"))\n",
"处理订单: 18%|█▊ | 1974/10868 [09:20<50:33, 2.93it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"请求失败,第 1 次重试... 错误: HTTPConnectionPool(host='rp.chezizhu.com', port=80): Max retries exceeded with url: /ReportServer?_=1752486488556&__boxModel__=true&op=page_content&sessionID=26250&pn=1&__fit__=false (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000002C3E3298E90>, 'Connection to rp.chezizhu.com timed out. (connect timeout=10)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"处理订单: 100%|██████████| 10868/10868 [2:03:15<00:00, 1.47it/s] \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"处理完成!\n",
"- 基本信息保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\订单基本信息.xlsx\n",
"- 消费项目保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\消费项目明细.xlsx\n",
"- 合并数据保存至: D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\历史维修记录明细-古交腾飞路店13593189858.xlsx\n"
]
}
],
"execution_count": 12
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 库存 (页面已支持导出)",
"id": "5e7ac3ee321a3549"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-16T09:51:20.409717Z",
"start_time": "2025-04-16T09:51:13.116335Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"from bs4 import BeautifulSoup\n",
"from urllib.parse import urlencode, quote\n",
"import time\n",
"from requests.exceptions import RequestException\n",
"\n",
"url = \"http://sp.chezizhu.com/alliance/store/list.htm\"\n",
"header = {\n",
" \"content-type\": \"application/x-www-form-urlencoded; charset=UTF-8\",\n",
" \"cookie\": \"JSESSIONID=28FFBA865A6CAAA76CB8CDB6A34B5886\",\n",
" \"host\": \"sp.chezizhu.com\",\n",
" \"origin\": \"http://sp.chezizhu.com\",\n",
" \"referer\": \"http://sp.chezizhu.com/alliance/index.htm\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0\",\n",
" \"x-requested-with\": \"XMLHttpRequest\"\n",
"}\n",
"all_data = []\n",
"for i in tqdm(range(1, 103)):\n",
" data = f'pageNum={i}&pageSize=20&dataType=json&keywords='\n",
"\n",
" res = requests.post(url, headers=header, data=data)\n",
" data_list = res.json().get(\"list\", [])\n",
"\n",
" for data in data_list:\n",
" tp_number = data.get(\"tp_number\")\n",
" damai_id = data.get(\"damai_id\")\n",
" prod_name = data.get(\"prod_name\")\n",
" price = data.get(\"price\")\n",
" standard = data.get(\"standard\")\n",
" unit = data.get(\"unit\")\n",
" count = data.get(\"count\")\n",
" check_count = data.get(\"check_count\")\n",
" check_date = data.get(\"check_date\")\n",
"\n",
" all_data.append([tp_number, damai_id, prod_name, price, standard, unit, count, check_count, check_date])\n",
"\n",
"df = pd.DataFrame(all_data,\n",
" columns=[\"tp_number\", \"damai_id\", \"prod_name\", \"price\", \"standard\", \"unit\", \"count\", \"check_count\",\n",
" \"check_date\"])\n",
"df.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\库存.xlsx\", index=False)\n",
"\n",
"\n",
"\n"
],
"id": "95616ee8b933e5ce",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 102/102 [00:07<00:00, 14.43it/s]\n"
]
}
],
"execution_count": 52
},
{
"metadata": {},
"cell_type": "markdown",
"source": "",
"id": "70a45b885b2739c"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 销售明细",
"id": "7df1375e5debe404"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-07-15T01:34:31.895645Z",
"start_time": "2025-07-15T01:32:17.223368Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"from bs4 import BeautifulSoup\n",
"\n",
"all_data_list = []\n",
"keys = [\"门店\", \"订单编号\", \"产品类型\", \"产品名称\", \"型号\", \"数量\", \"采购单价\", \"销售单价\",\n",
" \"采购金额\", \"销售金额\", \"毛利润\", \"下单人\", \"接单人\", \"车牌号\"]\n",
"reversed_keys = list(reversed(keys))\n",
"\n",
"for i in tqdm(range(1, 1390)):\n",
" url = f\"http://rp.chezizhu.com/ReportServer?_=1752541860351&__boxModel__=true&op=page_content&sessionID=91877&pn={i}&__fit__=false\"\n",
"\n",
" header = {\n",
" \"Referer\": \"http://rp.chezizhu.com/ReportServer?reportlet=czz/storage/prod_sale_dtl_jm.cpt&servicer_id=CJRuYehLSqLqy4snS5bLoo&hideexport=true&database=chezizhu_14\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
" }\n",
"\n",
" while True:\n",
" try:\n",
" res = requests.post(url, headers=header)\n",
" break\n",
" except RequestException as e:\n",
" print(f\"请求失败,正在重试... 错误信息:{str(e)}\")\n",
" time.sleep(1)\n",
" soup = BeautifulSoup(res.text, \"html.parser\")\n",
"\n",
" # 定位真正的数据行(跳过标题行)\n",
" for tr in soup.select('tr:not(:has(th))'): # 排除包含表头的行\n",
" tds = [td.get_text(strip=True) for td in tr.find_all(\"td\")]\n",
" reversed_tds = list(reversed(tds))\n",
"\n",
" # 如果 reversed_tds 长度不够,填充空字符串\n",
" if len(reversed_tds) < len(reversed_keys):\n",
" reversed_tds += [\"\"] * (len(reversed_keys) - len(reversed_tds))\n",
" elif len(reversed_tds) > len(reversed_keys):\n",
" reversed_tds = reversed_tds[:len(reversed_keys)]\n",
"\n",
" # 构建字典(反转后的 keys 和 tds\n",
" row_data = dict(zip(reversed_keys, reversed_tds))\n",
" all_data_list.append(row_data)\n",
"\n",
" # break\n",
"# print(all_data_list)\n",
"df = pd.DataFrame(all_data_list)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\大唛云销售明细.xlsx', index=False)"
],
"id": "b3100f77cc1061b1",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 1389/1389 [02:09<00:00, 10.70it/s]\n"
]
}
],
"execution_count": 14
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-29T07:16:14.900349Z",
"start_time": "2025-04-29T07:16:07.255065Z"
}
},
"cell_type": "code",
"source": [
"df = pd.DataFrame(all_data_list)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\大唛云销售明细-古交腾飞路店13593189858.xlsx', index=False)"
],
"id": "7671bfd65cc413c7",
"outputs": [],
"execution_count": 9
}
],
"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
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,448 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 客户车辆信息导出"
]
},
{
"cell_type": "code",
"metadata": {
"ExecuteTime": {
"end_time": "2025-07-08T01:22:38.302541Z",
"start_time": "2025-07-08T01:21:21.261993Z"
}
},
"source": [
"from selenium import webdriver\n",
"from selenium.webdriver.support.ui import Select\n",
"from selenium.webdriver import ActionChains\n",
"import time\n",
"import xlrd\n",
"import xlwt\n",
"import re\n",
"import datetime\n",
"from xlutils.copy import copy\n",
"from selenium.webdriver.common.keys import Keys\n",
"from selenium.webdriver.common.action_chains import ActionChains\n",
"from selenium.webdriver.common.by import By\n",
"import pandas as pd\n",
"\n",
"# 登录\n",
"name = '13568162018'\n",
"password = 'a123456'\n",
"option_chrome = webdriver.ChromeOptions()\n",
"option_chrome.add_argument('--headless')\n",
"http='https://qixiu.dada365.com/login'\n",
"from selenium import webdriver\n",
"from selenium.webdriver.chrome.service import Service\n",
"\n",
"# 如果 ChromeDriver 已经添加到系统的 PATH 中,可以这样写:\n",
"service = Service()\n",
"\n",
"# 如果 ChromeDriver 没有在 PATH 中,则需要指定其路径:\n",
"service = Service(executable_path=r\"D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe\")\n",
"\n",
"# 创建一个新的 Chrome 浏览器实例\n",
"driver = webdriver.Chrome(service=service)\n",
"\n",
"# 打开大大汽修平台登录页面\n",
"driver.get(http)\n",
"# driver = webdriver.Chrome(executable_path=r\"D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe\")\n",
"driver.maximize_window()\n",
"driver.implicitly_wait(1)\n",
"driver.get(http)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[1]/div/div/input').send_keys(name)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[2]/div/div/input').send_keys(password)\n",
"time.sleep(3)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[4]/div/button/span').click()\n",
"time.sleep(3)\n",
"# 点击车辆管理\n",
"\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[1]/div[1]/ul/div/div[3]/li/div/span').click()\n",
"# driver.find_element(By.XPATH,'(//div[@id=\"app\"]//ul/div[1]/div[3])[1]').click()\n",
"time.sleep(2)\n",
"# 点击车辆查询\n",
"driver.find_element(By.XPATH,'/html/body/div[2]/ul/li[1]/span').click()\n",
"time.sleep(3)\n",
"# 点击500条每页\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[2]/div[3]/div/span[2]/div/div/span/span/i').click()\n",
"\n",
"time.sleep(3)\n",
"driver.find_element(By.XPATH,'/html/body/div[3]/div[1]/div[1]/ul/li[6]/span').click()\n",
"\n",
"# 点击查看\n",
"time.sleep(10)\n",
"# for a in range(1,3):\n",
"for i in range(1,501):\n",
" try:\n",
" driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[2]/div[2]/div/div[2]/div[3]/table/tbody/tr[%s]/td[13]/div/button[1]/span'%i).click()\n",
" time.sleep(2)\n",
" car_no=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/span[1]') \n",
" name=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/span[2]')\n",
" print(2)\n",
"\n",
" phone_num=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[1]/li[1]')\n",
" print(3) \n",
" identity_num=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[1]/li[2]')\n",
" print(4)\n",
" insur_com=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[1]/li[3]')\n",
" print(5)\n",
" \n",
" insur_date=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[1]/li[4]')\n",
"\n",
" vin_num=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[2]/li[1]')\n",
" print(6)\n",
" car_modle=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[2]/li[2]/strong/span')\n",
" print(7)\n",
" engin_num=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[2]/li[3]')\n",
" car_date=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[2]/li[4]')\n",
" memo=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/div[4]/ul[5]/li/span[2]')\n",
" print(8)\n",
" print(car_no.text,\"@\",name.text,\"@\",phone_num.text,\"@\",identity_num.text,\"@\",insur_com.text,\"@\",vin_num.text,\"@\",car_modle.text,\"@\", memo.text)\n",
" driver.find_element(By.XPATH,'//*[@id=\"tab-item-2\"]/span[2]').click()\n",
" except:\n",
" print(\"有误\")\n",
" driver.find_element(By.XPATH,'//*[@id=\"tab-item-2\"]/span[2]').click()\n",
" # driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[2]/div[3]/div/ul/li[%s]'%a).click()\n",
" "
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SX3667 @ 何 @ 车主电话: 13982846671 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: JF1GP25C2DG065475 @ 斯巴鲁 XV XV 2.0 2012年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S339X6 @ 李 @ 车主电话: 18582830888 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LSVAK2185B2333118 @ 大众 朗逸 朗逸 1.6 2011年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SEZ717 @ 周欣 @ 车主电话: 15882942902 @ 身份证号码: 513001199312051019 @ 保险公司: 暂无 @ 车架号: LC0CG4DF7G0013987 @ 比亚迪 元 元 1.5 2016年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S250K0 @ 李 @ 车主电话: 15281866877 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LVSHFCAC5MS221747 @ 福特 锐际 锐际 2.0 2020年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SFT881 @ 唐艳 @ 车主电话: 15390125925 @ 身份证号码: 513023197405246746 @ 保险公司: 暂无 @ 车架号: LSVX065N9E2159128 @ 大众 途观 途观 1.8 2015年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SWZ316 @ 13982824053 @ 车主电话: 18780800015 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LHGCV1641L9001579 @ 本田 雅阁 第十代雅阁 1.5 2018年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S09F2T @ 袁远 @ 车主电话: 18481969666 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: WBA8X3103JBM92377 @ 宝马 3 Series [3系] GT 320i 2.0 2018年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川Y63V90 @ 阳 @ 车主电话: 18282745485 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LSVDU2BM6KN101225 @ 大众 凌渡 凌渡 1.4 2019年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S158V9 @ 魏 @ 车主电话: 15882940035 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LS4ASB2E7FA702842 @ 长安商用 欧诺 欧诺 1.5 2012年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SQ226F @ 雷亚军 @ 车主电话: 13547247727 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LZWDAAGA1C7215513 @ 五菱 荣光 荣光小卡 1.2 2010年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S97Q07 @ 卢姐 @ 车主电话: 13808241818 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: W1KUG5GB6LA533010 @ 奔驰 S-Class [S级] S 350 L 48V 3.0 2020年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S90E91 @ 杨 @ 车主电话: 13228276199 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LFPM4APE0J1A23984 @ 马自达 CX-4 CX-4 2.0 2018年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SYJ559 @ 李 @ 车主电话: 17760078550 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LGBM4AE44MS462782 @ 日产 奇骏 奇骏 2.0 2021年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S1D278 @ 罗 @ 车主电话: 13882895869 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LGWDBE194MB010263 @ 长城 风骏 风骏5 2.0 2021年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SEH608 @ 张 @ 车主电话: 15775628388 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LSV7N60T7M2026048 @ 大众 途观 途观L R-Line 2.0 2021年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"渝AFV6238 @ 王 @ 车主电话: 19160657666 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LB378LCZ3PB132953 @ 银河 L7 L7 1.5 2023年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川S8U220 @ 李 @ 车主电话: 18982881545 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LS5A3DEE9KA422866 @ 长安 CS55 CS55 1.5 2019年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川SD99133 @ 卢 @ 车主电话: 15228099005 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: LJ1E6A2UXRG009850 @ 蔚来 ES6 ES6 电动 2023年款 @ 暂无\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"川G8HE47 @ 孙 @ 车主电话: 18398080313 @ 身份证号码: 暂无 @ 保险公司: 暂无 @ 车架号: W0LLB6E02DB057005 @ 欧宝 Antara [安德拉] Antara [安德拉] 2.4 2013年款 @ 暂无\n",
"有误\n"
]
},
{
"ename": "InvalidSessionIdException",
"evalue": "Message: invalid session id\nStacktrace:\n\tGetHandleVerifier [0x0x7ff6d1fccda5+78885]\n\tGetHandleVerifier [0x0x7ff6d1fcce00+78976]\n\t(No symbol) [0x0x7ff6d1d899fc]\n\t(No symbol) [0x0x7ff6d1dd07df]\n\t(No symbol) [0x0x7ff6d1e08a52]\n\t(No symbol) [0x0x7ff6d1e03413]\n\t(No symbol) [0x0x7ff6d1e024d9]\n\t(No symbol) [0x0x7ff6d1d55d55]\n\tGetHandleVerifier [0x0x7ff6d22a4eed+3061101]\n\tGetHandleVerifier [0x0x7ff6d229f33d+3037629]\n\tGetHandleVerifier [0x0x7ff6d22be592+3165202]\n\tGetHandleVerifier [0x0x7ff6d1fe730e+186766]\n\tGetHandleVerifier [0x0x7ff6d1feeb3f+217535]\n\t(No symbol) [0x0x7ff6d1d54dca]\n\tGetHandleVerifier [0x0x7ff6d23c45e8+4238440]\n\tBaseThreadInitThunk [0x0x7ffa253de8d7+23]\n\tRtlUserThreadStart [0x0x7ffa25ddc34c+44]\n",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mInvalidSessionIdException\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[6], line 65\u001B[0m\n\u001B[0;32m 64\u001B[0m time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;241m2\u001B[39m)\n\u001B[1;32m---> 65\u001B[0m car_no\u001B[38;5;241m=\u001B[39mdriver\u001B[38;5;241m.\u001B[39mfind_element(By\u001B[38;5;241m.\u001B[39mXPATH,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m//*[@id=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mapp\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m]/div/div[2]/div[2]/div[3]/div[1]/span[1]\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m 66\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;241m1\u001B[39m) \n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:748\u001B[0m, in \u001B[0;36mWebDriver.find_element\u001B[1;34m(self, by, value)\u001B[0m\n\u001B[0;32m 746\u001B[0m value \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m[name=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mvalue\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m]\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[1;32m--> 748\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mexecute(Command\u001B[38;5;241m.\u001B[39mFIND_ELEMENT, {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124musing\u001B[39m\u001B[38;5;124m\"\u001B[39m: by, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m: value})[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m]\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:354\u001B[0m, in \u001B[0;36mWebDriver.execute\u001B[1;34m(self, driver_command, params)\u001B[0m\n\u001B[0;32m 353\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m response:\n\u001B[1;32m--> 354\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39merror_handler\u001B[38;5;241m.\u001B[39mcheck_response(response)\n\u001B[0;32m 355\u001B[0m response[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_unwrap_value(response\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m))\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\errorhandler.py:229\u001B[0m, in \u001B[0;36mErrorHandler.check_response\u001B[1;34m(self, response)\u001B[0m\n\u001B[0;32m 228\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace, alert_text) \u001B[38;5;66;03m# type: ignore[call-arg] # mypy is not smart enough here\u001B[39;00m\n\u001B[1;32m--> 229\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace)\n",
"\u001B[1;31mInvalidSessionIdException\u001B[0m: Message: invalid session id: session deleted as the browser has closed the connection\nfrom disconnected: not connected to DevTools\n (Session info: chrome=138.0.7204.97)\nStacktrace:\n\tGetHandleVerifier [0x0x7ff6d1fccda5+78885]\n\tGetHandleVerifier [0x0x7ff6d1fcce00+78976]\n\t(No symbol) [0x0x7ff6d1d89bca]\n\t(No symbol) [0x0x7ff6d1d759b5]\n\t(No symbol) [0x0x7ff6d1d9a9ca]\n\t(No symbol) [0x0x7ff6d1e105e5]\n\t(No symbol) [0x0x7ff6d1e30b42]\n\t(No symbol) [0x0x7ff6d1e08963]\n\t(No symbol) [0x0x7ff6d1dd16b1]\n\t(No symbol) [0x0x7ff6d1dd2443]\n\tGetHandleVerifier [0x0x7ff6d22a4eed+3061101]\n\tGetHandleVerifier [0x0x7ff6d229f33d+3037629]\n\tGetHandleVerifier [0x0x7ff6d22be592+3165202]\n\tGetHandleVerifier [0x0x7ff6d1fe730e+186766]\n\tGetHandleVerifier [0x0x7ff6d1feeb3f+217535]\n\tGetHandleVerifier [0x0x7ff6d1fd59b4+114740]\n\tGetHandleVerifier [0x0x7ff6d1fd5b69+115177]\n\tGetHandleVerifier [0x0x7ff6d1fbc368+10728]\n\tBaseThreadInitThunk [0x0x7ffa253de8d7+23]\n\tRtlUserThreadStart [0x0x7ffa25ddc34c+44]\n",
"\nDuring handling of the above exception, another exception occurred:\n",
"\u001B[1;31mInvalidSessionIdException\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[6], line 91\u001B[0m\n\u001B[0;32m 89\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m:\n\u001B[0;32m 90\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m有误\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m---> 91\u001B[0m driver\u001B[38;5;241m.\u001B[39mfind_element(By\u001B[38;5;241m.\u001B[39mXPATH,\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m//*[@id=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtab-item-2\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m]/span[2]\u001B[39m\u001B[38;5;124m'\u001B[39m)\u001B[38;5;241m.\u001B[39mclick()\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:748\u001B[0m, in \u001B[0;36mWebDriver.find_element\u001B[1;34m(self, by, value)\u001B[0m\n\u001B[0;32m 745\u001B[0m by \u001B[38;5;241m=\u001B[39m By\u001B[38;5;241m.\u001B[39mCSS_SELECTOR\n\u001B[0;32m 746\u001B[0m value \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m[name=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mvalue\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m]\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[1;32m--> 748\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mexecute(Command\u001B[38;5;241m.\u001B[39mFIND_ELEMENT, {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124musing\u001B[39m\u001B[38;5;124m\"\u001B[39m: by, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m: value})[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m]\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:354\u001B[0m, in \u001B[0;36mWebDriver.execute\u001B[1;34m(self, driver_command, params)\u001B[0m\n\u001B[0;32m 352\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcommand_executor\u001B[38;5;241m.\u001B[39mexecute(driver_command, params)\n\u001B[0;32m 353\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m response:\n\u001B[1;32m--> 354\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39merror_handler\u001B[38;5;241m.\u001B[39mcheck_response(response)\n\u001B[0;32m 355\u001B[0m response[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_unwrap_value(response\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m))\n\u001B[0;32m 356\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m response\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\errorhandler.py:229\u001B[0m, in \u001B[0;36mErrorHandler.check_response\u001B[1;34m(self, response)\u001B[0m\n\u001B[0;32m 227\u001B[0m alert_text \u001B[38;5;241m=\u001B[39m value[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124malert\u001B[39m\u001B[38;5;124m\"\u001B[39m]\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtext\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[0;32m 228\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace, alert_text) \u001B[38;5;66;03m# type: ignore[call-arg] # mypy is not smart enough here\u001B[39;00m\n\u001B[1;32m--> 229\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace)\n",
"\u001B[1;31mInvalidSessionIdException\u001B[0m: Message: invalid session id\nStacktrace:\n\tGetHandleVerifier [0x0x7ff6d1fccda5+78885]\n\tGetHandleVerifier [0x0x7ff6d1fcce00+78976]\n\t(No symbol) [0x0x7ff6d1d899fc]\n\t(No symbol) [0x0x7ff6d1dd07df]\n\t(No symbol) [0x0x7ff6d1e08a52]\n\t(No symbol) [0x0x7ff6d1e03413]\n\t(No symbol) [0x0x7ff6d1e024d9]\n\t(No symbol) [0x0x7ff6d1d55d55]\n\tGetHandleVerifier [0x0x7ff6d22a4eed+3061101]\n\tGetHandleVerifier [0x0x7ff6d229f33d+3037629]\n\tGetHandleVerifier [0x0x7ff6d22be592+3165202]\n\tGetHandleVerifier [0x0x7ff6d1fe730e+186766]\n\tGetHandleVerifier [0x0x7ff6d1feeb3f+217535]\n\t(No symbol) [0x0x7ff6d1d54dca]\n\tGetHandleVerifier [0x0x7ff6d23c45e8+4238440]\n\tBaseThreadInitThunk [0x0x7ffa253de8d7+23]\n\tRtlUserThreadStart [0x0x7ffa25ddc34c+44]\n"
]
}
],
"execution_count": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 维修历史导出"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from selenium import webdriver\n",
"from selenium.webdriver.support.ui import Select\n",
"from selenium.webdriver import ActionChains\n",
"import time\n",
"import xlrd\n",
"import xlwt\n",
"import re\n",
"import datetime\n",
"from xlutils.copy import copy\n",
"from selenium.webdriver.common.keys import Keys\n",
"from selenium.webdriver.common.action_chains import ActionChains\n",
"from selenium.webdriver.common.by import By\n",
"import pandas as pd\n",
"\n",
"# 登录\n",
"name = '18132039923'\n",
"password = 'jl123456'\n",
"option_chrome = webdriver.ChromeOptions()\n",
"option_chrome.add_argument('--headless')\n",
"http='https://qixiu.dada365.com/login'\n",
"driver = webdriver.Chrome(executable_path=r'C:\\chromedriver\\chromedriver_99\\chromedriver.exe')\n",
"driver.maximize_window()\n",
"driver.implicitly_wait(1)\n",
"driver.get(http)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[1]/div/div/input').send_keys(name)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[2]/div/div/input').send_keys(password)\n",
"time.sleep(1)\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div/div/div/form/div[4]/div/button/span').click()\n",
"time.sleep(4)\n",
"# 点击工单管理\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[1]/div[1]/ul/div/div[2]/li/div/span').click()\n",
"time.sleep(2)\n",
"# 点击工单查询\n",
"driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[1]/div[1]/div[1]/ul/li[1]/div/p').click()\n",
"\n",
"# '/html/body/div[3]/ul/li[2]/span'\n",
"# 点击已收款\n",
"driver.find_element(By.XPATH,'//*[@id=\"tab-paid\"]').click()\n",
"# 点击500条每页\n",
"time.sleep(2)\n",
"driver.find_element(By.XPATH,'//*[@id=\"pane-paid\"]/div/div[2]/div/span[2]/div/div[1]/span/span/i').click()\n",
"\n",
"time.sleep(3)\n",
"driver.find_element(By.XPATH,'//html/body/div[3]/div[1]/div[1]/ul/li[6]/span').click()\n",
"\n",
"# 点击查看\n",
"for j in range(2,5):\n",
" for h in range(1,501):\n",
" driver.find_element(By.XPATH,'//*[@id=\"pane-paid\"]/div/div[1]/div/div[3]/table/tbody/tr[%s]/td[10]/div/div/button[1]/span'%h).click()\n",
" time.sleep(2)\n",
" GD_num=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[1]/ul/li[1]')\n",
" start_date=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[2]/li[1]')\n",
" car_no_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[1]/li[1]')\n",
" name_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[1]/li[2]')\n",
" phone_num_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[1]/li[3]')\n",
" car_model_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[1]/li[4]/strong')\n",
" mile=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[2]/li[2]')\n",
" tech_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[2]/li[3]')\n",
" vin_GD=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[2]/ul[2]/li[4]')\n",
" print()\n",
" print(GD_num.text,\"@\",start_date.text,\"@\",car_no_GD.text,\"@\",name_GD.text,\"@\",phone_num_GD.text,\"@\",car_model_GD.text,\"@\",mile.text,\"@\",tech_GD.text,\"@\",vin_GD.text,\"@\")\n",
" try:\n",
" for c in range(2,100):\n",
" print(GD_num.text,end=\" 材料历史:\")\n",
" for d in range(2,15):\n",
" cl=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[3]/div[2]/table/tr[%s]/td[%s]'%(c,d))\n",
" print(cl.text,end=\"@\")\n",
" if d==14:\n",
" print()\n",
" except:\n",
" pass\n",
" print()\n",
" try:\n",
" for e in range(2,100):\n",
" print(GD_num.text,end=\" 项目历史:\")\n",
" for f in range(2,8):\n",
" if cl.text!=\"\":\n",
" xm=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div/div[3]/div[4]/table/tr[%s]/td[%s]'%(e,f))\n",
" # //*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[3]/div[4]/table/tr[2]/td[2]/span\n",
" # //*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[3]/div[4]/table/tr[2]/td[3]\n",
" # //*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[3]/div[4]/table/tr[2]/td[4]\n",
" # //*[@id=\"app\"]/div/div[2]/div[2]/div[3]/div[3]/div[4]/table/tr[2]/td[7]\n",
" else:\n",
" xm=driver.find_element(By.XPATH,'//*[@id=\"app\"]/div/div[2]/div[2]/div/div[4]/div[2]/table/tr[%s]/td[%s]/span'%(e,f))\n",
" print(xm.text,end=\"@\")\n",
" if f==7:\n",
" print()\n",
" except:\n",
" pass\n",
" driver.find_element(By.XPATH,'//*[@id=\"tab-item-2\"]/span[2]').click()\n",
"# 翻页\n",
" driver.find_element(By.XPATH,'//*[@id=\"pane-paid\"]/div/div[2]/div/ul/li[%s]'%j).click()"
]
}
],
"metadata": {
"interpreter": {
"hash": "59310123ccd3619229d524789fb6029e22b3ae7206c94adf033078aa9a774872"
},
"kernelspec": {
"display_name": "Python 3.9.6 ('F6')",
"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.9.6"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,156 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1787\n",
"数据已成功导出到car_data.xlsx\n"
]
}
],
"source": [
"import requests\n",
"from bs4 import BeautifulSoup\n",
"import pandas as pd\n",
"\n",
"pageSize = 10000\n",
"url = 'https://s19.kehu51.com/app/Customers/CusTools.aspx?action=GetGridData'\n",
"\n",
"json = f'showID=3&viewName=mycus&gridName=cuslistnew2&configGuid=&whereSql=E513575924A85785&sortName=lastfollowtime&sortMode=desc&pageSize={pageSize}&pageIndex=1&recordCount=1787&isComb=false&combName=&combIntTemp=_comb&completeSql=E513575924A85785&customParam=%7B%22field%22%3A%22selectUserID%22%2C%22key%22%3A0%7D'\n",
"# 构建请求头\n",
"headers = {\n",
" 'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate, br, zstd',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Content-Length': '299',\n",
" 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'Cookie': 'kehu51_user=18735521522; kehu51_pass=Xx123456; kehu51_server_username=cc9c4b66f19ec7ae6d489e6caaaceb0d; kehu51_server_serverid=19; ASP.NET_SessionId=lvhtxdfjbuymrsryoczhn5mi; teamCreateManID=0jkmaY3RdeFj2HX4WrJN5Q==; kehu51cookie=6958BDD7DCEADF0A83775994EFD09E5D722AF537BFB0741BB8E35CE4807E32F48097A08E3C914A52730C3D4B09AF6C9524BAA937C4EF2AF773D396081027AE7EA29932D831A19FA4D145E78564F9A85D63C305EE0B8DD39B2178B00340B34D3BEF70D88C8EF4FE02BC0EF6601A6B1F0FB762CBDAE71DDE08C27E62F90CCF7E155E41C9983E3327F67C170BF17387753B3B26C7D353085F23A2111D62896C9EE93174D53C5EB23DF8569C5FF49E615D498D62CEAA6DB5C73176112ACEA5DB5501C1A1B71C0B470239831165C0EB939B753AB79B0323E9AA06',\n",
" 'Origin': 'https://s19.kehu51.com',\n",
" 'Priority': 'u=1, i',\n",
" 'Referer': 'https://s19.kehu51.com/App/customers/cuslist.aspx?viewname=mycus&templateid=',\n",
" 'Sec-Ch-Ua': '\"Chromium\";v=\"130\", \"Microsoft Edge\";v=\"130\", \"Not?A_Brand\";v=\"99\"',\n",
" 'Sec-Ch-Ua-Mobile': '?0',\n",
" 'Sec-Ch-Ua-Platform': '\"Windows\"',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest'\n",
"}\n",
"\n",
"res = requests.post(url=url,data = json,headers=headers)\n",
"\n",
"data = res.json()\n",
"\n",
"gridHtml = data['gridHtml']\n",
"\n",
"soup = BeautifulSoup(gridHtml, 'lxml') # 使用lxml解析器\n",
"\n",
"tbody = soup.find_all('tbody')[0]\n",
"\n",
"data = []\n",
"\n",
"# 查找所有的行\n",
"rows = tbody.find_all('tr', class_='TableLine1 k5-grid-tr')\n",
"print(len(rows))\n",
"for row in rows:\n",
" td_tags=row.find_all('td')\n",
" # 客户名称(车牌)\n",
" customer_name = row.find('a', class_='A0').text.strip()\n",
" # 手机号\n",
" phone_number = row.find('a', class_='phonemenu-trigger')\n",
" if phone_number:\n",
" phone_number = phone_number.text.strip()\n",
" else:\n",
" phone_number = ''\n",
" # 机油\n",
" oil = row.find('a', href=lambda x: x and 'OpneQQDialog' in x)\n",
" if oil:\n",
" oil = oil.text.strip()\n",
" else:\n",
" oil = ''\n",
" # 车型\n",
" car_models =td_tags[5].get_text()\n",
" if car_models:\n",
" pass\n",
" else:\n",
" car_models=''\n",
" # 公里数\n",
" mileage = row.find('a', href=lambda x: x and 'OpenWangWang' in x)\n",
" if mileage:\n",
" mileage = mileage.text.strip()\n",
" else:\n",
" mileage = ''\n",
" # 其他联系方式\n",
" \n",
" other_contact = td_tags[7].get_text()\n",
" if other_contact:\n",
" pass\n",
" else:\n",
" other_contact = ''\n",
" # 日期\n",
" date = row.find('td', id=lambda x: x and x.startswith('Customize1_'))\n",
" if date:\n",
" date = date.text.strip()\n",
" else:\n",
" date = ''\n",
" # 价格\n",
" price = row.find('td', id=lambda x: x and x.startswith('Customize2_'))\n",
" if price:\n",
" price=price.text.strip()\n",
" else:\n",
" price=''\n",
" # 备注\n",
" remarks = row.find('td', id=lambda x: x and x.startswith('Customize3_'))\n",
" if remarks:\n",
" remarks=remarks.text.strip()\n",
" else:\n",
" remarks=''\n",
" # 姓名\n",
" name = row.find('td', id=lambda x: x and x.startswith('Customize4_'))\n",
" if name:\n",
" name = name.text.strip()\n",
" else:\n",
" name = ''\n",
"\n",
" # 将数据添加到列表中\n",
" data.append([customer_name, phone_number, oil,car_models, mileage, other_contact, date, price, remarks, name])\n",
"\n",
"# 创建DataFrame\n",
"df = pd.DataFrame(data, columns=['客户名称(车牌)', '手机号', '机油','车型', '公里数', '其他联系方式', '日期', '价格', '备注', '姓名'])\n",
"\n",
"# 导出到Excel\n",
"df.to_excel('car_data.xlsx', index=False)\n",
"\n",
"print(\"数据已成功导出到car_data.xlsx\")\n"
]
}
],
"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
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,38 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"车辆等级 /html/body/div[5]/div[1]/div/div/div[3]/table[1]/tbody/tr[3]/td[4]\n",
"开单时间 /html/body/div[5]/div[1]/div/div/div[3]/table[1]/tbody/tr[3]/td[2]/input 中的value"
]
}
],
"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
}
@@ -0,0 +1,29 @@
import requests
import pandas as pd
url = "https://czbbb.cn/mnt/czbbb/storeMember/czbbbApi.action"
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0',
"cookies":'JSESSIONID=0F4B4ACDA311E03EB20874676A234F31; Authorization=eyJhbGciOiJIUzUxMiJ9.eyJpZCI6IjVkOTk0MmQwLWNhMGEtNGVkMC04ZTA2LWQ0MWYyNzUwMjNmZSIsImV4cCI6MTcyOTA2OTk5NSwiZ3JvdXBJZCI6bnVsbCwibmJmIjoxNzI4OTgzNTk1LCJ1c2VyTmFtZSI6IumSn-WHjOS6kSIsInN0b3JlSWQiOiJiNjMwNDI4Zi05MDM0LTRjMTktOTM0NS0xYTBiNjBiMzJmOTYiLCJ1c2VyVHlwZSI6IjAifQ.4pwrYnvbmQvL2I_xF-5PMI8TWKCovtIdGKzx_Y6797_8kv_aIHq7SGW5O54irjFy6V7HmUH_ikjl4pAYKmlyhg; Hm_lvt_678c2a986264dd9650b6a59042718858=1728983596; HMACCOUNT=ABFCA62083E00432; Hm_lpvt_678c2a986264dd9650b6a59042718858=1728983627'
}
number = 1
all_data =pd.DataFrame()
for number in range(1,1591):
data = f'method=1239&data=%7B%22pageNo%22%3A{number}%2C%22pageSize%22%3A15%7D'
res = requests.post(url=url,headers=headers,data=data)
data = res.json()
for a in range(0,len(data['data'])):
data_list = [data['data'][a]]
df_new1 = pd.DataFrame(data_list)
# 将当前接口的数据添加到总数据中
all_data = all_data._append(df_new1, ignore_index=True)
print(number)
all_data.to_excel(r'D:\输出.xlsx')
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,105 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": [
"会员卡明细导出\n",
"\n",
"需要先导出会员表,之后做了处理 "
],
"id": "e5353530294464bc"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-03-04T03:47:56.685347Z",
"start_time": "2025-03-04T03:46:22.450480Z"
}
},
"source": [
"import pandas as pd\n",
"import requests\n",
"import json\n",
"import math\n",
"import xlrd\n",
"from pprint import pprint\n",
"from tqdm import tqdm\n",
"\n",
"url = \"https://www.600vip.cn/Business/GoodsConsume/GetBuyCountList\"\n",
"\n",
"df = pd.read_excel(r\"C:\\Users\\Administrator.DESKTOP-7IC2USJ\\Downloads\\会员表 (2).xls\",sheet_name='Sheet1')\n",
"headers = {\n",
" 'authority': 'www.600vip.cn',\n",
" 'method': 'POST',\n",
" 'path': '/Business/GoodsConsume/GetBuyCountList',\n",
" 'scheme': 'https',\n",
" 'accept': 'application/json, text/javascript, */*; q=0.01',\n",
" 'accept-encoding': 'gzip, deflate, br, zstd',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'content-length': '27',\n",
" 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'cookie': 'luckcode=15083577635; luckchain=uid=14871835413470208; rememberPassword=1; ucompcode=TC/rxRH2Nrb9Gamp9vSMxw==; uaccount=qZZOA1XVj9A=; upwd=LjbFhD/UoUs=; Hm_lvt_eb92647b72da97bebb9f81b44b7581a2=1740551044,1741059683; Hm_lpvt_eb92647b72da97bebb9f81b44b7581a2=1741059683; HMACCOUNT=ABFCA62083E00432; sid=f30ef4ef67994057ab41c58dc1385666; 15083577635IsLogonFirst=1; 15083577635LogonTime=202534',\n",
" 'origin': 'https://www.600vip.cn',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://www.600vip.cn/Business/ConsumeCount/Index',\n",
" 'sec-ch-ua': '\"Not(A:Brand\";v=\"99\", \"Microsoft Edge\";v=\"133\", \"Chromium\";v=\"133\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
" 'sec-fetch-dest': 'empty',\n",
" 'sec-fetch-mode': 'cors',\n",
" 'sec-fetch-site': 'same-origin',\n",
" 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0',\n",
" 'x-requested-with': 'XMLHttpRequest'\n",
"}\n",
"\n",
"all_data = []\n",
"\n",
"for index,row in tqdm(df.iterrows(), total=len(df)):\n",
" data = f\"page=1&rows=20&cardID={row['新会员卡号'].split('A')[1]}\" # 需要注意对会员卡号进行了处理\n",
" # print(data)\n",
" res = requests.post(url=url, headers=headers, data=data)\n",
" res = res.json()[\"rows\"]\n",
" for item in res:\n",
" all_data.append(item)\n",
" # break\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\普盛数据导出.xlsx\")\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"870it [01:33, 9.26it/s]\n"
]
}
],
"execution_count": 3
}
],
"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
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,520 @@
{
"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
}
@@ -0,0 +1,45 @@
import requests
from tqdm import tqdm
import pandas as pd
import time
cookies = {
'plum_session_manage': '557ja766db2on5fvet5nhvnavt',
}
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'priority': 'u=1, i',
'referer': 'https://qfy.lycjh.com/public/h5/carWeb/index.html',
'sec-ch-ua': '"Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',
# 'cookie': 'plum_session_manage=557ja766db2on5fvet5nhvnavt',
}
all_data = []
for i in tqdm(range(0, 52)):
params = {
'map': 'applet_car_vehicle_list',
'query': '',
'page': i,
'searchValue': '',
'useCount': '200',
'sourceType': 'web',
'token': '37209C2A406D3B40068394CF3C27EE0C',
'appid': 'wx5bc8c5b57e2223b9',
'suid': 'hcpza678h9',
'version': '1',
}
# 皖BF1821
response = requests.get('https://qfy.lycjh.com/applet.php', params=params, cookies=cookies, headers=headers)
data_list = response.json().get('data')
all_data.extend(data_list)
time.sleep(0.3)
df = pd.DataFrame(all_data)
df.to_csv(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\汽服云车辆信息.csv")
@@ -0,0 +1,304 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-06-26T05:39:09.305879Z",
"start_time": "2025-06-26T05:39:09.248395Z"
}
},
"source": [
"import requests\n",
"import pandas as pd\n",
"from retrying import retry\n",
"from tqdm import tqdm\n",
"\n",
"# 设置重试策略\n",
"@retry(stop_max_attempt_number=3, wait_fixed=2000) # 最多重试3次,每次间隔2秒\n",
"def fetch_url(url, params=None):\n",
" response = requests.get(url, headers=headers, params=params, timeout=10)\n",
" response.raise_for_status() # 抛出 HTTP 错误(如 500\n",
" return response.json()\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",
"car_data = []\n",
"operate_data = []\n",
"order_data = []\n",
"server_data = []\n",
"settlement_data = []\n",
"\n",
"for i in tqdm(range(1, 350)):\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",
"\n",
" response = fetch_url(list_url)\n",
"\n",
" history_list = response.get('data').get(\"listData\")\n",
" \n",
" for history in history_list:\n",
" orderId = history.get('orderId')\n",
"\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('https://ssapp-api.carisok.com/pc.php/GainRecord/get_order_detail', params=params, headers=headers)\n",
"\n",
" data = response.json().get('data')\n",
" \n",
" carInfo = data.get('carInfo', [])\n",
" operate = data.get('operate', [])\n",
" orderInfo = data.get('orderInfo', [])\n",
" serverInfo = data.get('serverInfo', [])\n",
" settlementInfo = data.get('settlementInfo', [])\n",
"\n",
"\n",
"\n",
" if isinstance(carInfo, dict):\n",
" carInfo[\"orderid\"] = orderId\n",
" car_data.append(carInfo)\n",
" elif isinstance(carInfo, list):\n",
" for item in carInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" car_data.append(item)\n",
" \n",
" # 处理 orderInfo(可能是字典或列表)\n",
" if isinstance(orderInfo, dict):\n",
" orderInfo[\"orderid\"] = orderId\n",
" order_data.append(orderInfo)\n",
" elif isinstance(orderInfo, list):\n",
" for item in orderInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" order_data.append(item)\n",
" \n",
" # 处理 operate(通常是列表,但也可能不是)\n",
" if isinstance(operate, list):\n",
" for item in operate:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" operate_data.append(item)\n",
" \n",
" # 处理 serverInfo(可能是字典或列表)\n",
" if isinstance(serverInfo, dict):\n",
" serverInfo[\"orderid\"] = orderId\n",
" server_data.append(serverInfo)\n",
" elif isinstance(serverInfo, list):\n",
" for item in serverInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" server_data.append(item)\n",
" \n",
" # 处理 settlementInfo(可能是字典或列表)\n",
" if isinstance(settlementInfo, dict):\n",
" settlementInfo[\"orderid\"] = orderId\n",
" settlement_data.append(settlementInfo)\n",
" elif isinstance(settlementInfo, list):\n",
" for item in settlementInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" settlement_data.append(item)\n",
" \n",
" \n",
"\n",
"# 写入 CSV 文件\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",
"output_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\\\'\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(\"✅ 数据写入完成\")"
],
"outputs": [
{
"ename": "NameError",
"evalue": "name 'tqdm' is not defined",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mNameError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[48], line 33\u001B[0m\n\u001B[0;32m 30\u001B[0m server_data \u001B[38;5;241m=\u001B[39m []\n\u001B[0;32m 31\u001B[0m settlement_data \u001B[38;5;241m=\u001B[39m []\n\u001B[1;32m---> 33\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m i \u001B[38;5;129;01min\u001B[39;00m tqdm(\u001B[38;5;28mrange\u001B[39m(\u001B[38;5;241m1\u001B[39m, \u001B[38;5;241m350\u001B[39m)):\n\u001B[0;32m 34\u001B[0m list_url \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhttps://ssapp-api.carisok.com/pc.php/PcPickcarOrder/lists?name=&mobile=&orderState=0&workState=0&businessType=0&page=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mi\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m&pagesize=20&carNo=&orderNo=&operate_count=&companyName=&startDate&endDate&api_version=4.00&__trace_id=6f72ab8e-f569-4b5d-aa7b-c890eec6756d-store&token=4d62a33aa979d6d242d6b0198afbbf27\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m 36\u001B[0m response \u001B[38;5;241m=\u001B[39m fetch_url(list_url)\n",
"\u001B[1;31mNameError\u001B[0m: name 'tqdm' is not defined"
]
}
],
"execution_count": 48
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-26T05:35:06.024711Z",
"start_time": "2025-06-26T05:35:05.187886Z"
}
},
"cell_type": "code",
"source": [
"import requests\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",
"orderId = '1334846'\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",
"\n",
"response = requests.get('https://ssapp-api.carisok.com/pc.php/GainRecord/get_order_detail', params=params, headers=headers)\n",
"\n",
"data = response.json().get('data')\n",
"\n",
"carInfo = data.get('carInfo', {})\n",
"operate = data.get('operate', [])\n",
"serverInfo = data.get('serverInfo', [])\n",
"orderInfo = data.get('orderInfo', {})\n",
"settlementInfo = data.get('settlementInfo', [])\n",
"\n",
"car_data=[]\n",
"operate_data=[]\n",
"order_data = []\n",
"server_data = []\n",
"settlement_data = []\n",
"# 处理 carInfo(可能是字典或列表)\n",
"if isinstance(carInfo, dict):\n",
" carInfo[\"orderid\"] = orderId\n",
" car_data.append(carInfo)\n",
"elif isinstance(carInfo, list):\n",
" for item in carInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" car_data.append(item)\n",
"\n",
"# 处理 orderInfo(可能是字典或列表)\n",
"if isinstance(orderInfo, dict):\n",
" orderInfo[\"orderid\"] = orderId\n",
" order_data.append(orderInfo)\n",
"elif isinstance(orderInfo, list):\n",
" for item in orderInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" order_data.append(item)\n",
"\n",
"# 处理 operate(通常是列表,但也可能不是)\n",
"if isinstance(operate, list):\n",
" for item in operate:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" operate_data.append(item)\n",
"\n",
"# 处理 serverInfo(可能是字典或列表)\n",
"if isinstance(serverInfo, dict):\n",
" serverInfo[\"orderid\"] = orderId\n",
" server_data.append(serverInfo)\n",
"elif isinstance(serverInfo, list):\n",
" for item in serverInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" server_data.append(item)\n",
"\n",
"# 处理 settlementInfo(可能是字典或列表)\n",
"if isinstance(settlementInfo, dict):\n",
" settlementInfo[\"orderid\"] = orderId\n",
" settlement_data.append(settlementInfo)\n",
"elif isinstance(settlementInfo, list):\n",
" for item in settlementInfo:\n",
" if isinstance(item, dict):\n",
" item[\"orderid\"] = orderId\n",
" settlement_data.append(item)\n",
" \n",
" \n",
" \n",
" \n",
"\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(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\car.csv', index=False)\n",
"df2.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\operate.csv', index=False)\n",
"df3.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\order.csv', index=False)\n",
"df4.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\server.csv', index=False)\n",
"df5.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\settlement.csv', index=False)\n",
"print(\"数据写入完成\")"
],
"id": "e1ca5734b455a269",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"数据写入完成\n"
]
}
],
"execution_count": 42
}
],
"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
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,251 @@
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from urllib.parse import urljoin
import pandas as pd
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service
from datetime import datetime
from selenium.webdriver.chrome.options import Options
from datetime import datetime, timedelta
from selenium.common.exceptions import NoSuchElementException
from tqdm import tqdm
from selenium.common.exceptions import TimeoutException
# 设置Chrome选项
chrome_options = Options()
# 设置为无头模式(不打开浏览器窗口)
# chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
# 指定ChromeDriver路径
service = Service(executable_path='D:\ProgramTools\chromedriver-win64\chromedriver.exe')
# 创建WebDriver对象
driver = webdriver.Chrome(service=service, options=chrome_options)
# 目标网址
url = 'http://best.aichedian.com/login/'
url1 = ''
username = '15307259977'
password = 'juanzi810119'
title = 'HGYH -- HGYH'
# 访问网页
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id="username"]'))).send_keys(username)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[4]/div/input'))).click()
time.sleep(2)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select-dom"]'))).click()
# time.sleep(200)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select_box"]/div/div[1]/div'))).click()
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select_box"]/div/div[1]/div/span[1]'))).click()
time.sleep(5)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[3]/div[2]/div/input'))).send_keys(password)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[4]/div/input'))).click()
time.sleep(2)
# 设置起始日期为今天,结束日期为两年前 # 需要修改日期
end_date = datetime.now()
start_date = end_date - timedelta(days=1465) # 1358
# demo_date =end_date - timedelta(days=786)
current_date = start_date
all_data = []
# 定义表头
headers = [
'订单号',
'开单时间', '入账时间', '车辆', '车主', '订单详情',
'车牌号码', '车辆品牌', '会员卡号', '车主姓名', '联系方式',
'服务名称', '销售人员', '施工人员', '应付金额', '施工时间', '完工时间', '服务评分',
'产品名称', '型号', '单价', '数量', '总价', '销售人员', '销售时间',
'支付方式', '账号', '金额', '时间', '备注'
]
# 进度条
date_range = pd.date_range(start=start_date, end=end_date)
# date_range = pd.date_range(start=start_date, end=demo_date)
with tqdm(total=len(date_range), desc="处理日期") as pbar:
no_data_count = 0 # 记录连续没有数据的次数
for current_date in date_range:
date_str = current_date.strftime('%Y/%m/%d')
# http://best.aichedian.com/report/order-count-detail/?dt=2024/12/01
url1 = f'http://best.aichedian.com/report/order-count-detail/?dt={date_str}'
driver.get(url1) # 获取每日订单
# 获取指定 XPath 下的所有 <tr> 元素
xpath = '//*[@id="x-single-content"]/table[2]/tbody/tr'
try:
rows = WebDriverWait(driver, 5).until(
EC.presence_of_all_elements_located((By.XPATH, xpath))
)
if not rows:
raise NoSuchElementException # 如果没有找到任何行,抛出异常
no_data_count = 0 # 重置计数器
except TimeoutException:
no_data_count += 1
if no_data_count >= 1000:
print("连续1000天没有数据,退出循环")
break
pbar.update(1)
continue
for row in rows:
# 获取每一行中的所有 <td> 元素
cells = row.find_elements(By.TAG_NAME, 'td')
row_data = [cell.text for cell in cells] # 将一行中的所有单元格文本存入列表
start_dj_data = row_data[0] # 开始时间
get_money_data = row_data[1] # 入账时间
car_number = row_data[2] # 车牌名称
customer = row_data[3] # 假设第二列是客户名称
order_details = '\n'.join(row_data) # 将行数据合并为一个字符串,每列之间用换行符分隔
for cell in cells:
try:
base_url = 'http://xlsf.aichedian.com/'
link = cell.find_element(By.XPATH, './/a[@class="underline-styled"]')
relative_url = link.get_attribute('href')
absolute_url = urljoin(base_url, relative_url) # 明细url
details_id = absolute_url.split('/')[-2]
driver.get(absolute_url) # 获取订单明细
# 获取基本信息
base_details = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="x-single-content"]/ul'))
)
li_items = base_details.find_elements(By.TAG_NAME, 'li')
base_info = {li.text.split(':')[0].strip(): li.text.split(':')[1].strip() if ':' in li.text else ''
for li in li_items}
# 获取具体信息,如果不存在则返回空字符串
license_plate = base_info.get('车牌号', '')
customer_name = base_info.get('客户名称', '')
order_id = base_info.get('订单编号', '')
# 获取服务项目
service_info = []
try:
h3_element = WebDriverWait(driver, 0.2).until(
EC.presence_of_element_located((By.XPATH, '//h3[text()="服务项目"]'))
)
if h3_element.text == "服务项目":
table = h3_element.find_element(By.XPATH, './following-sibling::table')
rows = table.find_elements(By.TAG_NAME, 'tr')
for row1 in rows[1:]:
li_items = row1.find_elements(By.TAG_NAME, 'td')
service_info.append({
'服务名称': li_items[0].text,
'销售人员': li_items[1].text,
'施工人员': li_items[2].text,
'应付金额': li_items[3].text,
'施工时间': li_items[4].text,
'完工时间': li_items[5].text,
'服务评分': li_items[6].text
})
except:
pass
# 获取销售产品
product_info = []
try:
h3_element = WebDriverWait(driver, 0.2).until(
EC.presence_of_element_located((By.XPATH, '//h3[text()="销售产品"]'))
)
if h3_element.text == "销售产品":
table = h3_element.find_element(By.XPATH, './following-sibling::table')
rows = table.find_elements(By.TAG_NAME, 'tr')
for row2 in rows[1:]:
li_items = row2.find_elements(By.TAG_NAME, 'td')
product_info.append({
'产品名称': li_items[0].text,
'型号': li_items[1].text,
'单价': li_items[2].text,
'数量': li_items[3].text,
'总价': li_items[4].text,
'销售人员': li_items[5].text,
'销售时间': li_items[6].text
})
except:
pass
# 获取支付记录
payment_info = []
try:
h3_element = WebDriverWait(driver, 0.2).until(
EC.presence_of_element_located((By.XPATH, '//h3[text()="支付记录"]'))
)
if h3_element.text == "支付记录":
table = h3_element.find_element(By.XPATH, './following-sibling::table')
rows = table.find_elements(By.TAG_NAME, 'tr')
for row3 in rows[1:]:
li_items = row3.find_elements(By.TAG_NAME, 'td')
payment_info.append({
'支付方式': li_items[0].text,
'账号': li_items[1].text,
'金额': li_items[2].text,
'时间': li_items[3].text,
'备注': li_items[4].text
})
except:
pass
# 将所有信息组合成一个字典
order_info = {
'订单号': details_id,
'开单时间': start_dj_data,
'入账时间': get_money_data,
'车辆': car_number,
'车主': customer,
'车牌号码': base_info.get('车牌号码', ''),
'车辆品牌': base_info.get('车辆品牌', ''),
'会员卡号': base_info.get('会员卡号', ''),
'车主姓名': base_info.get('车主姓名', ''),
'联系方式': base_info.get('联系方式', ''),
# '订单详情': order_details,
'服务名称': '\n'.join([item['服务名称'] for item in service_info]),
'销售人员': '\n'.join([item['销售人员'] for item in service_info]),
'施工人员': '\n'.join([item['施工人员'] for item in service_info]),
'应付金额': '\n'.join([item['应付金额'] for item in service_info]),
'施工时间': '\n'.join([item['施工时间'] for item in service_info]),
'完工时间': '\n'.join([item['完工时间'] for item in service_info]),
'服务评分': '\n'.join([item['服务评分'] for item in service_info]),
'产品名称': '\n'.join([item['产品名称'] for item in product_info]),
'型号': '\n'.join([item['型号'] for item in product_info]),
'单价': '\n'.join([item['单价'] for item in product_info]),
'数量': '\n'.join([item['数量'] for item in product_info]),
'总价': '\n'.join([item['总价'] for item in product_info]),
'销售人员': '\n'.join([item['销售人员'] for item in product_info]),
'销售时间': '\n'.join([item['销售时间'] for item in product_info]),
'支付方式': '\n'.join([item['支付方式'] for item in payment_info]),
'账号': '\n'.join([item['账号'] for item in payment_info]),
'金额': '\n'.join([item['金额'] for item in payment_info]),
'时间': '\n'.join([item['时间'] for item in payment_info]),
'备注': '\n'.join([item['备注'] for item in payment_info])
}
all_data.append(order_info) # 将完整订单信息添加到总数据列表中
time.sleep(0.1)
driver.back()
except NoSuchElementException:
continue # 如果没有找到 <a> 标签,继续下一个 <td>
driver.back()
pbar.update(1)
# 使用pandas将数据保存为Excel文件
df = pd.DataFrame(all_data, columns=headers)
df.to_excel('爱车店数据导出.xlsx', index=False) # 保存为Excel文件
# 关闭浏览器
driver.quit()
@@ -0,0 +1,141 @@
import pandas as pd
from tqdm import tqdm
import openpyxl
from openpyxl.styles import PatternFill
# 读取Excel文件
df = pd.read_excel(r"D:\Idea Project\F6+宜搭+其它(1)\new\竞品系统数据导出\爱车店数据导出.xlsx")
# 初始化一个新的列表来存储结果
result_list = []
# 定义一个函数来安全地拆分字符串
def safe_split(value, delimiter='\n'):
if pd.notna(value):
return value.split(delimiter)
return ['']
# 获取需要拆分的列名
columns_to_split = {
'产品名称组': ['产品名称', '型号', '单价', '数量', '总价', '销售人员', '销售时间'],
'服务名称组': ['服务名称', '施工人员', '应付金额', '施工时间', '完工时间', '服务评分'],
'支付方式组': ['支付方式', '账号', '金额', '时间', '备注']
}
# 获取需要保留的列名
columns_to_keep = ['订单号', '开单时间', '入账时间', '车辆', '车主', '订单详情']
# 使用 tqdm 包装 iterrows() 以显示进度条
for index, row in tqdm(df.iterrows(), total=len(df), desc="处理数据"):
# 存储每个组的拆分数据
split_data_groups = {}
# 拆分每个组的数据
for group_name, cols in columns_to_split.items():
split_data = {col: safe_split(row[col]) for col in cols}
max_length = max(len(split_data[col]) for col in cols)
for col in cols:
split_data[col] += [''] * (max_length - len(split_data[col]))
split_data_groups[group_name] = split_data
# 检查是否有数据
has_product_data = any(any(item.strip() != '' for item in split_data_groups['产品名称组'][col]) for col in
columns_to_split['产品名称组'])
has_service_data = any(any(item.strip() != '' for item in split_data_groups['服务名称组'][col]) for col in
columns_to_split['服务名称组'])
has_payment_data = any(any(item.strip() != '' for item in split_data_groups['支付方式组'][col]) for col in
columns_to_split['支付方式组'])
if not (has_product_data or has_service_data or has_payment_data):
continue
# 获取最大长度
max_length = max(
len(split_data_groups['产品名称组'][col][0]) for col in columns_to_split['产品名称组']
) + max(
len(split_data_groups['服务名称组'][col][0]) for col in columns_to_split['服务名称组']
) + max(
len(split_data_groups['支付方式组'][col][0]) for col in columns_to_split['支付方式组']
)
# 创建新的行
for i in range(max_length):
new_row = {}
# 添加需要保留的列的数据(开单时间组放在最前面)
for col in columns_to_keep:
new_row[col] = row[col]
# 添加产品名称组的数据
for col in columns_to_split['产品名称组']:
if i < len(split_data_groups['产品名称组'][col]):
new_row[col] = split_data_groups['产品名称组'][col][i].strip()
else:
new_row[col] = ''
# 添加服务名称组的数据
for col in columns_to_split['服务名称组']:
if i < len(split_data_groups['服务名称组'][col]):
new_row[col] = split_data_groups['服务名称组'][col][i].strip()
else:
new_row[col] = ''
# 添加支付方式组的数据
for col in columns_to_split['支付方式组']:
if i < len(split_data_groups['支付方式组'][col]):
new_row[col] = split_data_groups['支付方式组'][col][i].strip()
else:
new_row[col] = ''
# 检查新行是否有数据
has_data = any(new_row[col] != '' for col in columns_to_split['产品名称组']) or \
any(new_row[col] != '' for col in columns_to_split['服务名称组']) or \
any(new_row[col] != '' for col in columns_to_split['支付方式组'])
if has_data:
# 将新行添加到结果列表中
result_list.append(new_row)
# 将结果列表转换为DataFrame
result_df = pd.DataFrame(result_list)
# 保存结果到新的Excel文件
file_path = 'result.xlsx'
result_df.to_excel(file_path, index=False)
# 加载Excel文件并设置背景颜色
wb = openpyxl.load_workbook(file_path)
ws = wb.active
# 定义背景颜色
color_dict = {
'开单时间': 'FFFFFF', # 白色
'产品名称': 'FFFF00', # 黄色
'服务名称': '00FF00', # 绿色
'支付方式': '0000FF' # 蓝色
}
# 设置背景颜色
for row in ws.iter_rows(min_row=2, max_row=ws.max_row, min_col=1, max_col=ws.max_column):
for cell in row:
if cell.column_letter in [ws[1][i].column_letter for i, col in enumerate(columns_to_keep)]:
cell.fill = PatternFill(start_color=color_dict['开单时间'], end_color=color_dict['开单时间'],
fill_type='solid')
elif cell.column_letter in [ws[1][i].column_letter for i, col in enumerate(columns_to_split['产品名称组'])]:
cell.fill = PatternFill(start_color=color_dict['产品名称'], end_color=color_dict['产品名称'],
fill_type='solid')
elif cell.column_letter in [ws[1][i].column_letter for i, col in enumerate(columns_to_split['服务名称组'])]:
cell.fill = PatternFill(start_color=color_dict['服务名称'], end_color=color_dict['服务名称'],
fill_type='solid')
elif cell.column_letter in [ws[1][i].column_letter for i, col in enumerate(columns_to_split['支付方式组'])]:
cell.fill = PatternFill(start_color=color_dict['支付方式'], end_color=color_dict['支付方式'],
fill_type='solid')
# 保存Excel文件
wb.save(file_path)
wb.close()
print("数据拆分完成,已保存到result.xlsx")
@@ -0,0 +1,199 @@
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
from urllib.parse import urljoin
import pandas as pd
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from datetime import datetime, timedelta
from selenium.common.exceptions import NoSuchElementException
from tqdm import tqdm
import re
from selenium.common.exceptions import TimeoutException
from bs4 import BeautifulSoup
# 设置Chrome选项
chrome_options = Options()
# 设置为无头模式(不打开浏览器窗口)
# chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
# 指定ChromeDriver路径
service = Service(executable_path='D:\ProgramTools\chromedriver-win64\chromedriver.exe')
# 创建WebDriver对象
driver = webdriver.Chrome(service=service, options=chrome_options)
# 目标网址
url = 'http://best.aichedian.com/login/'
url1 = ''
username = '15307259977'
password = 'juanzi810119'
title = 'HGYH -- HGYH'
# 访问网页
driver.get(url)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id="username"]'))).send_keys(username)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[4]/div/input'))).click()
time.sleep(2)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select-dom"]'))).click()
# time.sleep(200)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select_box"]/div/div[1]/div'))).click()
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="select_box"]/div/div[1]/div/span[1]'))).click()
time.sleep(5)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[3]/div[2]/div/input'))).send_keys(password)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="login_form"]/div[4]/div/input'))).click()
time.sleep(2)
all_data = []
page = 1
# 定义表头
headers = [
'订单号',
'挂账时间', '挂账金额', # 入账订单列表
'车牌号码', '车辆品牌', '车主姓名', '联系方式', '进站公里数', '业务类型', # 基础信息
'服务名称', '销售人员', '施工人员', '应付金额', '施工时间', '完工时间', '服务评分', # 服务项目
'产品名称', '型号', '单价', '数量', '总价', '销售人员', '销售时间',
]
for page in tqdm(range(1, 18)): # 循环页码
url1 = f'http://best.aichedian.com/order/debt/?q=&page={page}'
driver.get(url1) # 获取挂账列表
xpath = '//*[@id="data-table-1"]/tbody'
tbody = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, xpath))
)
rows = tbody[0].find_elements(By.TAG_NAME, 'tr')
if not rows:
raise NoSuchElementException # 如果没有找到任何行,抛出异常
for row in rows: # 循环行
cells = row.find_elements(By.TAG_NAME, 'td')
transaction_time = cells[0].text
price_cell = cells[3].text
# print(price_cell)
match = re.search(r'¥(\d+\.\d{2})', price_cell)
if match:
price = float(match.group(1))
else:
price = "未匹配到金额"
# print(transaction_time) # 打印挂账时间
# print(price) # 打印挂账金额
detail_url = cells[4].find_element(By.TAG_NAME, 'a').get_attribute('href')
# print(detail_url)
driver.get(detail_url)
details_id = detail_url.split('/')[-2]
# 获取基本信息
base_details = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, f'//*[@id="x-single-content"]/ul'))
)
li_items = base_details.find_elements(By.TAG_NAME, 'li')
base_info = {li.text.split(':')[0].strip(): li.text.split(':')[1].strip() if ':' in li.text else ''
for li in li_items}
# print(base_info)
# 获取具体信息,如果不存在则返回空字符串
license_plate = base_info.get('车牌号', '')
customer_name = base_info.get('客户名称', '')
order_id = base_info.get('订单编号', '')
# 获取服务项目
service_info = []
try:
h3_element = WebDriverWait(driver, 0.2).until(
EC.presence_of_element_located((By.XPATH, '//h3[text()="服务项目"]'))
)
if h3_element.text == "服务项目":
table = h3_element.find_element(By.XPATH, './following-sibling::table')
rows = table.find_elements(By.TAG_NAME, 'tr')
for row1 in rows[1:]:
li_items = row1.find_elements(By.TAG_NAME, 'td')
service_info.append({
'服务名称': li_items[0].text,
'销售人员': li_items[1].text,
'施工人员': li_items[2].text,
'应付金额': li_items[3].text,
'施工时间': li_items[4].text,
'完工时间': li_items[5].text,
'服务评分': li_items[6].text
})
except:
pass
# 获取销售产品
product_info = []
try:
h3_element = WebDriverWait(driver, 0.2).until(
EC.presence_of_element_located((By.XPATH, '//h3[text()="销售产品"]'))
)
if h3_element.text == "销售产品":
table = h3_element.find_element(By.XPATH, './following-sibling::table')
rows = table.find_elements(By.TAG_NAME, 'tr')
for row2 in rows[1:]:
li_items = row2.find_elements(By.TAG_NAME, 'td')
product_info.append({
'产品名称': li_items[0].text,
'型号': li_items[1].text,
'单价': li_items[2].text,
'数量': li_items[3].text,
'总价': li_items[4].text,
'销售人员': li_items[5].text,
'销售时间': li_items[6].text
})
except:
pass
# 将所有信息组合成一个字典
order_info = {
'订单号': details_id,
'挂账时间': transaction_time,
'挂账金额': price,
'车牌号码': base_info.get('车牌号码', ''),
'车辆品牌': base_info.get('车辆品牌', ''),
# '会员卡号': base_info.get('会员卡号', ''),
'车主姓名': base_info.get('车主姓名', ''),
'联系方式': base_info.get('联系方式', ''),
'进站公里数': base_info.get('进站公里数', ''),
'业务类型': base_info.get('业务类型', ''),
# '订单详情': order_details,
'服务名称': '\n'.join([item['服务名称'] for item in service_info]),
'销售人员': '\n'.join([item['销售人员'] for item in service_info]),
'施工人员': '\n'.join([item['施工人员'] for item in service_info]),
'应付金额': '\n'.join([item['应付金额'] for item in service_info]),
'施工时间': '\n'.join([item['施工时间'] for item in service_info]),
'完工时间': '\n'.join([item['完工时间'] for item in service_info]),
'服务评分': '\n'.join([item['服务评分'] for item in service_info]),
'产品名称': '\n'.join([item['产品名称'] for item in product_info]),
'型号': '\n'.join([item['型号'] for item in product_info]),
'单价': '\n'.join([item['单价'] for item in product_info]),
'数量': '\n'.join([item['数量'] for item in product_info]),
'总价': '\n'.join([item['总价'] for item in product_info]),
'销售人员': '\n'.join([item['销售人员'] for item in product_info]),
'销售时间': '\n'.join([item['销售时间'] for item in product_info]),
}
all_data.append(order_info) # 将完整订单信息添加到总数据列表中
driver.back()
df = pd.DataFrame(all_data, columns=headers)
df.to_excel('爱车店应收账款数据导出.xlsx', index=False) # 保存为Excel文件
@@ -0,0 +1,978 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-06-23T05:28:31.780431Z",
"start_time": "2025-06-23T05:26:25.738579Z"
}
},
"source": [
"from selenium import webdriver\n",
"from selenium.webdriver.common.by import By\n",
"from selenium.webdriver.support.ui import WebDriverWait\n",
"from selenium.webdriver.support import expected_conditions as EC\n",
"import time\n",
"from urllib.parse import urljoin\n",
"import pandas as pd\n",
"from selenium.webdriver import Chrome\n",
"from selenium.webdriver.chrome.service import Service\n",
"from datetime import datetime\n",
"from selenium.webdriver.chrome.options import Options\n",
"from datetime import datetime, timedelta\n",
"from selenium.common.exceptions import NoSuchElementException\n",
"from tqdm import tqdm\n",
"from selenium.common.exceptions import TimeoutException\n",
"\n",
"# 设置Chrome选项\n",
"chrome_options = Options()\n",
"# 设置为无头模式(不打开浏览器窗口)\n",
"# chrome_options.add_argument('--headless')\n",
"chrome_options.add_argument('--disable-gpu')\n",
"chrome_options.add_argument('--no-sandbox')\n",
"\n",
"# 指定ChromeDriver路径\n",
"service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')\n",
"\n",
"# 创建WebDriver对象\n",
"driver = webdriver.Chrome(service=service, options=chrome_options)\n",
"\n",
"# 目标网址\n",
"# url = 'http://xlsf.aichedian.com/order/order-detail/1115935207959/ # 爱车店有不同的网址\n",
"url = 'http://best.aichedian.com/order/order-detail/1115935207959/'\n",
"username = '15307259977'\n",
"password = 'juanzi810119'\n",
"\n",
"# 访问网页\n",
"driver.get(url)\n",
"\n",
"WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id=\"username\"]'))).send_keys(username)\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[4]/div/input'))).click()\n",
"time.sleep(5) # 提供时间选择门店\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[3]/div[2]/div/input'))).send_keys(password)\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[4]/div/input'))).click()\n",
"\n",
"time.sleep(2)\n",
"\n",
"# 设置起始日期为今天,结束日期为两年前 # 需要修改日期\n",
"end_date = datetime.now()\n",
"start_date = end_date - timedelta(days=1552) #786\n",
"current_date = start_date\n",
"all_data = []\n",
"\n",
"# 定义表头\n",
"headers = [\n",
" '订单号',\n",
" '开单时间', '入账时间', '车辆', '车主', '订单详情',\n",
" '车牌号码', '车辆品牌', '会员卡号', '车主姓名', '联系方式',\n",
" '服务名称', '销售人员', '施工人员', '应付金额', '施工时间', '完工时间', '服务评分',\n",
" '产品名称', '型号', '单价', '数量', '总价', '销售人员', '销售时间',\n",
" '支付方式', '账号', '金额', '时间', '备注'\n",
"]\n",
"\n",
"# 起始日期和当前日期\n",
"first_date = \"2021-04-03\"\n",
"now_date = datetime.now().strftime('%Y-%m-%d')\n",
"\n",
"# 转换为 pandas 的 Timestamp 类型\n",
"start = pd.to_datetime(first_date)\n",
"end = pd.to_datetime(now_date)\n",
"\n",
"# 初始化当前时间指针\n",
"current = start\n",
"\n",
"# 计算总共有多少年,用于进度条\n",
"total_years = (end - start).days // 365 + 1\n",
"\n",
"all_url = []\n",
"\n",
"with tqdm(total=total_years, desc=\"处理时间段\") as pbar:\n",
" no_data_count=0\n",
" while current <= end:\n",
" # 计算这一年的结束日期\n",
" year_end = current + pd.DateOffset(years=1) - pd.Timedelta(days=1)\n",
" if year_end > end:\n",
" year_end = end\n",
"\n",
" # 格式化成 URL 需要的格式:YYYY/MM/DD\n",
" url_start = current.strftime('%Y/%m/%d')\n",
" url_end = year_end.strftime('%Y/%m/%d')\n",
"\n",
" # 构造 URL\n",
" url = f'http://best.aichedian.com/report/order-stat/?start_date={url_start}&end_date={url_end}&tab=1'\n",
"\n",
" driver.get(url) # 获取每日订单\n",
" # 获取指定 XPath 下的所有 <tr> 元素\n",
" xpath = '//*[@id=\"order-profit-count\"]/table[2]'\n",
" try:\n",
" rows = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_all_elements_located((By.XPATH, xpath))\n",
" )\n",
" if not rows:\n",
" raise NoSuchElementException # 如果没有找到任何行,抛出异常\n",
" no_data_count = 0 # 重置计数器\n",
" except TimeoutException:\n",
" no_data_count += 1\n",
" if no_data_count >= 30:\n",
" print(\"连续30天没有数据,退出循环\")\n",
" break\n",
" continue\n",
"\n",
" for row in tqdm(rows):\n",
" # 获取每一行中的所有 <td> 元素\n",
" cells = row.find_elements(By.TAG_NAME, 'td')\n",
" row_data = [cell.text for cell in cells] # 将一行中的所有单元格文本存入列表\n",
" start_dj_data = row_data[0] # 开始时间\n",
" get_money_data = row_data[1] # 入账时间\n",
" car_number = row_data[2] # 车牌名称\n",
" customer = row_data[3] # 假设第二列是客户名称\n",
" order_details = '\\n'.join(row_data) # 将行数据合并为一个字符串,每列之间用换行符分隔\n",
"\n",
" for cell in cells:\n",
" try:\n",
" links = cell.find_elements(By.TAG_NAME, 'a') # 获取当前单元格内的所有 <a> 标签\n",
" absolute_url = None\n",
" all_absolute_urls = []\n",
" for link in links:\n",
" if link.text == \"查看详细\":\n",
" relative_url = link.get_attribute('href')\n",
" absolute_url = urljoin('http://best.aichedian.com/', relative_url)\n",
" all_absolute_urls.append(absolute_url)\n",
" else:\n",
" continue\n",
" \n",
" if not all_absolute_urls:\n",
" continue\n",
" \n",
" for absolute_url in all_absolute_urls:\n",
" \n",
" driver.get(absolute_url) # 获取查看详情\n",
" \n",
" n_xpath = '//*[@id=\"x-single-content\"]'\n",
" try:\n",
" n_rows = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_all_elements_located((By.XPATH, n_xpath))\n",
" )\n",
" except:\n",
" continue\n",
" first_row = n_rows[0] # 此时为一个列表\n",
" n_cells = first_row.find_elements(By.TAG_NAME, 'td')\n",
" \n",
" for n_cell in n_cells:\n",
" n_links = n_cell.find_elements(By.TAG_NAME, 'a') # 获取当前单元格内的所有 <a> 标签\n",
" n_absolute_url = None\n",
" details_id= \"\"\n",
" for n_link in n_links:\n",
" # print(n_link.text)\n",
" if n_link.text == \"明细\":\n",
" n_relative_url = n_link.get_attribute('href')\n",
" n_absolute_url = urljoin('http://best.aichedian.com/', n_relative_url)\n",
" details_id = n_absolute_url.split('/')[-2]\n",
" all_url.append(n_absolute_url)\n",
" else:\n",
" continue\n",
" \n",
" if not n_absolute_url:\n",
" continue\n",
" \n",
" \n",
" time.sleep(0.1)\n",
" driver.back()\n",
"\n",
" except :\n",
" continue # 如果没有找到 <a> 标签,继续下一个 <td\n",
"\n",
"\n",
" # 返回页面\n",
" driver.back()\n",
" # 获取每日订单\n",
" pbar.update(1)\n",
" \n",
"for url in all_url:\n",
" driver.get(url) # 获取明细数据\n",
"\n",
" xpath1 = '//*[@id=\"x-single-content\"]/h2'\n",
" h2 = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_element_located((By.XPATH, xpath1))\n",
" )\n",
"\n",
" if \"车辆检测单\" in h2.text or \"订单详情\" not in h2.text:\n",
" driver.back()\n",
" print(\"跳过\")\n",
" time.sleep(\n",
" 5\n",
" )\n",
" continue\n",
"\n",
"\n",
" # 获取基本信息\n",
" try:\n",
" base_details = WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"x-single-content\"]/ul'))\n",
" )\n",
" li_items = base_details.find_elements(By.TAG_NAME, 'li')\n",
" base_info = {li.text.split(':')[0].strip(): li.text.split(':')[1].strip() if ':' in li.text else ''\n",
" for li in li_items}\n",
" # 获取具体信息,如果不存在则返回空字符串\n",
" license_plate = base_info.get('车牌号', '')\n",
" customer_name = base_info.get('客户名称', '')\n",
" order_id = base_info.get('订单编号', '')\n",
" except TimeoutException:\n",
" continue # 获取不到基本信息\n",
"\n",
"\n",
" # 获取服务项目\n",
" service_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"服务项目\"]'))\n",
" )\n",
" if h3_element.text == \"服务项目\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row1 in rows[1:]:\n",
" li_items = row1.find_elements(By.TAG_NAME, 'td')\n",
" service_info.append({\n",
" '服务名称': li_items[0].text,\n",
" '销售人员': li_items[1].text,\n",
" '施工人员': li_items[2].text,\n",
" '应付金额': li_items[3].text,\n",
" '施工时间': li_items[4].text,\n",
" '完工时间': li_items[5].text,\n",
" '服务评分': li_items[6].text\n",
" })\n",
" except:\n",
" pass\n",
"\n",
" # 获取销售产品\n",
" product_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"销售产品\"]'))\n",
" )\n",
" if h3_element.text == \"销售产品\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row2 in rows[1:]:\n",
" li_items = row2.find_elements(By.TAG_NAME, 'td')\n",
" product_info.append({\n",
" '产品名称': li_items[0].text,\n",
" '型号': li_items[1].text,\n",
" '单价': li_items[2].text,\n",
" '数量': li_items[3].text,\n",
" '总价': li_items[4].text,\n",
" '销售人员': li_items[5].text,\n",
" '销售时间': li_items[6].text\n",
" })\n",
" except:\n",
" pass\n",
"\n",
" # 获取支付记录\n",
" payment_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"支付记录\"]'))\n",
" )\n",
" if h3_element.text == \"支付记录\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row3 in rows[1:]:\n",
" li_items = row3.find_elements(By.TAG_NAME, 'td')\n",
" payment_info.append({\n",
" '支付方式': li_items[0].text,\n",
" '账号': li_items[1].text,\n",
" '金额': li_items[2].text,\n",
" '时间': li_items[3].text,\n",
" '备注': li_items[4].text\n",
" })\n",
" except:\n",
" pass\n",
"\n",
" # 将所有信息组合成一个字典\n",
" order_info = {\n",
" '订单号': details_id,\n",
" '开单时间': start_dj_data,\n",
" '入账时间': get_money_data,\n",
" '车辆': car_number,\n",
" '车主': customer,\n",
" '车牌号码': base_info.get('车牌号码', ''),\n",
" '车辆品牌': base_info.get('车辆品牌', ''),\n",
" '会员卡号': base_info.get('会员卡号', ''),\n",
" '车主姓名': base_info.get('车主姓名', ''),\n",
" '联系方式': base_info.get('联系方式', ''),\n",
" # '订单详情': order_details,\n",
" '服务名称': '\\n'.join([item['服务名称'] for item in service_info]),\n",
" '销售人员': '\\n'.join([item['销售人员'] for item in service_info]),\n",
" '施工人员': '\\n'.join([item['施工人员'] for item in service_info]),\n",
" '应付金额': '\\n'.join([item['应付金额'] for item in service_info]),\n",
" '施工时间': '\\n'.join([item['施工时间'] for item in service_info]),\n",
" '完工时间': '\\n'.join([item['完工时间'] for item in service_info]),\n",
" '服务评分': '\\n'.join([item['服务评分'] for item in service_info]),\n",
" '产品名称': '\\n'.join([item['产品名称'] for item in product_info]),\n",
" '型号': '\\n'.join([item['型号'] for item in product_info]),\n",
" '单价': '\\n'.join([item['单价'] for item in product_info]),\n",
" '数量': '\\n'.join([item['数量'] for item in product_info]),\n",
" '总价': '\\n'.join([item['总价'] for item in product_info]),\n",
" '销售人员': '\\n'.join([item['销售人员'] for item in product_info]),\n",
" '销售时间': '\\n'.join([item['销售时间'] for item in product_info]),\n",
" '支付方式': '\\n'.join([item['支付方式'] for item in payment_info]),\n",
" '账号': '\\n'.join([item['账号'] for item in payment_info]),\n",
" '金额': '\\n'.join([item['金额'] for item in payment_info]),\n",
" '时间': '\\n'.join([item['时间'] for item in payment_info]),\n",
" '备注': '\\n'.join([item['备注'] for item in payment_info])\n",
" }\n",
"\n",
" all_data.append(order_info) # 将完整订单信息添加到总数据列表中\n",
"\n",
"# 使用pandas将数据保存为Excel文件\n",
"df = pd.DataFrame(all_data, columns=headers)\n",
"df.to_excel('爱车店数据导出.xlsx', index=False) # 保存为Excel文件\n",
"\n",
"# 关闭浏览器\n",
"driver.quit()"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:25: SyntaxWarning: invalid escape sequence '\\P'\n",
"<>:25: SyntaxWarning: invalid escape sequence '\\P'\n",
"C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_20808\\1843733566.py:25: SyntaxWarning: invalid escape sequence '\\P'\n",
" service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')\n",
"处理时间段: 0%| | 0/5 [00:00<?, ?it/s]\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"100%|██████████| 1/1 [00:58<00:00, 58.80s/it]\u001B[A\n",
"\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"100%|██████████| 1/1 [00:56<00:00, 56.86s/it]\u001B[A\n",
"处理时间段: 0%| | 0/5 [01:56<?, ?it/s]\n",
"C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_20808\\1843733566.py:25: SyntaxWarning: invalid escape sequence '\\P'\n",
" service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')\n"
]
},
{
"ename": "InvalidSessionIdException",
"evalue": "Message: invalid session id\nStacktrace:\n\tGetHandleVerifier [0x0x7ff728a4cda5+78885]\n\tGetHandleVerifier [0x0x7ff728a4ce00+78976]\n\t(No symbol) [0x0x7ff7288099fc]\n\t(No symbol) [0x0x7ff7288507df]\n\t(No symbol) [0x0x7ff728888a52]\n\t(No symbol) [0x0x7ff728883413]\n\t(No symbol) [0x0x7ff7288824d9]\n\t(No symbol) [0x0x7ff7287d5d55]\n\tGetHandleVerifier [0x0x7ff728d24eed+3061101]\n\tGetHandleVerifier [0x0x7ff728d1f33d+3037629]\n\tGetHandleVerifier [0x0x7ff728d3e592+3165202]\n\tGetHandleVerifier [0x0x7ff728a6730e+186766]\n\tGetHandleVerifier [0x0x7ff728a6eb3f+217535]\n\t(No symbol) [0x0x7ff7287d4dca]\n\tGetHandleVerifier [0x0x7ff728e445e8+4238440]\n\tBaseThreadInitThunk [0x0x7fff2f1de8d7+23]\n\tRtlUserThreadStart [0x0x7fff307bc34c+44]\n",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mInvalidSessionIdException\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[49], line 95\u001B[0m\n\u001B[0;32m 92\u001B[0m \u001B[38;5;66;03m# 构造 URL\u001B[39;00m\n\u001B[0;32m 93\u001B[0m url \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhttp://best.aichedian.com/report/order-stat/?start_date=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00murl_start\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m&end_date=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00murl_end\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m&tab=1\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[1;32m---> 95\u001B[0m driver\u001B[38;5;241m.\u001B[39mget(url) \u001B[38;5;66;03m# 获取每日订单\u001B[39;00m\n\u001B[0;32m 96\u001B[0m \u001B[38;5;66;03m# 获取指定 XPath 下的所有 <tr> 元素\u001B[39;00m\n\u001B[0;32m 97\u001B[0m xpath \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124m//*[@id=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124morder-profit-count\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m]/table[2]\u001B[39m\u001B[38;5;124m'\u001B[39m\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:363\u001B[0m, in \u001B[0;36mWebDriver.get\u001B[1;34m(self, url)\u001B[0m\n\u001B[0;32m 361\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget\u001B[39m(\u001B[38;5;28mself\u001B[39m, url: \u001B[38;5;28mstr\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m 362\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"Loads a web page in the current browser session.\"\"\"\u001B[39;00m\n\u001B[1;32m--> 363\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mexecute(Command\u001B[38;5;241m.\u001B[39mGET, {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124murl\u001B[39m\u001B[38;5;124m\"\u001B[39m: url})\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\webdriver.py:354\u001B[0m, in \u001B[0;36mWebDriver.execute\u001B[1;34m(self, driver_command, params)\u001B[0m\n\u001B[0;32m 352\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcommand_executor\u001B[38;5;241m.\u001B[39mexecute(driver_command, params)\n\u001B[0;32m 353\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m response:\n\u001B[1;32m--> 354\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39merror_handler\u001B[38;5;241m.\u001B[39mcheck_response(response)\n\u001B[0;32m 355\u001B[0m response[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_unwrap_value(response\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28;01mNone\u001B[39;00m))\n\u001B[0;32m 356\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m response\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\selenium\\webdriver\\remote\\errorhandler.py:229\u001B[0m, in \u001B[0;36mErrorHandler.check_response\u001B[1;34m(self, response)\u001B[0m\n\u001B[0;32m 227\u001B[0m alert_text \u001B[38;5;241m=\u001B[39m value[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124malert\u001B[39m\u001B[38;5;124m\"\u001B[39m]\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtext\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[0;32m 228\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace, alert_text) \u001B[38;5;66;03m# type: ignore[call-arg] # mypy is not smart enough here\u001B[39;00m\n\u001B[1;32m--> 229\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception_class(message, screen, stacktrace)\n",
"\u001B[1;31mInvalidSessionIdException\u001B[0m: Message: invalid session id\nStacktrace:\n\tGetHandleVerifier [0x0x7ff728a4cda5+78885]\n\tGetHandleVerifier [0x0x7ff728a4ce00+78976]\n\t(No symbol) [0x0x7ff7288099fc]\n\t(No symbol) [0x0x7ff7288507df]\n\t(No symbol) [0x0x7ff728888a52]\n\t(No symbol) [0x0x7ff728883413]\n\t(No symbol) [0x0x7ff7288824d9]\n\t(No symbol) [0x0x7ff7287d5d55]\n\tGetHandleVerifier [0x0x7ff728d24eed+3061101]\n\tGetHandleVerifier [0x0x7ff728d1f33d+3037629]\n\tGetHandleVerifier [0x0x7ff728d3e592+3165202]\n\tGetHandleVerifier [0x0x7ff728a6730e+186766]\n\tGetHandleVerifier [0x0x7ff728a6eb3f+217535]\n\t(No symbol) [0x0x7ff7287d4dca]\n\tGetHandleVerifier [0x0x7ff728e445e8+4238440]\n\tBaseThreadInitThunk [0x0x7fff2f1de8d7+23]\n\tRtlUserThreadStart [0x0x7fff307bc34c+44]\n"
]
}
],
"execution_count": 49
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-23T05:15:55.507074Z",
"start_time": "2025-06-23T05:15:55.444172Z"
}
},
"cell_type": "code",
"source": [
"# 使用pandas将数据保存为Excel文件\n",
"df = pd.DataFrame(all_data, columns=headers)\n",
"df.to_excel('爱车店数据导出.xlsx', index=False) # 保存为Excel文件"
],
"id": "911d116f7d50ffd2",
"outputs": [],
"execution_count": 44
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-23T11:53:26.818502Z",
"start_time": "2025-06-23T06:29:37.293543Z"
}
},
"cell_type": "code",
"source": [
"from selenium import webdriver\n",
"from selenium.webdriver.common.by import By\n",
"from selenium.webdriver.support.ui import WebDriverWait\n",
"from selenium.webdriver.support import expected_conditions as EC\n",
"import time\n",
"from urllib.parse import urljoin\n",
"import pandas as pd\n",
"from selenium.webdriver import Chrome\n",
"from selenium.webdriver.chrome.service import Service\n",
"from datetime import datetime\n",
"from selenium.webdriver.chrome.options import Options\n",
"from datetime import datetime, timedelta\n",
"from selenium.common.exceptions import NoSuchElementException\n",
"from tqdm import tqdm\n",
"from selenium.common.exceptions import TimeoutException\n",
"\n",
"# 设置Chrome选项\n",
"chrome_options = Options()\n",
"# 设置为无头模式(不打开浏览器窗口)\n",
"# chrome_options.add_argument('--headless')\n",
"chrome_options.add_argument('--disable-gpu')\n",
"chrome_options.add_argument('--no-sandbox')\n",
"\n",
"# 指定ChromeDriver路径\n",
"service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')\n",
"\n",
"# 创建WebDriver对象\n",
"driver = webdriver.Chrome(service=service, options=chrome_options)\n",
"\n",
"# 目标网址\n",
"# url = 'http://xlsf.aichedian.com/order/order-detail/1115935207959/ # 爱车店有不同的网址\n",
"url = 'http://best.aichedian.com/order/order-detail/1115935207959/'\n",
"username = '15307259977'\n",
"password = 'juanzi810119'\n",
"\n",
"# 访问网页\n",
"driver.get(url)\n",
"\n",
"WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id=\"username\"]'))).send_keys(username)\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[4]/div/input'))).click()\n",
"time.sleep(5) # 提供时间选择门店\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[3]/div[2]/div/input'))).send_keys(password)\n",
"WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"login_form\"]/div[4]/div/input'))).click()\n",
"\n",
"time.sleep(2)\n",
"\n",
"# 设置起始日期为今天,结束日期为两年前 # 需要修改日期\n",
"end_date = datetime.now()\n",
"start_date = end_date - timedelta(days=1552) #786\n",
"current_date = start_date\n",
"all_data = []\n",
"\n",
"# 定义表头\n",
"headers = [\n",
" '订单号',\n",
" '开单时间', '入账时间', '车辆', '车主', '订单详情',\n",
" '车牌号码', '车辆品牌', '会员卡号', '车主姓名', '联系方式',\n",
" '服务名称', '销售人员', '施工人员', '应付金额', '施工时间', '完工时间', '服务评分',\n",
" '产品名称', '型号', '单价', '数量', '总价', '销售人员', '销售时间',\n",
" '支付方式', '账号', '金额', '时间', '备注'\n",
"]\n",
"\n",
"# 起始日期和当前日期\n",
"first_date = \"2021-04-03\"\n",
"now_date = datetime.now().strftime('%Y-%m-%d')\n",
"\n",
"# 转换为 pandas 的 Timestamp 类型\n",
"start = pd.to_datetime(first_date)\n",
"end = pd.to_datetime(now_date)\n",
"\n",
"# 初始化当前时间指针\n",
"current = start\n",
"\n",
"# 计算总共有多少年,用于进度条\n",
"total_years = (end - start).days // 365 + 1\n",
"\n",
"all_url = []\n",
"\n",
"with tqdm(total=total_years, desc=\"处理时间段\") as pbar:\n",
" no_data_count=0\n",
" while current <= end:\n",
" # 计算这一年的结束日期\n",
" year_end = current + pd.DateOffset(years=1) - pd.Timedelta(days=1)\n",
" if year_end > end:\n",
" year_end = end\n",
"\n",
" # 格式化成 URL 需要的格式:YYYY/MM/DD\n",
" url_start = current.strftime('%Y/%m/%d')\n",
" url_end = year_end.strftime('%Y/%m/%d')\n",
"\n",
" # 构造 URL\n",
" url = f'http://best.aichedian.com/report/order-stat/?start_date={url_start}&end_date={url_end}&tab=1'\n",
"\n",
" driver.get(url) # 获取每日订单\n",
"\n",
" # 更新当前日期指针到下一年的开始\n",
" current = year_end + pd.Timedelta(days=1)\n",
" # 获取指定 XPath 下的所有 <tr> 元素\n",
" xpath = '//*[@id=\"order-profit-count\"]/table[2]'\n",
" try:\n",
" rows = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_all_elements_located((By.XPATH, xpath))\n",
" )\n",
" if not rows:\n",
" raise NoSuchElementException # 如果没有找到任何行,抛出异常\n",
" no_data_count = 0 # 重置计数器\n",
" except TimeoutException:\n",
" no_data_count += 1\n",
" if no_data_count >= 30:\n",
" print(\"连续30天没有数据,退出循环\")\n",
" break\n",
" continue\n",
"\n",
" for row in tqdm(rows):\n",
" # 获取每一行中的所有 <td> 元素\n",
" cells = row.find_elements(By.TAG_NAME, 'td')\n",
" row_data = [cell.text for cell in cells] # 将一行中的所有单元格文本存入列表\n",
" start_dj_data = row_data[0] # 开始时间\n",
" get_money_data = row_data[1] # 入账时间\n",
" car_number = row_data[2] # 车牌名称\n",
" customer = row_data[3] # 假设第二列是客户名称\n",
" order_details = '\\n'.join(row_data) # 将行数据合并为一个字符串,每列之间用换行符分隔\n",
"\n",
" for cell in cells:\n",
" try:\n",
" links = cell.find_elements(By.TAG_NAME, 'a') # 获取当前单元格内的所有 <a> 标签\n",
" absolute_url = None\n",
" all_absolute_urls = []\n",
" for link in links:\n",
" if link.text == \"查看详细\":\n",
" relative_url = link.get_attribute('href')\n",
" absolute_url = urljoin('http://best.aichedian.com/', relative_url)\n",
" all_absolute_urls.append(absolute_url)\n",
" else:\n",
" continue\n",
"\n",
" if not all_absolute_urls:\n",
" continue\n",
"\n",
" for absolute_url in all_absolute_urls:\n",
"\n",
" driver.get(absolute_url) # 获取查看详情\n",
"\n",
" n_xpath = '//*[@id=\"x-single-content\"]'\n",
" try:\n",
" n_rows = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_all_elements_located((By.XPATH, n_xpath))\n",
" )\n",
" except:\n",
" continue\n",
"\n",
" for row in n_rows:\n",
" n_cells = row.find_elements(By.TAG_NAME, 'td')\n",
" for n_cell in n_cells:\n",
" n_links = n_cell.find_elements(By.TAG_NAME, 'a')\n",
" for n_link in n_links:\n",
" if n_link.text == \"明细\":\n",
" n_relative_url = n_link.get_attribute('href')\n",
" n_absolute_url = urljoin('http://best.aichedian.com/', n_relative_url)\n",
" all_url.append(n_absolute_url)\n",
"\n",
" time.sleep(0.1)\n",
" driver.back()\n",
" except :\n",
" continue # 如果没有找到 <a> 标签,继续下一个 <td\n",
" # 返回页面\n",
" driver.back()\n",
" # 获取每日订单\n",
" pbar.update(1)\n",
"\n",
"\n",
"df1 = pd.DataFrame(all_url)\n",
"df1.to_csv('all_url.csv', index=False)\n",
"for url in tqdm(all_url):\n",
" try:\n",
" driver.get(url) # 获取明细数据\n",
" details_id = url.split('/')[-2]\n",
" \n",
" xpath1 = '//*[@id=\"x-single-content\"]/h2'\n",
" h2 = WebDriverWait(driver, 5).until(\n",
" EC.presence_of_element_located((By.XPATH, xpath1))\n",
" )\n",
" \n",
" if \"车辆检测单\" in h2.text or \"订单详情\" not in h2.text:\n",
" driver.back()\n",
" print(\"跳过\")\n",
" time.sleep(\n",
" 5\n",
" )\n",
" continue\n",
" \n",
" \n",
" # 获取基本信息\n",
" try:\n",
" base_details = WebDriverWait(driver, 10).until(\n",
" EC.presence_of_element_located((By.XPATH, f'//*[@id=\"x-single-content\"]/ul'))\n",
" )\n",
" li_items = base_details.find_elements(By.TAG_NAME, 'li')\n",
" base_info = {li.text.split(':')[0].strip(): li.text.split(':')[1].strip() if ':' in li.text else ''\n",
" for li in li_items}\n",
" # 获取具体信息,如果不存在则返回空字符串\n",
" license_plate = base_info.get('车牌号', '')\n",
" customer_name = base_info.get('客户名称', '')\n",
" order_id = base_info.get('订单编号', '')\n",
" except TimeoutException:\n",
" continue # 获取不到基本信息\n",
" \n",
" \n",
" # 获取服务项目\n",
" service_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"服务项目\"]'))\n",
" )\n",
" if h3_element.text == \"服务项目\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row1 in rows[1:]:\n",
" li_items = row1.find_elements(By.TAG_NAME, 'td')\n",
" service_info.append({\n",
" '服务名称': li_items[0].text,\n",
" '销售人员': li_items[1].text,\n",
" '施工人员': li_items[2].text,\n",
" '应付金额': li_items[3].text,\n",
" '施工时间': li_items[4].text,\n",
" '完工时间': li_items[5].text,\n",
" '服务评分': li_items[6].text\n",
" })\n",
" except:\n",
" pass\n",
" \n",
" # 获取销售产品\n",
" product_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"销售产品\"]'))\n",
" )\n",
" if h3_element.text == \"销售产品\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row2 in rows[1:]:\n",
" li_items = row2.find_elements(By.TAG_NAME, 'td')\n",
" product_info.append({\n",
" '产品名称': li_items[0].text,\n",
" '型号': li_items[1].text,\n",
" '单价': li_items[2].text,\n",
" '数量': li_items[3].text,\n",
" '总价': li_items[4].text,\n",
" '销售人员': li_items[5].text,\n",
" '销售时间': li_items[6].text\n",
" })\n",
" except:\n",
" pass\n",
" \n",
" # 获取支付记录\n",
" payment_info = []\n",
" try:\n",
" h3_element = WebDriverWait(driver, 0.2).until(\n",
" EC.presence_of_element_located((By.XPATH, '//h3[text()=\"支付记录\"]'))\n",
" )\n",
" if h3_element.text == \"支付记录\":\n",
" table = h3_element.find_element(By.XPATH, './following-sibling::table')\n",
" rows = table.find_elements(By.TAG_NAME, 'tr')\n",
" for row3 in rows[1:]:\n",
" li_items = row3.find_elements(By.TAG_NAME, 'td')\n",
" payment_info.append({\n",
" '支付方式': li_items[0].text,\n",
" '账号': li_items[1].text,\n",
" '金额': li_items[2].text,\n",
" '时间': li_items[3].text,\n",
" '备注': li_items[4].text\n",
" })\n",
" except:\n",
" pass\n",
" \n",
" # 将所有信息组合成一个字典\n",
" order_info = {\n",
" '订单号': details_id,\n",
" '开单时间': start_dj_data,\n",
" '入账时间': get_money_data,\n",
" '车辆': car_number,\n",
" '车主': customer,\n",
" '车牌号码': base_info.get('车牌号码', ''),\n",
" '车辆品牌': base_info.get('车辆品牌', ''),\n",
" '会员卡号': base_info.get('会员卡号', ''),\n",
" '车主姓名': base_info.get('车主姓名', ''),\n",
" '联系方式': base_info.get('联系方式', ''),\n",
" # '订单详情': order_details,\n",
" '服务名称': '\\n'.join([item['服务名称'] for item in service_info]),\n",
" '销售人员': '\\n'.join([item['销售人员'] for item in service_info]),\n",
" '施工人员': '\\n'.join([item['施工人员'] for item in service_info]),\n",
" '应付金额': '\\n'.join([item['应付金额'] for item in service_info]),\n",
" '施工时间': '\\n'.join([item['施工时间'] for item in service_info]),\n",
" '完工时间': '\\n'.join([item['完工时间'] for item in service_info]),\n",
" '服务评分': '\\n'.join([item['服务评分'] for item in service_info]),\n",
" '产品名称': '\\n'.join([item['产品名称'] for item in product_info]),\n",
" '型号': '\\n'.join([item['型号'] for item in product_info]),\n",
" '单价': '\\n'.join([item['单价'] for item in product_info]),\n",
" '数量': '\\n'.join([item['数量'] for item in product_info]),\n",
" '总价': '\\n'.join([item['总价'] for item in product_info]),\n",
" '销售人员': '\\n'.join([item['销售人员'] for item in product_info]),\n",
" '销售时间': '\\n'.join([item['销售时间'] for item in product_info]),\n",
" '支付方式': '\\n'.join([item['支付方式'] for item in payment_info]),\n",
" '账号': '\\n'.join([item['账号'] for item in payment_info]),\n",
" '金额': '\\n'.join([item['金额'] for item in payment_info]),\n",
" '时间': '\\n'.join([item['时间'] for item in payment_info]),\n",
" '备注': '\\n'.join([item['备注'] for item in payment_info])\n",
" }\n",
" \n",
" all_data.append(order_info) # 将完整订单信息添加到总数据列表中\n",
" except:\n",
" pass\n",
"\n",
"# 使用pandas将数据保存为Excel文件\n",
"df = pd.DataFrame(all_data, columns=headers)\n",
"df.to_excel('爱车店数据导出.xlsx', index=False) # 保存为Excel文件\n",
"\n",
"# 关闭浏览器\n",
"driver.quit()"
],
"id": "3bdcde801e98b6bd",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:25: SyntaxWarning: invalid escape sequence '\\P'\n",
"<>:25: SyntaxWarning: invalid escape sequence '\\P'\n",
"C:\\Users\\Administrator.DESKTOP-7IC2USJ\\AppData\\Local\\Temp\\ipykernel_27060\\653923207.py:25: SyntaxWarning: invalid escape sequence '\\P'\n",
" service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')\n",
"处理时间段: 0%| | 0/5 [00:00<?, ?it/s]\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A\n",
"100%|██████████| 1/1 [04:13<00:00, 253.29s/it]\u001B[A\n",
"\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A\n",
"100%|██████████| 1/1 [04:49<00:00, 289.93s/it]\u001B[A\n",
"\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A\n",
"100%|██████████| 1/1 [05:09<00:00, 309.01s/it]\u001B[A\n",
"\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A\n",
"100%|██████████| 1/1 [04:25<00:00, 265.08s/it]\u001B[A\n",
"\n",
" 0%| | 0/1 [00:00<?, ?it/s]\u001B[A\n",
"100%|██████████| 1/1 [00:02<00:00, 2.59s/it]\u001B[A\n",
"处理时间段: 20%|██ | 1/5 [18:44<1:14:57, 1124.42s/it]\n",
" 0%| | 39/14439 [00:37<3:54:19, 1.02it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|▏ | 183/14439 [02:55<4:05:12, 1.03s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|▏ | 184/14439 [03:00<9:07:41, 2.31s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|▏ | 198/14439 [03:15<2:58:07, 1.33it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|▏ | 199/14439 [03:20<8:21:44, 2.11s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|▏ | 200/14439 [03:26<12:27:17, 3.15s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 2%|▏ | 219/14439 [03:48<3:40:41, 1.07it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 2%|▏ | 220/14439 [03:53<8:49:45, 2.24s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 2%|▏ | 281/14439 [04:54<3:38:17, 1.08it/s] "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 6%|▌ | 813/14439 [14:18<4:40:52, 1.24s/it]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 36%|███▌ | 5177/14439 [1:30:02<2:24:55, 1.07it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"跳过\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 14439/14439 [5:04:48<00:00, 1.27s/it] \n"
]
}
],
"execution_count": 5
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-06-23T06:06:18.139653Z",
"start_time": "2025-06-23T06:06:18.131895Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_url)\n",
"df1.to_csv('all_url.csv', index=False)"
],
"id": "a68ff75a6184bae",
"outputs": [],
"execution_count": 3
}
],
"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
}
@@ -0,0 +1,131 @@
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
import os
import pickle
import json
from datetime import datetime, timedelta
# ==================== 配置 ====================
COOKIE_FILE = "sina_cookies.pkl" # 保存 Cookies 的文件名
LOGIN_URL = "https://tousu.sina.com.cn/"
DOMAIN = "tousu.sina.com.cn"
MAX_COOKIE_AGE_DAYS = 7 # Cookies 最大有效期(天)
def is_cookie_valid():
"""检查 Cookies 是否存在且未过期"""
if not os.path.exists(COOKIE_FILE):
return False
with open(COOKIE_FILE, "rb") as f:
cookies = pickle.load(f)
# 获取 Cookies 中的过期时间(假设有一个 Cookie 有 'expiry' 字段)
for cookie in cookies:
if 'expiry' in cookie:
expiry_time = datetime.fromtimestamp(cookie['expiry'])
if expiry_time < datetime.now():
print("Cookies 已过期")
return False
return True
def save_cookies(driver):
"""保存当前会话的 Cookies 到文件"""
cookies = driver.get_cookies()
with open(COOKIE_FILE, "wb") as f:
pickle.dump(cookies, f)
print("Cookies 已保存")
def load_cookies(driver):
"""加载 Cookies 到当前浏览器会话"""
driver.get(LOGIN_URL) # 必须先访问一次目标网站才能设置 Cookies
with open(COOKIE_FILE, "rb") as f:
cookies = pickle.load(f)
for cookie in cookies:
# 移除不必要的字段
cookie.pop('sameSite', None)
cookie.pop('expiry', None) if 'expiry' in cookie and cookie['expiry'] < time.time() else None
driver.add_cookie(cookie)
print("Cookies 加载成功")
def check_login_status(driver):
"""检查用户是否登录"""
try:
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#SI_User > div.ac-login.ac-logined"))
)
print("检测到已登录状态")
return True
except:
print("未登录或登录状态失效")
return False
def collect_complaints(driver, keyword, max_items=1000):
search_url = f"https://tousu.sina.com.cn/index/search/?keywords={keyword}&t=1"
driver.get(search_url)
collected_items = set()
no_new_count = 0
while len(collected_items) < max_items and no_new_count < 3:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
complaints = driver.find_elements(By.CSS_SELECTOR, "#search_tab > div.blackcat-container > div.tab-con.tousu-list > div > a > h1")
current_count = len(collected_items)
for complaint in complaints:
text = complaint.text.strip()
if text and text not in collected_items:
collected_items.add(text)
if len(collected_items) == current_count:
no_new_count += 1
else:
no_new_count = 0
return list(collected_items)
def main():
# 配置 Chrome 浏览器选项
chrome_options = Options()
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36")
# 启动浏览器
chrome_service = Service(executable_path='D:\\ProgramTools\\chromedriver-win64\\chromedriver.exe')
driver = webdriver.Chrome(service=chrome_service, options=chrome_options)
# 检查是否已有 Cookies
if is_cookie_valid():
print("使用保存的 Cookies 登录...")
load_cookies(driver)
driver.get(LOGIN_URL)
if not check_login_status(driver):
print("Cookies 无效,需要手动登录")
input("请手动登录后按回车继续...")
save_cookies(driver)
else:
print("首次登录,请手动登录")
driver.get(LOGIN_URL)
input("请手动登录后按回车继续...")
save_cookies(driver)
# 获取搜索关键词
keyword = input("请输入搜索关键词(例如:F6汽车科技): ")
# 收集投诉内容
complaints = collect_complaints(driver, keyword)
# 保存结果
with open("tousu.txt", "w", encoding="utf-8") as f:
for item in complaints:
f.write(item + "\n")
print(f"成功收集到{len(complaints)}条投诉信息,已保存到tousu.txt")
driver.quit()
if __name__ == "__main__":
main()
File diff suppressed because one or more lines are too long
@@ -0,0 +1,216 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-12-29T03:33:47.044410Z",
"start_time": "2025-12-29T03:31:04.703879800Z"
}
},
"source": [
"import requests\n",
"from bs4 import BeautifulSoup\n",
"import pandas as pd\n",
"import time\n",
"from tqdm.notebook import tqdm # Jupyter 专属进度条\n",
"\n",
"# ---------------------- 配置请求参数 ----------------------\n",
"cookies = {\n",
" 'ECSCP[admin_id]': '108',\n",
" 'ECSCP[admin_pass]': 'a7a7436dc3cdb9a0cf46db404553e361',\n",
" 'ECS_LastCheckOrder': 'Mon%2C%2029%20Dec%202025%2003%3A26%3A30%20GMT',\n",
" 'ECSCP[lastfilterfile]': '9028E76F',\n",
" 'ECSCP[lastfilter]': 'a%253A12%253A%257Bs%253A9%253A%2522user_name%2522%253Bs%253A0%253A%2522%2522%253Bs%253A9%253A%2522note_name%2522%253Bs%253A0%253A%2522%2522%253Bs%253A9%253A%2522carnumber%2522%253Bs%253A0%253A%2522%2522%253Bs%253A5%253A%2522cates%2522%253Bs%253A0%253A%2522%2522%253Bs%253A12%253A%2522insurance_id%2522%253Bi%253A0%253Bs%253A6%253A%2522inyear%2522%253Bi%253A0%253Bs%253A6%253A%2522intime%2522%253Bi%253A0%253Bs%253A12%253A%2522record_count%2522%253Bs%253A4%253A%25222309%2522%253Bs%253A9%253A%2522page_size%2522%253Bi%253A15%253Bs%253A4%253A%2522page%2522%253Bi%253A1%253Bs%253A10%253A%2522page_count%2522%253Bd%253A154%253Bs%253A5%253A%2522start%2522%253Bi%253A0%253B%257D',\n",
" 'ECSCP[lastfiltersql]': 'U0VMRUNUIHUuKiwgcC51c2VyX25hbWUgYXMgcGFyZW50X25hbWUsIGEuY2F0X25hbWUsIGIuY2F0X25hbWUgYXMgY2FyX25hbWUsIHUuc2VjdXJpdHlkYXRlLCBpLmluc3VyYW5jZV9uYW1lIEZST00gYHRlamlhbHVudGFpX2NvbWAuYGVjc191c2Vyc2AgYXMgdSBsZWZ0IGpvaW4gYHRlamlhbHVudGFpX2NvbWAuYGVjc191c2Vyc2AgYXMgcCBvbiBwLnVzZXJfaWQgPSB1LnBhcmVudF9pZCAgbGVmdCBqb2luIGB0ZWppYWx1bnRhaV9jb21gLmBlY3NfaW5zdXJhbmNlYCBhcyBpIG9uIGkuaW5zdXJhbmNlX2lkID0gdS5pbnN1cmFuY2VfaWQgIGxlZnQgam9pbiBgdGVqaWFsdW50YWlfY29tYC5gZWNzX2NhdGVnb3J5YCBhcyBhIG9uIGEuY2F0X2lkID0gdS5jc3J0X2lkICBsZWZ0IGpvaW4gYHRlamlhbHVudGFpX2NvbWAuYGVjc19jYXRlZ29yeWAgYXMgeSBvbiBhLnBhcmVudF9pZCA9IHkuY2F0X2lkICBsZWZ0IGpvaW4gYHRlamlhbHVudGFpX2NvbWAuYGVjc19jYXRlZ29yeWAgYXMgYyBvbiB5LnBhcmVudF9pZCA9IGMuY2F0X2lkICBsZWZ0IGpvaW4gYHRlamlhbHVudGFpX2NvbWAuYGVjc19jYXRlZ29yeWAgYXMgYiBvbiBjLnBhcmVudF9pZCA9IGIuY2F0X2lkICB3aGVyZSAxIEFORCB1LnN1cHBsaWVyc19pZCA9ICcnIE9SREVSIEJZIHVzZXJfaWQgREVTQyBMSU1JVCAwLDE1',\n",
" 'real_ipd': '221.226.144.180',\n",
" 'ECSCP_ID': '1be4bfb53679215381f4dac51482e1152b69f88a',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'cache-control': 'no-cache',\n",
" 'content-type': 'application/x-www-form-urlencoded',\n",
" 'origin': 'https://tejialuntai.com',\n",
" 'pragma': 'no-cache',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://tejialuntai.com/admin2/suppliers_users.php?act=list',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
" 'sec-fetch-dest': 'empty',\n",
" 'sec-fetch-mode': 'cors',\n",
" 'sec-fetch-site': 'same-origin',\n",
" 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
"}\n",
"\n",
"params = {'is_ajax': '1'}\n",
"base_data = {\n",
" 'act': 'query',\n",
" 'user_name': '',\n",
" 'note_name': '',\n",
" 'carnumber': '',\n",
" 'cates': '0',\n",
" 'insurance_id': '0',\n",
" 'inyear': '0',\n",
" 'intime': '0',\n",
" 'record_count': '2309',\n",
" 'page_size': '15',\n",
" 'page_count': '154',\n",
"}\n",
"\n",
"# ---------------------- 定义数据提取函数 ----------------------\n",
"def get_page_data(page):\n",
" \"\"\"\n",
" 请求指定页码的数据并解析\n",
" :param page: 页码\n",
" :return: 解析后的当前页数据列表, 总页数\n",
" \"\"\"\n",
" start = (page - 1) * 15\n",
" data = base_data.copy()\n",
" data.update({'page': str(page), 'start': str(start)})\n",
"\n",
" try:\n",
" # 发送请求,添加超时和重试机制\n",
" response = requests.post(\n",
" 'https://tejialuntai.com/admin2/suppliers_users.php',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" data=data,\n",
" timeout=15\n",
" )\n",
" response.raise_for_status() # 抛出HTTP错误\n",
" res_json = response.json()\n",
" except requests.exceptions.RequestException as e:\n",
" print(f\"\\n请求第 {page} 页失败: {str(e)}\")\n",
" return [], None\n",
"\n",
" # 解析HTML表格\n",
" soup = BeautifulSoup(res_json['content'], 'html.parser')\n",
" table = soup.find('table')\n",
" if not table:\n",
" print(f\"\\n第 {page} 页未找到数据表格\")\n",
" return [], None\n",
"\n",
" rows = table.find_all('tr')[1:] # 跳过表头\n",
" page_data = []\n",
" for row in rows:\n",
" cols = row.find_all('td')\n",
" if len(cols) < 17:\n",
" continue\n",
"\n",
" # 提取每列数据\n",
" user_info = {\n",
" '用户id': cols[0].text.strip(),\n",
" '用户名称': cols[1].text.strip(),\n",
" '备注名称': cols[2].text.strip(),\n",
" '手机号码': cols[3].text.strip(),\n",
" '注册时间': cols[4].text.strip(),\n",
" '推荐人': cols[5].text.strip(),\n",
" '车型': cols[6].text.strip(),\n",
" '变速箱': cols[7].text.strip(),\n",
" '机油信息': cols[8].text.strip(),\n",
" '车牌号': cols[9].text.strip(),\n",
" '微信号': cols[10].text.strip(),\n",
" '余额': cols[11].text.strip(),\n",
" '保险公司': cols[12].text.strip(),\n",
" '保险到期': cols[13].text.strip(),\n",
" '旗下车辆': cols[14].text.strip(),\n",
" '车架号': cols[15].text.strip(),\n",
" '操作': cols[16].text.strip()\n",
" }\n",
" page_data.append(user_info)\n",
"\n",
" return page_data, res_json.get('page_count', 154)\n",
"\n",
"# ---------------------- 主执行逻辑 ----------------------\n",
"if __name__ == '__main__':\n",
" all_data = []\n",
" # 1. 获取第1页数据,确认总页数\n",
" first_page_data, total_pages = get_page_data(1)\n",
" if not first_page_data:\n",
" print(\"无法获取第1页数据,程序终止\")\n",
" else:\n",
" all_data.extend(first_page_data)\n",
" print(f\"第1页数据提取完成,共{len(first_page_data)}条\")\n",
"\n",
" # 2. 遍历剩余页码,使用进度条\n",
" for page in tqdm(range(2, int(total_pages) + 1), desc=\"提取所有页面数据\"):\n",
" page_data, _ = get_page_data(page)\n",
" all_data.extend(page_data)\n",
" time.sleep(0.5) # 延迟0.5秒,避免请求过快\n",
"\n",
" # 3. 转换为DataFrame并保存为xlsx\n",
" if all_data:\n",
" df = pd.DataFrame(all_data)\n",
" # 保存到当前目录,文件名:会员数据全量.xlsx\n",
" df.to_excel('会员数据全量.xlsx', index=False, engine='openpyxl')\n",
" print(f\"\\n所有数据提取完成!共{len(all_data)}条\")\n",
" print(f\"文件已保存为:会员数据全量.xlsx\")\n",
" else:\n",
" print(\"未提取到任何数据\")"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"第1页数据提取完成,共16条\n"
]
},
{
"data": {
"text/plain": [
"提取所有页面数据: 0%| | 0/153 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "5c7aad4f6153456fa5d7347d3733eb5a"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"所有数据提取完成!共2463条\n",
"文件已保存为:会员数据全量.xlsx\n"
]
}
],
"execution_count": 3
}
],
"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
}
@@ -0,0 +1,156 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2024-11-22T08:49:41.787341Z",
"start_time": "2024-11-22T08:09:20.489931Z"
}
},
"source": [
"import requests\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"import time\n",
"# 历史维修记录明细\n",
"# 请求过于频繁会挂掉\n",
"\n",
"url = 'https://erp.byjy168.cn/top/statistics/fix/worksheetHistory/summary/new'\n",
"\n",
"headers = {\n",
" 'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate, br, zstd',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9',\n",
" 'Connection': 'keep-alive',\n",
" 'Cookie': 'JSESSIONID=D0A01E7B7FA40CB76F1770BF36556A66',\n",
" 'Host': 'erp.byjy168.cn',\n",
" 'Referer': 'https://erp.byjy168.cn/dashboard/index/reportforms/history',\n",
" 'Sec-Ch-Ua': '\"Microsoft Edge\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"',\n",
" 'Sec-Ch-Ua-Mobile': '?0',\n",
" 'Sec-Ch-Ua-Platform': '\"Windows\"',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'Token':'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzMDMxNyIsInVzZXJuYW1lIjoi5p2O54KcIiwibmFtZSI6IiIsImNvbXBhbnlJZCI6NDIzOSwib3BlcmF0b3JJZCI6MywicGhvbmUiOiIxODY4ODU1MjI3OCIsIm1lbnVUeXBlIjoiMSIsImNvbW5vIjoiQTAxIiwicGNvcmFwcCI6InBjIiwiZXhwIjoxNzMyNjk0NTkyfQ.EgVtyoVcOWZ4EmdYHv52k6Cruk8FExTF4Gp-u_4Ug3I',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0'\n",
"}\n",
"\n",
"all_data_list = []\n",
"for i in tqdm(range(1, 655), desc='Processing pages', unit='page'):\n",
" time.sleep(2)\n",
" data = f'current={i}&size=10&status=&gridCode=GS011340&isOtherAccess=1&comno=A01&shopCode=A01'\n",
"\n",
" response = requests.post(url=url, headers=headers, data=data)\n",
"\n",
" if response.status_code == 200:\n",
" data = response.json()\n",
" data_list = data['data']['records']\n",
"\n",
" for data in data_list:\n",
" work_sheet_code = data['worksheetCode']\n",
" all_data_list.append(data)\n",
" url1 = f'https://erp.byjy168.cn/api/repairServiceHistory/getListByCode?worksheetCode={work_sheet_code}&shopCode=A01'\n",
" res = requests.get(url=url1, headers=headers)\n",
" if res.status_code == 200:\n",
" data1 = res.json()\n",
" details = []\n",
" for detail in data1['data']:\n",
" all_data_list.append(detail)\n",
" time.sleep(1)\n",
" else:\n",
" print(f\"Failed to get details for worksheetCode {work_sheet_code}, status code: {res.status_code}\")\n",
" else:\n",
" print(f\"Failed to retrieve page {i}, status code: {response.status_code}\")\n",
" \n",
"df = pd.DataFrame(all_data_list)\n",
"# 定义新列名\n",
"new_columns = {\n",
" 'inDate': '收银时间',\n",
" 'customerName': '客户名称',\n",
" 'registerNo': '车牌号',\n",
" 'model': '车型',\n",
" 'status': '状态',\n",
" 'receptionSource': '客户来源',\n",
" 'serviceType': '业务类型',\n",
" 'relasalesName': '客户经理',\n",
" 'recpersonName': '接待人',\n",
" 'mainworkerName': '维修技师',\n",
" 'recmoneyDate': '收银时间',\n",
" 'timeAmount': '工时金额',\n",
" 'partAmount': '配件金额',\n",
" 'addAmount': '增值金额',\n",
" 'amount': '合计金额',\n",
" 'otherAmount': '其他金额',\n",
" 'discountAmount': '减收金额',\n",
" 'totalAmount': '实收金额',\n",
" 'costAmount': '实收成本',\n",
" 'cashAmount': '现金',\n",
" 'arrearAmount': '挂帐金额',\n",
" 'cardAmount': '刷卡',\n",
" 'wxAmount': '微信支付',\n",
" 'zfbAmount': '支付宝支付',\n",
" 'accotherdetail': '其它支付明细',\n",
" 'balanceAmount': '欠款余额',\n",
" 'serviceCode': '项目编码',\n",
" 'serviceName': '项目名称',\n",
" 'workTime': '工时',\n",
" 'timePrice': '项目单价',\n",
" 'mainWorkerName': '主修员',\n",
" # 继续添加更多的列名映射...\n",
"}\n",
"# 使用rename方法替换列名\n",
"df.rename(columns=new_columns, inplace=True)\n",
"# 保存到Excel文件\n",
"file_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\百少侠导出数据.xlsx'\n",
"df.to_excel(file_path, index=False)\n",
"\n",
"print(f\"数据已成功保存至{file_path}\") \n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Processing pages: 43%|████▎ | 282/654 [40:21<53:13, 8.59s/page] \n"
]
},
{
"ename": "KeyError",
"evalue": "'data'",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mKeyError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[17], line 45\u001B[0m\n\u001B[0;32m 43\u001B[0m data1 \u001B[38;5;241m=\u001B[39m res\u001B[38;5;241m.\u001B[39mjson()\n\u001B[0;32m 44\u001B[0m details \u001B[38;5;241m=\u001B[39m []\n\u001B[1;32m---> 45\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m detail \u001B[38;5;129;01min\u001B[39;00m data1[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mdata\u001B[39m\u001B[38;5;124m'\u001B[39m]:\n\u001B[0;32m 46\u001B[0m all_data_list\u001B[38;5;241m.\u001B[39mappend(detail)\n\u001B[0;32m 47\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n",
"\u001B[1;31mKeyError\u001B[0m: 'data'"
]
}
],
"execution_count": 17
}
],
"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
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,343 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "",
"id": "647cfbcdeaa27eb5"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-01-17T03:08:53.359083Z",
"start_time": "2025-01-17T03:08:53.166826Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"\n",
"header = {\n",
" \"Host\": \"yqhm.vip5968.com\",\n",
" \"Origin\": \"http://yqhm.vip5968.com\",\n",
" \"Referer\": \"http://yqhm.vip5968.com/Module/Member/MemInfo.aspx?PID=42&MemCard=810076\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
"}\n",
"\n",
"cookies = {\n",
" \"ASP.NET_SessionId\": \"lzkml2bs2crzysshj2nutb5v\",\n",
" \"TestCookie\": \"\",\n",
" \"LoginState\": \"68AD1028E54520B1EDDB8584F2768630F73F7846610C020F0270B0E2C34FA16B27D3F2A5A659FD92\"\n",
"}\n",
"\n",
"data = {\n",
" \"Method\": \"MemInfoCountExpenseGet\",\n",
" \"memid\": \"1185\"\n",
"}\n",
"\n",
"url = 'http://yqhm.vip5968.com/AjaxService/Service.ashx?Method=MemInfoCountExpenseGet'\n",
"\n",
"res = requests.post(url=url, headers=header, cookies=cookies, data=data)\n",
"data_list = res.json()\n",
"\n",
"for data in data_list:\n",
" df = data.Dataframe()\n",
" df.to_excel(f'成浩美车会员管理系统导出.xlsx')\n"
],
"id": "4930c73284248d36",
"outputs": [
{
"data": {
"text/plain": [
"{'List': [{'OrderAccount': '2025010617115616',\n",
" 'OrderEndTime': '2900/1/1 0:00:00',\n",
" 'OrderDetailID': '9897',\n",
" 'OrderID': '9445',\n",
" 'OrderAccount1': '2025010617115616',\n",
" 'GoodsID': '272',\n",
" 'GoodsDetailBidPrice': '0.0000',\n",
" 'OrderDetailPrice': '580.0000',\n",
" 'OrderDetailDiscountPrice': '580.0000',\n",
" 'OrderDetailItemPoint': '0.0000',\n",
" 'OrderDetailPoint': '0',\n",
" 'OrderDetailNumber': '5',\n",
" 'OrderDetailType': '1',\n",
" 'OrderDetailStaffID': '0',\n",
" 'OrderDetailCreateTime': '2025/1/6 17:12:06',\n",
" 'OrderDetaiEndTime': '2900/1/1 0:00:00',\n",
" 'OrderDetailRemark': '',\n",
" 'OrderDetailOldID': '0',\n",
" 'OrderDetailCountNum': '5',\n",
" 'DeductGoodsID': '0',\n",
" 'GoodsID1': '272',\n",
" 'GoodsCode': '190623082115',\n",
" 'GoodsName': '隐形车衣保养',\n",
" 'GoodsNameCode': 'YXCYBY',\n",
" 'GoodsPrice': '580.0000',\n",
" 'GoodsUnit': '块',\n",
" 'GoodsSalePercet': '0',\n",
" 'GoodsClassID': '12',\n",
" 'CommissionType': '0',\n",
" 'CommissionNumber': '0',\n",
" 'GoodsPoint': '0',\n",
" 'MinPercent': '0',\n",
" 'GoodsType': 'True',\n",
" 'GoodsBidPrice': '0.0000',\n",
" 'GoodsRemark': '',\n",
" 'GoodsPicture': '',\n",
" 'CreateShopID': '3',\n",
" 'CreateUserID': '4',\n",
" 'CreateTime': '2022/10/12 10:51:49',\n",
" 'GoodsNumberLowest': '0',\n",
" 'GoodsWeiXinPrice': '0.0000',\n",
" 'IsPutAway': 'False'}]}"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 2
},
{
"metadata": {},
"cell_type": "markdown",
"source": "请求列表",
"id": "cd5414f2e299d35a"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-01-18T02:28:51.436282Z",
"start_time": "2025-01-18T02:28:51.300809Z"
}
},
"source": [
"import requests\n",
"import pandas as pd\n",
"from bs4 import BeautifulSoup\n",
"from tqdm import tqdm\n",
"\n",
"headers = {\n",
" \"cookie\": \"td_cookie=2691013127; ASP.NET_SessionId=lzkml2bs2crzysshj2nutb5v; TestCookie=; LoginState=68AD1028E54520B1EDDB8584F2768630F73F7846610C020FB26F23CFB749BC377C96B23EE9919A65\",\n",
" \"host\": \"yqhm.vip5968.com\",\n",
" \"upgrade-insecure-requests\": \"1\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0\"\n",
"}\n",
"viewstate = None\n",
"eventvalidation = None\n",
"all_data_list = []\n",
"for page in tqdm(range(1, 56)): # 总页数注意+1\n",
" url = 'http://yqhm.vip5968.com/Module/Member/MemList.aspx?PID=3'\n",
"\n",
" data = {\n",
" \"PID\": \"3\",\n",
" \"__EVENTTARGET\": \"NetPager\",\n",
" \"__EVENTARGUMENT\": page,\n",
" \"__VIEWSTATE\": viewstate,\n",
" \"__EVENTVALIDATION\": eventvalidation\n",
"\n",
" }\n",
"\n",
" res = requests.post(url=url, headers=headers, data=data)\n",
" print(res.text)\n",
" soup = BeautifulSoup(res.text, 'html.parser')\n",
"\n",
" viewstate = soup.find('input', {'id': '__VIEWSTATE'})['value']\n",
" eventvalidation = soup.find('input', {'id': '__EVENTVALIDATION'})['value']\n",
"\n",
" input_tags = soup.find_all('input', {'id': lambda x: x and 'rptDataList_chkItem' in x})\n",
"\n",
" # 遍历找到的<input>标签并提取memid和memcard属性\n",
" for tag in input_tags:\n",
" memid = tag.get('memid')\n",
" memcard = tag.get('memcard')\n",
" # print(f\"MemID: {memid}, MemCard: {memcard}\")\n",
" new_data = {\n",
" \"Method\": \"MemInfoCountExpenseGet\",\n",
" \"memid\": memid\n",
" }\n",
" print(memid)\n",
" new_url = 'http://yqhm.vip5968.com/AjaxService/Service.ashx?Method=MemInfoCountExpenseGet'\n",
" res = requests.post(url=new_url, headers=headers, data=new_data)\n",
" list = res.json().get('List')\n",
" for data in list:\n",
" data['memcard'] = memcard\n",
" all_data_list.append(data)\n",
"\n",
"df = pd.DataFrame(all_data_list)\n",
"\n",
"df.to_excel(f'成浩美车会员管理系统导出.xlsx')\n",
"\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
" 0%| | 0/55 [00:00<?, ?it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
},
{
"ename": "TypeError",
"evalue": "'NoneType' object is not subscriptable",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mTypeError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[32], line 31\u001B[0m\n\u001B[0;32m 28\u001B[0m \u001B[38;5;28mprint\u001B[39m(res\u001B[38;5;241m.\u001B[39mtext)\n\u001B[0;32m 29\u001B[0m soup \u001B[38;5;241m=\u001B[39m BeautifulSoup(res\u001B[38;5;241m.\u001B[39mtext, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhtml.parser\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[1;32m---> 31\u001B[0m viewstate \u001B[38;5;241m=\u001B[39m soup\u001B[38;5;241m.\u001B[39mfind(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124minput\u001B[39m\u001B[38;5;124m'\u001B[39m, {\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mid\u001B[39m\u001B[38;5;124m'\u001B[39m: \u001B[38;5;124m'\u001B[39m\u001B[38;5;124m__VIEWSTATE\u001B[39m\u001B[38;5;124m'\u001B[39m})[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m'\u001B[39m]\n\u001B[0;32m 32\u001B[0m eventvalidation \u001B[38;5;241m=\u001B[39m soup\u001B[38;5;241m.\u001B[39mfind(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124minput\u001B[39m\u001B[38;5;124m'\u001B[39m, {\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mid\u001B[39m\u001B[38;5;124m'\u001B[39m: \u001B[38;5;124m'\u001B[39m\u001B[38;5;124m__EVENTVALIDATION\u001B[39m\u001B[38;5;124m'\u001B[39m})[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mvalue\u001B[39m\u001B[38;5;124m'\u001B[39m]\n\u001B[0;32m 34\u001B[0m input_tags \u001B[38;5;241m=\u001B[39m soup\u001B[38;5;241m.\u001B[39mfind_all(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124minput\u001B[39m\u001B[38;5;124m'\u001B[39m, {\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mid\u001B[39m\u001B[38;5;124m'\u001B[39m: \u001B[38;5;28;01mlambda\u001B[39;00m x: x \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mrptDataList_chkItem\u001B[39m\u001B[38;5;124m'\u001B[39m \u001B[38;5;129;01min\u001B[39;00m x})\n",
"\u001B[1;31mTypeError\u001B[0m: 'NoneType' object is not subscriptable"
]
}
],
"execution_count": 32
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-01-18T02:35:24.666100Z",
"start_time": "2025-01-18T02:35:24.666100Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"from bs4 import BeautifulSoup\n",
"from tqdm import tqdm\n",
"\n",
"headers = {\n",
" \"cookie\": \"td_cookie=2698739984; ASP.NET_SessionId=lzkml2bs2crzysshj2nutb5v; TestCookie=; td_cookie=2764366113; LoginState=68AD1028E54520B1EDDB8584F2768630F73F7846610C020FCDEE011B12E86E6E806A72CE142D4339\",\n",
" \"host\": \"yqhm.vip5968.com\",\n",
" \"upgrade-insecure-requests\": \"1\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0\"\n",
"}\n",
"\n",
"all_data_list = []\n",
"# for page in tqdm(range(1, 56)): # 总页数注意+1\n",
"url = 'http://yqhm.vip5968.com/Module/Member/MemList.aspx?PID=3'\n",
"\n",
"data = {\n",
" \"PID\": \"3\",\n",
" # \"__EVENTTARGET\": \"NetPager\",\n",
" # \"__EVENTARGUMENT\": page,\n",
" # \"__VIEWSTATE\": viewstate,\n",
" # \"__EVENTVALIDATION\": eventvalidation\n",
"\n",
"}\n",
"res = requests.post(url=url, headers=headers, data=data)\n",
"print(res.text)\n",
"soup = BeautifulSoup(res.text, 'html.parser')\n",
"\n",
"viewstate = soup.find('input', {'id': '__VIEWSTATE'})['value']\n",
"eventvalidation = soup.find('input', {'id': '__EVENTVALIDATION'})['value']\n",
"\n",
"input_tags = soup.find_all('input', {'id': lambda x: x and 'rptDataList_chkItem' in x})\n",
"\n",
"# 遍历找到的<input>标签并提取memid和memcard属性\n",
"for tag in input_tags:\n",
" memid = tag.get('memid')\n",
" memcard = tag.get('memcard')\n",
" # print(f\"MemID: {memid}, MemCard: {memcard}\")\n",
" new_data = {\n",
" \"Method\": \"MemInfoCountExpenseGet\",\n",
" \"memid\": memid\n",
" }\n",
" print(memid)\n",
" new_url = 'http://yqhm.vip5968.com/AjaxService/Service.ashx?Method=MemInfoCountExpenseGet'\n",
" res = requests.post(url=new_url, headers=headers, data=new_data)\n",
" list = res.json().get('List')\n",
" for data in list:\n",
" data['memcard'] = memcard\n",
" all_data_list.append(data)\n",
"\n",
"for page in tqdm(range(2, 56)): # 总页数注意+1\n",
" url = 'http://yqhm.vip5968.com/Module/Member/MemList.aspx?PID=3'\n",
"\n",
" data = {\n",
" \"PID\": \"3\",\n",
" \"__EVENTTARGET\": \"NetPager\",\n",
" \"__EVENTARGUMENT\": page,\n",
" \"__VIEWSTATE\": viewstate,\n",
" \"__EVENTVALIDATION\": eventvalidation\n",
"\n",
" }\n",
"\n",
" res = requests.post(url=url, headers=headers, data=data)\n",
" # print(res.text)\n",
" soup = BeautifulSoup(res.text, 'html.parser')\n",
"\n",
" viewstate = soup.find('input', {'id': '__VIEWSTATE'})['value']\n",
" eventvalidation = soup.find('input', {'id': '__EVENTVALIDATION'})['value']\n",
"\n",
" input_tags = soup.find_all('input', {'id': lambda x: x and 'rptDataList_chkItem' in x})\n",
"\n",
" # 遍历找到的<input>标签并提取memid和memcard属性\n",
" for tag in input_tags:\n",
" memid = tag.get('memid')\n",
" memcard = tag.get('memcard')\n",
" # print(f\"MemID: {memid}, MemCard: {memcard}\")\n",
" new_data = {\n",
" \"Method\": \"MemInfoCountExpenseGet\",\n",
" \"memid\": memid\n",
" }\n",
" print(memid)\n",
" new_url = 'http://yqhm.vip5968.com/AjaxService/Service.ashx?Method=MemInfoCountExpenseGet'\n",
" res = requests.post(url=new_url, headers=headers, data=new_data)\n",
" list = res.json().get('List')\n",
" for data in list:\n",
" data['memcard'] = memcard\n",
" all_data_list.append(data)\n",
"\n",
"df = pd.DataFrame(all_data_list)\n",
"\n",
"df.to_excel(f'成浩美车会员管理系统导出.xlsx')\n",
"\n"
],
"id": "4743835b87d92aa8",
"outputs": [],
"execution_count": null
}
],
"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
}
@@ -0,0 +1,361 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "# 车辆信息",
"id": "f7881b6d57bf77d2"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-05T09:54:23.113999400Z",
"start_time": "2026-01-05T09:52:58.415160Z"
}
},
"source": [
"import requests\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"import pandas as pd\n",
"\n",
"cookies = {\n",
" 'feehi_session': '695b7d067fd99',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMwMTI2MDEwNTE1MjgxMDAwMSwic2NvcGVzIjoiYXQiLCJpc3MiOiJzaHVpZGFvLnNlcnZlciIsImF1ZCI6InNodWlkYW8uY2xpZW50IiwianRpIjoiZTkzNTUzIiwiaWF0IjoxNzY3NjAzODk1LjY1MTg3NSwibmJmIjoxNzY3NjAzODk1LjY1MTg3NSwiZXhwIjoxNzY3NjkwMjk1LjY1MTg3NX0.POSVuvUhvpWBoNqHypiMNL58eAzrSlHUmd-DOvt7-18',\n",
" 'origin': 'https://daotian.shuidao.com',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://daotian.shuidao.com/',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\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/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" # 'cookie': 'feehi_session=695b7d067fd99',\n",
"}\n",
"\n",
"all_data = []\n",
"for i in tqdm(range(0, 174)):\n",
" rtick = str(int(time.time() * 1000))\n",
" params = {\n",
" 'key': '',\n",
" 'skip': 15 * i,\n",
" 'limit': '15',\n",
" 'rtick': rtick,\n",
" }\n",
"\n",
" response = requests.get('https://api.shuidao.com/daotian_web/customer/customer-list', params=params,\n",
" cookies=cookies, headers=headers)\n",
" res_data = response.json().get('res').get('list')\n",
" all_data.extend(res_data)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田车辆信息.xlsx\")\n",
"\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:42: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:42: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\1310767323.py:42: SyntaxWarning: invalid escape sequence '\\I'\n",
" df.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田车辆信息.xlsx\")\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/174 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "edadc9db42ef484c899c7d63c01dc3ce"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 7
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 工单信息",
"id": "fcea901e3ea7ec4f"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T01:18:48.885923Z",
"start_time": "2026-01-06T01:12:44.344552600Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"import pandas as pd\n",
"\n",
"cookies = {\n",
" 'feehi_session': '695c609649781',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMwMTI2MDEwNTE1MjgxMDAwMSwic2NvcGVzIjoiYXQiLCJpc3MiOiJzaHVpZGFvLnNlcnZlciIsImF1ZCI6InNodWlkYW8uY2xpZW50IiwianRpIjoiZTkzNTUzIiwiaWF0IjoxNzY3NjYxNzE4LjMwMDE2OSwibmJmIjoxNzY3NjYxNzE4LjMwMDE2OSwiZXhwIjoxNzY3NzQ4MTE4LjMwMDE2OX0.J_-dwMBaXiUEYLWcYC-sNfo4hc2CLCy-4w3qqxUJYyU',\n",
" 'origin': 'https://daotian.shuidao.com',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://daotian.shuidao.com/',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\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/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" # 'cookie': 'feehi_session=695c609649781',\n",
"}\n",
"\n",
"all_bill_data = []\n",
"for i in tqdm(range(0, 620)):\n",
" rtick = str(int(time.time() * 1000))\n",
" response = requests.get(\n",
" f'https://api.shuidao.com/daotian_web/maintain/intention-list?key=&status=0,1&pay_status=-1&type=-2&skip={15 * i}&limit=15&rtick=1767661717801',\n",
" cookies=cookies,\n",
" headers=headers,\n",
" )\n",
" res_data = response.json().get('res').get('list')\n",
" all_bill_data.extend(res_data)\n",
"\n",
"df1 = pd.DataFrame(all_bill_data)\n",
"df1.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\")"
],
"id": "c9bec35aa87c47cd",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:39: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:39: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\725055950.py:39: SyntaxWarning: invalid escape sequence '\\I'\n",
" df.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\")\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/620 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "4effc6449f0a40dfbf1c23b82bfdaa5c"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 10
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T01:46:15.258049900Z",
"start_time": "2026-01-06T01:46:04.200209200Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_bill_data)\n",
"df1.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\")"
],
"id": "cd6a4b2fd5b30cd1",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:2: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:2: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\374022918.py:2: SyntaxWarning: invalid escape sequence '\\I'\n",
" df1.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\")\n"
]
}
],
"execution_count": 11
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 明细数据",
"id": "f1cd6158da5b6b95"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T07:03:02.964073Z",
"start_time": "2026-01-06T05:40:38.583462300Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"\n",
"cookies = {\n",
" 'feehi_session': '695c609649781',\n",
"}\n",
"\n",
"headers = {\n",
" 'accept': '*/*',\n",
" 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjMwMTI2MDEwNTE1MjgxMDAwMSwic2NvcGVzIjoiYXQiLCJpc3MiOiJzaHVpZGFvLnNlcnZlciIsImF1ZCI6InNodWlkYW8uY2xpZW50IiwianRpIjoiZTkzNTUzIiwiaWF0IjoxNzY3NjYyNjMyLjUzMzA1MiwibmJmIjoxNzY3NjYyNjMyLjUzMzA1MiwiZXhwIjoxNzY3NzQ5MDMyLjUzMzA1Mn0.hOQXKo5BgSf-oPNCRhdHtiDUkHNBBagE5YULNRmKLtM',\n",
" 'origin': 'https://daotian.shuidao.com',\n",
" 'priority': 'u=1, i',\n",
" 'referer': 'https://daotian.shuidao.com/',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\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/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" # 'cookie': 'feehi_session=695c609649781',\n",
"}\n",
"\n",
"df1 = pd.read_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\", sheet_name=0)\n",
"\n",
"bill_detail_list =[]\n",
"# start_index = 2055\n",
"for index, row in tqdm(df1.iterrows(),total=len(df1)):\n",
" params = {\n",
" 'intention_id': row[\"_id\"],\n",
" 'rtick': '1767664096987',\n",
" }\n",
" try:\n",
" response = requests.get(\n",
" 'https://api.shuidao.com/daotian_web/maintain/intention-item-list',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" )\n",
" bill_detail_list.extend(response.json().get(\"res\").get(\"list\"))\n",
" time.sleep(0.1)\n",
" except Exception as e:\n",
" print(e)\n",
" pass\n",
"\n",
"df2 = pd.DataFrame(bill_detail_list)\n",
"\n",
"df2.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单明细信息1.xlsx\")\n",
"\n"
],
"id": "4fa2e08ed6bfb614",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:24: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:48: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:24: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:48: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\3065781067.py:24: SyntaxWarning: invalid escape sequence '\\I'\n",
" df1 = pd.read_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单信息.xlsx\", sheet_name=0)\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\3065781067.py:48: SyntaxWarning: invalid escape sequence '\\I'\n",
" df2.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单明细信息1.xlsx\")\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/9295 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "9cdf16f7030848218582f41071d2fec0"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 22
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T02:28:33.164475100Z",
"start_time": "2026-01-06T02:28:16.357244200Z"
}
},
"cell_type": "code",
"source": [
"df2 = pd.DataFrame(bill_detail_list)\n",
"\n",
"df2.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单明细信息.xlsx\")"
],
"id": "c7f67a5d2a9e0845",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:3: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:3: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_3692\\3122899901.py:3: SyntaxWarning: invalid escape sequence '\\I'\n",
" df2.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\稻田工单明细信息.xlsx\")\n"
]
}
],
"execution_count": 16
}
],
"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
}
@@ -0,0 +1,377 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "# 车辆信息导出",
"id": "a738ca16021a9e3b"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-12-22T09:33:52.535439Z",
"start_time": "2025-12-22T09:24:33.820278Z"
}
},
"source": [
"import time\n",
"\n",
"import pandas as pd\n",
"import requests\n",
"from tqdm import tqdm\n",
"\n",
"cookies = {\n",
" 'acw_tc': '0a472f4517663729846515826e48e5fe00deb9589551f37ca83749c9ce043f',\n",
" 'Hm_lvt_684c22b31d0037eca5a691cde16370ad': '1765863565,1766372987',\n",
" 'Hm_lpvt_684c22b31d0037eca5a691cde16370ad': '1766372987',\n",
" 'HMACCOUNT': '55F2182717FD6AE6',\n",
" 'e_token': 'd6c91f1dbb754081948988a722287335',\n",
" 'weixin_token': 'Y',\n",
" 'e_c': 'MzY3NTI1OTM0OTg4NzQxMA==',\n",
" 'e_i_o_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JTVCKzIwMDI3NDUrJTVEJTIy',\n",
" 'e_i_p_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JUU1JUJBJTk3JUU0JUI4JUJCJTVCKzIwMjk4NjkrJTVEJTIy',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/plain, */*',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/json;charset=UTF-8',\n",
" 'Irisclient': 'PC-web#tedspc',\n",
" 'Origin': 'https://teds.tyreplus.com.cn',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'https://teds.tyreplus.com.cn/tedspc/index.html',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"all_data = []\n",
"for i in tqdm(range(1, 1144)):\n",
" json_data = {\n",
" 'pageStart': i,\n",
" 'pageNums': 10,\n",
" 'pageNum': 1,\n",
" 'pageSize': 10,\n",
" }\n",
"\n",
" response = requests.post(\n",
" 'https://teds.tyreplus.com.cn/api/v1/custom/vehicle/queryVehicleInfosByStore',\n",
" cookies=cookies,\n",
" headers=headers,\n",
" json=json_data,\n",
" )\n",
" data_list = response.json()['obj']['list']\n",
" all_data += data_list\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\驰加车辆信息.xlsx\", index=False)\n",
"\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 1143/1143 [08:56<00:00, 2.13it/s]\n"
]
}
],
"execution_count": 4
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 历史维修记录列表(结算单)",
"id": "e166fa181fddc651"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-22T03:17:34.270096Z",
"start_time": "2025-12-22T03:12:30.351185Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"\n",
"cookies = {\n",
" 'acw_tc': '0a472f4517663729846515826e48e5fe00deb9589551f37ca83749c9ce043f',\n",
" 'Hm_lvt_684c22b31d0037eca5a691cde16370ad': '1765863565,1766372987',\n",
" 'Hm_lpvt_684c22b31d0037eca5a691cde16370ad': '1766372987',\n",
" 'HMACCOUNT': '55F2182717FD6AE6',\n",
" 'e_token': 'd6c91f1dbb754081948988a722287335',\n",
" 'weixin_token': 'Y',\n",
" 'e_c': 'MzY3NTI1OTM0OTg4NzQxMA==',\n",
" 'e_i_o_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JTVCKzIwMDI3NDUrJTVEJTIy',\n",
" 'e_i_p_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JUU1JUJBJTk3JUU0JUI4JUJCJTVCKzIwMjk4NjkrJTVEJTIy',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/plain, */*',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/json;charset=UTF-8',\n",
" 'Irisclient': 'PC-web#tedspc',\n",
" 'Origin': 'https://teds.tyreplus.com.cn',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'https://teds.tyreplus.com.cn/tedspc/index.html',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"history_all_data = []\n",
"for i in tqdm(range(1, 848)):\n",
" json_data = {\n",
" # 记得修改门店list\n",
" 'storeCodeList': [\n",
" '302558',\n",
" '366900',\n",
" ],\n",
" 'pageStart': i,\n",
" 'pageNums': 10,\n",
" 'pageNum': i,\n",
" 'pageSize': 10,\n",
" }\n",
"\n",
" response = requests.post(\n",
" 'https://teds.tyreplus.com.cn/api/aftersales/payment/queryPaymentSettlementListByCondition',\n",
" cookies=cookies,\n",
" headers=headers,\n",
" json=json_data,\n",
" )\n",
" history_data_list = response.json()['obj']['list']\n",
" history_all_data += history_data_list\n",
"\n",
"df = pd.DataFrame(history_all_data)\n",
"df.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\结算单.xlsx\", index=False)\n"
],
"id": "51f8f4b21505280a",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 847/847 [04:53<00:00, 2.89it/s]\n"
]
}
],
"execution_count": 2
},
{
"metadata": {},
"cell_type": "markdown",
"source": "历史维修记录明细(结算单明细)",
"id": "44cdf0d8f5f01c7d"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-22T09:16:59.210944Z",
"start_time": "2025-12-22T05:46:03.111327Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm.notebook import tqdm\n",
"import pandas as pd\n",
"import time\n",
"\n",
"cookies = {\n",
" 'acw_tc': '0a472f4517663729846515826e48e5fe00deb9589551f37ca83749c9ce043f',\n",
" 'Hm_lvt_684c22b31d0037eca5a691cde16370ad': '1765863565,1766372987',\n",
" 'Hm_lpvt_684c22b31d0037eca5a691cde16370ad': '1766372987',\n",
" 'HMACCOUNT': '55F2182717FD6AE6',\n",
" 'e_token': 'd6c91f1dbb754081948988a722287335',\n",
" 'weixin_token': 'Y',\n",
" 'e_c': 'MzY3NTI1OTM0OTg4NzQxMA==',\n",
" 'e_i_o_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JTVCKzIwMDI3NDUrJTVEJTIy',\n",
" 'e_i_p_c_n': 'JTIyJUU5JUE5JUIwJUU1JThBJUEwJUU2JUIxJUJEJUU4JUJEJUE2JUU2JTlDJThEJUU1JThBJUExJUU0JUI4JUFEJUU1JUJGJTgzJUU5JUJDJThFJUU2JUI5JTk2JUU1JThDJUJBJUU1JTlEJTkxJUU1JThGJUEzJUU1JUJBJTk3JUU1JUJBJTk3JUU0JUI4JUJCJTVCKzIwMjk4NjkrJTVEJTIy',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/plain, */*',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Cache-Control': 'no-cache',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/json;charset=UTF-8',\n",
" 'Irisclient': 'PC-web#tedspc',\n",
" 'Origin': 'https://teds.tyreplus.com.cn',\n",
" 'Pragma': 'no-cache',\n",
" 'Referer': 'https://teds.tyreplus.com.cn/tedspc/index.html',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
"}\n",
"\n",
"df = pd.read_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\结算单.xlsx\", sheet_name='Sheet1')\n",
"\n",
"all_data_list = []\n",
"all_service_data = []\n",
"all_order_data = []\n",
"all_payment_data = []\n",
"\n",
"for index, row in tqdm(df.iterrows(), total=len(df)):\n",
" id = row[\"paymentNo\"]\n",
" json_data = {\n",
" 'paymentNo': id,\n",
" }\n",
"\n",
" retry_count = 0\n",
" success = False\n",
"\n",
" while retry_count < 5 and not success:\n",
" try:\n",
" response = requests.post(\n",
" 'https://teds.tyreplus.com.cn/api/v2/aftersales/payment/queryPaymentSettlementDetail',\n",
" cookies=cookies,\n",
" headers=headers,\n",
" json=json_data,\n",
" timeout=10 # 建议加上超时防止卡死\n",
" )\n",
"\n",
" # 检查响应状态码和返回内容是否有效\n",
" if response.status_code == 200:\n",
" resp_json = response.json()\n",
" if resp_json.get('code') == 'success' and 'obj' in resp_json:\n",
" all_data = resp_json['obj']\n",
" service_list = all_data.get('orderServiceList', [])\n",
" order_list = all_data.get('orderSkuList', [])\n",
" paymentMethodList = all_data.get('paymentMethodList', [])\n",
"\n",
" # 添加 paymentNo 字段\n",
" all_data['paymentNo'] = id\n",
" all_data_list.append(all_data)\n",
"\n",
" for service in service_list:\n",
" service['paymentNo'] = id\n",
" all_service_data.append(service)\n",
"\n",
" for order in order_list:\n",
" order['paymentNo'] = id\n",
" all_order_data.append(order)\n",
"\n",
" for payment in paymentMethodList:\n",
" payment['paymentNo'] = id\n",
" all_payment_data.append(payment)\n",
"\n",
" success = True # 成功获取数据,跳出重试循环\n",
" else:\n",
" print(f\"请求返回非成功状态: {resp_json.get('message', '未知错误')} (paymentNo: {id})\")\n",
" else:\n",
" print(f\"HTTP 请求失败,状态码: {response.status_code} (paymentNo: {id})\")\n",
"\n",
" except Exception as e:\n",
" print(f\"请求异常: {e} (paymentNo: {id})\")\n",
"\n",
" if not success:\n",
" retry_count += 1\n",
" if retry_count < 5:\n",
" time.sleep(2) # 等待 2 秒后重试\n",
" else:\n",
" print(f\"已达到最大重试次数,跳过 paymentNo: {id}\")\n",
"\n",
" time.sleep(1) # 正常请求之间仍保留 1 秒间隔\n",
"\n",
"# 创建DataFrame\n",
"df = pd.DataFrame(all_data_list)\n",
"df1 = pd.DataFrame(all_service_data)\n",
"df2 = pd.DataFrame(all_order_data)\n",
"df3 = pd.DataFrame(all_payment_data)\n",
"\n",
"# 保存到Excel\n",
"df.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\历史维修记录明细.xlsx\", index=False)\n",
"df1.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\历史维修记录明细-服务明细.xlsx\", index=False)\n",
"df2.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\历史维修记录明细-产品明细.xlsx\", index=False)\n",
"df3.to_excel(r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\历史维修记录明细-支付方式.xlsx\", index=False)\n"
],
"id": "b7e0d7a4da6c9b03",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:37: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:37: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\zy187\\AppData\\Local\\Temp\\ipykernel_29896\\1397566597.py:37: SyntaxWarning: invalid escape sequence '\\I'\n",
" df = pd.read_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\结算单.xlsx\", sheet_name='Sheet1')\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/8463 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "6e51c0e7de2f4a7aab44e2c939cba811"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"HTTP 请求失败,状态码: 504 (paymentNo: SI2512141629588397)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2509131018744247)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2508260841398950)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2508171023222117)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2508091817076414)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2508081059041103)\n",
"请求异常: HTTPSConnectionPool(host='teds.tyreplus.com.cn', port=443): Read timed out. (read timeout=10) (paymentNo: SI2508011823922622)\n"
]
}
],
"execution_count": 3
}
],
"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
}
@@ -0,0 +1,262 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "## 客户信息导出(含解密手机号)",
"id": "9c3ce59cd7160150"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-06T01:50:04.573176600Z",
"start_time": "2026-01-06T01:41:33.836804400Z"
}
},
"source": [
"import requests\n",
"import pandas as pd\n",
"from tqdm import tqdm\n",
"\n",
"cookies = {\n",
" 'MD_accessToken': '6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/plain, */*',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Authorization': 'Bearer6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/json;charset=UTF-8',\n",
" 'Origin': 'https://store.fuchuang.com',\n",
" 'Referer': 'https://store.fuchuang.com/store/index.html',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" 'X-FC-TRACE-ID': '0924ec43dfae4ba48176700dee39833b',\n",
" 'loginPlatform': 'store_pc',\n",
" 'platform': 'store_pc',\n",
" 'searchInfo': '%E5%AE%A2%E6%88%B7%E8%BD%A6%E8%BE%86,%E5%AE%A2%E6%88%B7%E7%AE%A1%E7%90%86,%E6%9F%A5%E8%AF%A2',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
" 'user-info-wms': '{\"token\":\"Bearer6864ddf5-fa96-466f-b228-f2621516a2bf\",\"platform\":\"store_pc\"}',\n",
" 'x-fc-client': 'web',\n",
" # 'Cookie': 'MD_accessToken=6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
"}\n",
"\n",
"\n",
"json_data = {\n",
" 'phone': '',\n",
" 'name': '',\n",
" 'storeLabelIds': [],\n",
" 'fcLabelIds': [],\n",
" 'customerSource': None,\n",
" 'customerType': None,\n",
" 'sourceChannel': None,\n",
" 'pageSize': 10,\n",
" 'pageNum': 1,\n",
"}\n",
"\n",
"all_data = []\n",
"for i in tqdm(range(1, 758)):\n",
" json_data['pageNum'] = i\n",
" response = requests.post(\n",
" 'https://store.fuchuang.com/api/store-crm/crm/customer/query',\n",
" cookies=cookies,\n",
" headers=headers,\n",
" json=json_data,\n",
" )\n",
" data_list= response.json()['data']['list']\n",
" if len(data_list) == 0:\n",
" break\n",
" data_list= response.json()['data']['list']\n",
" for data in data_list:\n",
" all_data.append(data)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息.xlsx', index=False)\n"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:63: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:63: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_31392\\364108658.py:63: SyntaxWarning: invalid escape sequence '\\I'\n",
" df.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息.xlsx', index=False)\n",
"100%|██████████| 757/757 [08:25<00:00, 1.50it/s]\n"
]
}
],
"execution_count": 1
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 客户明细",
"id": "d9b13e7006671ff2"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T06:59:53.687706100Z",
"start_time": "2026-01-06T05:40:36.873045Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import time\n",
"from tqdm.notebook import tqdm\n",
"import pandas as pd\n",
"cookies = {\n",
" 'MD_accessToken': '6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/plain, */*',\n",
" 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',\n",
" 'Authorization': 'Bearer6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
" 'Connection': 'keep-alive',\n",
" 'Content-Type': 'application/json;charset=UTF-8',\n",
" 'Origin': 'https://store.fuchuang.com',\n",
" 'Referer': 'https://store.fuchuang.com/store/',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',\n",
" 'X-FC-TRACE-ID': 'a26acd1fe3c5460e890e80c8ad88a6da',\n",
" 'loginPlatform': 'store_pc',\n",
" 'platform': 'store_pc',\n",
" 'sec-ch-ua': '\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"',\n",
" 'sec-ch-ua-mobile': '?0',\n",
" 'sec-ch-ua-platform': '\"Windows\"',\n",
" 'user-info-wms': '{\"token\":\"Bearer6864ddf5-fa96-466f-b228-f2621516a2bf\",\"platform\":\"store_pc\"}',\n",
" 'x-fc-client': 'web',\n",
" # 'Cookie': 'MD_accessToken=6864ddf5-fa96-466f-b228-f2621516a2bf',\n",
"}\n",
"df1 = pd.read_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息.xlsx', sheet_name =0)\n",
"detail_list = []\n",
"start_index = 2658\n",
"for index, row in tqdm(df1.iterrows(), total=len(df1)):\n",
" params = {\n",
" 'id': row[\"id\"],\n",
" }\n",
"\n",
" json_data = {}\n",
" try:\n",
" response = requests.post(\n",
" 'https://store.fuchuang.com/api/store-crm/crm/customer/detail',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" json=json_data,\n",
" )\n",
" detail_list.append(response.json()['data'])\n",
" except Exception as e:\n",
" print(e)\n",
" pass\n",
" time.sleep(0.2)\n",
"\n",
"df2 = pd.DataFrame(detail_list)\n",
"df2.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息明细1.xlsx', index=False)\n"
],
"id": "d096136584e77781",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:31: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:55: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:31: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:55: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_31392\\1770658545.py:31: SyntaxWarning: invalid escape sequence '\\I'\n",
" df1 = pd.read_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息.xlsx', sheet_name =0)\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_31392\\1770658545.py:55: SyntaxWarning: invalid escape sequence '\\I'\n",
" df2.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息明细1.xlsx', index=False)\n"
]
},
{
"data": {
"text/plain": [
" 0%| | 0/7567 [00:00<?, ?it/s]"
],
"application/vnd.jupyter.widget-view+json": {
"version_major": 2,
"version_minor": 0,
"model_id": "755b9172bf87470583e777ee60281e95"
}
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"('Connection aborted.', ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None))\n"
]
}
],
"execution_count": 10
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-01-06T05:35:20.575883300Z",
"start_time": "2026-01-06T05:35:18.435503400Z"
}
},
"cell_type": "code",
"source": [
"df2 = pd.DataFrame(detail_list)\n",
"df2.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息明细2.xlsx', index=False)"
],
"id": "71fe765d89e1fc8d",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:2: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:2: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_31392\\2944444433.py:2: SyntaxWarning: invalid escape sequence '\\I'\n",
" df2.to_excel('D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\美孚客户信息明细2.xlsx', index=False)\n"
]
}
],
"execution_count": 7
}
],
"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
}
@@ -0,0 +1,103 @@
from playwright.sync_api import sync_playwright
import time
import pandas as pd
def extract_table_data(page):
"""从当前页面提取表格数据"""
rows = page.query_selector_all("table.dg tbody tr")
data = []
for row in rows:
# 跳过表头和合计行
if row.query_selector("th") or "合计" in row.text_content():
continue
cells = row.query_selector_all("td")
if len(cells) < 12:
continue # 非数据行
record_id = row.query_selector("input[title]").get_attribute("title") or ""
car_no = cells[2].text_content().strip()
name = cells[3].text_content().strip()
card_no = cells[4].text_content().strip()
card_type = cells[5].text_content().strip()
package = cells[6].text_content().strip()
total_times = cells[7].text_content().strip()
consumed = cells[8].text_content().strip()
remaining = cells[9].text_content().strip()
remaining_cost = cells[10].text_content().strip()
expire_date = cells[11].text_content().strip()
data.append({
"ID": record_id,
"车牌": car_no,
"姓名": name,
"卡号": card_no,
"卡类型": card_type,
"套餐项目": package,
"总次数": total_times,
"消费": consumed,
"剩余": remaining,
"剩余成本": remaining_cost,
"到期日期": expire_date
})
return data
def main():
# ====== 手动设置页码范围 ======
start_page = 1 # 起始页(包含)
end_page = 5 # 结束页(包含)
# ============================
with sync_playwright() as p:
browser = p.chromium.launch(headless=False, slow_mo=300)
context = browser.new_context()
# 设置你的 Cookie(请根据实际情况更新)
context.add_cookies([
{"name": "ASP.NET_SessionId", "value": "knhs0hxsbmolk20gidmlis3j", "domain": "crm.zhongtukj.com",
"path": "/"},
{"name": "ztrjnew@4db97b96-12af-45b0-b232-fd1e9b7a672e@",
"value": "PassWord=wZn2IuvdWeE=&RememberPwd=RXv90LpPskw=&UserId=nzK31b3ZYVQ=&CSID=VjfeyHPOjnU=&UserName=fDfTOArNJXHmbGEeaShOsw==&SID=nkNRF6dD83c=&RoleId=1X5bqQAfxQY=&GroupId=KUxCDdt69t4=",
"domain": "crm.zhongtukj.com", "path": "/"}
])
page = context.new_page()
print(f"正在加载第 {start_page} 页(初始页)...")
page.goto("http://crm.zhongtukj.com/Boss/Customer/CustomerPackageList.aspx")
page.wait_for_load_state("networkidle")
time.sleep(2)
all_data = []
for current_page in range(start_page, end_page + 1):
if current_page == 1:
# 第 1 页已加载,直接提取
pass
else:
# 跳转到指定页码
print(f"正在跳转到第 {current_page} 页...")
page.evaluate(f"() => __doPostBack('AspNetPager', '{current_page}')")
page.wait_for_load_state("networkidle")
time.sleep(2) # 稳定等待
# 提取当前页数据
data = extract_table_data(page)
all_data.extend(data)
print(f"{current_page} 页提取 {len(data)} 条记录")
browser.close()
# 保存结果
if all_data:
df = pd.DataFrame(all_data)
filename = f"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\套餐卡_第{start_page}{end_page}页.xlsx"
df.to_excel(filename, index=False)
print(f"\n✅ 共提取 {len(all_data)} 条记录,已保存到 '{filename}'")
else:
print("⚠️ 未提取到任何数据")
if __name__ == "__main__":
main()
@@ -0,0 +1,112 @@
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "# 有效会员卡导出",
"id": "ea10c552c30ccb5d"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2026-01-27T02:00:26.466693100Z",
"start_time": "2026-01-27T02:00:16.549976600Z"
}
},
"source": [
"import time\n",
"\n",
"import requests\n",
"import pandas as pd\n",
"cookies = {\n",
" 'td_cookie': '628168942',\n",
" 'td_cookie': '627897944',\n",
" 'ASP.NET_SessionId': 'q5qzer2z51b4uzsxrhterzop',\n",
" 'ztrjnew@4db97b96-12af-45b0-b232-fd1e9b7a672e@': 'PassWord=wZn2IuvdWeE=&RememberPwd=RXv90LpPskw=&UserId=nzK31b3ZYVQ=&CSID=VjfeyHPOjnU=&UserName=fDfTOArNJXHmbGEeaShOsw==&SID=nkNRF6dD83c=&RoleId=1X5bqQAfxQY=&GroupId=KUxCDdt69t4=',\n",
"}\n",
"\n",
"headers = {\n",
" 'Accept': 'application/json, text/javascript, */*; q=0.01',\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",
" 'Referer': 'http://crm.zhongtukj.com/Boss/Customer/CustomerCardListMem.aspx',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest',\n",
" # 'Cookie': 'td_cookie=628168942; td_cookie=627897944; ASP.NET_SessionId=q5qzer2z51b4uzsxrhterzop; ztrjnew@4db97b96-12af-45b0-b232-fd1e9b7a672e@=PassWord=wZn2IuvdWeE=&RememberPwd=RXv90LpPskw=&UserId=nzK31b3ZYVQ=&CSID=VjfeyHPOjnU=&UserName=fDfTOArNJXHmbGEeaShOsw==&SID=nkNRF6dD83c=&RoleId=1X5bqQAfxQY=&GroupId=KUxCDdt69t4=',\n",
"}\n",
"all_data= []\n",
"for i in range(1,4):\n",
" params = {\n",
" 'action': 'GetList',\n",
" 'groupId': '9',\n",
" 'keyword': '',\n",
" 'page': i,\n",
" 'rows': '20',\n",
" 'sort': 'ID',\n",
" 'order': 'desc',\n",
" }\n",
" time.sleep(1)\n",
"\n",
" response = requests.get(\n",
" 'http://crm.zhongtukj.com/Boss/Customer/CustomerCardListMem.aspx',\n",
" params=params,\n",
" cookies=cookies,\n",
" headers=headers,\n",
" verify=False,\n",
" )\n",
" rows = response.json().get(\"rows\")\n",
" all_data.extend(rows)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\谷途有效会员卡.xlsx\",index=False)"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"<>:42: SyntaxWarning: invalid escape sequence '\\I'\n",
"<>:42: SyntaxWarning: invalid escape sequence '\\I'\n",
"C:\\Users\\hp_z66\\AppData\\Local\\Temp\\ipykernel_27516\\3060641384.py:42: SyntaxWarning: invalid escape sequence '\\I'\n",
" df.to_excel(\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\谷途有效会员卡.xlsx\",index=False)\n"
]
}
],
"execution_count": 3
},
{
"metadata": {},
"cell_type": "markdown",
"source": [
"# 会员卡消费记录\n",
"\n",
"通过py文件获取"
],
"id": "d91331ded096a8a5"
}
],
"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
}
@@ -0,0 +1,37 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
""
]
}
],
"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
}
@@ -0,0 +1,129 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
""
]
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-21T03:07:30.465213Z",
"start_time": "2024-11-21T03:07:26.328734Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"import pandas as pd\n",
"\n",
"number = '5000'\n",
"\n",
"url = f\"http://www.chezhanggui.com:92/SupplierBackstage/Customer/GetMemberList?pageSize={number}&page=1&searchkey=&isCardVip=&IsMoney=&cardName=&employeeName=&CompanyName=&isExpire=\"\n",
"\n",
"headers = {\n",
" 'Cookie': 'ASP.NET_SessionId=q1f0j143i4ccqbfx1bpui2mp; LoginUserKey=D8B10FB06FD166E2B81949BB6DC5E35D65EFB7BD900C78247B2FCC443BB295017C07AD4FDD10B7528CC943B0FFF637916ADD46C705F76A935BF6BC39B966D1CB315BE55C2D4BEEDDC1B5CB070949F8DAF00E62BE916B55226C054C2443D06842A5E898BA1539F11B8B1AA65B3842D9FD33CB788A63C7C075E69F073BBC1CE4B8A91F57BA7D4DB975696A9F99FE389F2F623E9257DE9EA2E96E349D643A17A38CE67A365F96AD515DD547284758555B025664BFA21549999C9B7629FB823BD2E3AEABA0D9B945CACA47A174CE0953DD8975E1BA985F04E48C876EBD7FF8BF4E122CACD8880DB4220B9924159BBEDB56F10E19276C6920D2CB66C827D402101D15B5B6ED707C153C12A92AE6A0B6F7C4078EDC6655033B5AF2A1817777FABE4AF235DE687FF001CB4E9C99E132CF1E6886F840DDBADE5F2912CE6FF4FC47C44F132E31D310A28A15D49AB9EF0C1E822947B0362C0DA1E4CFF9F0506A3A36FB3065805163BA135EA6C49D7744213154EA2EBD9CE2E64F547473EE5CA550BC3033A9814788DBDCCE2F3BFFE90A17D82CC8A12684266CFD8F22D74E2F334114C7A557C13C989345EC803B36F20053897B22C7B080EB2A0176084629CF9E1700FB0C1B9C64852703C3AFB64FC265D071044C127DA663AA0EC9966E9F35D14D0960CE4C5A4CABAF7ABB8472404AA8D61B1DF9BDB251F12DEBE6D7E83B58F46314BCBB8F7BA2EE1B36848C1FA15257350AD7C97C461F6E41D21A2A2EAA2E38CF99B0985219EAB1FD2D682E732C1D723DC4B5F21AEE607D2BB6E6409CD9A7A57CC1C4C8BA5929782CC654AC9CE70D54A60E1AB3934A0A2C66CB033EF7E8532609A6364D90B0EC455B01F3C394D6B6367FB596900108093A50ADA3159559A0A713C9FEA230A1EE845C3C2D569A3803F8D5A2700A797CAEAB667C7809F066DD649CE26DEDC71C9DB841A5D83EF72B94ADE8AD5338E33E2D4D271B85CC27427A23EC8052A7DE782817940BD322819002D1D5BE1A07C0',\n",
" 'Host': 'www.chezhanggui.com:92',\n",
" 'Proxy-Connection': 'keep-alive',\n",
" 'Referer': 'http://www.chezhanggui.com:92/SupplierBackstage/Customer/MemberInfoPage',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest'\n",
"}\n",
"data = f'pageSize={number}&page=1&searchkey=&isCardVip=&IsMoney=&cardName=&employeeName=&CompanyName=&isExpire='\n",
"\n",
"response = requests.get(url=url, headers=headers, data=data)\n",
"# print(response.json())\n",
"all_data = response.json()\n",
"\n",
"data = all_data['Rows']\n",
"\n",
"df = pd.DataFrame(data)\n",
"\n",
"# 定义新列名\n",
"new_columns = {\n",
" 'CustomerName': '客户名称',\n",
" 'CustomerMobile': '手机号',\n",
" 'CustomerCarNumbers': '车牌',\n",
" 'CustomerCreateTime': '创建时间',\n",
" 'CardNum': '卡号',\n",
" 'CardMoney': '卡上余额',\n",
" 'CardName': '卡类型',\n",
" 'CardCreateTime': '办卡日期',\n",
" 'EmployeeName': '负责客服',\n",
" 'EndDT': '过期时间',\n",
" 'iswechat': '是否关注微信',\n",
" 'Telephone': '其他联系方式',\n",
" # 继续添加更多的列名映射...\n",
"}\n",
"# 使用rename方法替换列名\n",
"df.rename(columns=new_columns, inplace=True)\n",
"\n",
"# 保存到Excel文件\n",
"file_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\车好了导出数据.xlsx'\n",
"df.to_excel(file_path, index=False)\n",
"\n",
"print(f\"数据已成功保存至{file_path}\")\n"
],
"id": "ad55012a4aac09d6",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"数据已成功保存至D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\车好了导出数据.xlsx\n"
]
}
],
"execution_count": 13
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2024-11-21T02:46:21.760427Z",
"start_time": "2024-11-21T02:46:21.718012Z"
}
},
"cell_type": "code",
"source": "",
"id": "f21b669a780e6800",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"数据已成功保存至D:\\customer_data.xlsx\n"
]
}
],
"execution_count": 3
}
],
"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
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,64 @@
import requests
import re
import json
url = "https://auto.51autoshop.com/Customer/CustCardList"
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': 'Hm_lvt_b13246fd95aec7bfc57d9c415dfefe18=1733898115; __RequestVerificationToken=W1tpkb8doRLe28rYbhoVDiAF5kxH7vis6yUPWbL8CHIkABRM1QBjNpE3WV72mklwY9snog2sP0b_wz9NAevw5AV38-U1; HMACCOUNT=ABFCA62083E00432; LoginInfo=2412349ad7894c01b66cd10b894ff2d4; GetShopValidity=1; SERVERID=df24b70122439a42ff2eaa4b483d47a0|1733971685|1733934764; Hm_lpvt_b13246fd95aec7bfc57d9c415dfefe18=1733971687',
'Origin': 'https://auto.51autoshop.com',
'Priority': 'u=0, i',
'Referer': 'https://auto.51autoshop.com/Customer/CustCardList',
'Sec-Ch-Ua': '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'Sec-Fetch-Dest': 'iframe',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0'
}
data = {
'__RequestVerificationToken': '1OTyeT2u_1P6DQTBCMLDs1jTbEE4FmnXbz1d2N9-wox36wkGAkIKCcyXZkl9KW2BcGsW0lZjb6QDGcwQoryIiBme-Z81',
'Keywords': '',
'StartTime': '',
'EndTime': '',
'WCompanyID': '',
'ExpiredOnly': 'false',
'DetialUrl': '/Customer/CustCardDetial',
'PageIndex': '1',
'PageSize': '10000',
'SortField': '',
'SortDir': '',
'IsExpired': '',
'CompanyName': ''
}
res = requests.post(url, data=data, headers=headers)
html_text = res.text
import re
import pandas as pd
text = '''
"CustCardID": 710943,
"OtherField": "SomeValue",
"CustCardID": 123456,
"CustCardID": 987654,
'''
pattern = r'"CardCode":\s*"([^"]+)"'
pattern1 = r'"CustCardID":(\d+)'
matches1 = re.findall(pattern1, html_text)
matches = re.findall(pattern, html_text)
print(matches) # 输出: ['710943', '123456', '987654']
# 将匹配结果转换为 DataFrame
df = pd.DataFrame(matches, columns=['CardCode'])
df.to_excel('CardCode.xlsx', index=False)
df1 = pd.DataFrame(matches1, columns=['CustCardID'])
# 将 DataFrame 保存为 Excel 文件
df1.to_excel('CardCode1.xlsx', index=False)
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long