340 lines
12 KiB
Python
340 lines
12 KiB
Python
|
# # -*- coding: utf-8 -*-
|
|||
|
# """
|
|||
|
# @Time : 2025/8/1 10:53
|
|||
|
# @Auth : 九月的海
|
|||
|
# @File : cookie.py
|
|||
|
# @IDE : PyCharm
|
|||
|
# @Motto : Catch as catch can....
|
|||
|
# """
|
|||
|
# import requests
|
|||
|
# from datetime import datetime, timedelta
|
|||
|
# import json
|
|||
|
# import logging
|
|||
|
# import http.client
|
|||
|
# import urllib3
|
|||
|
#
|
|||
|
# # 启用详细日志记录
|
|||
|
# urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|||
|
# http.client.HTTPConnection.debuglevel = 1
|
|||
|
#
|
|||
|
# # 配置更详细的日志
|
|||
|
# logging.basicConfig(level=logging.DEBUG)
|
|||
|
# logger = logging.getLogger('requests.packages.urllib3')
|
|||
|
# logger.setLevel(logging.DEBUG)
|
|||
|
# logger.propagate = True
|
|||
|
#
|
|||
|
#
|
|||
|
# # 创建自定义的 HTTP 适配器用于记录请求/响应细节
|
|||
|
# class DebugHTTPAdapter(requests.adapters.HTTPAdapter):
|
|||
|
# def send(self, request, **kwargs):
|
|||
|
# """发送请求并记录所有细节"""
|
|||
|
# # 记录请求详情
|
|||
|
# print("\n" + "=" * 40)
|
|||
|
# print(f"请求方法: {request.method}")
|
|||
|
# print(f"请求URL: {request.url}")
|
|||
|
# print("请求头:")
|
|||
|
# for key, value in request.headers.items():
|
|||
|
# print(f" {key}: {value}")
|
|||
|
#
|
|||
|
# if request.body:
|
|||
|
# print("请求体:")
|
|||
|
# if isinstance(request.body, bytes):
|
|||
|
# try:
|
|||
|
# body = request.body.decode('utf-8')
|
|||
|
# print(body)
|
|||
|
# except UnicodeDecodeError:
|
|||
|
# print("<无法解码的二进制数据>")
|
|||
|
# else:
|
|||
|
# print(request.body)
|
|||
|
# else:
|
|||
|
# print("无请求体")
|
|||
|
#
|
|||
|
# # 发送请求
|
|||
|
# response = super().send(request, **kwargs)
|
|||
|
#
|
|||
|
# # 记录响应详情
|
|||
|
# print("\n" + "=" * 40)
|
|||
|
# print(f"响应状态码: {response.status_code}")
|
|||
|
# print("响应头:")
|
|||
|
# for key, value in response.headers.items():
|
|||
|
# print(f" {key}: {value}")
|
|||
|
#
|
|||
|
# # 尝试解析JSON响应体
|
|||
|
# try:
|
|||
|
# if response.text:
|
|||
|
# print("响应内容:")
|
|||
|
# # 尝试格式化为可读JSON
|
|||
|
# try:
|
|||
|
# json_data = json.loads(response.text)
|
|||
|
# print(json.dumps(json_data, indent=2, ensure_ascii=False))
|
|||
|
# except json.JSONDecodeError:
|
|||
|
# print(response.text)
|
|||
|
# else:
|
|||
|
# print("无响应内容")
|
|||
|
# except Exception as e:
|
|||
|
# print(f"解析响应失败: {e}")
|
|||
|
#
|
|||
|
# print("=" * 40 + "\n")
|
|||
|
#
|
|||
|
# return response
|
|||
|
#
|
|||
|
#
|
|||
|
# class MobgiAPIClient:
|
|||
|
# def __init__(self):
|
|||
|
# self.session = requests.Session()
|
|||
|
#
|
|||
|
# # 添加调试适配器
|
|||
|
# adapter = DebugHTTPAdapter()
|
|||
|
# self.session.mount('http://', adapter)
|
|||
|
# self.session.mount('https://', adapter)
|
|||
|
#
|
|||
|
# self.login_time = None
|
|||
|
# self.expire_time = None
|
|||
|
# self.api_base = "https://cli1.mobgi.com"
|
|||
|
# self.is_logged_in = False
|
|||
|
# self.session_cookie = None
|
|||
|
# self.user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
|
|||
|
#
|
|||
|
# def login(self, email, password, expire_hours=24):
|
|||
|
# """登录并保存会话状态"""
|
|||
|
# # 清除可能的旧会话
|
|||
|
# self.session.cookies.clear()
|
|||
|
# self.is_logged_in = False
|
|||
|
# url = f"{self.api_base}/User/AdminUser/login"
|
|||
|
# payload = {"email": email, "password": password, "product_version": 0}
|
|||
|
# try:
|
|||
|
# # 登录请求使用独立的 headers
|
|||
|
# headers = {
|
|||
|
# "Content-Type": "application/json",
|
|||
|
# "User-Agent": self.user_agent
|
|||
|
# }
|
|||
|
# # 打印登录请求细节
|
|||
|
# print("\n" + "*" * 50)
|
|||
|
# print("发送登录请求...")
|
|||
|
# print("*" * 50 + "\n")
|
|||
|
# response = self.session.post(
|
|||
|
# url,
|
|||
|
# json=payload,
|
|||
|
# headers=headers,
|
|||
|
# timeout=10
|
|||
|
# )
|
|||
|
# response.raise_for_status()
|
|||
|
# # 解析响应
|
|||
|
# resp_data = response.json()
|
|||
|
# if resp_data.get('code') != 0:
|
|||
|
# print(f"登录失败: {resp_data.get('message', '未知错误')}")
|
|||
|
# print(f"完整响应: {json.dumps(resp_data, indent=2)}")
|
|||
|
# return False
|
|||
|
# # 提取并保存会话 cookie
|
|||
|
# self.session_cookie = self._extract_session_cookie(response)
|
|||
|
#
|
|||
|
# if not self.session_cookie:
|
|||
|
# print("ERROR: 未能获取会话cookie")
|
|||
|
# if 'Set-Cookie' in response.headers:
|
|||
|
# print(f"Set-Cookie 头: {response.headers['Set-Cookie']}")
|
|||
|
# else:
|
|||
|
# print("响应中没有 Set-Cookie 头")
|
|||
|
# return False
|
|||
|
#
|
|||
|
# # 更新登录状态
|
|||
|
# self.login_time = datetime.now()
|
|||
|
# self.expire_time = self.login_time + timedelta(hours=expire_hours)
|
|||
|
# self.is_logged_in = True
|
|||
|
#
|
|||
|
# print(f"登录成功! 会话有效期至 {self.expire_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
|||
|
# print(f"获取的会话Cookie: {self.session_cookie}")
|
|||
|
# return True
|
|||
|
#
|
|||
|
# except requests.exceptions.RequestException as e:
|
|||
|
# print(f"登录请求异常: {str(e)}")
|
|||
|
# if e.response is not None:
|
|||
|
# print(f"响应状态码: {e.response.status_code}")
|
|||
|
# try:
|
|||
|
# print(f"响应内容: {e.response.text}")
|
|||
|
# except:
|
|||
|
# pass
|
|||
|
# return False
|
|||
|
# except json.JSONDecodeError as e:
|
|||
|
# print(f"登录响应解析失败: 无效的JSON格式, 原始内容: {response.text}")
|
|||
|
# return False
|
|||
|
# except Exception as e:
|
|||
|
# print(f"登录过程中发生意外错误: {str(e)}")
|
|||
|
# return False
|
|||
|
#
|
|||
|
# def _extract_session_cookie(self, response):
|
|||
|
# """从响应中提取会话cookie"""
|
|||
|
# # 方法1: 从cookies字典获取
|
|||
|
# if 'chuangliang_session' in response.cookies:
|
|||
|
# cookie_value = response.cookies['chuangliang_session']
|
|||
|
# return f"chuangliang_session={cookie_value};"
|
|||
|
#
|
|||
|
# # 方法2: 从Set-Cookie头获取
|
|||
|
# if 'Set-Cookie' in response.headers:
|
|||
|
# set_cookie = response.headers['Set-Cookie']
|
|||
|
# # 寻找chuangliang_session条目
|
|||
|
# for cookie_str in set_cookie.split(','):
|
|||
|
# if 'chuangliang_session' in cookie_str:
|
|||
|
# # 提取cookie值
|
|||
|
# parts = cookie_str.split(';')
|
|||
|
# for part in parts:
|
|||
|
# if 'chuangliang_session' in part:
|
|||
|
# return part.strip() + ';'
|
|||
|
#
|
|||
|
# # 方法3: 如果cookie是多个值,可能在cookie jar中
|
|||
|
# for cookie in response.cookies:
|
|||
|
# if cookie.name == 'chuangliang_session':
|
|||
|
# return f"{cookie.name}={cookie.value};"
|
|||
|
#
|
|||
|
# return None
|
|||
|
#
|
|||
|
# def _get_request_headers(self):
|
|||
|
# """构造请求头,包含必要的cookie"""
|
|||
|
# headers = {
|
|||
|
# "Content-Type": "application/json",
|
|||
|
# "User-Agent": self.user_agent,
|
|||
|
# # 添加其他可能需要的通用头
|
|||
|
# }
|
|||
|
#
|
|||
|
# if self.session_cookie:
|
|||
|
# # 将会话 cookie 添加到 headers
|
|||
|
# headers["Cookie"] = self.session_cookie
|
|||
|
#
|
|||
|
# return headers
|
|||
|
#
|
|||
|
# def check_session(self):
|
|||
|
# """检查会话有效性"""
|
|||
|
# if not self.is_logged_in or not self.expire_time:
|
|||
|
# print("会话未初始化,请先登录")
|
|||
|
# return False
|
|||
|
#
|
|||
|
# if datetime.now() > self.expire_time:
|
|||
|
# print(f"会话已过期,有效期至 {self.expire_time.strftime('%Y-%m-%d %H:%M:%S')}")
|
|||
|
# return False
|
|||
|
#
|
|||
|
# return True
|
|||
|
#
|
|||
|
# def get_advertiser_list(
|
|||
|
# self,
|
|||
|
# start_date="2025-07-31",
|
|||
|
# end_date="2025-07-31",
|
|||
|
# conditions=None,
|
|||
|
# page=1,
|
|||
|
# page_size=20
|
|||
|
# ):
|
|||
|
# """获取广告主列表数据"""
|
|||
|
# if not self.check_session():
|
|||
|
# return None
|
|||
|
#
|
|||
|
# # 准备请求参数
|
|||
|
# params = {
|
|||
|
# "conditions": json.dumps(conditions) if conditions else json.dumps({
|
|||
|
# "companys": [],
|
|||
|
# "cl_project_id": [],
|
|||
|
# "optimize_user_id": [],
|
|||
|
# "keyword": ""
|
|||
|
# }),
|
|||
|
# "start_date": start_date,
|
|||
|
# "end_date": end_date,
|
|||
|
# "page": page,
|
|||
|
# "page_size": page_size,
|
|||
|
# "total_count": 0,
|
|||
|
# "total_page": 1,
|
|||
|
# "sort_field": "",
|
|||
|
# "sort_direction": "",
|
|||
|
# "data_type": "list"
|
|||
|
# }
|
|||
|
#
|
|||
|
# url = f"{self.api_base}/Baidu/Advertiser/getList"
|
|||
|
#
|
|||
|
# try:
|
|||
|
# # 获取带 cookie 的 headers
|
|||
|
# headers = self._get_request_headers()
|
|||
|
#
|
|||
|
# # 打印API请求细节
|
|||
|
# print("\n" + "*" * 50)
|
|||
|
# print(f"发送广告主列表请求到: {url}")
|
|||
|
# print("*" * 50 + "\n")
|
|||
|
#
|
|||
|
# response = self.session.post(
|
|||
|
# url,
|
|||
|
# json=params,
|
|||
|
# headers=headers,
|
|||
|
# timeout=15
|
|||
|
# )
|
|||
|
# response.raise_for_status()
|
|||
|
#
|
|||
|
# # 检查是否有新的cookie
|
|||
|
# if 'Set-Cookie' in response.headers:
|
|||
|
# new_cookie = self._extract_session_cookie(response)
|
|||
|
# if new_cookie:
|
|||
|
# print(f"接收到新cookie: {new_cookie}")
|
|||
|
# self.session_cookie = new_cookie
|
|||
|
# else:
|
|||
|
# print("响应包含Set-Cookie,但未解析出有效值")
|
|||
|
#
|
|||
|
# resp_data = response.json()
|
|||
|
# if resp_data.get('code') != 0:
|
|||
|
# print(f"广告主列表请求失败: {resp_data.get('message', '未知错误')}")
|
|||
|
# print(f"完整响应: {json.dumps(resp_data, indent=2)}")
|
|||
|
# return None
|
|||
|
#
|
|||
|
# return resp_data.get('data', {})
|
|||
|
#
|
|||
|
# except requests.exceptions.RequestException as e:
|
|||
|
# print(f"广告主列表请求异常: {str(e)}")
|
|||
|
# if e.response is not None:
|
|||
|
# print(f"响应状态码: {e.response.status_code}")
|
|||
|
# try:
|
|||
|
# print(f"响应内容: {e.response.text}")
|
|||
|
# except:
|
|||
|
# pass
|
|||
|
# return None
|
|||
|
# except json.JSONDecodeError:
|
|||
|
# print(f"广告主列表响应解析失败: 无效的JSON格式, 原始内容: {response.text}")
|
|||
|
# return None
|
|||
|
# except Exception as e:
|
|||
|
# print(f"广告主列表请求过程中发生意外错误: {str(e)}")
|
|||
|
# return None
|
|||
|
#
|
|||
|
# def __del__(self):
|
|||
|
# """关闭会话"""
|
|||
|
# self.session.close()
|
|||
|
# print("会话已关闭")
|
|||
|
#
|
|||
|
#
|
|||
|
# # 使用示例
|
|||
|
# if __name__ == "__main__":
|
|||
|
# print("=" * 60)
|
|||
|
# print("启动 API 客户端调试")
|
|||
|
# print("=" * 60)
|
|||
|
#
|
|||
|
# # 初始化客户端
|
|||
|
# client = MobgiAPIClient()
|
|||
|
#
|
|||
|
# # 登录(使用您提供的凭证)
|
|||
|
# if client.login(
|
|||
|
# email="974509022@qq.com",
|
|||
|
# password="0e3bc01f8f0409f4541015737925ed8e"
|
|||
|
# ):
|
|||
|
# print("\n登录成功! 尝试获取广告主列表...")
|
|||
|
#
|
|||
|
# # 获取广告主列表
|
|||
|
# advertiser_data = client.get_advertiser_list(
|
|||
|
# start_date="2025-07-01",
|
|||
|
# end_date="2025-07-31",
|
|||
|
# conditions=None,
|
|||
|
# page=1,
|
|||
|
# page_size=50
|
|||
|
# )
|
|||
|
#
|
|||
|
# if advertiser_data:
|
|||
|
# print("\n成功获取广告主列表数据:")
|
|||
|
# print(f"总记录数: {advertiser_data.get('total_count', 0)}")
|
|||
|
# print(f"总页数: {advertiser_data.get('total_page', 1)}")
|
|||
|
# print(f"返回记录数: {len(advertiser_data.get('list', []))}")
|
|||
|
# else:
|
|||
|
# print("\n获取广告主列表失败")
|
|||
|
# else:
|
|||
|
# print("\n登录失败,无法继续")
|
|||
|
#
|
|||
|
# print("\n调试结束")
|