import requests
from bs4 import BeautifulSoup
import json
from urllib.parse import quote
import time
# import certifi # 不再需要 certifi
import urllib3
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm
import os

# --- 配置 ---
# !! 修改这里的路径为你实际的文件路径 !!
INPUT_FILE_PATH = '/content/drive/MyDrive/vocable_list.json'
OUTPUT_FILE_PATH = '/content/drive/MyDrive/vocable_results.json'

BASE_URL = "https://koshashri-dc.ac.in"
# API URL 模板，我们将使用它来构造请求
API_URL_TEMPLATE = BASE_URL + "/search/basicSearch/1/500?facetRequired=true&isHighlightRequired=true"

# 并发线程数，可以根据您的网络情况调整。10-20 通常是个不错的开始。
MAX_WORKERS = 15 

# 禁用因忽略SSL验证而产生的警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def setup_session_and_token():
    """
    初始化一个 requests.Session 并获取 CSRF 令牌。
    这个函数只在程序开始时运行一次。
    """
    print("[*] 正在初始化 Session 并获取安全令牌...")
    session = requests.Session()
    
    # ************************ 关键修改点 ************************
    # 关闭 SSL 证书验证
    session.verify = False
    # **********************************************************
    
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    })

    try:
        # 我们需要访问任意一个页面来获取初始cookie和CSRF令牌
        initial_url = f"{BASE_URL}/search/searchResult/1/10?searchTerm=%E0%A4%85&specificSearch=vocable&filters=%7B%7D"
        response = session.get(initial_url) # Session 的 verify=False 设置会自动应用到这里
        response.raise_for_status()
        
        soup = BeautifulSoup(response.text, 'html.parser')
        csrf_token_tag = soup.find('meta', {'name': '_csrf'})
        
        if not csrf_token_tag:
            print("[!] 致命错误：无法在页面上找到 CSRF 令牌。程序退出。")
            return None, None

        csrf_token = csrf_token_tag['content']
        print(f"[*] 成功获取 CSRF 令牌: {csrf_token[:10]}...")
        return session, csrf_token
    except requests.exceptions.RequestException as e:
        print(f"[!] 初始化 Session 失败: {e}")
        return None, None

def fetch_results_for_vocable(session, csrf_token, vocable):
    """
    为单个 vocable 抓取数据。此函数将在多线程中运行。
    """
    if not vocable:
        return []

    try:
        headers = {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': csrf_token,
            'Accept': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
        }
        payload = {
            "searchElement": vocable,
            "searchComplexity": "BASIC",
            "filters": {},
            "searchWithIn": "",
            "outputType": "devanagari_unicode",
            "specificSearch": "vocable"
        }
        
        # Session 的 verify=False 设置会自动应用到这里
        response = session.post(API_URL_TEMPLATE, headers=headers, json=payload, timeout=20) # 设置20秒超时
        response.raise_for_status()
        data = response.json()

        if data.get("resultFound") and "listOfResult" in data:
            results = []
            for item in data["listOfResult"]:
                # 只保留我们需要的信息
                results.append({
                    "id": item.get("id"),
                    "vocable": item.get("vocable")
                })
            return results
        else:
            return []
    except requests.exceptions.RequestException:
        # 捕获请求错误（如超时），为这个词返回空列表，但不中断整个过程
        return []
    except json.JSONDecodeError:
        # API可能返回了非JSON内容
        return []

def main():
    """
    主执行函数
    """
    # 1. 加载输入的 vocable 列表
    try:
        with open(INPUT_FILE_PATH, 'r', encoding='utf-8') as f:
            vocable_list = json.load(f)
        # 提取 vocable 字符串，并去重以避免重复搜索
        vocables_to_search = sorted(list(set(item['vocable'] for item in vocable_list if 'vocable' in item)))
        print(f"[*] 从 '{INPUT_FILE_PATH}' 加载了 {len(vocable_list)} 个条目，去重后得到 {len(vocables_to_search)} 个独立 vocable。")
    except FileNotFoundError:
        print(f"[!] 错误: 输入文件未找到 '{INPUT_FILE_PATH}'")
        return
    except json.JSONDecodeError:
        print(f"[!] 错误: 输入文件 '{INPUT_FILE_PATH}' 不是有效的 JSON 格式。")
        return

    # 2. 初始化 Session 和 Token
    session, csrf_token = setup_session_and_token()
    if not session or not csrf_token:
        return

    all_results = []
    start_time = time.time()

    # 3. 使用 ThreadPoolExecutor 进行并发抓取
    with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
        # 创建 future 任务字典，方便后续处理
        future_to_vocable = {executor.submit(fetch_results_for_vocable, session, csrf_token, voc): voc for voc in vocables_to_search}
        
        # 使用 tqdm 创建进度条
        progress_bar = tqdm(as_completed(future_to_vocable), total=len(vocables_to_search), desc="正在抓取 Vocables")
        
        for future in progress_bar:
            vocable = future_to_vocable[future]
            try:
                results = future.result()
                if results:
                    all_results.extend(results)
            except Exception as exc:
                progress_bar.write(f'[!] Vocable "{vocable}" 生成了一个异常: {exc}')

    end_time = time.time()
    
    # 4. 汇总和保存结果
    print("\n" + "="*50)
    print("抓取完成！")
    print(f"处理总耗时: {end_time - start_time:.2f} 秒")
    print(f"共为 {len(vocables_to_search)} 个 vocable 抓取到 {len(all_results)} 条记录。")

    # 确保输出目录存在
    output_dir = os.path.dirname(OUTPUT_FILE_PATH)
    if output_dir:
        os.makedirs(output_dir, exist_ok=True)
        
    with open(OUTPUT_FILE_PATH, 'w', encoding='utf-8') as f:
        json.dump(all_results, f, indent=2, ensure_ascii=False)

    print(f"[*] 结果已成功保存到: '{OUTPUT_FILE_PATH}'")
    print("="*50)


if __name__ == "__main__":
    main()