from requests import get import time import os import pandas as pd import tqdm from datetime import datetime, timedelta teamId = 19 ip = "http://band.hxzhxy.cn" param = { "username": "xtl", "password": "xia123456", "client_id": "client", "grant_type": "password", "client_secret": "123456", } data = get(url=f"{ip}/oauth/token", params=param).json() token = data["access_token"] header = { "content-type": "application/json", "authorization": f"Bearer {token}", } url = f"{ip}/pay/trads/findPayTtadsNews" output_dir = r"e:\project\python\工具\智慧校园\本部\消费数据\24-26消费信息" FIELD_MAP = { "gradeName": "年级名称", "termName": "交易地点", "teamId": "团队ID", "stuId": "学生ID", "areaName": "设备区域名称", "bagName": "交易账户", "userNumb": "学号/工号", "dealCount": "交易流水号/笔次", "className": "班级名称", "remark": "备注/充值类型", "cardCode": "物理卡号", "dealType": "消费方式", "cardValue": "余额", "userXm": "姓名", "cardNo": "卡号", "createDate": "入库时间", "dealValue": "交易金额", "recordType": "记录类型", "id": "记录ID", "recordId": "终端原始记录ID", "userId": "用户唯一ID", "dealTime": "交易时间" } OUTPUT_COLUMNS = list(FIELD_MAP.values()) def day_range(start_date, end_date): current = start_date while current <= end_date: yield current current += timedelta(days=1) def month_range(start_date, end_date): current = datetime(start_date.year, start_date.month, 1) end_month = datetime(end_date.year, end_date.month, 1) while current <= end_month: yield current if current.month == 12: current = datetime(current.year + 1, 1, 1) else: current = datetime(current.year, current.month + 1, 1) def to_timestamp_ms(dt): return int(dt.timestamp() * 1000) def fetch_day_records(day_dt): day_start = datetime(day_dt.year, day_dt.month, day_dt.day, 0, 0, 0) day_end = datetime(day_dt.year, day_dt.month, day_dt.day, 23, 59, 59) begin_time = to_timestamp_ms(day_start) end_time = to_timestamp_ms(day_end) page_number = 0 page_size = 100 day_records = [] while True: params = { "teamId": teamId, "pageNumber": page_number, "pageSize": page_size, "screen": 1, "beginTime": begin_time, "endTime": end_time, "name": "", "recordType": 1, "termName": "", "type": 1, "classId": "", "gradeId": "" } resp = get(url=url, params=params, headers=header, timeout=60) resp.raise_for_status() result = resp.json() if not result.get("success"): raise Exception(f"接口返回失败: {result}") data = result.get("data") or {} content = data.get("content") or [] total_pages = data.get("totalPages", 0) total_elements = data.get("totalElements", 0) day_records.extend(content) print( f"{day_dt.strftime('%Y-%m-%d')} 第 {page_number + 1}/{max(total_pages, 1)} 页," f"当前页 {len(content)} 条,当天累计 {len(day_records)} 条,总计 {total_elements} 条" ) page_number += 1 if page_number >= total_pages or total_pages == 0: break time.sleep(0.1) return day_records def parse_date(date_str): return datetime.strptime(date_str, "%Y-%m-%d") def convert_records_to_df(records): rows = [] for record in records: row = {} for en_key, cn_key in FIELD_MAP.items(): row[cn_key] = record.get(en_key) rows.append(row) if not rows: return pd.DataFrame(columns=OUTPUT_COLUMNS) return pd.DataFrame(rows, columns=OUTPUT_COLUMNS) def get_month_start_end(month_dt, start_date, end_date): month_start = datetime(month_dt.year, month_dt.month, 1) if month_dt.month == 12: next_month = datetime(month_dt.year + 1, 1, 1) else: next_month = datetime(month_dt.year, month_dt.month + 1, 1) month_end = next_month - timedelta(days=1) if month_start < start_date: month_start = start_date if month_end > end_date: month_end = end_date return month_start, month_end def save_month_excel(month_dt, records): df = convert_records_to_df(records) file_name = f"{month_dt.strftime('%Y%m')}_学生消费记录.xlsx" file_path = os.path.join(output_dir, file_name) df.to_excel(file_path, index=False) return file_path, len(df) def main(): print("开始拉取数据...") start_date_str = os.getenv("START_DATE", "2024-01-01") end_date_str = os.getenv("END_DATE", "2026-05-19") start_date = parse_date(start_date_str) end_date = parse_date(end_date_str) all_month_list = list(month_range(start_date, end_date)) total_records = 0 success_months = 0 with tqdm.tqdm(all_month_list, desc="按月拉取消费记录") as month_pbar: for month_dt in month_pbar: try: month_start, month_end = get_month_start_end(month_dt, start_date, end_date) month_records = [] month_days = list(day_range(month_start, month_end)) for day_dt in month_days: day_records = fetch_day_records(day_dt) month_records.extend(day_records) time.sleep(0.2) file_path, count = save_month_excel(month_dt, month_records) total_records += count success_months += 1 month_pbar.set_postfix({ "month": month_dt.strftime("%Y-%m"), "count": count, "total": total_records }) print(f"已输出: {file_path}") except Exception as e: print(f"{month_dt.strftime('%Y-%m')} 拉取失败: {e}") print("\n完成") print(f"成功月份: {success_months}") print(f"总记录数: {total_records}") print(f"输出目录: {output_dir}") if __name__ == "__main__": main()