337 lines
13 KiB
Python
337 lines
13 KiB
Python
from pathlib import Path
|
|
import traceback
|
|
import requests
|
|
import json
|
|
import time
|
|
from datetime import datetime
|
|
from tqdm import tqdm
|
|
import pandas as pd
|
|
import os
|
|
|
|
#+
|
|
# f6_module = F6_module()
|
|
#
|
|
# # 1.向服务器发送请求登录
|
|
# username = "13799889725"
|
|
# password = "Lc1234"
|
|
# store_name = "禹城榕桦"
|
|
module = 1
|
|
#
|
|
# res = f6_module.login_in(username, password, store_name)
|
|
# # cookies = requests.utils.dict_from_cookiejar(res.cookies)
|
|
|
|
cookies = {
|
|
'memberSESSIONID': '639e52b2-1260-47a9-8d0b-d0cd41054738',
|
|
'erpLanguage': 'zh-CN',
|
|
'tmall': 'false',
|
|
'Hm_lvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1776909170,1776923216,1777270359,1777277857',
|
|
'HMACCOUNT': 'A6A0585E8C70051D',
|
|
'unp': '16023446149142708289',
|
|
'un': '16023446149142708289',
|
|
'_up': '-NillNN-qyBEJ--t3vnSknvoOF1_z_KJtMsE13I-XuVaVvnDr5DQjaZJ9Q3d-WrAAGgt60MgQHajHWBHMKKxj0CuWypi1JgKCFP1EPEk-HbqE_QQq4Ml3wcK_PBRv-ZNHu3M-GTf3pqyEXOur-lciO8Yl1bLPBtmrEj90x3BhsH6PGY.',
|
|
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2216023446149142708289%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',
|
|
'prodOrg': '16070511835941490720',
|
|
'Hm_lpvt_25f5e7a3a5dbb293d7dd35d5f1be8d0a': '1777428810',
|
|
}
|
|
|
|
print("cookies loaded")
|
|
|
|
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"C:\Users\hp_z66\Desktop\客户信息.xlsx",sheet_name="客户信息").astype(str)
|
|
|
|
|
|
if module == 1: # 客户信息删除
|
|
# --- 初始化日志列表 ---
|
|
delete_logs = [] # 删除操作日志
|
|
query_logs = [] # 查询日志
|
|
|
|
# --- 1. 数据准备 ---
|
|
df['手机号码'] = df['手机号码'].astype(str).str.strip().str.replace('.0$', '', regex=True)
|
|
df['手机号码'].dropna(inplace=True)
|
|
# 将需要删除的手机号转为集合,查询速度更快
|
|
phones_to_delete = set(df['手机号码'].values)
|
|
print(f"待删除手机号数量: {len(phones_to_delete)}")
|
|
|
|
# --- 2. 分页查询所有客户 ---
|
|
base_url = "https://yunxiu.f6car.cn/member/customer/listForPermission"
|
|
id_own_org = "16070511835941490720"
|
|
page_size = 100
|
|
page_no = 1
|
|
|
|
all_customers = []
|
|
|
|
print("正在获取所有客户数据...")
|
|
while True:
|
|
params = {
|
|
"idOwnOrg": id_own_org,
|
|
"pageSize": page_size,
|
|
"pageNo": page_no
|
|
}
|
|
try:
|
|
res = requests.get(base_url, params=params, cookies=cookies)
|
|
query_log = {
|
|
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"module": module,
|
|
"action": "customer_list_page",
|
|
"url": res.url,
|
|
"page_no": page_no
|
|
}
|
|
query_log["status_code"] = getattr(res, "status_code", None)
|
|
query_log["ok"] = getattr(res, "ok", None)
|
|
|
|
data = res.json()
|
|
query_log["response_json"] = json.dumps(data, ensure_ascii=False)
|
|
request_results.append(query_log)
|
|
query_logs.append(query_log)
|
|
|
|
# 获取当前页的数据列表
|
|
page_data = data.get('data', {}).get('data', [])
|
|
|
|
# 如果当前页没有数据了,说明已经取完,跳出循环
|
|
if not page_data:
|
|
print(f"第 {page_no} 页没有数据了,获取完毕。")
|
|
break
|
|
|
|
all_customers.extend(page_data)
|
|
print(f"已获取第 {page_no} 页,共 {len(page_data)} 条数据。累计获取: {len(all_customers)} 条")
|
|
|
|
page_no += 1
|
|
time.sleep(0.5)
|
|
|
|
except Exception as e:
|
|
print(f"获取第 {page_no} 页数据时出错: {e}")
|
|
error_log = {
|
|
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"module": module,
|
|
"action": "customer_list_error",
|
|
"page_no": page_no,
|
|
"error": str(e)
|
|
}
|
|
query_logs.append(error_log)
|
|
break
|
|
|
|
# --- 3. 遍历所有客户并执行删除 ---
|
|
print(f"开始处理删除操作,共需检查 {len(all_customers)} 个客户...")
|
|
|
|
success_count = 0
|
|
failed_count = 0
|
|
|
|
for item in tqdm(all_customers):
|
|
try:
|
|
idCustomer = item['idCustomer']
|
|
phone = item['cellPhone']
|
|
phone_clean = str(phone).strip().replace('.0', '')
|
|
|
|
# 检查手机号是否在待删除列表中
|
|
if phone_clean in phones_to_delete:
|
|
print(f"\n正在删除: {phone_clean}")
|
|
url = f"https://yunxiu.f6car.cn/member/customer/{idCustomer}"
|
|
|
|
# 记录删除开始
|
|
delete_log = {
|
|
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"module": module,
|
|
"action": "customer_delete",
|
|
"url": url,
|
|
"idCustomer": idCustomer,
|
|
"cellPhone": phone_clean,
|
|
}
|
|
|
|
res = requests.delete(url, cookies=cookies)
|
|
|
|
delete_log["status_code"] = getattr(res, "status_code", None)
|
|
delete_log["ok"] = getattr(res, "ok", None)
|
|
|
|
# 解析响应
|
|
try:
|
|
response_data = res.json()
|
|
delete_log["response_json"] = json.dumps(response_data, ensure_ascii=False)
|
|
delete_log["response_code"] = response_data.get('code', '')
|
|
delete_log["response_msg"] = response_data.get('msg', '')
|
|
except Exception:
|
|
delete_log["response_text"] = res.text
|
|
delete_log["response_code"] = ''
|
|
delete_log["response_msg"] = '响应解析失败'
|
|
|
|
# 判断删除是否成功
|
|
if res.ok and delete_log.get("response_code") == 200:
|
|
delete_log["delete_status"] = "成功"
|
|
success_count += 1
|
|
print(f"✓ 成功删除: {phone_clean}")
|
|
else:
|
|
delete_log["delete_status"] = "失败"
|
|
failed_count += 1
|
|
print(f"✗ 删除失败: {phone_clean}")
|
|
|
|
request_results.append(delete_log)
|
|
delete_logs.append(delete_log)
|
|
|
|
# 打印详细结果
|
|
try:
|
|
print(response_data)
|
|
except:
|
|
print(res.text[:200]) # 只打印前200个字符
|
|
|
|
time.sleep(3)
|
|
|
|
except Exception as e:
|
|
# 记录异常情况
|
|
error_log = {
|
|
"ts": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
"module": module,
|
|
"action": "customer_delete_error",
|
|
"idCustomer": item.get('idCustomer', '未知'),
|
|
"cellPhone": phone_clean if 'phone_clean' in locals() else item.get('cellPhone', '未知'),
|
|
"error": str(e),
|
|
"delete_status": "异常"
|
|
}
|
|
delete_logs.append(error_log)
|
|
failed_count += 1
|
|
print(f"处理客户 {item.get('idCustomer', '未知')} 时出错: {e}")
|
|
|
|
# --- 4. 保存日志到Excel文件 ---
|
|
print("\n正在保存日志文件...")
|
|
|
|
# 创建日志目录
|
|
log_dir = "delete_logs"
|
|
if not os.path.exists(log_dir):
|
|
os.makedirs(log_dir)
|
|
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
# 保存删除操作日志
|
|
if delete_logs:
|
|
df_delete_logs = pd.DataFrame(delete_logs)
|
|
|
|
# 选择要保存的列(可根据需要调整)
|
|
columns_to_save = [
|
|
"ts", "action", "idCustomer", "cellPhone",
|
|
"delete_status", "status_code", "ok",
|
|
"response_code", "response_msg", "error"
|
|
]
|
|
|
|
# 只保存存在的列
|
|
existing_columns = [col for col in columns_to_save if col in df_delete_logs.columns]
|
|
df_delete_logs = df_delete_logs[existing_columns]
|
|
|
|
delete_log_file = f"{log_dir}/删除操作日志_{timestamp}.xlsx"
|
|
df_delete_logs.to_excel(delete_log_file, index=False, engine='openpyxl')
|
|
print(f"删除操作日志已保存到: {delete_log_file}")
|
|
|
|
# 保存查询日志
|
|
if query_logs:
|
|
df_query_logs = pd.DataFrame(query_logs)
|
|
query_log_file = f"{log_dir}/查询日志_{timestamp}.xlsx"
|
|
df_query_logs.to_excel(query_log_file, index=False, engine='openpyxl')
|
|
print(f"查询日志已保存到: {query_log_file}")
|
|
|
|
# 保存汇总信息
|
|
summary_data = {
|
|
"项目": ["待删除手机号数量", "查询到的客户总数", "实际执行删除数", "删除成功", "删除失败", "执行时间"],
|
|
"数值": [
|
|
len(phones_to_delete),
|
|
len(all_customers),
|
|
success_count + failed_count,
|
|
success_count,
|
|
failed_count,
|
|
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
]
|
|
}
|
|
df_summary = pd.DataFrame(summary_data)
|
|
summary_file = f"{log_dir}/删除汇总_{timestamp}.xlsx"
|
|
df_summary.to_excel(summary_file, index=False, engine='openpyxl')
|
|
print(f"删除汇总已保存到: {summary_file}")
|
|
|
|
# 打印最终统计
|
|
print("\n" + "=" * 50)
|
|
print("删除操作完成!")
|
|
print(f"待删除手机号: {len(phones_to_delete)} 个")
|
|
print(f"查询到客户总数: {len(all_customers)} 个")
|
|
print(f"实际执行删除: {success_count + failed_count} 次")
|
|
print(f"删除成功: {success_count} 个")
|
|
print(f"删除失败/异常: {failed_count} 个")
|
|
print(f"日志文件保存在: {log_dir}/ 目录下")
|
|
print("=" * 50)
|
|
|
|
if module == 2: # 客户车辆信息删除
|
|
for index, row in tqdm(df.iterrows(), total=len(df)):
|
|
car_number = row['车牌号']
|
|
car_Id = row["carId"]
|
|
customerId = row["customerId"]
|
|
|
|
try:
|
|
# print("删除:", car_number)
|
|
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)
|
|
|
|
now = datetime.now()
|
|
if now.hour >= 20:
|
|
time.sleep(1)
|
|
else:
|
|
time.sleep(3)
|
|
except:
|
|
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
|