4.18备份
This commit is contained in:
+106
-13
@@ -3,6 +3,10 @@ import requests
|
||||
from module import F6_module
|
||||
import time
|
||||
from tqdm import tqdm
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
import json
|
||||
import traceback
|
||||
|
||||
#+
|
||||
# f6_module = F6_module()
|
||||
@@ -17,22 +21,27 @@ module = 2
|
||||
# # cookies = requests.utils.dict_from_cookiejar(res.cookies)
|
||||
|
||||
cookies = {
|
||||
'memberSESSIONID': 'a6c5084a-7393-426e-9cdc-c3fb8c0d6960',
|
||||
'memberSESSIONID': '38d027b4-1f86-44fe-a8d2-2211fbd46394',
|
||||
'erpLanguage': 'zh-CN',
|
||||
'tmall': 'false',
|
||||
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1760494904,1760510876,1760584685,1760671187',
|
||||
'HMACCOUNT': '55F2182717FD6AE6',
|
||||
'prodOrg': '16001002822673915925',
|
||||
'unp': '16001002823772827677',
|
||||
'un': '16001002823772827677',
|
||||
'_up': '-NillNN-qyBEJ--t3vnSknvoOF1_zfCNsM8N0Xg4XeVVVPbHoJ7QjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqEvMdqoIq3wEI9_JRv-ZNHu3M-GTf3piwFXeqpu9WjuwYmFTEOBRorEj9mmew_aOwUBk.',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2216001002823772827677%22%2C%22first_id%22%3A%22198a89fdaa54f-0a897244f8104b8-4c657b58-2073600-198a89fdaa61b71%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22198a89fdaa54f-0a897244f8104b8-4c657b58-2073600-198a89fdaa61b71%22%7D',
|
||||
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1760939885',
|
||||
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1775553704,1775799422,1776043595,1776153876',
|
||||
'HMACCOUNT': 'A6A0585E8C70051D',
|
||||
'prodOrg': '11240984669918128522',
|
||||
'unp': '15851362811188895763',
|
||||
'un': '15851362811188895763',
|
||||
'_up': '-NillNN-qyBEJ--t3vnSknvoOF53yPCOts8N0no-Uu9VX_TGoZrQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqE_UXoIgm0QIF_PBRv-ZNHu3M-GTc1p2wFnGqpuxUiOMSmF_GORVsrEj92RzBn7rDYmA.',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2215851362811188895763%22%2C%22first_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%7D',
|
||||
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1776393475',
|
||||
}
|
||||
|
||||
print(cookies) # 登录获取cookies
|
||||
print("cookies loaded")
|
||||
|
||||
df = pd.read_excel(fr"C:\Users\zy187\Desktop\钉钉文件\车辆信息-修复-太乙1020.xls",sheet_name="Sheet4").astype(str)
|
||||
request_results = []
|
||||
script_dir = Path(__file__).resolve().parent
|
||||
output_base = script_dir / f"请求结果_{datetime.now():%Y%m%d_%H%M%S}"
|
||||
|
||||
|
||||
df = pd.read_excel(fr"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\车辆信息.xlsx",sheet_name="Sheet2").astype(str)
|
||||
|
||||
|
||||
if module == 1: # 客户信息删除
|
||||
@@ -40,6 +49,17 @@ if module == 1: # 客户信息删除
|
||||
df['手机号码'].dropna(inplace=True)
|
||||
url = "https://yunxiu.f6car.cn/member/customer/listForPermission?pageSize=50000&pageNo=1" # 获取客户信息列表
|
||||
res = requests.get(url, cookies=cookies)
|
||||
row = {"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "module": module, "action": "customer_list", "url": url}
|
||||
row["status_code"] = getattr(res, "status_code", None)
|
||||
row["ok"] = getattr(res, "ok", None)
|
||||
try:
|
||||
row["response_json"] = json.dumps(res.json(), ensure_ascii=False)
|
||||
except Exception:
|
||||
try:
|
||||
row["response_text"] = res.text
|
||||
except Exception:
|
||||
row["response_text"] = None
|
||||
request_results.append(row)
|
||||
data = res.json()
|
||||
for item in tqdm(data['data']['data']):
|
||||
try:
|
||||
@@ -50,6 +70,24 @@ if module == 1: # 客户信息删除
|
||||
print("删除:", phone)
|
||||
url = f"https://yunxiu.f6car.cn/member/customer/{idCustomer}" # 客户信息删除url
|
||||
res = requests.delete(url, cookies=cookies) # 客户信息删除
|
||||
row = {
|
||||
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"module": module,
|
||||
"action": "customer_delete",
|
||||
"url": url,
|
||||
"idCustomer": idCustomer,
|
||||
"cellPhone": phone_clean,
|
||||
}
|
||||
row["status_code"] = getattr(res, "status_code", None)
|
||||
row["ok"] = getattr(res, "ok", None)
|
||||
try:
|
||||
row["response_json"] = json.dumps(res.json(), ensure_ascii=False)
|
||||
except Exception:
|
||||
try:
|
||||
row["response_text"] = res.text
|
||||
except Exception:
|
||||
row["response_text"] = None
|
||||
request_results.append(row)
|
||||
print(res.json(), idCustomer, phone)
|
||||
time.sleep(3)
|
||||
else:
|
||||
@@ -69,14 +107,69 @@ if module == 2: # 客户车辆信息删除
|
||||
url = f"https://yunxiu.f6car.cn/member/car/deleteCar/{car_Id}/{customerId}"
|
||||
# url = f"https://yunxiu.f6car.cn/macan/coupon/car/batchRemove?customerId={customerId}&carId={carId}&operateOrgId={operateOrgId}" # 删除客户车辆信息url
|
||||
res = requests.delete(url, cookies=cookies) # 客户车辆信息删除
|
||||
row = {
|
||||
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"module": module,
|
||||
"action": "car_delete",
|
||||
"url": url,
|
||||
"car_number": car_number,
|
||||
"carId": car_Id,
|
||||
"customerId": customerId,
|
||||
}
|
||||
row["status_code"] = getattr(res, "status_code", None)
|
||||
row["ok"] = getattr(res, "ok", None)
|
||||
try:
|
||||
row["response_json"] = json.dumps(res.json(), ensure_ascii=False)
|
||||
except Exception:
|
||||
try:
|
||||
row["response_text"] = res.text
|
||||
except Exception:
|
||||
row["response_text"] = None
|
||||
request_results.append(row)
|
||||
print("delete——", res.json(), customerId, car_Id)
|
||||
|
||||
from datetime import datetime
|
||||
now = datetime.now()
|
||||
if now.hour >= 20:
|
||||
time.sleep(1)
|
||||
else:
|
||||
time.sleep(3)
|
||||
except:
|
||||
print("删除失败:", res.json(), customerId, car_Id)
|
||||
res_tmp = locals().get("res")
|
||||
row = {
|
||||
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"module": module,
|
||||
"action": "car_delete",
|
||||
"url": locals().get("url"),
|
||||
"car_number": car_number,
|
||||
"carId": car_Id,
|
||||
"customerId": customerId,
|
||||
"error": "删除失败",
|
||||
"traceback": traceback.format_exc(),
|
||||
}
|
||||
if res_tmp is not None:
|
||||
row["status_code"] = getattr(res_tmp, "status_code", None)
|
||||
row["ok"] = getattr(res_tmp, "ok", None)
|
||||
try:
|
||||
row["response_json"] = json.dumps(res_tmp.json(), ensure_ascii=False)
|
||||
except Exception:
|
||||
try:
|
||||
row["response_text"] = res_tmp.text
|
||||
except Exception:
|
||||
row["response_text"] = None
|
||||
request_results.append(row)
|
||||
try:
|
||||
print("删除失败:", res_tmp.json(), customerId, car_Id)
|
||||
except Exception:
|
||||
print("删除失败:", getattr(res_tmp, "text", None), customerId, car_Id)
|
||||
continue
|
||||
|
||||
if request_results:
|
||||
df_out = pd.DataFrame(request_results)
|
||||
df_out.to_csv(f"{output_base}.csv", index=False, encoding="utf-8-sig")
|
||||
with open(f"{output_base}.jsonl", "w", encoding="utf-8") as f:
|
||||
for row in request_results:
|
||||
f.write(json.dumps(row, ensure_ascii=False) + "\n")
|
||||
try:
|
||||
df_out.to_excel(f"{output_base}.xlsx", index=False)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"ts": "2026-04-17 14:19:44", "module": 2, "action": "car_delete", "url": "https://yunxiu.f6car.cn/member/car/deleteCar/11960986442127142934/11960986160949391626", "car_number": "蒙K1Y302", "carId": "11960986442127142934", "customerId": "11960986160949391626", "status_code": 200, "ok": true, "response_json": "{\"success\": true, \"code\": 200, \"message\": null, \"data\": true}"}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,101 @@
|
||||
import requests
|
||||
import pandas as pd
|
||||
import time
|
||||
from tqdm import tqdm
|
||||
|
||||
cookies = {
|
||||
'memberSESSIONID': '485a36b9-eb05-4f25-806c-ddea074cb6a2',
|
||||
'erpLanguage': 'zh-CN',
|
||||
'tmall': 'false',
|
||||
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1775553704,1775799422,1776043595,1776153876',
|
||||
'HMACCOUNT': 'A6A0585E8C70051D',
|
||||
'prodOrg': '11240984669918128522',
|
||||
'unp': '15851362811188895763',
|
||||
'un': '15851362811188895763',
|
||||
'_up': '-NillNN-qyBEJ--t3vnSknvoOF53yPCOts8N0no-Uu9VX_TGoZrQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqE_UQqY4i0wEO9vFRv-ZNHu3M-GTc1p2wFnGqpuxUiOMSmF_GORVsrEj9nR66kMm3MhA.',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2215851362811188895763%22%2C%22first_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%7D',
|
||||
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1776405066',
|
||||
}
|
||||
|
||||
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',
|
||||
'content-type': 'application/json;charset=UTF-8',
|
||||
'origin': 'https://yunxiu.f6car.cn',
|
||||
'priority': 'u=1, i',
|
||||
'referer': 'https://yunxiu.f6car.cn/erp/view/index.html',
|
||||
'sec-ch-ua': '"Microsoft Edge";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'sec-ch-ua-platform': '"Windows"',
|
||||
'sec-fetch-dest': 'empty',
|
||||
'sec-fetch-mode': 'cors',
|
||||
'sec-fetch-site': 'same-origin',
|
||||
'traceparent': '00-83110f5326614e2db80da5c48ab36d5d-ce4bdbb226a3286a-01',
|
||||
'tracestate': 'rum=v2&browser&dz2uw0c5ay@e5930ea8eb782ae&9134c88bc6224ae4a4167c07dc0ad82e&uid_nli6u6uor4pqvx0f',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0',
|
||||
'x-requested-with': 'XMLHttpRequest',
|
||||
# 'cookie': 'memberSESSIONID=485a36b9-eb05-4f25-806c-ddea074cb6a2; erpLanguage=zh-CN; tmall=false; Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a=1775553704,1775799422,1776043595,1776153876; HMACCOUNT=A6A0585E8C70051D; prodOrg=11240984669918128522; unp=15851362811188895763; un=15851362811188895763; _up=-NillNN-qyBEJ--t3vnSknvoOF53yPCOts8N0no-Uu9VX_TGoZrQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqE_UQqY4i0wEO9vFRv-ZNHu3M-GTc1p2wFnGqpuxUiOMSmF_GORVsrEj9nR66kMm3MhA.; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2215851362811188895763%22%2C%22first_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%7D; Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a=1776405066',
|
||||
}
|
||||
|
||||
url = 'https://yunxiu.f6car.cn/member/car/carListForPermission'
|
||||
|
||||
source_excel_path = r"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\车辆信息.xlsx"
|
||||
source_sheet_name = "Sheet3"
|
||||
output_path = r"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\车辆信息_按车牌导出.xlsx"
|
||||
|
||||
df = pd.read_excel(source_excel_path, sheet_name=source_sheet_name)
|
||||
all_data = []
|
||||
|
||||
for _, row in tqdm(df.iterrows(), total=len(df)):
|
||||
car_number = str(row.get('车牌号', '')).strip()
|
||||
if not car_number or car_number.lower() == 'nan':
|
||||
continue
|
||||
|
||||
page_no = 1
|
||||
matched = False
|
||||
while True:
|
||||
json_data = {
|
||||
'keyWord': car_number,
|
||||
'pageSize': 100,
|
||||
'pageNo': page_no,
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
url,
|
||||
cookies=cookies,
|
||||
headers=headers,
|
||||
json=json_data,
|
||||
timeout=30,
|
||||
)
|
||||
data = response.json()
|
||||
data_block = (data.get('data') or {})
|
||||
items = (data_block.get('data') or [])
|
||||
|
||||
for item in items:
|
||||
tm_car = item.get('tmCarInfo') or {}
|
||||
tm_customer = item.get('tmCustomerInfo') or {}
|
||||
current_car_number = f"{tm_car.get('carPrefix', '')}{tm_car.get('carNo', '')}"
|
||||
if current_car_number == car_number:
|
||||
car_id = tm_car.get('pkId')
|
||||
customer_id = tm_customer.get('pkId')
|
||||
all_data.append([car_id, customer_id, current_car_number])
|
||||
matched = True
|
||||
break
|
||||
|
||||
if matched:
|
||||
break
|
||||
|
||||
total = data_block.get('total') or 0
|
||||
if page_no * 100 >= int(total):
|
||||
break
|
||||
page_no += 1
|
||||
time.sleep(0.3)
|
||||
|
||||
if not matched:
|
||||
all_data.append([None, None, car_number])
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
result_df = pd.DataFrame(all_data, columns=['carId', 'customerId', 'car_number'])
|
||||
result_df.to_excel(output_path, index=False)
|
||||
print("已保存:", str(output_path))
|
||||
+18
-14
@@ -3,32 +3,34 @@ import requests
|
||||
# from module import F6_module
|
||||
import time
|
||||
from tqdm import tqdm
|
||||
from pathlib import Path
|
||||
|
||||
# f6_module = F6_module()
|
||||
#
|
||||
|
||||
# # 1.向服务器发送请求登录
|
||||
# username = "13799889725"
|
||||
# password = "Lc1234"
|
||||
# store_name = "禹城榕桦"
|
||||
# module = 2
|
||||
#
|
||||
|
||||
# res = f6_module.login_in(username, password, store_name)
|
||||
# cookies = requests.utils.dict_from_cookiejar(res.cookies)
|
||||
|
||||
cookies = {
|
||||
'memberSESSIONID': 'a6c5084a-7393-426e-9cdc-c3fb8c0d6960',
|
||||
'memberSESSIONID': '38d027b4-1f86-44fe-a8d2-2211fbd46394',
|
||||
'erpLanguage': 'zh-CN',
|
||||
'tmall': 'false',
|
||||
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1760494904,1760510876,1760584685,1760671187',
|
||||
'HMACCOUNT': '55F2182717FD6AE6',
|
||||
'prodOrg': '16001002822673915925',
|
||||
'unp': '16001002823772827677',
|
||||
'un': '16001002823772827677',
|
||||
'_up': '-NillNN-qyBEJ--t3vnSknvoOF1_zfCNsM8N0Xg4XeVVVPbHoJ7QjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqEvMdqoIq3wEI9_JRv-ZNHu3M-GTf3piwFXeqpu9WjuwYmFTEOBRorEj9mmew_aOwUBk.',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2216001002823772827677%22%2C%22first_id%22%3A%22198a89fdaa54f-0a897244f8104b8-4c657b58-2073600-198a89fdaa61b71%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22198a89fdaa54f-0a897244f8104b8-4c657b58-2073600-198a89fdaa61b71%22%7D',
|
||||
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1760939885',
|
||||
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1775553704,1775799422,1776043595,1776153876',
|
||||
'HMACCOUNT': 'A6A0585E8C70051D',
|
||||
'prodOrg': '11240984669918128522',
|
||||
'unp': '15851362811188895763',
|
||||
'un': '15851362811188895763',
|
||||
'_up': '-NillNN-qyBEJ--t3vnSknvoOF53yPCOts8N0no-Uu9VX_TGoZrQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqE_UXoIgm0QIF_PBRv-ZNHu3M-GTc1p2wFnGqpuxUiOMSmF_GORVsrEj92RzBn7rDYmA.',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2215851362811188895763%22%2C%22first_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df76a22f46-04a98afdd2a11d8-4c657b58-1327104-19b6df76a2312c7%22%7D',
|
||||
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1776393475',
|
||||
}
|
||||
|
||||
|
||||
print(cookies) # 登录获取cookies
|
||||
all_data = []
|
||||
operateOrgId = cookies['prodOrg']
|
||||
@@ -41,10 +43,10 @@ data = {"pageSize": 100, "pageNo": 1} # 根据需求修改
|
||||
res = requests.post(url=url, cookies=cookies, json=data, headers=header) # 注意需要用json发送数据
|
||||
total = res.json().get('data').get('total')
|
||||
total = int(total)
|
||||
all_page = int(total / 1000) + 1
|
||||
all_page = int(total / 100) + 1
|
||||
|
||||
for i in tqdm(range(1, all_page)):
|
||||
data = {"pageSize": 1000, "pageNo": i} # 根据需求修改
|
||||
data = {"pageSize": 100, "pageNo": i} # 根据需求修改
|
||||
res = requests.post(url=url, cookies=cookies, json=data, headers=header) # 注意需要用json发送数据
|
||||
data1 = res.json()
|
||||
for item in data1['data']['data']:
|
||||
@@ -54,4 +56,6 @@ for i in tqdm(range(1, all_page)):
|
||||
all_data.append([carId, customerId, car_number])
|
||||
time.sleep(2)
|
||||
df = pd.DataFrame(all_data, columns=['carId', 'customerId', 'car_number'])
|
||||
df.to_excel(fr"C:\Users\zy187\Desktop\车辆信息.xlsx")
|
||||
output_path = "D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\车辆信息.xlsx"
|
||||
df.to_excel(output_path, index=False)
|
||||
print("已保存:", str(output_path))
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import requests
|
||||
|
||||
cookies = {
|
||||
'hive-adminSESSIONID': '34068dac-9e90-4632-a7e5-48281f181d59',
|
||||
'_oauth2_proxy': 'hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=',
|
||||
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D',
|
||||
'_yg_pre': 'leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',
|
||||
}
|
||||
|
||||
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://manage-pre.f6yc.com/',
|
||||
'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Microsoft Edge";v="146"',
|
||||
'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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
'x-requested-with': 'XMLHttpRequest',
|
||||
# 'cookie': 'hive-adminSESSIONID=34068dac-9e90-4632-a7e5-48281f181d59; _oauth2_proxy=hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D; _yg_pre=leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',
|
||||
}
|
||||
|
||||
params = {
|
||||
'orderTypeList': '',
|
||||
'buyerGroupId': '',
|
||||
'reservationNumber': '',
|
||||
'payChannel': '',
|
||||
'priceMin': '',
|
||||
'priceMax': '',
|
||||
'userContactTel': '',
|
||||
'idEmployee': '',
|
||||
'dealUserId': '',
|
||||
'orderSource': '',
|
||||
'idManager': '',
|
||||
'orderStatusStr': '',
|
||||
'orderReserveTimeStart': '',
|
||||
'orderReserveTimeEnd': '',
|
||||
'orderPayFinishTimeStart': '1775100171457',
|
||||
'orderPayFinishTimeEnd': '1775704971457',
|
||||
'dealTimeStart': '',
|
||||
'dealTimeEnd': '',
|
||||
'invoiceStatusList': '',
|
||||
'openTimeStartTime': '',
|
||||
'openTimeEndTime': '',
|
||||
}
|
||||
|
||||
response = requests.get('https://manage-pre.f6yc.com/hive-admin/order/export', params=params, cookies=cookies, headers=headers)
|
||||
print(response.json())
|
||||
@@ -0,0 +1,302 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "# 订单导出请求",
|
||||
"id": "360eeaa3edfeeea5"
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"execution_count": null,
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"cookies = {\n",
|
||||
" 'hive-adminSESSIONID': '34068dac-9e90-4632-a7e5-48281f181d59',\n",
|
||||
" '_oauth2_proxy': 'hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=',\n",
|
||||
" 'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D',\n",
|
||||
" '_yg_pre': 'leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\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",
|
||||
" 'priority': 'u=1, i',\n",
|
||||
" 'referer': 'https://manage-pre.f6yc.com/',\n",
|
||||
" 'sec-ch-ua': '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Microsoft Edge\";v=\"146\"',\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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',\n",
|
||||
" 'x-requested-with': 'XMLHttpRequest',\n",
|
||||
" # 'cookie': 'hive-adminSESSIONID=34068dac-9e90-4632-a7e5-48281f181d59; _oauth2_proxy=hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D; _yg_pre=leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"params = {\n",
|
||||
" 'orderTypeList': '',\n",
|
||||
" 'buyerGroupId': '',\n",
|
||||
" 'reservationNumber': '',\n",
|
||||
" 'payChannel': '',\n",
|
||||
" 'priceMin': '',\n",
|
||||
" 'priceMax': '',\n",
|
||||
" 'userContactTel': '',\n",
|
||||
" 'idEmployee': '',\n",
|
||||
" 'dealUserId': '',\n",
|
||||
" 'orderSource': '',\n",
|
||||
" 'idManager': '',\n",
|
||||
" 'orderStatusStr': '',\n",
|
||||
" 'orderReserveTimeStart': '',\n",
|
||||
" 'orderReserveTimeEnd': '',\n",
|
||||
" 'orderPayFinishTimeStart': '1775100171457', # 开始时间\n",
|
||||
" 'orderPayFinishTimeEnd': '1775704971457', # 结束时间\n",
|
||||
" 'dealTimeStart': '',\n",
|
||||
" 'dealTimeEnd': '',\n",
|
||||
" 'invoiceStatusList': '',\n",
|
||||
" 'openTimeStartTime': '',\n",
|
||||
" 'openTimeEndTime': '',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"response = requests.get('https://manage-pre.f6yc.com/hive-admin/order/export', params=params, cookies=cookies, headers=headers)\n",
|
||||
"print(response.json())"
|
||||
],
|
||||
"id": "910dc9bf840168d2"
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "# 优惠券发放记录请求导出",
|
||||
"id": "4612b9c083aecec1"
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"execution_count": null,
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"cookies = {\n",
|
||||
" 'hive-adminSESSIONID': '7d9d2c6c-6ef4-4dba-8371-68d23a486dd2',\n",
|
||||
" '_oauth2_proxy': 'hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=',\n",
|
||||
" 'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D',\n",
|
||||
" '_yg_pre': 'leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\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",
|
||||
" 'content-type': 'application/json;charset=UTF-8',\n",
|
||||
" 'origin': 'https://manage-pre.f6yc.com',\n",
|
||||
" 'priority': 'u=1, i',\n",
|
||||
" 'referer': 'https://manage-pre.f6yc.com/',\n",
|
||||
" 'sec-ch-ua': '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Microsoft Edge\";v=\"146\"',\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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',\n",
|
||||
" 'x-requested-with': 'XMLHttpRequest',\n",
|
||||
" # 'cookie': 'hive-adminSESSIONID=7d9d2c6c-6ef4-4dba-8371-68d23a486dd2; _oauth2_proxy=hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D; _yg_pre=leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"json_data = {\n",
|
||||
" 'statusList': [],\n",
|
||||
" 'couponName': '',\n",
|
||||
" 'createBy': '',\n",
|
||||
" 'takeSourceCode': '',\n",
|
||||
" 'keyword': '',\n",
|
||||
" 'takeTimeBegin': '2026-03-10', # 开始时间\n",
|
||||
" 'takeTimeEnd': '2026-04-09', #结束时间\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"response = requests.post('https://manage-pre.f6yc.com/hive-admin/coupon/export', cookies=cookies, headers=headers, json=json_data)\n",
|
||||
"\n"
|
||||
],
|
||||
"id": "917b264f2d45a022"
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "# 获取导出列表",
|
||||
"id": "109cfbab50a5f15"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"id": "4c4a36f3",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-04-09T05:58:42.655993700Z",
|
||||
"start_time": "2026-04-09T05:58:42.133250300Z"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"cookies = {\n",
|
||||
" 'hive-adminSESSIONID': 'cf22b8bf-1b92-43cf-946e-584d9b159cca',\n",
|
||||
" '_oauth2_proxy': 'hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=',\n",
|
||||
" 'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D',\n",
|
||||
" '_yg_pre': 'leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\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",
|
||||
" 'priority': 'u=1, i',\n",
|
||||
" 'referer': 'https://manage-pre.f6yc.com/',\n",
|
||||
" 'sec-ch-ua': '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Microsoft Edge\";v=\"146\"',\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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',\n",
|
||||
" 'x-requested-with': 'XMLHttpRequest',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"response = requests.get('https://manage-pre.f6yc.com/hive-admin/download/queryList', cookies=cookies, headers=headers)\n",
|
||||
"download_list = response.json().get(\"data\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'code': 200,\n",
|
||||
" 'data': [{'creationtime': 1775705041000,\n",
|
||||
" 'id': '111',\n",
|
||||
" 'statDesc': '导出完成',\n",
|
||||
" 'state': 20,\n",
|
||||
" 'type': 10,\n",
|
||||
" 'typeDesc': '订单导出'},\n",
|
||||
" {'creationtime': 1775704980000,\n",
|
||||
" 'id': '110',\n",
|
||||
" 'statDesc': '导出完成',\n",
|
||||
" 'state': 20,\n",
|
||||
" 'type': 10,\n",
|
||||
" 'typeDesc': '订单导出'},\n",
|
||||
" {'creationtime': 1775703259000,\n",
|
||||
" 'id': '109',\n",
|
||||
" 'statDesc': '导出完成',\n",
|
||||
" 'state': 20,\n",
|
||||
" 'type': 20,\n",
|
||||
" 'typeDesc': '优惠券发放记录导出'},\n",
|
||||
" {'creationtime': 1775703199000,\n",
|
||||
" 'id': '108',\n",
|
||||
" 'statDesc': '导出完成',\n",
|
||||
" 'state': 20,\n",
|
||||
" 'type': 10,\n",
|
||||
" 'typeDesc': '订单导出'}],\n",
|
||||
" 'message': 'SUCCESS'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"execution_count": 1
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "# 获取下载链接",
|
||||
"id": "57bfbf72959cb37c"
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-04-09T06:00:49.811171700Z",
|
||||
"start_time": "2026-04-09T06:00:49.449069900Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"cookies = {\n",
|
||||
" 'hive-adminSESSIONID': '7d9d2c6c-6ef4-4dba-8371-68d23a486dd2',\n",
|
||||
" '_oauth2_proxy': 'hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=',\n",
|
||||
" 'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D',\n",
|
||||
" '_yg_pre': 'leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\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",
|
||||
" 'priority': 'u=1, i',\n",
|
||||
" 'referer': 'https://manage-pre.f6yc.com/',\n",
|
||||
" 'sec-ch-ua': '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Microsoft Edge\";v=\"146\"',\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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',\n",
|
||||
" 'x-requested-with': 'XMLHttpRequest',\n",
|
||||
" # 'cookie': 'hive-adminSESSIONID=7d9d2c6c-6ef4-4dba-8371-68d23a486dd2; _oauth2_proxy=hBgKHp7tNo1IhJZBL2UqonqXc1V6HO7cdu0ldRAQeTz7I7_FJtZhnxQI5sLfWeRvWYI-6jA2oHgv284pIyK3MR2w6QPfhJgwJWuIvp5Cmt89M72kRzdpyYNaUjQVuMaR4x4cnOiyRe1gPR7e3eDtd8R7IkNmFSXjiK2ADU29o0Ay5QmN6GBmciJ0EwiWUtpwToOXldGn4vpgbxEdmxWLFEmucCK_2E3THUq2zjnje0P2OznxeQzVDUJ4xdfVFso1tiMicxevHLTOadyp2hdKFSjJ40dLlCX47JaWzWnth72pQBiUKejXkIeiO7iJ_xC21JwDdUT5sVZg2KHnG2p-BqUF9klUBhMaqozcodelKAg-62XuhrOYsk6BHV5ObIJ0jhqmq84n8mzuKNPeNERjZjNZ68-xwzT4uYi0Ffor3b7C64zmQ1LkTbOCQkF7B0Uh1tNv4ebDTDwffvaBN4JmbLm7BxGeymuLBiuWig3POpgUAQ00f7jXM78cWTD1G7B42IfokgiQHb9fWH_L7JOQ3_5hh-OD6heuqRu2vEkkgf8oGnS3ZCgL3YcExINio_jaO6qZjNR0A3nUvXApihvPn4JG7YWg2wYRM2yaXr_wA8ES3oklTDl7COldCLphaGzHntmWKK0hkQX2jZA4l94bfa7faDADiBi4B3A7U4UjoCJkmyXv0VOvke2Qmq7kodTi2A54LOm9UPZTaPlZ_vAt20nVYMiLTeXeLRjavaM70LclTKuHrYWZKhPREH3w255MqGiMiArmRUNHtzglYwdL4ncid-x3foLj3DZKwmZ5pdKXxV1aNPcvkewCMYNq19skv6goqU0KJ8urd46VjI1bKoquw6FdbmjRFNmHKBwAI3l-xzjYQrmFJYXUabmVeN7pqIULY46P640XngoElijcvYL7r6mo4rdmZwRXDc8oKOhh_A6QmEpvIQp47b6p-pJc9GOz1W221CLNG3O0hG5o7DfpHJBsy3pASJjjwiNedzbnyu57OTTu3JWr3epq0WyrmWBH0TAdmUyAoSDTka-7-Wo6bHcVThC6HzRSbc7-J9nAKkjEaostrfzKTHVZAaBUcyAjlqn1hz_-mRq8bYif3GQkzspQ-em0Em0pczfmOBwsmQJknE3oxi9safWmgqs9UIIrqECYzCJ-mhg-7GVN-tZYuHdYvzEoPh5kHXpRYgo1s8neh54HwcLj28BWD_34Dr2BhuReKH82GGJt5-WQzJ3JDsKLADDIx7mNW06GwLERit34I8T4KNU_5B8UgvDtkBGkGY9FeteROnuCaHGCLafLt6uNCdK6A7Gqa0oFDSZHfY-nJVXQPrSpZo19JlrirA5Xk6s2jCVSwi5LZAxR1EFzQjOZADfDmYKDU35B2wKAV5I-agUPokheCarDmotj4hffqKcGs9DnhwzHTe9O3enO8NV-RHkNRYcgb7DydMwhEG8FIlyQhPzuKainBdkySJNNGCyF8tp8k1EA0-b_aDnMjr7SNMyVqmzCNlq8GoLJ16L51B-LEMmpq_0LG3-fCZpqH-VcF4_eJqIAn4JsqwY8nZJZt2AjxEz4QmtAxunNeRnwPQgwimOfVpZJGDWO4TqY_gvtDqpOPt404Wb3Ln4DF9e_W6RS3gq5_X7QXKyadI1rcqJX8KRkZNw5PraU5Wr4OkGgTvGlaFyxkEoEB1AmxDk5Lhp10TYG6cGcQLcHKfXkpHCHlCVsJwFtbz6r4v0vzjM2Q9ZN1_t2eQ2t1uvwAUJdj9O1IM7OFNU3ru1xUihQMAyIdsTdyYPxd3q01U1kKhstR5oUWA2XsAu6aZGKQwG6sAcO4wumKbPc9He4OCPY10zcmBNJyx2aOVAuUXARYp5HX-0CwLXvKUf8DmV2L7aXCLtdCp1jFFmlufERyBopFFLRGptRqDSfG9Y7JvdemjuqcVQPswJEhWZKBb81eG-Mb2ouHBsnUdiKnBhn7P7B8iq5BgM1W0kqVLKU3LbSEULxM8FoN7jIzgTXbD0aNHqBuwu3kcGwtbU9w9mrgAGLHUy96n0L2Py-fhV_Vzz6D0u9nUWdN5uhOR-pDzFY5YBfrIS5BgEiqX-epXq7Ishdf2X6caM5G6zLnCRcE2HR31XyjGHfwVeeqIcJeQAP_Y6l6NquLu1xFH3fx_IyY5qsnyI_S6W4-9yItHK7jZ2N8pEaB0u6yCkAG82yjw8o3v0-z7KZbTWs5vtwK0vhpBl3TgFrtE_yTK1gY9GqsWj1GtrvBRyUXiHqF85oHRcjuH_GUGgewXEfDn4m6PvcTBk5A2NkHce-LpF96ZjMFrrnnKxXATVPzIvnqsjjwj8tEPhd5m5A3v6Qn-5J0cX_1PAHgQwDGXRVzq2O4E96JEKqZQgpQTCIkZs9XGVHUoEALezg0C2OLNVNRfch9hAEja9YN7pf21B52bmjH6W7wv3C9qiE-Q-RxNn17Xu8j-8GKNlmwz7TaHcUfRWlGsQIUJ4lMeCU78A9zfZBZASCLaDX0oUyaNn77xddpTb96R-RTJqzl3dyKXbDScPFRdkB5td-Jql_ByjetxcUuDhof4WXHdXSN1nv1L6cET7imShEFk-RvFD2qvQveXzqvjngqpV-C_X7Jd4iYmqPerXdW22_Wh_soFLYSLLiKzlZ5JSxZ_WLt5uYzvBv04YXVWam_O07vJPwePSRvT8QbvNCC58IiVAJOeCYSopPVaTdD9uw94ybE5F5Sy0XlAB23nWSjrEd6Zy7yYza02iTIX7idxvNb0VWogGoCBjb6FowXpS5wLOEtFIMNVHowJEV4MkLasF7LQled2T5AkSQFSZFSCkWD96bhvuIUi9_fttTUKtQoSrFjhtg21f8lHA2pwlFK7jLbLzDTYnODK2qu9N6b8WcZauWpaSrkTyOC0s=|1775179342|E8jGyUr-5HOtfbTYWCgElRa2gR6Yx3HFKSrSKJYLBZk=; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%224210192048793363%22%2C%22first_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2219b6df4cc821138-0de2a4b89caaa9-4c657b58-1327104-19b6df4cc8319da%22%7D; _yg_pre=leYfk4cBTaeTaeIcuU0sC6XCYYmJSaD4MorRnro9uSMIP-Z5r1zrru_998WKASt_UFFGnCwPU98C6t_7V69MHHL-vlT1XQQim7M4X_8fi-PIHBKqE2UWzd2KGTF_8FMahKURVFkOSph1LsiEHwX_PtbxyGmy4cvPpyxJ',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"params = {\n",
|
||||
" 'id': download_list[0].get(\"id\"),\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"response = requests.get(\n",
|
||||
" 'https://manage-pre.f6yc.com/hive-admin/download/getFilePath',\n",
|
||||
" params=params,\n",
|
||||
" cookies=cookies,\n",
|
||||
" headers=headers,\n",
|
||||
")\n",
|
||||
"response.json()\n",
|
||||
"download_url = response.json().get(\"data\")"
|
||||
],
|
||||
"id": "d2a8883a6a563a45",
|
||||
"outputs": [],
|
||||
"execution_count": 2
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-04-09T06:01:04.066051500Z",
|
||||
"start_time": "2026-04-09T06:01:03.978024500Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": "response.json()",
|
||||
"id": "8b35e2d9f511f79d",
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'code': 200,\n",
|
||||
" 'data': 'https://f.f6yc.com/hive-admin/pre/coupon/97ebd3b858254f7885cba4e7000dd899.xls?Expires=1775715048&OSSAccessKeyId=LTAI5t6DU5niE8MN7hYh8AVs&Signature=J0nPbFraDmNmoWhr21u51NA61CQ%3D',\n",
|
||||
" 'message': 'SUCCESS'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"execution_count": 4
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "F6+宜搭+其它",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"version": "3.13.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class Main:
|
||||
FORMID1 = "FORM-33666CB1XDU37AU57RKPK990C79S2YMOEEC8LS" # [表单]异常服务跟进待办2023
|
||||
|
||||
# 读取excel表格
|
||||
df = pd.read_excel(r"C:\Users\hp_z66\OneDrive\Desktop\钉钉文件\2026-3已导入.xlsx",
|
||||
df = pd.read_excel(r"C:\Users\hp_z66\OneDrive\Desktop\钉钉文件\2026-3回访导入.xlsx",
|
||||
sheet_name='刷数据(注意部分字段替换)', dtype='string', header=1) # 此处将表头设置为了第二行
|
||||
df.fillna('', inplace=True)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class Main:
|
||||
|
||||
|
||||
# 读取excel表格获取数据
|
||||
ceshi_data = pd.read_excel(r"C:\Users\hp_z66\OneDrive\Desktop\钉钉文件\2026-3已导入.xlsx",sheet_name='7天节点且联系上(自动同意)')
|
||||
ceshi_data = pd.read_excel(r"C:\Users\hp_z66\OneDrive\Desktop\钉钉文件\2026-3回访导入.xlsx",sheet_name='7天节点且联系上(自动同意)')
|
||||
print("已读取表格")
|
||||
|
||||
# 执行自动化脚本
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from html import unescape
|
||||
from typing import Dict, Iterable, List, Optional, Sequence, Tuple
|
||||
from urllib.parse import urlencode
|
||||
|
||||
import requests
|
||||
|
||||
BASE_URL = "https://scrm.h1cd.com"
|
||||
|
||||
DEFAULT_COOKIES = {
|
||||
"showSmsActivity": "1",
|
||||
"showEasyMoney": "1",
|
||||
"LOGIN_URL": "https%3A%2F%2Fscrm.h1cd.com%2Flogin-h1cd.html",
|
||||
"adminpd": "jVISiRrtcJplFhLoCuUIxK9XG5ekdfwzq%2B0y482ZKxE%3D",
|
||||
"adminun": "15224781773",
|
||||
"uid": "10291",
|
||||
"PHPSESSID": "nbn58laakng0rv5iqln82a6qpu",
|
||||
}
|
||||
|
||||
DEFAULT_HEADERS = {
|
||||
"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",
|
||||
"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",
|
||||
"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/146.0.0.0 Safari/537.36 Edg/146.0.0.0",
|
||||
"sec-ch-ua": '"Chromium";v="146", "Not-A.Brand";v="24", "Microsoft Edge";v="146"',
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-ch-ua-platform": '"Windows"',
|
||||
}
|
||||
|
||||
DEFAULT_PARAMS = {
|
||||
"type": "",
|
||||
"expired": "",
|
||||
"storeId": "0",
|
||||
"search": "",
|
||||
}
|
||||
|
||||
_TABLE_RE = re.compile(r"<table\b[^>]*>.*?</table>", re.IGNORECASE | re.DOTALL)
|
||||
_TR_RE = re.compile(r"<tr\b[^>]*>.*?</tr>", re.IGNORECASE | re.DOTALL)
|
||||
_CELL_RE = re.compile(r"<t[hd]\b[^>]*>(.*?)</t[hd]>", re.IGNORECASE | re.DOTALL)
|
||||
_TAG_RE = re.compile(r"<[^>]+>", re.DOTALL)
|
||||
_BR_RE = re.compile(r"<\s*br\s*/?\s*>", re.IGNORECASE)
|
||||
_NBSP_RE = re.compile(r"(\xa0| )+", re.IGNORECASE)
|
||||
|
||||
|
||||
def _clean_html_text(raw: str) -> str:
|
||||
raw = _BR_RE.sub("\n", raw)
|
||||
raw = _TAG_RE.sub("", raw)
|
||||
raw = unescape(raw)
|
||||
raw = _NBSP_RE.sub(" ", raw)
|
||||
raw = raw.replace("\r", "").strip()
|
||||
raw = re.sub(r"[ \t]+\n", "\n", raw)
|
||||
raw = re.sub(r"\n{3,}", "\n\n", raw)
|
||||
raw = re.sub(r"[ \t]{2,}", " ", raw)
|
||||
return raw.strip()
|
||||
|
||||
|
||||
def build_cards_url(page: int) -> str:
|
||||
if page <= 1:
|
||||
return f"{BASE_URL}/admin/members/cards.html"
|
||||
return f"{BASE_URL}/admin/members/cards_{page}.html"
|
||||
|
||||
|
||||
def _load_cookies() -> Dict[str, str]:
|
||||
env_json = os.environ.get("H1_COOKIES_JSON")
|
||||
if env_json:
|
||||
loaded = json.loads(env_json)
|
||||
if not isinstance(loaded, dict):
|
||||
raise ValueError("H1_COOKIES_JSON must be a JSON object")
|
||||
return {str(k): str(v) for k, v in loaded.items()}
|
||||
return dict(DEFAULT_COOKIES)
|
||||
|
||||
|
||||
def _fetch_html(
|
||||
session: requests.Session,
|
||||
page: int,
|
||||
params: Dict[str, str],
|
||||
base_headers: Dict[str, str],
|
||||
timeout_seconds: int = 30,
|
||||
) -> str:
|
||||
url = build_cards_url(page)
|
||||
headers = dict(base_headers)
|
||||
|
||||
if page >= 2:
|
||||
referer_params = dict(params)
|
||||
headers["Referer"] = f"{build_cards_url(page - 1)}?{urlencode(referer_params, doseq=True)}"
|
||||
else:
|
||||
referer_params = dict(params)
|
||||
headers["Referer"] = f"{build_cards_url(1)}?{urlencode(referer_params, doseq=True)}"
|
||||
|
||||
resp = session.get(url, params=params, headers=headers, timeout=timeout_seconds)
|
||||
resp.raise_for_status()
|
||||
if not resp.encoding:
|
||||
resp.encoding = "utf-8"
|
||||
return resp.text
|
||||
|
||||
|
||||
def _parse_table(table_html: str) -> Tuple[List[str], List[List[str]]]:
|
||||
header: List[str] = []
|
||||
data_rows: List[List[str]] = []
|
||||
|
||||
for tr_match in _TR_RE.finditer(table_html):
|
||||
tr_html = tr_match.group(0)
|
||||
cell_html_list = _CELL_RE.findall(tr_html)
|
||||
if not cell_html_list:
|
||||
continue
|
||||
|
||||
cells = [_clean_html_text(c) for c in cell_html_list]
|
||||
if not any(cells):
|
||||
continue
|
||||
|
||||
is_header = bool(re.search(r"<th\b", tr_html, re.IGNORECASE))
|
||||
if is_header and not header:
|
||||
header = cells
|
||||
else:
|
||||
data_rows.append(cells)
|
||||
|
||||
if not data_rows:
|
||||
return header, []
|
||||
|
||||
if not header:
|
||||
max_cols = max(len(r) for r in data_rows)
|
||||
header = [f"col_{i + 1}" for i in range(max_cols)]
|
||||
|
||||
width = len(header)
|
||||
normalized_rows: List[List[str]] = []
|
||||
for row in data_rows:
|
||||
if len(row) < width:
|
||||
row = row + [""] * (width - len(row))
|
||||
elif len(row) > width:
|
||||
row = row[:width]
|
||||
normalized_rows.append(row)
|
||||
|
||||
return header, normalized_rows
|
||||
|
||||
|
||||
def parse_cards_page(html_text: str) -> Tuple[List[str], List[Dict[str, str]]]:
|
||||
tables = _TABLE_RE.findall(html_text)
|
||||
best_header: List[str] = []
|
||||
best_rows: List[List[str]] = []
|
||||
|
||||
for table_html in tables:
|
||||
header, rows = _parse_table(table_html)
|
||||
if len(header) <= 1:
|
||||
continue
|
||||
if len(rows) > len(best_rows):
|
||||
best_header, best_rows = header, rows
|
||||
|
||||
if not best_rows:
|
||||
return best_header, []
|
||||
|
||||
records = [dict(zip(best_header, row)) for row in best_rows]
|
||||
return best_header, records
|
||||
|
||||
|
||||
def _merge_headers(existing: List[str], incoming: Sequence[str]) -> List[str]:
|
||||
seen = set(existing)
|
||||
merged = list(existing)
|
||||
for col in incoming:
|
||||
if col not in seen:
|
||||
merged.append(col)
|
||||
seen.add(col)
|
||||
return merged
|
||||
|
||||
|
||||
def export_all_cards(
|
||||
output_csv_path: str,
|
||||
params: Optional[Dict[str, str]] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
max_pages: int = 200,
|
||||
sleep_seconds: float = 0.3,
|
||||
) -> Tuple[int, int]:
|
||||
cookies = _load_cookies()
|
||||
params = dict(DEFAULT_PARAMS if params is None else params)
|
||||
headers = dict(DEFAULT_HEADERS if headers is None else headers)
|
||||
|
||||
session = requests.Session()
|
||||
session.cookies.update(cookies)
|
||||
|
||||
all_records: List[Dict[str, str]] = []
|
||||
merged_header: List[str] = []
|
||||
seen_keys: set[Tuple[str, ...]] = set()
|
||||
|
||||
pages_fetched = 0
|
||||
for page in range(1, max_pages + 1):
|
||||
html_text = _fetch_html(session=session, page=page, params=params, base_headers=headers)
|
||||
page_header, page_records = parse_cards_page(html_text)
|
||||
pages_fetched += 1
|
||||
|
||||
if not page_records:
|
||||
break
|
||||
|
||||
merged_header = _merge_headers(merged_header, page_header)
|
||||
|
||||
for rec in page_records:
|
||||
key = tuple(rec.get(col, "") for col in page_header)
|
||||
if key in seen_keys:
|
||||
continue
|
||||
seen_keys.add(key)
|
||||
all_records.append(rec)
|
||||
|
||||
if sleep_seconds > 0:
|
||||
time.sleep(sleep_seconds)
|
||||
|
||||
if not all_records:
|
||||
raise RuntimeError("未解析到任何表格数据(可能是登录失效/页面结构变化/被重定向到登录页)")
|
||||
|
||||
if not merged_header:
|
||||
merged_header = sorted({k for r in all_records for k in r.keys()})
|
||||
|
||||
os.makedirs(os.path.dirname(os.path.abspath(output_csv_path)) or ".", exist_ok=True)
|
||||
with open(output_csv_path, "w", encoding="utf-8-sig", newline="") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=merged_header, extrasaction="ignore")
|
||||
writer.writeheader()
|
||||
for rec in all_records:
|
||||
writer.writerow({k: rec.get(k, "") for k in merged_header})
|
||||
|
||||
return pages_fetched, len(all_records)
|
||||
|
||||
|
||||
def _self_test() -> None:
|
||||
html_text = """
|
||||
<html><body>
|
||||
<table>
|
||||
<tr><th>会员名</th><th>卡号</th><th>余额</th></tr>
|
||||
<tr><td>张三</td><td>NO001</td><td>100</td></tr>
|
||||
<tr><td>李四</td><td>NO002</td><td>200</td></tr>
|
||||
</table>
|
||||
</body></html>
|
||||
"""
|
||||
header, records = parse_cards_page(html_text)
|
||||
assert header == ["会员名", "卡号", "余额"]
|
||||
assert records[0]["卡号"] == "NO001"
|
||||
assert records[1]["余额"] == "200"
|
||||
|
||||
|
||||
def main(argv: Optional[Sequence[str]] = None) -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--output", default="H1会员卡.csv")
|
||||
parser.add_argument("--storeId", default=DEFAULT_PARAMS["storeId"])
|
||||
parser.add_argument("--search", default=DEFAULT_PARAMS["search"])
|
||||
parser.add_argument("--type", default=DEFAULT_PARAMS["type"])
|
||||
parser.add_argument("--expired", default=DEFAULT_PARAMS["expired"])
|
||||
parser.add_argument("--max-pages", type=int, default=200)
|
||||
parser.add_argument("--sleep", type=float, default=0.3)
|
||||
parser.add_argument("--self-test", action="store_true")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.self_test:
|
||||
_self_test()
|
||||
print("self-test ok")
|
||||
return 0
|
||||
|
||||
params = {
|
||||
"type": str(args.type),
|
||||
"expired": str(args.expired),
|
||||
"storeId": str(args.storeId),
|
||||
"search": str(args.search),
|
||||
}
|
||||
|
||||
pages_fetched, rows = export_all_cards(
|
||||
output_csv_path=args.output,
|
||||
params=params,
|
||||
max_pages=args.max_pages,
|
||||
sleep_seconds=args.sleep,
|
||||
)
|
||||
print(f"导出完成: pages={pages_fetched}, rows={rows}, output={os.path.abspath(args.output)}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,424 @@
|
||||
"""
|
||||
H1车店系统 - 会员卡信息导出
|
||||
从 https://scrm.h1cd.com/admin/members/cards.html 导出会员卡信息
|
||||
注意:脚本解析HTML表格,导出的原始数据格式不规范,需要清洗处理
|
||||
"""
|
||||
|
||||
import requests
|
||||
import pandas as pd
|
||||
from bs4 import BeautifulSoup
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# ===================== 【配置区】 =====================
|
||||
# Cookie(请根据实际情况更新)
|
||||
COOKIES = {
|
||||
'showSmsActivity': '1',
|
||||
'showEasyMoney': '1',
|
||||
'LOGIN_URL': 'https%3A%2F%2Fscrm.h1cd.com%2Flogin-h1cd.html',
|
||||
'adminpd': 'jVISiRrtcJplFhLoCuUIxK9XG5ekdfwzq%2B0y482ZKxE%3D',
|
||||
'adminun': '15224781773',
|
||||
'uid': '10291',
|
||||
'PHPSESSID': 'nbn58laakng0rv5iqln82a6qpu',
|
||||
}
|
||||
|
||||
HEADERS = {
|
||||
'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',
|
||||
'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': 'https://scrm.h1cd.com/admin/members/cards.html',
|
||||
'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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
'sec-ch-ua': '"Chromium";v="146", "Not-A.Brand";v="24", "Microsoft Edge";v="146"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'sec-ch-ua-platform': '"Windows"',
|
||||
}
|
||||
|
||||
# 查询参数
|
||||
PARAMS = {
|
||||
'type': '',
|
||||
'expired': '',
|
||||
'storeId': '0',
|
||||
'search': '',
|
||||
}
|
||||
|
||||
# 输出目录
|
||||
OUTPUT_DIR = r"D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出"
|
||||
|
||||
# =====================================================
|
||||
|
||||
|
||||
def get_page_html(page_num, cookies, params):
|
||||
"""获取指定页面的HTML内容"""
|
||||
try:
|
||||
if page_num == 1:
|
||||
url = "https://scrm.h1cd.com/admin/members/cards.html"
|
||||
else:
|
||||
url = f"https://scrm.h1cd.com/admin/members/cards_{page_num}.html"
|
||||
|
||||
r = requests.get(url, headers=HEADERS, cookies=cookies, params=params, timeout=30)
|
||||
|
||||
# 检查是否被重定向到登录页
|
||||
if 'login' in r.url.lower() or '登录' in r.text[:2000]:
|
||||
print(f" ⚠️ 第{page_num}页检测到跳转登录,Cookie可能已失效。")
|
||||
return None
|
||||
|
||||
r.raise_for_status()
|
||||
r.encoding = 'utf-8'
|
||||
return r.text
|
||||
except Exception as e:
|
||||
print(f" ❌ 第{page_num}页请求失败: {str(e)}")
|
||||
return None
|
||||
|
||||
|
||||
def parse_cards_table(html):
|
||||
"""
|
||||
解析会员卡HTML表格,提取数据并做规范化处理。
|
||||
|
||||
H1系统会员卡页面特点:
|
||||
- 部分单元格包含多行信息(用<br>分隔),如姓名和手机号在同一格
|
||||
- 状态信息可能包含多余文本
|
||||
- 数值字段可能包含非数字字符
|
||||
- 操作列包含按钮文本需要过滤
|
||||
"""
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
table = soup.find('table', class_='table')
|
||||
if not table:
|
||||
table = soup.find('table')
|
||||
if not table:
|
||||
return [], []
|
||||
|
||||
# 提取表头
|
||||
header = []
|
||||
thead = table.find('thead')
|
||||
if thead:
|
||||
ths = thead.find_all('th')
|
||||
header = [th.get_text(strip=True) for th in ths]
|
||||
|
||||
# 如果没有 thead,尝试从第一行 tr 中获取
|
||||
if not header:
|
||||
first_tr = table.find('tr')
|
||||
if first_tr:
|
||||
ths = first_tr.find_all('th')
|
||||
if ths:
|
||||
header = [th.get_text(strip=True) for th in ths]
|
||||
|
||||
# 提取数据行
|
||||
tbody = table.find('tbody')
|
||||
rows = tbody.find_all('tr') if tbody else table.find_all('tr')
|
||||
|
||||
data_rows = []
|
||||
for tr in rows:
|
||||
# 跳过表头行
|
||||
if tr.find('th'):
|
||||
continue
|
||||
tds = tr.find_all('td')
|
||||
if not tds or len(tds) < 3:
|
||||
continue
|
||||
|
||||
row_data = []
|
||||
for td in tds:
|
||||
# 保留<br>产生的换行,使用separator分隔
|
||||
text = td.get_text(separator='|', strip=True)
|
||||
# 清理多余空格
|
||||
text = re.sub(r'\s+', ' ', text)
|
||||
row_data.append(text.strip())
|
||||
|
||||
if any(row_data):
|
||||
data_rows.append(row_data)
|
||||
|
||||
return header, data_rows
|
||||
|
||||
|
||||
def clean_card_record(row_dict, header):
|
||||
"""
|
||||
清洗单条会员卡记录,处理不规范的数据格式。
|
||||
|
||||
主要处理:
|
||||
1. 姓名+手机号合并在一个字段中 → 拆分为独立的"客户名称"和"手机号"
|
||||
2. 状态字段中的多余文本
|
||||
3. 数值字段中的非数字字符
|
||||
4. 操作列中的按钮文本
|
||||
"""
|
||||
cleaned = {}
|
||||
|
||||
# 定义可能的列名映射(H1系统表头可能包含的关键字)
|
||||
col_mappings = {
|
||||
'name_col': ['会员名', '姓名', '会员名称', '客户', '车主'],
|
||||
'phone_col': ['手机', '电话', '联系电话'],
|
||||
'card_no_col': ['卡号', '会员卡号', '卡编号'],
|
||||
'card_type_col': ['卡类型', '卡名称', '类型'],
|
||||
'balance_col': ['余额', '储值余额', '可用余额'],
|
||||
'total_recharge_col': ['充值', '累计充值', '总充值', '充值金额'],
|
||||
'total_consume_col': ['消费', '累计消费', '总消费', '消费金额'],
|
||||
'status_col': ['状态', '卡状态'],
|
||||
'create_time_col': ['开卡时间', '创建时间', '注册时间'],
|
||||
'expire_time_col': ['到期时间', '有效期', '过期时间'],
|
||||
'store_col': ['门店', '所属门店', '门店名称'],
|
||||
'level_col': ['等级', '会员等级', '会员级别'],
|
||||
}
|
||||
|
||||
# 查找列索引
|
||||
col_index = {}
|
||||
for key, keywords in col_mappings.items():
|
||||
for kw in keywords:
|
||||
for i, h in enumerate(header):
|
||||
if kw in h:
|
||||
col_index[key] = i
|
||||
break
|
||||
if key in col_index:
|
||||
break
|
||||
|
||||
# 逐列清洗
|
||||
for i, h in enumerate(header):
|
||||
value = row_dict.get(h, '') if isinstance(row_dict, dict) else (row_dict[i] if i < len(row_dict) else '')
|
||||
|
||||
# 处理操作列(通常在最后一列,包含"充值记录"、"消费记录"等按钮文本)
|
||||
if '操作' in h:
|
||||
cleaned[h] = ''
|
||||
continue
|
||||
|
||||
# 处理复选框列
|
||||
if '选择' in h or '勾选' in h:
|
||||
cleaned[h] = ''
|
||||
continue
|
||||
|
||||
# 处理姓名+手机号合并的情况
|
||||
if i == col_index.get('name_col'):
|
||||
name, phone = '', ''
|
||||
if '|' in value:
|
||||
parts = [p.strip() for p in value.split('|')]
|
||||
for part in parts:
|
||||
phone_match = re.search(r'1[3-9]\d{9}', part)
|
||||
if phone_match:
|
||||
phone = phone_match.group()
|
||||
elif part and not re.match(r'^\d{11}$', part):
|
||||
name = part if not name else name + part
|
||||
elif re.match(r'^\d{11}$', part):
|
||||
phone = part
|
||||
else:
|
||||
phone_match = re.search(r'1[3-9]\d{9}', value)
|
||||
if phone_match:
|
||||
phone = phone_match.group()
|
||||
name = value.replace(phone, '').strip()
|
||||
else:
|
||||
name = value.strip()
|
||||
|
||||
cleaned['客户名称'] = name
|
||||
cleaned['手机号'] = phone
|
||||
continue
|
||||
|
||||
# 处理手机号列(独立列)
|
||||
if i == col_index.get('phone_col'):
|
||||
phone_match = re.search(r'1[3-9]\d{9}', value)
|
||||
cleaned['手机号'] = phone_match.group() if phone_match else value
|
||||
continue
|
||||
|
||||
# 处理数值列(去掉非数字字符,保留小数点)
|
||||
if i == col_index.get('balance_col') or i == col_index.get('total_recharge_col') or i == col_index.get('total_consume_col'):
|
||||
num_match = re.search(r'[\d.]+', value.replace(',', ''))
|
||||
cleaned[h] = num_match.group() if num_match else value
|
||||
continue
|
||||
|
||||
# 清理其他字段中的多余空白和分隔符
|
||||
clean_val = value.replace('|', ' ').strip()
|
||||
clean_val = re.sub(r'\s+', ' ', clean_val)
|
||||
# 去除 "查看详情"、"编辑" 等按钮文本
|
||||
clean_val = re.sub(r'(查看详情|编辑|删除|充值记录|消费记录|详情)', '', clean_val).strip()
|
||||
cleaned[h] = clean_val
|
||||
|
||||
return cleaned
|
||||
|
||||
|
||||
def normalize_dataframe(df):
|
||||
"""
|
||||
对整个DataFrame进行规范化处理。
|
||||
处理各种数据不规范的情况。
|
||||
"""
|
||||
# 去除完全重复的行
|
||||
before_count = len(df)
|
||||
df = df.drop_duplicates()
|
||||
after_count = len(df)
|
||||
if before_count != after_count:
|
||||
print(f" 🔍 去重:{before_count} 条 → {after_count} 条(去除 {before_count - after_count} 条重复)")
|
||||
|
||||
# 尝试拆分合并列(如"姓名|手机号")
|
||||
for col in df.columns:
|
||||
# 检测该列是否包含手机号(超过30%的值匹配手机号模式)
|
||||
phone_ratio = df[col].astype(str).apply(lambda x: bool(re.search(r'1[3-9]\d{9}', x))).mean()
|
||||
name_ratio = df[col].astype(str).apply(lambda x: bool(re.search(r'[\u4e00-\u9fa5]{2,4}', x))).mean()
|
||||
|
||||
if phone_ratio > 0.3 and name_ratio > 0.3 and '名称' in col:
|
||||
# 该列同时包含姓名和手机号,需要拆分
|
||||
if '客户名称' not in df.columns:
|
||||
df['客户名称'] = df[col].apply(
|
||||
lambda x: re.sub(r'1[3-9]\d{9}', '', str(x)).replace('|', '').strip()
|
||||
)
|
||||
if '手机号' not in df.columns:
|
||||
df['手机号'] = df[col].apply(
|
||||
lambda x: (re.search(r'1[3-9]\d{9}', str(x)) or type('', (), {'group': lambda s: ''})()).group()
|
||||
)
|
||||
|
||||
# 清理数值列
|
||||
for col in df.columns:
|
||||
if any(kw in col for kw in ['余额', '充值', '消费', '金额']):
|
||||
df[col] = df[col].astype(str).apply(
|
||||
lambda x: re.search(r'[\d.]+', x.replace(',', '')).group() if re.search(r'[\d.]+', x.replace(',', '')) else x
|
||||
)
|
||||
|
||||
# 清理操作列
|
||||
for col in df.columns:
|
||||
if '操作' in col or '选择' in col or '勾选' in col:
|
||||
df = df.drop(columns=[col])
|
||||
|
||||
# 清理所有列中的按钮文本残留
|
||||
for col in df.columns:
|
||||
df[col] = df[col].astype(str).apply(
|
||||
lambda x: re.sub(r'(查看详情|编辑|删除|充值记录|消费记录|详情|迁移)', '', str(x)).strip()
|
||||
)
|
||||
# 替换 'nan' 为空字符串
|
||||
df[col] = df[col].replace('nan', '')
|
||||
df[col] = df[col].replace('None', '')
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def get_max_page(html):
|
||||
"""从页面中提取最大页数"""
|
||||
if not html:
|
||||
return 1
|
||||
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
text = soup.get_text()
|
||||
|
||||
# 尝试匹配 "共X页" 格式
|
||||
match = re.search(r'共\s*(\d+)\s*页', text)
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
|
||||
# 尝试匹配 "页 1/X" 格式
|
||||
match = re.search(r'页\s*1/(\d+)', text)
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
|
||||
# 尝试匹配分页链接
|
||||
page_links = soup.find_all('a', href=re.compile(r'cards_\d+\.html'))
|
||||
if page_links:
|
||||
max_page = 1
|
||||
for a in page_links:
|
||||
num_match = re.search(r'cards_(\d+)\.html', a.get('href', ''))
|
||||
if num_match:
|
||||
max_page = max(max_page, int(num_match.group(1)))
|
||||
return max_page
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 50)
|
||||
print("开始爬取 H1系统 会员卡信息...")
|
||||
print(f"当前 StoreID: {PARAMS['storeId']}")
|
||||
print("=" * 50)
|
||||
|
||||
# 获取第一页,确定总页数
|
||||
print("正在获取总页数...")
|
||||
first_html = get_page_html(1, COOKIES, PARAMS)
|
||||
if not first_html:
|
||||
print("❌ 无法获取第一页数据,请检查 Cookie 或网络。")
|
||||
return
|
||||
|
||||
max_page = get_max_page(first_html)
|
||||
print(f"✅ 成功获取最大页数:{max_page}")
|
||||
|
||||
# 爬取所有页面
|
||||
all_data = []
|
||||
merged_header = []
|
||||
|
||||
for page in range(1, max_page + 1):
|
||||
print(f"正在爬取第 {page}/{max_page} 页...")
|
||||
|
||||
if page == 1:
|
||||
html = first_html
|
||||
else:
|
||||
html = get_page_html(page, COOKIES, PARAMS)
|
||||
if not html:
|
||||
print(f"❌ 第 {page} 页获取失败,跳过。")
|
||||
continue
|
||||
|
||||
header, rows = parse_cards_table(html)
|
||||
|
||||
if not header and not rows:
|
||||
print(f"⚠️ 第 {page} 页未解析到表格数据。")
|
||||
continue
|
||||
|
||||
# 合并表头(不同页的表头可能略有差异)
|
||||
if header:
|
||||
for h in header:
|
||||
if h not in merged_header:
|
||||
merged_header.append(h)
|
||||
|
||||
all_data.extend(rows)
|
||||
|
||||
# 请求间隔,避免过于频繁
|
||||
if page < max_page:
|
||||
time.sleep(0.3)
|
||||
|
||||
if not all_data:
|
||||
print("\n❌ 未获取到任何数据,请检查 Cookie 或网络。")
|
||||
return
|
||||
|
||||
print(f"\n✅ 爬取完成,共获取 {len(all_data)} 条原始记录")
|
||||
|
||||
# 构建DataFrame
|
||||
if merged_header:
|
||||
# 标准化行长度
|
||||
normalized_rows = []
|
||||
width = len(merged_header)
|
||||
for row in all_data:
|
||||
if len(row) < width:
|
||||
row = row + [''] * (width - len(row))
|
||||
elif len(row) > width:
|
||||
row = row[:width]
|
||||
normalized_rows.append(row)
|
||||
df = pd.DataFrame(normalized_rows, columns=merged_header)
|
||||
else:
|
||||
df = pd.DataFrame(all_data)
|
||||
|
||||
print(f"📋 原始列名:{list(df.columns)}")
|
||||
print(f"📋 原始数据前3行:")
|
||||
print(df.head(3).to_string())
|
||||
|
||||
# 数据规范化处理
|
||||
print("\n开始数据规范化处理...")
|
||||
df = normalize_dataframe(df)
|
||||
|
||||
# 保存结果
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
time_str = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"H1会员卡信息_{time_str}.xlsx"
|
||||
filepath = os.path.join(OUTPUT_DIR, filename)
|
||||
|
||||
try:
|
||||
df.to_excel(filepath, index=False)
|
||||
print("=" * 50)
|
||||
print(f"✅ 导出完成!")
|
||||
print(f"📊 最终有效条数:{len(df)}")
|
||||
print(f"📁 已保存到:{filepath}")
|
||||
print("=" * 50)
|
||||
except Exception as e:
|
||||
print(f"❌ 保存Excel失败: {e}")
|
||||
# 降级为CSV
|
||||
csv_path = filepath.replace('.xlsx', '.csv')
|
||||
df.to_csv(csv_path, index=False, encoding='utf-8-sig')
|
||||
print(f"💡 已转为 CSV 保存至:{csv_path}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+640
-303
@@ -10,6 +10,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "70a8b0da",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
@@ -17,6 +18,64 @@
|
||||
"start_time": "2026-03-25T03:51:31.198595700Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"正在获取总页数...\n",
|
||||
"总页数:34 页\n",
|
||||
"正在爬取第 1/34 页...\n",
|
||||
"正在爬取第 2/34 页...\n",
|
||||
"正在爬取第 3/34 页...\n",
|
||||
"正在爬取第 4/34 页...\n",
|
||||
"正在爬取第 5/34 页...\n",
|
||||
"正在爬取第 6/34 页...\n",
|
||||
"正在爬取第 7/34 页...\n",
|
||||
"正在爬取第 8/34 页...\n",
|
||||
"正在爬取第 9/34 页...\n",
|
||||
"正在爬取第 10/34 页...\n",
|
||||
"正在爬取第 11/34 页...\n",
|
||||
"正在爬取第 12/34 页...\n",
|
||||
"正在爬取第 13/34 页...\n",
|
||||
"正在爬取第 14/34 页...\n",
|
||||
"正在爬取第 15/34 页...\n",
|
||||
"正在爬取第 16/34 页...\n",
|
||||
"正在爬取第 17/34 页...\n",
|
||||
"正在爬取第 18/34 页...\n",
|
||||
"正在爬取第 19/34 页...\n",
|
||||
"正在爬取第 20/34 页...\n",
|
||||
"正在爬取第 21/34 页...\n",
|
||||
"正在爬取第 22/34 页...\n",
|
||||
"正在爬取第 23/34 页...\n",
|
||||
"正在爬取第 24/34 页...\n",
|
||||
"正在爬取第 25/34 页...\n",
|
||||
"正在爬取第 26/34 页...\n",
|
||||
"正在爬取第 27/34 页...\n",
|
||||
"正在爬取第 28/34 页...\n",
|
||||
"正在爬取第 29/34 页...\n",
|
||||
"正在爬取第 30/34 页...\n",
|
||||
"正在爬取第 31/34 页...\n",
|
||||
"正在爬取第 32/34 页...\n",
|
||||
"正在爬取第 33/34 页...\n",
|
||||
"正在爬取第 34/34 页...\n",
|
||||
"\n",
|
||||
"========== 爬取完成 ==========\n",
|
||||
"总计数据:666 行\n",
|
||||
"\n",
|
||||
"✅ 文件已保存到桌面:\n",
|
||||
"📊 Excel文件:C:\\Users\\hp_z66\\Desktop\\车辆数据_已拆分_20260325_1151531.csv\n",
|
||||
"📄 文本文件:C:\\Users\\hp_z66\\Desktop\\车辆数据_已拆分_20260325_115153.txt\n",
|
||||
"\n",
|
||||
"前5行数据预览:\n",
|
||||
"1 ['1', '豫NA477R', '卢忠厚', '', '', '', '/', '', '118933km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"2 ['2', '豫NF3722', '刘建利', '', '', '', '/', '', '198609km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"3 ['3', '豫N13B58', '石', '15090629992', '', '', '/', '', '22462km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"4 ['4', '京PYB297', '科迪黄青春', '', '', '', '/', '', '119584km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"5 ['5', '豫NN982M', '大众', '', '', '', '/', '', '197504km', '', '', '消费记录 编辑 迁移 删除']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
@@ -215,66 +274,7 @@
|
||||
" print(\"\\n前5行数据预览:\")\n",
|
||||
" for i, row in enumerate(all_data[:5]):\n",
|
||||
" print(i+1, row)"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"正在获取总页数...\n",
|
||||
"总页数:34 页\n",
|
||||
"正在爬取第 1/34 页...\n",
|
||||
"正在爬取第 2/34 页...\n",
|
||||
"正在爬取第 3/34 页...\n",
|
||||
"正在爬取第 4/34 页...\n",
|
||||
"正在爬取第 5/34 页...\n",
|
||||
"正在爬取第 6/34 页...\n",
|
||||
"正在爬取第 7/34 页...\n",
|
||||
"正在爬取第 8/34 页...\n",
|
||||
"正在爬取第 9/34 页...\n",
|
||||
"正在爬取第 10/34 页...\n",
|
||||
"正在爬取第 11/34 页...\n",
|
||||
"正在爬取第 12/34 页...\n",
|
||||
"正在爬取第 13/34 页...\n",
|
||||
"正在爬取第 14/34 页...\n",
|
||||
"正在爬取第 15/34 页...\n",
|
||||
"正在爬取第 16/34 页...\n",
|
||||
"正在爬取第 17/34 页...\n",
|
||||
"正在爬取第 18/34 页...\n",
|
||||
"正在爬取第 19/34 页...\n",
|
||||
"正在爬取第 20/34 页...\n",
|
||||
"正在爬取第 21/34 页...\n",
|
||||
"正在爬取第 22/34 页...\n",
|
||||
"正在爬取第 23/34 页...\n",
|
||||
"正在爬取第 24/34 页...\n",
|
||||
"正在爬取第 25/34 页...\n",
|
||||
"正在爬取第 26/34 页...\n",
|
||||
"正在爬取第 27/34 页...\n",
|
||||
"正在爬取第 28/34 页...\n",
|
||||
"正在爬取第 29/34 页...\n",
|
||||
"正在爬取第 30/34 页...\n",
|
||||
"正在爬取第 31/34 页...\n",
|
||||
"正在爬取第 32/34 页...\n",
|
||||
"正在爬取第 33/34 页...\n",
|
||||
"正在爬取第 34/34 页...\n",
|
||||
"\n",
|
||||
"========== 爬取完成 ==========\n",
|
||||
"总计数据:666 行\n",
|
||||
"\n",
|
||||
"✅ 文件已保存到桌面:\n",
|
||||
"📊 Excel文件:C:\\Users\\hp_z66\\Desktop\\车辆数据_已拆分_20260325_1151531.csv\n",
|
||||
"📄 文本文件:C:\\Users\\hp_z66\\Desktop\\车辆数据_已拆分_20260325_115153.txt\n",
|
||||
"\n",
|
||||
"前5行数据预览:\n",
|
||||
"1 ['1', '豫NA477R', '卢忠厚', '', '', '', '/', '', '118933km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"2 ['2', '豫NF3722', '刘建利', '', '', '', '/', '', '198609km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"3 ['3', '豫N13B58', '石', '15090629992', '', '', '/', '', '22462km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"4 ['4', '京PYB297', '科迪黄青春', '', '', '', '/', '', '119584km', '', '', '消费记录 编辑 迁移 删除']\n",
|
||||
"5 ['5', '豫NN982M', '大众', '', '', '', '/', '', '197504km', '', '', '消费记录 编辑 迁移 删除']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 1
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -286,6 +286,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "5392bfc0",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
@@ -293,6 +294,67 @@
|
||||
"start_time": "2026-03-25T03:53:18.688209100Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"==================================================\n",
|
||||
"开始爬取库存数据...\n",
|
||||
"当前 StoreID: 13435\n",
|
||||
"当前 HouseID: 9079\n",
|
||||
"==================================================\n",
|
||||
"✅ 成功获取最大页数:40\n",
|
||||
"正在爬取第 1/40 页...\n",
|
||||
"正在爬取第 2/40 页...\n",
|
||||
"正在爬取第 3/40 页...\n",
|
||||
"正在爬取第 4/40 页...\n",
|
||||
"正在爬取第 5/40 页...\n",
|
||||
"正在爬取第 6/40 页...\n",
|
||||
"正在爬取第 7/40 页...\n",
|
||||
"正在爬取第 8/40 页...\n",
|
||||
"正在爬取第 9/40 页...\n",
|
||||
"正在爬取第 10/40 页...\n",
|
||||
"正在爬取第 11/40 页...\n",
|
||||
"正在爬取第 12/40 页...\n",
|
||||
"正在爬取第 13/40 页...\n",
|
||||
"正在爬取第 14/40 页...\n",
|
||||
"正在爬取第 15/40 页...\n",
|
||||
"正在爬取第 16/40 页...\n",
|
||||
"正在爬取第 17/40 页...\n",
|
||||
"正在爬取第 18/40 页...\n",
|
||||
"正在爬取第 19/40 页...\n",
|
||||
"正在爬取第 20/40 页...\n",
|
||||
"正在爬取第 21/40 页...\n",
|
||||
"正在爬取第 22/40 页...\n",
|
||||
"正在爬取第 23/40 页...\n",
|
||||
"正在爬取第 24/40 页...\n",
|
||||
"正在爬取第 25/40 页...\n",
|
||||
"正在爬取第 26/40 页...\n",
|
||||
"正在爬取第 27/40 页...\n",
|
||||
"正在爬取第 28/40 页...\n",
|
||||
"正在爬取第 29/40 页...\n",
|
||||
"正在爬取第 30/40 页...\n",
|
||||
"正在爬取第 31/40 页...\n",
|
||||
"正在爬取第 32/40 页...\n",
|
||||
"正在爬取第 33/40 页...\n",
|
||||
"正在爬取第 34/40 页...\n",
|
||||
"正在爬取第 35/40 页...\n",
|
||||
"正在爬取第 36/40 页...\n",
|
||||
"正在爬取第 37/40 页...\n",
|
||||
"正在爬取第 38/40 页...\n",
|
||||
"正在爬取第 39/40 页...\n",
|
||||
"正在爬取第 40/40 页...\n",
|
||||
"\n",
|
||||
"🔍 去重完成 (基于列: 配件编码):原始 782 条 → 去重后 782 条\n",
|
||||
"==================================================\n",
|
||||
"✅ 爬取 + 去重 完成!\n",
|
||||
"📊 最终有效条数:782\n",
|
||||
"📁 已保存到桌面:库存数据_13435_去重版1.xlsx\n",
|
||||
"==================================================\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"import pandas as pd\n",
|
||||
@@ -499,69 +561,7 @@
|
||||
"\n",
|
||||
"if __name__ == '__main__':\n",
|
||||
" main()"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"==================================================\n",
|
||||
"开始爬取库存数据...\n",
|
||||
"当前 StoreID: 13435\n",
|
||||
"当前 HouseID: 9079\n",
|
||||
"==================================================\n",
|
||||
"✅ 成功获取最大页数:40\n",
|
||||
"正在爬取第 1/40 页...\n",
|
||||
"正在爬取第 2/40 页...\n",
|
||||
"正在爬取第 3/40 页...\n",
|
||||
"正在爬取第 4/40 页...\n",
|
||||
"正在爬取第 5/40 页...\n",
|
||||
"正在爬取第 6/40 页...\n",
|
||||
"正在爬取第 7/40 页...\n",
|
||||
"正在爬取第 8/40 页...\n",
|
||||
"正在爬取第 9/40 页...\n",
|
||||
"正在爬取第 10/40 页...\n",
|
||||
"正在爬取第 11/40 页...\n",
|
||||
"正在爬取第 12/40 页...\n",
|
||||
"正在爬取第 13/40 页...\n",
|
||||
"正在爬取第 14/40 页...\n",
|
||||
"正在爬取第 15/40 页...\n",
|
||||
"正在爬取第 16/40 页...\n",
|
||||
"正在爬取第 17/40 页...\n",
|
||||
"正在爬取第 18/40 页...\n",
|
||||
"正在爬取第 19/40 页...\n",
|
||||
"正在爬取第 20/40 页...\n",
|
||||
"正在爬取第 21/40 页...\n",
|
||||
"正在爬取第 22/40 页...\n",
|
||||
"正在爬取第 23/40 页...\n",
|
||||
"正在爬取第 24/40 页...\n",
|
||||
"正在爬取第 25/40 页...\n",
|
||||
"正在爬取第 26/40 页...\n",
|
||||
"正在爬取第 27/40 页...\n",
|
||||
"正在爬取第 28/40 页...\n",
|
||||
"正在爬取第 29/40 页...\n",
|
||||
"正在爬取第 30/40 页...\n",
|
||||
"正在爬取第 31/40 页...\n",
|
||||
"正在爬取第 32/40 页...\n",
|
||||
"正在爬取第 33/40 页...\n",
|
||||
"正在爬取第 34/40 页...\n",
|
||||
"正在爬取第 35/40 页...\n",
|
||||
"正在爬取第 36/40 页...\n",
|
||||
"正在爬取第 37/40 页...\n",
|
||||
"正在爬取第 38/40 页...\n",
|
||||
"正在爬取第 39/40 页...\n",
|
||||
"正在爬取第 40/40 页...\n",
|
||||
"\n",
|
||||
"🔍 去重完成 (基于列: 配件编码):原始 782 条 → 去重后 782 条\n",
|
||||
"==================================================\n",
|
||||
"✅ 爬取 + 去重 完成!\n",
|
||||
"📊 最终有效条数:782\n",
|
||||
"📁 已保存到桌面:库存数据_13435_去重版1.xlsx\n",
|
||||
"==================================================\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 2
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -573,13 +573,191 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "cbd4eeb0a30b3e15",
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2026-03-25T03:58:48.443601700Z",
|
||||
"start_time": "2026-03-25T03:56:48.226330400Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"🔧 开始导出维修记录...\n",
|
||||
"📄 正在获取第 1 页以分析页数...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists.html\n",
|
||||
"📊 预估总页数: 53\n",
|
||||
"🔄 正在处理第 1/53 页...\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 2/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_2.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 3/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_3.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 4/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_4.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 5/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_5.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 6/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_6.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 7/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_7.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 8/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_8.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 9/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_9.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 10/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_10.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 11/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_11.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 12/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_12.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 13/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_13.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 14/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_14.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 15/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_15.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 16/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_16.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 17/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_17.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 18/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_18.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 19/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_19.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 20/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_20.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 21/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_21.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 22/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_22.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 23/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_23.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 24/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_24.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 25/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_25.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 26/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_26.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 27/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_27.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 28/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_28.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 29/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_29.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 30/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_30.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 31/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_31.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 32/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_32.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 33/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_33.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 34/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_34.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 35/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_35.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 36/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_36.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 37/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_37.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 38/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_38.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 39/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_39.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 40/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_40.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 41/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_41.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 42/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_42.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 43/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_43.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 44/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_44.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 45/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_45.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 46/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_46.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 47/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_47.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 48/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_48.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 49/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_49.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 50/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_50.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 51/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_51.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 52/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_52.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 53/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_53.html\n",
|
||||
" ✅ 本页提取 8 条记录\n",
|
||||
"\n",
|
||||
"==============================\n",
|
||||
"✅ 导出成功!\n",
|
||||
"📁 文件路径: D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\维修记录_完美导出版.xlsx\n",
|
||||
"📈 总记录数: 1048\n",
|
||||
"==============================\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"import pandas as pd\n",
|
||||
@@ -885,185 +1063,344 @@
|
||||
" print(\"💡 请运行以下命令安装: pip install \" + \" \".join(missing))\n",
|
||||
" else:\n",
|
||||
" main()"
|
||||
],
|
||||
"id": "cbd4eeb0a30b3e15",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"🔧 开始导出维修记录...\n",
|
||||
"📄 正在获取第 1 页以分析页数...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists.html\n",
|
||||
"📊 预估总页数: 53\n",
|
||||
"🔄 正在处理第 1/53 页...\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 2/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_2.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 3/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_3.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 4/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_4.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 5/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_5.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 6/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_6.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 7/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_7.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 8/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_8.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 9/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_9.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 10/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_10.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 11/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_11.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 12/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_12.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 13/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_13.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 14/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_14.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 15/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_15.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 16/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_16.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 17/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_17.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 18/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_18.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 19/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_19.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 20/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_20.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 21/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_21.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 22/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_22.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 23/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_23.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 24/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_24.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 25/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_25.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 26/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_26.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 27/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_27.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 28/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_28.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 29/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_29.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 30/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_30.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 31/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_31.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 32/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_32.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 33/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_33.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 34/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_34.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 35/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_35.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 36/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_36.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 37/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_37.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 38/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_38.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 39/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_39.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 40/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_40.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 41/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_41.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 42/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_42.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 43/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_43.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 44/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_44.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 45/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_45.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 46/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_46.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 47/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_47.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 48/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_48.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 49/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_49.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 50/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_50.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 51/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_51.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 52/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_52.html\n",
|
||||
" ✅ 本页提取 20 条记录\n",
|
||||
"🔄 正在处理第 53/53 页...\n",
|
||||
" 正在请求: https://scrm.h1cd.com/admin/billings/Lists_53.html\n",
|
||||
" ✅ 本页提取 8 条记录\n",
|
||||
"\n",
|
||||
"==============================\n",
|
||||
"✅ 导出成功!\n",
|
||||
"📁 文件路径: D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\\维修记录_完美导出版.xlsx\n",
|
||||
"📈 总记录数: 1048\n",
|
||||
"==============================\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 3
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b3decf1d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 会员卡信息导出\n",
|
||||
"\n",
|
||||
"从 H1 系统导出会员卡信息(储值卡、套餐卡等),自动分页爬取并做数据规范化处理。\n",
|
||||
"\n",
|
||||
"> ⚠️ **注意**:H1系统导出的原始数据格式不规范(如姓名和手机号混在同一字段、操作列包含按钮文本等),脚本已内置清洗逻辑。\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9ab86773",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"import pandas as pd\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"import os\n",
|
||||
"import re\n",
|
||||
"import time\n",
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"# ===================== 【配置区】 =====================\n",
|
||||
"# Cookie(请根据实际情况更新,登录后从浏览器DevTools复制)\n",
|
||||
"COOKIES = {\n",
|
||||
" 'showSmsActivity': '1',\n",
|
||||
" 'showEasyMoney': '1',\n",
|
||||
" 'LOGIN_URL': 'https%3A%2F%2Fscrm.h1cd.com%2Flogin-h1cd.html',\n",
|
||||
" 'adminpd': 'jVISiRrtcJplFhLoCuUIxK9XG5ekdfwzq%2B0y482ZKxE%3D',\n",
|
||||
" 'adminun': '15224781773',\n",
|
||||
" 'uid': '10291',\n",
|
||||
" 'PHPSESSID': 'nbn58laakng0rv5iqln82a6qpu',\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-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': 'https://scrm.h1cd.com/admin/members/cards.html',\n",
|
||||
" 'Sec-Fetch-Dest': 'iframe',\n",
|
||||
" 'Sec-Fetch-Mode': 'navigate',\n",
|
||||
" 'Sec-Fetch-Site': 'same-origin',\n",
|
||||
" 'Sec-Fetch-User': '?1',\n",
|
||||
" 'Upgrade-Insecure-Requests': '1',\n",
|
||||
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0',\n",
|
||||
" 'sec-ch-ua': '\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Microsoft Edge\";v=\"146\"',\n",
|
||||
" 'sec-ch-ua-mobile': '?0',\n",
|
||||
" 'sec-ch-ua-platform': '\"Windows\"',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"# 查询参数\n",
|
||||
"PARAMS = {\n",
|
||||
" 'type': '',\n",
|
||||
" 'expired': '',\n",
|
||||
" 'storeId': '0',\n",
|
||||
" 'search': '',\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"# 输出目录\n",
|
||||
"OUTPUT_DIR = r\"D:\\Idea Project\\F6+宜搭+其它(1)\\张阳脚本\\文件输出\"\n",
|
||||
"# =====================================================\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_page_html(page_num):\n",
|
||||
" \"\"\"获取指定页面的HTML内容\"\"\"\n",
|
||||
" try:\n",
|
||||
" if page_num == 1:\n",
|
||||
" url = \"https://scrm.h1cd.com/admin/members/cards.html\"\n",
|
||||
" else:\n",
|
||||
" url = f\"https://scrm.h1cd.com/admin/members/cards_{page_num}.html\"\n",
|
||||
"\n",
|
||||
" r = requests.get(url, headers=HEADERS, cookies=COOKIES, params=PARAMS, timeout=30)\n",
|
||||
"\n",
|
||||
" # 检查是否被重定向到登录页\n",
|
||||
" if 'login' in r.url.lower() or '登录' in r.text[:2000]:\n",
|
||||
" print(f\" ⚠️ 第{page_num}页检测到跳转登录,Cookie可能已失效。\")\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" r.raise_for_status()\n",
|
||||
" r.encoding = 'utf-8'\n",
|
||||
" return r.text\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\" ❌ 第{page_num}页请求失败: {str(e)}\")\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def parse_cards_table(html):\n",
|
||||
" \"\"\"\n",
|
||||
" 解析会员卡HTML表格,提取数据。\n",
|
||||
" \n",
|
||||
" H1系统会员卡页面特点:\n",
|
||||
" - 部分单元格包含多行信息(用<br>分隔),如姓名和手机号在同一格\n",
|
||||
" - 操作列包含按钮文本需要过滤\n",
|
||||
" \"\"\"\n",
|
||||
" soup = BeautifulSoup(html, 'html.parser')\n",
|
||||
" table = soup.find('table', class_='table')\n",
|
||||
" if not table:\n",
|
||||
" table = soup.find(\"table\")\n",
|
||||
" if not table:\n",
|
||||
" return [], []\n",
|
||||
"\n",
|
||||
" # 提取表头\n",
|
||||
" header = []\n",
|
||||
" thead = table.find(\"thead\")\n",
|
||||
" if thead:\n",
|
||||
" ths = thead.find_all('th')\n",
|
||||
" header = [th.get_text(strip=True) for th in ths]\n",
|
||||
"\n",
|
||||
" if not header:\n",
|
||||
" first_tr = table.find(\"tr\")\n",
|
||||
" if first_tr:\n",
|
||||
" ths = first_tr.find_all('th')\n",
|
||||
" if ths:\n",
|
||||
" header = [th.get_text(strip=True) for th in ths]\n",
|
||||
"\n",
|
||||
" # 提取数据行\n",
|
||||
" tbody = table.find(\"tbody\")\n",
|
||||
" rows = tbody.find_all(\"tr\") if tbody else table.find_all(\"tr\")\n",
|
||||
"\n",
|
||||
" data_rows = []\n",
|
||||
" for tr in rows:\n",
|
||||
" if tr.find(\"th\"):\n",
|
||||
" continue\n",
|
||||
" tds = tr.find_all('td')\n",
|
||||
" if not tds or len(tds) < 3:\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" row_data = []\n",
|
||||
" for td in tds:\n",
|
||||
" text = td.get_text(separator='|', strip=True)\n",
|
||||
" text = re.sub(r'\\s+', ' ', text)\n",
|
||||
" row_data.append(text.strip())\n",
|
||||
"\n",
|
||||
" if any(row_data):\n",
|
||||
" data_rows.append(row_data)\n",
|
||||
"\n",
|
||||
" return header, data_rows\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def normalize_dataframe(df):\n",
|
||||
" \"\"\"\n",
|
||||
" 对整个DataFrame进行规范化处理。\n",
|
||||
" 处理H1系统导出数据不规范的情况:\n",
|
||||
" 1. 去重\n",
|
||||
" 2. 拆分姓名+手机号合并字段\n",
|
||||
" 3. 清理数值列\n",
|
||||
" 4. 去除操作列和按钮文本残留\n",
|
||||
" \"\"\"\n",
|
||||
" # 去除完全重复的行\n",
|
||||
" before_count = len(df)\n",
|
||||
" df = df.drop_duplicates()\n",
|
||||
" after_count = len(df)\n",
|
||||
" if before_count != after_count:\n",
|
||||
" print(f\" 🔍 去重:{before_count} 条 → {after_count} 条(去除 {before_count - after_count} 条重复)\")\n",
|
||||
"\n",
|
||||
" # 拆分合并列(如\"会员名\"列中同时包含姓名和手机号)\n",
|
||||
" for col in df.columns:\n",
|
||||
" if any(kw in col for kw in [\"会员名\", \"姓名\", \"客户名称\", \"车主\"]):\n",
|
||||
" # 检测该列是否同时包含姓名和手机号\n",
|
||||
" sample = df[col].astype(str).head(20)\n",
|
||||
" has_phone = sample.apply(lambda x: bool(re.search(r'1[3-9]\\d{9}', x))).any()\n",
|
||||
" if has_phone and '手机号' not in df.columns:\n",
|
||||
" df[\"客户名称\"] = df[col].apply(\n",
|
||||
" lambda x: re.sub(r\"1[3-9]\\d{9}\", \"\", str(x)).replace(\"|\", \"\").strip()\n",
|
||||
" )\n",
|
||||
" df[\"手机号\"] = df[col].apply(\n",
|
||||
" lambda x: (re.search(r\"1[3-9]\\d{9}\", str(x)).group() if re.search(r\"1[3-9]\\d{9}\", str(x)) else \"\")\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # 清理数值列\n",
|
||||
" for col in df.columns:\n",
|
||||
" if any(kw in col for kw in [\"余额\", \"充值\", \"消费\", \"金额\"]):\n",
|
||||
" df[col] = df[col].astype(str).apply(\n",
|
||||
" lambda x: (re.search(r\"[\\d.]+\", str(x).replace(\",\", \"\")).group() if re.search(r\"[\\d.]+\", str(x).replace(\",\", \"\")) else x)\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # 清理操作列\n",
|
||||
" cols_to_drop = [col for col in df.columns if any(kw in col for kw in [\"操作\", \"选择\", \"勾选\"])]\n",
|
||||
" if cols_to_drop:\n",
|
||||
" df = df.drop(columns=cols_to_drop)\n",
|
||||
"\n",
|
||||
" # 清理所有列中的按钮文本残留\n",
|
||||
" btn_patterns = r\"(查看详情|编辑|删除|充值记录|消费记录|详情|迁移|查看)\"\n",
|
||||
" for col in df.columns:\n",
|
||||
" df[col] = df[col].astype(str).apply(\n",
|
||||
" lambda x: re.sub(btn_patterns, \"\", str(x)).strip()\n",
|
||||
" )\n",
|
||||
" df[col] = df[col].replace({'nan': '', 'None': ''})\n",
|
||||
"\n",
|
||||
" return df\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def get_max_page(html):\n",
|
||||
" \"\"\"从页面中提取最大页数\"\"\"\n",
|
||||
" if not html:\n",
|
||||
" return 1\n",
|
||||
"\n",
|
||||
" soup = BeautifulSoup(html, 'html.parser')\n",
|
||||
" text = soup.get_text()\n",
|
||||
"\n",
|
||||
" match = re.search(r'共\\s*(\\d+)\\s*页', text)\n",
|
||||
" if match:\n",
|
||||
" return int(match.group(1))\n",
|
||||
"\n",
|
||||
" match = re.search(r'页\\s*1/(\\d+)', text)\n",
|
||||
" if match:\n",
|
||||
" return int(match.group(1))\n",
|
||||
"\n",
|
||||
" page_links = soup.find_all('a', href=re.compile(r'cards_\\d+\\.html'))\n",
|
||||
" if page_links:\n",
|
||||
" max_page = 1\n",
|
||||
" for a in page_links:\n",
|
||||
" num_match = re.search(r'cards_(\\d+)\\.html', a.get('href', ''))\n",
|
||||
" if num_match:\n",
|
||||
" max_page = max(max_page, int(num_match.group(1)))\n",
|
||||
" return max_page\n",
|
||||
"\n",
|
||||
" return 1\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def main():\n",
|
||||
" print(\"=\" * 50)\n",
|
||||
" print(\"开始爬取 H1系统 会员卡信息...\")\n",
|
||||
" print(f\"当前 StoreID: {PARAMS['storeId']}\")\n",
|
||||
" print(\"=\" * 50)\n",
|
||||
"\n",
|
||||
" # 获取第一页,确定总页数\n",
|
||||
" print(\"正在获取总页数...\")\n",
|
||||
" first_html = get_page_html(1)\n",
|
||||
" if not first_html:\n",
|
||||
" print(\"❌ 无法获取第一页数据,请检查 Cookie 或网络。\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" max_page = get_max_page(first_html)\n",
|
||||
" print(f\"✅ 成功获取最大页数:{max_page}\")\n",
|
||||
"\n",
|
||||
" # 爬取所有页面\n",
|
||||
" all_data = []\n",
|
||||
" merged_header = []\n",
|
||||
"\n",
|
||||
" for page in range(1, max_page + 1):\n",
|
||||
" print(f\"正在爬取第 {page}/{max_page} 页...\")\n",
|
||||
"\n",
|
||||
" if page == 1:\n",
|
||||
" html = first_html\n",
|
||||
" else:\n",
|
||||
" html = get_page_html(page)\n",
|
||||
" if not html:\n",
|
||||
" print(f\"❌ 第 {page} 页获取失败,跳过。\")\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" header, rows = parse_cards_table(html)\n",
|
||||
"\n",
|
||||
" if not header and not rows:\n",
|
||||
" print(f\"⚠️ 第 {page} 页未解析到表格数据。\")\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" # 合并表头(不同页的表头可能略有差异)\n",
|
||||
" if header:\n",
|
||||
" for h in header:\n",
|
||||
" if h not in merged_header:\n",
|
||||
" merged_header.append(h)\n",
|
||||
"\n",
|
||||
" all_data.extend(rows)\n",
|
||||
"\n",
|
||||
" # 请求间隔\n",
|
||||
" if page < max_page:\n",
|
||||
" time.sleep(0.3)\n",
|
||||
"\n",
|
||||
" if not all_data:\n",
|
||||
" print(\"\\n❌ 未获取到任何数据,请检查 Cookie 或网络。\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" print(f\"\\n✅ 爬取完成,共获取 {len(all_data)} 条原始记录\")\n",
|
||||
"\n",
|
||||
" # 构建DataFrame\n",
|
||||
" if merged_header:\n",
|
||||
" normalized_rows = []\n",
|
||||
" width = len(merged_header)\n",
|
||||
" for row in all_data:\n",
|
||||
" if len(row) < width:\n",
|
||||
" row = row + [\"\"] * (width - len(row))\n",
|
||||
" elif len(row) > width:\n",
|
||||
" row = row[:width]\n",
|
||||
" normalized_rows.append(row)\n",
|
||||
" df = pd.DataFrame(normalized_rows, columns=merged_header)\n",
|
||||
" else:\n",
|
||||
" df = pd.DataFrame(all_data)\n",
|
||||
"\n",
|
||||
" print(f\"📋 原始列名:{list(df.columns)}\")\n",
|
||||
" print(f\"📋 原始数据前3行:\")\n",
|
||||
" print(df.head(3).to_string())\n",
|
||||
"\n",
|
||||
" # 数据规范化处理\n",
|
||||
" print(\"\\n开始数据规范化处理...\")\n",
|
||||
" df = normalize_dataframe(df)\n",
|
||||
"\n",
|
||||
" # 保存结果\n",
|
||||
" os.makedirs(OUTPUT_DIR, exist_ok=True)\n",
|
||||
" time_str = datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n",
|
||||
" filename = f\"H1会员卡信息_{time_str}.xlsx\"\n",
|
||||
" filepath = os.path.join(OUTPUT_DIR, filename)\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" df.to_excel(filepath, index=False)\n",
|
||||
" print(\"=\" * 50)\n",
|
||||
" print(\"✅ 导出完成!\")\n",
|
||||
" print(f\"📊 最终有效条数:{len(df)}\")\n",
|
||||
" print(f\"📁 已保存到:{filepath}\")\n",
|
||||
" print(\"=\" * 50)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"❌ 保存Excel失败: {e}\")\n",
|
||||
" csv_path = filepath.replace(\".xlsx\", \".csv\")\n",
|
||||
" df.to_csv(csv_path, index=False, encoding=\"utf-8-sig\")\n",
|
||||
" print(f\"💡 已转为 CSV 保存至:{csv_path}\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"if __name__ == '__main__':\n",
|
||||
" main()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4c658267",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 运行导出\n",
|
||||
"main()\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
+17
-1
@@ -263,7 +263,21 @@
|
||||
- 逐个查询会员卡明细
|
||||
- 使用lxml解析HTML
|
||||
|
||||
### 34. 途虎养车系统
|
||||
### 35. H1车店系统
|
||||
- **文件**: `H1车店数据导出.ipynb`, `H1会员卡.py`
|
||||
- **功能**:
|
||||
- 车辆信息导出
|
||||
- 库存信息导出
|
||||
- 历史维修记录导出
|
||||
- 开单管理数据导出
|
||||
- 会员卡信息导出(储值卡、套餐卡等)
|
||||
- **接口**: `https://scrm.h1cd.com`
|
||||
- **特点**:
|
||||
- 使用Cookie认证,需要定期更新
|
||||
- HTML表格解析,分页URL模式为 `cards_{page}.html`
|
||||
- **数据格式不规范**:导出的原始数据中姓名和手机号可能混在同一字段、操作列包含按钮文本、数值字段含非数字字符等,脚本内置了数据规范化处理(拆分合并列、清理按钮文本、数值标准化、去重等)
|
||||
|
||||
### 36. 途虎养车系统
|
||||
- **文件**: `途虎养车脚本导出.ipynb`
|
||||
- **功能**:
|
||||
- 客户信息导出
|
||||
@@ -460,6 +474,8 @@
|
||||
├── 大唛云管理平台.ipynb # 大唛云管理平台
|
||||
├── 大大汽修token登录(1).ipynb # 大大汽修Token登录
|
||||
├── 大大汽修点击导出(1).ipynb # 大大汽修点击导出
|
||||
├── H1车店数据导出.ipynb # H1车店系统 - 车辆/库存/维修记录/会员卡导出
|
||||
├── H1会员卡.py # H1车店系统 - 会员卡信息导出(独立脚本)
|
||||
├── 好店长.ipynb # 好店长系统
|
||||
├── 客户无忧.ipynb # 客户无忧系统
|
||||
├── 客管家数据导出(1).ipynb # 客管家数据导出
|
||||
|
||||
+240
-182
File diff suppressed because one or more lines are too long
@@ -0,0 +1,286 @@
|
||||
"""
|
||||
神汽链(sqzone.com)登录+数据导出 一体化脚本
|
||||
- 自动登录获取JSESSIONID(Playwright + ddddocr验证码识别)
|
||||
- 导出近10年历史维修记录
|
||||
"""
|
||||
import sys, io
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
|
||||
|
||||
import requests
|
||||
import re
|
||||
import hashlib
|
||||
import time
|
||||
import json
|
||||
import base64
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from tqdm import tqdm
|
||||
import pandas as pd
|
||||
import urllib3
|
||||
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
# ============ 配置 ============
|
||||
ACCOUNT = '17690802976'
|
||||
PASSWORD = '123321'
|
||||
URL = 'https://www.sqzone.com/launa/pc/dataCenter/queryShopTurnoverInfo'
|
||||
OUTPUT_FILE = r'D:\Idea Project\F6+宜搭+其它(1)\张阳脚本\文件输出\神汽链10年历史数据.xlsx'
|
||||
DATE_RANGE_START = (2016, 4) # 近10年起始
|
||||
DATE_RANGE_END = (2026, 3) # 截止到上个月
|
||||
# ==============================
|
||||
|
||||
def md5(text):
|
||||
return hashlib.md5(text.encode('utf-8')).hexdigest()
|
||||
|
||||
def get_sqzone_cookies(account=ACCOUNT, password=PASSWORD, max_captcha_retries=5):
|
||||
"""通过Playwright浏览器自动化登录,获取JSESSIONID"""
|
||||
from playwright.sync_api import sync_playwright
|
||||
import ddddocr
|
||||
|
||||
ocr = ddddocr.DdddOcr(show_ad=False)
|
||||
|
||||
with sync_playwright() as p:
|
||||
print("[登录] 启动浏览器...")
|
||||
browser = p.chromium.launch(headless=True)
|
||||
context = browser.new_context(
|
||||
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
viewport={'width': 1280, 'height': 720}
|
||||
)
|
||||
page = context.new_page()
|
||||
|
||||
print("[登录] 访问神汽链登录页...")
|
||||
page.goto('https://www.sqzone.com/launa/pc/login', wait_until='domcontentloaded', timeout=30000)
|
||||
page.wait_for_timeout(3000)
|
||||
|
||||
uuid = page.evaluate('() => typeof uuid !== "undefined" ? uuid : ""')
|
||||
if not uuid:
|
||||
print("[登录] 未获取到uuid,登录页可能加载异常")
|
||||
browser.close()
|
||||
return None
|
||||
print(f"[登录] uuid: {uuid}")
|
||||
|
||||
for attempt in range(max_captcha_retries):
|
||||
print(f"[登录] 尝试 {attempt+1}/{max_captcha_retries}...")
|
||||
|
||||
captcha_result = page.evaluate('''async () => {
|
||||
const resp = await fetch('/fauna/qrloginserver/getPasswordCaptcha?t=' + Date.now());
|
||||
return await resp.json();
|
||||
}''')
|
||||
|
||||
captcha_code = ''
|
||||
if captcha_result.get('success'):
|
||||
img_data = base64.b64decode(captcha_result['data'])
|
||||
captcha_code = ocr.classification(img_data)
|
||||
print(f"[登录] 验证码: {captcha_code}")
|
||||
else:
|
||||
print(f"[登录] 获取验证码失败")
|
||||
continue
|
||||
|
||||
login_result = page.evaluate('''async (params) => {
|
||||
const resp = await fetch('/fauna/qrloginserver/backOfficePwdLogin', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json;charset=UTF-8'},
|
||||
body: JSON.stringify(params)
|
||||
});
|
||||
return await resp.json();
|
||||
}''', {
|
||||
'mobilephone': account,
|
||||
'password': md5(password),
|
||||
'pwdCaptcha': captcha_code,
|
||||
'referer': page.url,
|
||||
'uuid': uuid,
|
||||
'loginType': 'SAAS',
|
||||
})
|
||||
|
||||
if login_result.get('success'):
|
||||
print("[登录] SSO登录成功!")
|
||||
break
|
||||
elif '验证码错误' in (login_result.get('errorMsg') or ''):
|
||||
print("[登录] 验证码错误,重试...")
|
||||
continue
|
||||
elif '密码' in (login_result.get('errorMsg') or ''):
|
||||
print(f"[登录] 密码错误: {login_result.get('errorMsg')}")
|
||||
browser.close()
|
||||
return None
|
||||
else:
|
||||
print(f"[登录] 错误: {login_result.get('errorMsg')}")
|
||||
continue
|
||||
else:
|
||||
print("[登录] 验证码多次失败")
|
||||
browser.close()
|
||||
return None
|
||||
|
||||
# 刷新页面让authorize回调完成
|
||||
print("[登录] 刷新页面完成授权...")
|
||||
page.reload(wait_until='domcontentloaded', timeout=30000)
|
||||
page.wait_for_timeout(2000)
|
||||
|
||||
# 跳转到sqzone主页
|
||||
page.goto('https://www.sqzone.com/launa/web/dc/turnover', wait_until='domcontentloaded', timeout=30000)
|
||||
page.wait_for_timeout(2000)
|
||||
|
||||
# 获取cookies
|
||||
cookies = context.cookies()
|
||||
sqzone_cookies = {}
|
||||
for c in cookies:
|
||||
if 'sqzone' in c.get('domain', ''):
|
||||
sqzone_cookies[c['name']] = c['value']
|
||||
|
||||
# 验证cookies
|
||||
if sqzone_cookies.get('JSESSIONID'):
|
||||
test_result = page.evaluate('''async () => {
|
||||
const resp = await fetch('/launa/pc/dataCenter/queryShopTurnoverInfo', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'appName': 'SQLINK',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
keyword: '', pageSize: 1, curPage: 1,
|
||||
shopId: '', payId: [], payStatus: '',
|
||||
startTime: '2026-03-01', endTime: '2026-03-31',
|
||||
})
|
||||
});
|
||||
return await resp.json();
|
||||
}''')
|
||||
|
||||
if test_result.get('success') or test_result.get('data'):
|
||||
print(f"[登录] Cookies有效! JSESSIONID={sqzone_cookies['JSESSIONID'][:20]}...")
|
||||
else:
|
||||
print(f"[登录] Cookies无效: {str(test_result)[:100]}")
|
||||
browser.close()
|
||||
return None
|
||||
else:
|
||||
print("[登录] 未获取到JSESSIONID")
|
||||
browser.close()
|
||||
return None
|
||||
|
||||
browser.close()
|
||||
return sqzone_cookies
|
||||
|
||||
|
||||
def get_month_range(start_year, start_month, end_year, end_month):
|
||||
dates = []
|
||||
current = datetime(start_year, start_month, 1)
|
||||
end = datetime(end_year, end_month, 1)
|
||||
while current <= end:
|
||||
next_month = (current.replace(day=28) + timedelta(days=4)).replace(day=1)
|
||||
last_day = next_month - timedelta(days=1)
|
||||
dates.append((current.strftime('%Y-%m-%d'), last_day.strftime('%Y-%m-%d')))
|
||||
current = next_month
|
||||
return dates
|
||||
|
||||
|
||||
def fetch_page_with_retry(cookies, headers, start_date, end_date, page_num, max_retries=3):
|
||||
json_data = {
|
||||
'keyword': '', 'pageSize': 50, 'curPage': page_num,
|
||||
'shopId': '', 'payId': [], 'payStatus': '',
|
||||
'startTime': start_date, 'endTime': end_date,
|
||||
}
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
response = requests.post(URL, cookies=cookies, headers=headers, json=json_data, timeout=15, verify=False)
|
||||
if response.status_code == 200:
|
||||
res_json = response.json()
|
||||
if res_json.get('data'):
|
||||
return res_json['data'].get('contents', [])
|
||||
else:
|
||||
# 检查是否需要重新登录
|
||||
if res_json.get('code') == '-1302':
|
||||
print(f" Session过期! 需要重新登录")
|
||||
return 'SESSION_EXPIRED'
|
||||
print(f" 第{page_num}页业务异常: {res_json}")
|
||||
else:
|
||||
print(f" 第{page_num}页HTTP错误: {response.status_code}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" 第{page_num}页请求失败 ({attempt+1}/{max_retries}): {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep((attempt + 1) * 2)
|
||||
return None
|
||||
|
||||
|
||||
def export_data(cookies):
|
||||
"""导出历史数据"""
|
||||
headers = {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
||||
'Connection': 'keep-alive',
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'Origin': 'https://www.sqzone.com',
|
||||
'Referer': 'https://www.sqzone.com/launa/web/dc/turnover',
|
||||
'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/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'appName': 'SQLINK',
|
||||
}
|
||||
|
||||
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
|
||||
all_data = []
|
||||
month_ranges = get_month_range(*DATE_RANGE_START, *DATE_RANGE_END)
|
||||
print(f"\n[导出] 共 {len(month_ranges)} 个月份需要抓取")
|
||||
|
||||
for start_date, end_date in tqdm(month_ranges, desc="正在抓取数据"):
|
||||
page = 1
|
||||
while True:
|
||||
data_list = fetch_page_with_retry(cookies, headers, start_date, end_date, page)
|
||||
|
||||
if data_list == 'SESSION_EXPIRED':
|
||||
return 'SESSION_EXPIRED', all_data
|
||||
|
||||
if data_list is None:
|
||||
print(f"\n {start_date}-{end_date} 第{page}页多次失败,跳过")
|
||||
break
|
||||
|
||||
if not data_list:
|
||||
break
|
||||
|
||||
for data in data_list:
|
||||
parts = data.get('partsViews', [])
|
||||
customer_info = {k: v for k, v in data.items() if k != 'partsViews'}
|
||||
if parts:
|
||||
for part in parts:
|
||||
record = {**customer_info, **part}
|
||||
all_data.append(record)
|
||||
|
||||
page += 1
|
||||
time.sleep(1)
|
||||
|
||||
# 每5000条临时保存
|
||||
if len(all_data) > 0 and len(all_data) % 5000 == 0:
|
||||
temp_file = OUTPUT_FILE.replace('.xlsx', '_temp.xlsx')
|
||||
pd.DataFrame(all_data).to_excel(temp_file, index=False)
|
||||
print(f"\n 临时保存: {len(all_data)} 条")
|
||||
|
||||
return 'OK', all_data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 登录获取cookies
|
||||
cookies = get_sqzone_cookies()
|
||||
if not cookies:
|
||||
print("登录失败,退出")
|
||||
sys.exit(1)
|
||||
|
||||
# 导出数据(支持Session过期自动重新登录)
|
||||
while True:
|
||||
status, all_data = export_data(cookies)
|
||||
if status == 'SESSION_EXPIRED':
|
||||
print("\nSession过期,重新登录...")
|
||||
cookies = get_sqzone_cookies()
|
||||
if not cookies:
|
||||
print("重新登录失败,保存已有数据")
|
||||
break
|
||||
continue
|
||||
break
|
||||
|
||||
# 保存最终数据
|
||||
if all_data:
|
||||
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
|
||||
pd.DataFrame(all_data).to_excel(OUTPUT_FILE, index=False)
|
||||
print(f"\n全部完成! 共 {len(all_data)} 条数据,已保存至 {OUTPUT_FILE}")
|
||||
else:
|
||||
print("\n未抓取到数据")
|
||||
@@ -0,0 +1,89 @@
|
||||
import requests
|
||||
import pandas as pd
|
||||
|
||||
cookies = {
|
||||
'JSESSIONID': 'FA68674FDDA302C51E2775091B995EEA',
|
||||
'td_cookie': '3009435466',
|
||||
}
|
||||
|
||||
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=totalCount&datafrom=2026-01-01&datato=2026-04-13&sshopId=&type=1',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
}
|
||||
|
||||
def get_data(page=0, page_size=50):
|
||||
url = f'http://www.idsz.xin:7070/posapi_invoke?apiname=kpi_memberVerifiAndSurplusQuery&detailtype=1&startTime=2026-01-01&endTime=2026-04-13&key=totalCount&sshopId=×CardId=&option=&page={page}&pageSize={page_size}'
|
||||
response = requests.get(url=url, headers=headers, cookies=cookies)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
print("正在请求会员卡数据...")
|
||||
try:
|
||||
# 先获取第一页数据,获取总数
|
||||
first_page = get_data(page=0)
|
||||
total = first_page.get('total', 0)
|
||||
page_size = 50
|
||||
total_pages = (total + page_size - 1) // page_size
|
||||
|
||||
print(f"数据总条数: {total}")
|
||||
print(f"每页条数: {page_size}")
|
||||
print(f"总页数: {total_pages}")
|
||||
|
||||
TCK = []
|
||||
|
||||
# 获取第一页数据
|
||||
if 'rows' in first_page and len(first_page['rows']) > 0:
|
||||
for row in first_page['rows']:
|
||||
TCK1 = {
|
||||
'车牌号': row.get('carNo', ''),
|
||||
'卡名称': row.get('cardType', ''),
|
||||
'到期时间': row.get('endTime', ''),
|
||||
'发动机号': row.get('engineNumber', ''),
|
||||
'剩余明细': row.get('goodsName', ''),
|
||||
'剩余次数': row.get('qty', ''),
|
||||
'手机号': row.get('mobilePhone', ''),
|
||||
'客户姓名': row.get('name', ''),
|
||||
'备注': row.get('remark', ''),
|
||||
'Vin码': row.get('vin', '')
|
||||
}
|
||||
TCK.append(TCK1)
|
||||
print(f"已获取第1页数据,累计 {len(TCK)} 条")
|
||||
|
||||
# 获取剩余页数据
|
||||
for page in range(1, total_pages):
|
||||
try:
|
||||
data = get_data(page=page)
|
||||
if 'rows' in data and len(data['rows']) > 0:
|
||||
for row in data['rows']:
|
||||
TCK1 = {
|
||||
'车牌号': row.get('carNo', ''),
|
||||
'卡名称': row.get('cardType', ''),
|
||||
'到期时间': row.get('endTime', ''),
|
||||
'发动机号': row.get('engineNumber', ''),
|
||||
'剩余明细': row.get('goodsName', ''),
|
||||
'剩余次数': row.get('qty', ''),
|
||||
'手机号': row.get('mobilePhone', ''),
|
||||
'客户姓名': row.get('name', ''),
|
||||
'备注': row.get('remark', ''),
|
||||
'Vin码': row.get('vin', '')
|
||||
}
|
||||
TCK.append(TCK1)
|
||||
print(f"已获取第{page+1}页数据,累计 {len(TCK)} 条")
|
||||
except Exception as e:
|
||||
print(f"获取第{page+1}页数据失败: {e}")
|
||||
continue
|
||||
|
||||
# 导出数据
|
||||
df = pd.DataFrame(TCK)
|
||||
output_path = '会员卡.xlsx'
|
||||
df.to_excel(output_path, index=False)
|
||||
print(f"\n成功导出 {len(TCK)} 条会员卡数据到 {output_path}")
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"请求失败: {e}")
|
||||
except ValueError as e:
|
||||
print(f"JSON解析失败: {e}")
|
||||
@@ -0,0 +1,89 @@
|
||||
import requests
|
||||
import pandas as pd
|
||||
|
||||
cookies = {
|
||||
'JSESSIONID': 'FA68674FDDA302C51E2775091B995EEA',
|
||||
'td_cookie': '3008847516',
|
||||
}
|
||||
|
||||
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=2026-01-01&datato=2026-04-13&sshopId=&type=1',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
}
|
||||
|
||||
def get_data(page=0, page_size=50):
|
||||
url = f'http://www.idsz.xin:7070/posapi_invoke?apiname=kpi_memberVerifiAndSurplusQuery&detailtype=1&startTime=2026-01-01&endTime=2026-04-13&key=totalBalance&sshopId=×CardId=&option=&page={page}&pageSize={page_size}'
|
||||
response = requests.get(url=url, headers=headers, cookies=cookies)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
print("正在请求数据...")
|
||||
try:
|
||||
# 先获取第一页数据,获取总数
|
||||
first_page = get_data(page=0)
|
||||
total = first_page.get('total', 0)
|
||||
page_size = 50
|
||||
total_pages = (total + page_size - 1) // page_size
|
||||
|
||||
print(f"数据总条数: {total}")
|
||||
print(f"每页条数: {page_size}")
|
||||
print(f"总页数: {total_pages}")
|
||||
|
||||
CZK = []
|
||||
|
||||
# 获取第一页数据
|
||||
if 'rows' in first_page and len(first_page['rows']) > 0:
|
||||
for row in first_page['rows']:
|
||||
CZK1 = {
|
||||
'车牌号': row.get('carNo', ''),
|
||||
'卡名称': row.get('cardType', ''),
|
||||
'到期时间': row.get('endTime', ''),
|
||||
'发动机号': row.get('engineNumber', ''),
|
||||
'剩余金额': row.get('leftAmount', ''),
|
||||
'剩余赠送金额': row.get('leftsendAmount', ''),
|
||||
'手机号': row.get('mobilePhone', ''),
|
||||
'客户姓名': row.get('name', ''),
|
||||
'备注': row.get('remark', ''),
|
||||
'Vin码': row.get('vin', '')
|
||||
}
|
||||
CZK.append(CZK1)
|
||||
print(f"已获取第1页数据,累计 {len(CZK)} 条")
|
||||
|
||||
# 获取剩余页数据
|
||||
for page in range(1, total_pages):
|
||||
try:
|
||||
data = get_data(page=page)
|
||||
if 'rows' in data and len(data['rows']) > 0:
|
||||
for row in data['rows']:
|
||||
CZK1 = {
|
||||
'车牌号': row.get('carNo', ''),
|
||||
'卡名称': row.get('cardType', ''),
|
||||
'到期时间': row.get('endTime', ''),
|
||||
'发动机号': row.get('engineNumber', ''),
|
||||
'剩余金额': row.get('leftAmount', ''),
|
||||
'剩余赠送金额': row.get('leftsendAmount', ''),
|
||||
'手机号': row.get('mobilePhone', ''),
|
||||
'客户姓名': row.get('name', ''),
|
||||
'备注': row.get('remark', ''),
|
||||
'Vin码': row.get('vin', '')
|
||||
}
|
||||
CZK.append(CZK1)
|
||||
print(f"已获取第{page+1}页数据,累计 {len(CZK)} 条")
|
||||
except Exception as e:
|
||||
print(f"获取第{page+1}页数据失败: {e}")
|
||||
continue
|
||||
|
||||
# 导出数据
|
||||
df = pd.DataFrame(CZK)
|
||||
output_path = '储值卡.xlsx'
|
||||
df.to_excel(output_path, index=False)
|
||||
print(f"\n成功导出 {len(CZK)} 条数据到 {output_path}")
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"请求失败: {e}")
|
||||
except ValueError as e:
|
||||
print(f"JSON解析失败: {e}")
|
||||
+1030
-28
File diff suppressed because it is too large
Load Diff
+100
@@ -0,0 +1,100 @@
|
||||
# 可以引用一些第三方库.
|
||||
import requests
|
||||
import time
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
version = str(triggerConf.get('_widget_17758020150661'))
|
||||
research_leve1 = str(triggerConf.get('_widget_17758020157781'))
|
||||
research_leve2 =str(triggerConf.get('_widget_17758020169011'))
|
||||
|
||||
# 简道云 API 调用 Token(Bearer 形式)
|
||||
api_key="675b900991ad2491c69389ca"
|
||||
# 简道云 API 通用请求头
|
||||
entry_id ="69c0affbdef38560ddc3d0d0"
|
||||
|
||||
API_TOKEN = "Bearer qygHulymo1fekJk4CIZyNKjyQAzG8CFN"
|
||||
HEADERS = {'Authorization': API_TOKEN, 'Content-Type': 'application/json'}
|
||||
|
||||
def entry_data_list(
|
||||
data: Dict[str, Any],
|
||||
max_retries: int = 5,
|
||||
# 获取多条表单数据(自动分页:用上一页最后一条的 _id 作为 data_id)
|
||||
limit: int = 90,
|
||||
timeout: int = 10,
|
||||
) -> Dict[str, List[Dict[str, Any]]]:
|
||||
url = 'https://api.jiandaoyun.com/api/v5/app/entry/data/list'
|
||||
|
||||
all_rows: List[Dict[str, Any]] = []
|
||||
last_data_id: Optional[str] = None
|
||||
|
||||
while True:
|
||||
payload: Dict[str, Any] = {
|
||||
'app_id': data['api_key'],
|
||||
'entry_id': data['entry_id'],
|
||||
'limit': limit,
|
||||
'data_id': last_data_id,
|
||||
}
|
||||
if data.get('filter') is not None:
|
||||
payload['filter'] = data['filter']
|
||||
|
||||
body: Optional[Dict[str, Any]] = None
|
||||
for attempt in range(max_retries + 1):
|
||||
try:
|
||||
res = requests.post(url=url, json=payload, headers=HEADERS, timeout=timeout)
|
||||
res.raise_for_status()
|
||||
# 网络抖动/超时等异常,按最大重试次数重试
|
||||
body = res.json()
|
||||
break
|
||||
except requests.RequestException:
|
||||
if attempt >= max_retries:
|
||||
raise
|
||||
time.sleep(0.5)
|
||||
|
||||
batch = (body or {}).get('data') or []
|
||||
if not batch:
|
||||
# 下一页从本页最后一条数据之后继续拉取
|
||||
break
|
||||
|
||||
all_rows.extend(batch)
|
||||
last_data_id = batch[-1].get('_id')
|
||||
|
||||
return {'data': all_rows}
|
||||
filter_not_empty = {
|
||||
'rel': 'and',
|
||||
'cond': [
|
||||
{
|
||||
'field': '_widget_1774235645167',
|
||||
'type': 'text',
|
||||
'method': 'eq',
|
||||
'value': [version],
|
||||
},
|
||||
{
|
||||
'field': '_widget_1774235645172',
|
||||
'type': 'text',
|
||||
'method': 'eq',
|
||||
'value': [research_leve1],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
# 拉取满足过滤条件的所有数据
|
||||
result = entry_data_list({'api_key': api_key, 'entry_id': entry_id, 'filter': filter_not_empty})
|
||||
data_list = result.get("data")
|
||||
|
||||
all_data = []
|
||||
for data in data_list :
|
||||
# 先检查字段是否存在,避免KeyError
|
||||
if "_widget_1774235645156" in data and "_widget_1774235645158" in data:
|
||||
if research_leve2 in data["_widget_1774235645156"]:
|
||||
item = data["_widget_1774235645158"]
|
||||
if isinstance(item, list):
|
||||
all_data.extend(item)
|
||||
else:
|
||||
all_data.append(item)
|
||||
all_data = list(set(all_data))
|
||||
all_data = ["业绩管理","AI海报"]
|
||||
return {
|
||||
"all_data": ["业绩管理","AI海报"],
|
||||
"other":all_data
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
# 可以引用一些第三方库.
|
||||
import requests
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
version = str(triggerConf.get('_widget_17758020150661'))
|
||||
research_leve1 = triggerConf.get('_widget_17758020157781')
|
||||
research_leve2 = triggerConf.get('_widget_17758020169011')
|
||||
|
||||
# 统一处理可能是JSON字符串或者原生list的情况
|
||||
def parse_list_value(value):
|
||||
if isinstance(value, list):
|
||||
return value
|
||||
try:
|
||||
# 尝试解析JSON数组字符串
|
||||
return json.loads(value)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
# 解析失败就返回单个元素的列表
|
||||
return [str(value)]
|
||||
|
||||
research_leve1_list = parse_list_value(research_leve1)
|
||||
research_leve2_list = parse_list_value(research_leve2)
|
||||
|
||||
# 简道云 API 调用 Token(Bearer 形式)
|
||||
api_key="675b900991ad2491c69389ca"
|
||||
# 简道云 API 通用请求头
|
||||
entry_id ="69c0affbdef38560ddc3d0d0"
|
||||
|
||||
API_TOKEN = "Bearer qygHulymo1fekJk4CIZyNKjyQAzG8CFN"
|
||||
HEADERS = {'Authorization': API_TOKEN, 'Content-Type': 'application/json'}
|
||||
|
||||
def entry_data_list(
|
||||
data: Dict[str, Any],
|
||||
max_retries: int = 5,
|
||||
# 获取多条表单数据(自动分页:用上一页最后一条的 _id 作为 data_id)
|
||||
limit: int = 90,
|
||||
timeout: int = 10,
|
||||
) -> Dict[str, List[Dict[str, Any]]]:
|
||||
url = 'https://api.jiandaoyun.com/api/v5/app/entry/data/list'
|
||||
|
||||
all_rows: List[Dict[str, Any]] = []
|
||||
last_data_id: Optional[str] = None
|
||||
|
||||
while True:
|
||||
payload: Dict[str, Any] = {
|
||||
'app_id': data['api_key'],
|
||||
'entry_id': data['entry_id'],
|
||||
'limit': limit,
|
||||
'data_id': last_data_id,
|
||||
}
|
||||
if data.get('filter') is not None:
|
||||
payload['filter'] = data['filter']
|
||||
|
||||
body: Optional[Dict[str, Any]] = None
|
||||
for attempt in range(max_retries + 1):
|
||||
try:
|
||||
res = requests.post(url=url, json=payload, headers=HEADERS, timeout=timeout)
|
||||
res.raise_for_status()
|
||||
# 网络抖动/超时等异常,按最大重试次数重试
|
||||
body = res.json()
|
||||
break
|
||||
except requests.RequestException:
|
||||
if attempt >= max_retries:
|
||||
raise
|
||||
time.sleep(0.5)
|
||||
|
||||
batch = (body or {}).get('data') or []
|
||||
if not batch:
|
||||
# 下一页从本页最后一条数据之后继续拉取
|
||||
break
|
||||
|
||||
all_rows.extend(batch)
|
||||
last_data_id = batch[-1].get('_id')
|
||||
|
||||
return {'data': all_rows}
|
||||
filter_not_empty = {
|
||||
'rel': 'and',
|
||||
'cond': [
|
||||
{
|
||||
'field': '_widget_1774235645167',
|
||||
'type': 'text',
|
||||
'method': 'eq',
|
||||
'value': [version],
|
||||
},
|
||||
{
|
||||
'field': '_widget_1774235645172',
|
||||
'type': 'text',
|
||||
'method': 'eq',
|
||||
'value': research_leve1_list,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
# 拉取满足过滤条件的所有数据
|
||||
result = entry_data_list({'api_key': api_key, 'entry_id': entry_id, 'filter': filter_not_empty})
|
||||
data_list = result.get("data")
|
||||
|
||||
all_data = []
|
||||
for data in data_list :
|
||||
# 先检查字段是否存在,避免KeyError
|
||||
if "_widget_1774235645156" in data and "_widget_1774235645158" in data:
|
||||
field_value = data["_widget_1774235645156"]
|
||||
# 判断两个list是否有交集(只要有一个共同元素就算匹配)
|
||||
if any(item in field_value for item in research_leve2_list):
|
||||
item = data["_widget_1774235645158"]
|
||||
if isinstance(item, list):
|
||||
all_data.extend(item)
|
||||
else:
|
||||
all_data.append(item)
|
||||
all_data = list(set(all_data))
|
||||
return {
|
||||
"all_data": ["业绩管理","AI海报"],
|
||||
"other": all_data
|
||||
}
|
||||
Reference in New Issue
Block a user