import time import json import redis import requests import urllib3 from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry from typing import Optional, Dict, Any, Union class HttpClient: def __init__(self, max_retries: int = 3, backoff_factor: float = 0.5): self.session = requests.Session() # 配置重试策略 retry_strategy = Retry( total=max_retries, backoff_factor=backoff_factor, status_forcelist=[500, 502, 503, 504, 429] ) adapter = HTTPAdapter(max_retries=retry_strategy) self.session.mount("http://", adapter) self.session.mount("https://", adapter) def request(self, method: str, url: str, headers: Optional[Dict] = None, params: Optional[Dict] = None, data: Optional[Union[Dict, str]] = None, cookies: Optional[Dict] = None, allow_redirects: bool = True, timeout: int = 30, **kwargs) -> requests.Response: try: response = self.session.request( method=method, url=url, headers=headers, params=params, data=data, cookies=cookies, allow_redirects=allow_redirects, timeout=timeout, **kwargs ) response.raise_for_status() return response except requests.exceptions.RequestException as e: print(f"请求失败: {url}, 错误: {str(e)}") raise def get(self, url: str, **kwargs) -> requests.Response: return self.request("GET", url, **kwargs) def post(self, url: str, **kwargs) -> requests.Response: return self.request("POST", url, **kwargs) # 创建全局的 HTTP 客户端实例 http_client = HttpClient() _REDIS_CONF = { "host": "192.144.230.75", "port": 6379, "password": "qwert@$123!&", "decode_responses": True, "db": 1, } def save_report_token(key_name: str, json_data: dict): r = redis.Redis(**_REDIS_CONF) key = key_name json_str = json.dumps(json_data, ensure_ascii=False) r.set(key, json_str) print(f"已在 Redis(DB {_REDIS_CONF['db']}) 中写入 key -> {key}") def get_report_token(key_name: str): r = redis.Redis(**_REDIS_CONF) key = key_name json_str = r.get(key) if not json_str: return None return json.loads(json_str) def login(): try: headers = { "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "no-cache", "Connection": "keep-alive", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://www.dailymotion.com", "Pragma": "no-cache", "Referer": "https://www.dailymotion.com/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0", "sec-ch-ua": "\"Chromium\";v=\"136\", \"Microsoft Edge\";v=\"136\", \"Not.A/Brand\";v=\"99\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"" } url = "https://graphql.api.dailymotion.com/oauth/token" data = { "client_id": "f1a362d288c1b98099c7", "client_secret": "eea605b96e01c796ff369935357eca920c5da4c5", "grant_type": "password", "username": "copyright@qiyi.com", "password": "ppsIQIYI2018@", "scope": "userinfo,email,manage_subscriptions,manage_history,manage_likes,manage_playlists,manage_videos", "version": "2", "traffic_segment": "962042", "visitor_id": "359703fb-66c2-43d2-bd0d-b1cac9c7ae8a" } response = http_client.post(url, headers=headers, data=data) data = { "update_time": int(time.time()), "username": "copyright@qiyi.com", "password": "ppsIQIYI2018@", "token": response.json() } save_report_token('token', data) return data except Exception as e: print(f"登录失败: {str(e)}") raise def get_cookies(access_token: str, refresh_token: str): try: cookies = { "access_token": access_token, "refresh_token": refresh_token, } url = "https://www.dailymotion.com/cookie/refresh_token" http_client.post(url, cookies=cookies, allow_redirects=True) except Exception as e: print(f"刷新 cookie 失败: {str(e)}") raise def get_cookies1(access_token: str, refresh_token: str): """302 跳转""" try: cookies = { "access_token": access_token, "refresh_token": refresh_token, } url = "https://www.dailymotion.com/zendesk" params = { "return_to": "https://faq.dailymotion.com/hc/en-us/requests/new", "timestamp": str(int(time.time())), } response = http_client.get(url, cookies=cookies, params=params, allow_redirects=True) cookies_dict = {"update_time": int(time.time()), "cookies": dict(http_client.session.cookies)} save_report_token('cookies', cookies_dict) return cookies_dict except Exception as e: print(f"获取 cookies 失败: {str(e)}") raise def get_csrftoken(): try: url = "https://faq.dailymotion.com/hc/api/internal/csrf_token.json" response = http_client.get(url) data = {"update_time": int(time.time()), "csrf_token": response.json()} save_report_token('csrf_token', data) return data except Exception as e: print(f"获取 CSRF token 失败: {str(e)}") raise def report(csrf_token:str, cookies:dict): try: headers = { "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "no-cache", "Connection": "keep-alive", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": "https://faq.dailymotion.com", "Pragma": "no-cache", "Referer": "https://faq.dailymotion.com/hc/en-us/requests/new", "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/136.0.0.0 Safari/537.36 Edg/136.0.0.0", "sec-ch-ua": "\"Chromium\";v=\"136\", \"Microsoft Edge\";v=\"136\", \"Not.A/Brand\";v=\"99\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "X-CSRF-Token": csrf_token } data = { "request[subject]": "版权投诉", "request[description]": "请删除侵权视频", "request[email]": "copyright@qiyi.com", "request[ticket_form_id]": "360000717219" } response = http_client.post('https://faq.dailymotion.com/hc/en-us/requests', cookies=cookies, headers=headers, data=data) return response.status_code == 200 except Exception as e: print(f"提交报告失败: {str(e)}") raise def prepare_data(): try: token = get_report_token('token') cookies = get_report_token('cookies') csrf_token = get_report_token('csrf_token') min_update_time = min(d.get('update_time', 0) for d in (token, cookies, csrf_token) if d) if not min_update_time or min_update_time + (24 * 60 * 60) < time.time(): token = login() if not token: raise Exception("登录失败") access_token = token['token']['access_token'] refresh_token = token['token']['refresh_token'] get_cookies(access_token, refresh_token) cookies = get_cookies1(access_token, refresh_token) csrf_token = get_csrftoken() if not all([cookies, csrf_token]): raise Exception("获取 cookies 或 csrf_token 失败") if not all([token, cookies, csrf_token]): raise Exception("获取令牌失败") success = report(csrf_token['csrf_token']['current_session']['csrf_token'], cookies['cookies']) if not success: raise Exception("提交投诉失败") except Exception as e: print(f"处理数据失败: {str(e)}") raise