You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python跨浏览器通用获取Cookie的解决方案求助

Python 提取多浏览器明文Cookie解决方案

需求背景

需用Python以明文格式打印浏览器Cookie,已知Chrome的Cookie为加密状态。尝试多个脚本后,要么出现权限拒绝提示(已尝试管理员运行仍无效),要么找不到目标文件/数据表。需要支持Edge、Chrome、Firefox、Brave及所有Chromium内核浏览器。

原脚本问题分析

  • 直接访问正在运行的浏览器Cookie数据库会被文件锁定,导致权限拒绝(即使管理员运行也无法绕过)
  • 未处理Chromium内核浏览器的Cookie值加密逻辑(Windows环境下采用DPAPI加密)
  • 仅适配Chrome默认用户目录,未覆盖Edge、Brave等其他Chromium浏览器路径
  • 未支持Firefox浏览器的Cookie提取

完整实现方案

依赖安装

先安装所需第三方库:

pip install pycryptodome pywin32

代码实现

import os
import sqlite3
import shutil
import tempfile
from datetime import datetime, timedelta
import win32crypt
from Crypto.Cipher import AES
import json

# 处理Chromium内核浏览器通用函数
def get_chromium_cookies(browser_name, db_path_template):
    cookies = []
    user_profile = os.environ["USERPROFILE"]
    db_path = os.path.join(user_profile, db_path_template)
    
    if not os.path.isfile(db_path):
        print(f"{browser_name} Cookie数据库未找到: {db_path}")
        return cookies
    
    # 复制数据库到临时文件,避免浏览器锁定
    with tempfile.NamedTemporaryFile(mode='w+b', delete=False, suffix='.sqlite') as tmp_db:
        shutil.copyfile(db_path, tmp_db.name)
        tmp_db_path = tmp_db.name
    
    try:
        # 连接临时数据库
        conn = sqlite3.connect(tmp_db_path)
        cursor = conn.cursor()
        
        # 获取加密密钥(从Local State文件读取)
        local_state_path = os.path.join(os.path.dirname(os.path.dirname(db_path)), "Local State")
        with open(local_state_path, 'r', encoding='utf-8') as f:
            local_state = json.load(f)
        encrypted_key = local_state['os_crypt']['encrypted_key']
        # 解密密钥(去除DPAPI前缀)
        encrypted_key = bytes.fromhex(encrypted_key[5:])
        key = win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1]
        
        # 查询Cookie数据
        cursor.execute("""
        SELECT host_key, name, value, encrypted_value, creation_utc, last_access_utc, expires_utc
        FROM cookies
        """)
        
        for row in cursor.fetchall():
            host_key, name, value, encrypted_value, creation_utc, last_access_utc, expires_utc = row
            
            # 解密Cookie值
            if encrypted_value:
                try:
                    # AES-GCM模式解密
                    nonce = encrypted_value[3:15]
                    ciphertext = encrypted_value[15:-16]
                    tag = encrypted_value[-16:]
                    cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
                    decrypted_value = cipher.decrypt_and_verify(ciphertext, tag).decode('utf-8')
                except:
                    decrypted_value = "解密失败"
            else:
                decrypted_value = value
            
            # 转换UTC时间为可读格式
            def convert_utc(utc):
                if utc == 0:
                    return "永久有效"
                return (datetime(1601, 1, 1) + timedelta(microseconds=utc)).strftime('%Y-%m-%d %H:%M:%S UTC')
            
            cookies.append({
                '浏览器': browser_name,
                '域名': host_key,
                'Cookie名称': name,
                '明文值': decrypted_value,
                '创建时间': convert_utc(creation_utc),
                '最后访问时间': convert_utc(last_access_utc),
                '过期时间': convert_utc(expires_utc)
            })
        
        conn.close()
    except Exception as e:
        print(f"{browser_name}处理出错: {str(e)}")
    finally:
        # 删除临时文件
        os.unlink(tmp_db_path)
    
    return cookies

# 处理Firefox浏览器函数
def get_firefox_cookies():
    cookies = []
    firefox_paths = [
        os.path.join(os.environ["USERPROFILE"], "AppData", "Roaming", "Mozilla", "Firefox", "Profiles"),
        os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Mozilla", "Firefox", "Profiles")
    ]
    
    profile_found = False
    for base_path in firefox_paths:
        if not os.path.exists(base_path):
            continue
        for profile_dir in os.listdir(base_path):
            profile_path = os.path.join(base_path, profile_dir)
            db_path = os.path.join(profile_path, "cookies.sqlite")
            if not os.path.isfile(db_path):
                continue
            profile_found = True
            
            # 复制到临时文件
            with tempfile.NamedTemporaryFile(mode='w+b', delete=False, suffix='.sqlite') as tmp_db:
                shutil.copyfile(db_path, tmp_db.name)
                tmp_db_path = tmp_db.name
            
            try:
                conn = sqlite3.connect(tmp_db_path)
                cursor = conn.cursor()
                cursor.execute("PRAGMA key = '';")  # 默认无主密码时直接读取
                
                cursor.execute("""
                SELECT host, name, value, creationTime, lastAccessed, expiry
                FROM moz_cookies
                """)
                
                for row in cursor.fetchall():
                    host, name, value, creationTime, lastAccessed, expiry = row
                    
                    def convert_firefox_time(timestamp):
                        if timestamp == 0:
                            return "永久有效"
                        return (datetime(1970, 1, 1) + timedelta(microseconds=timestamp)).strftime('%Y-%m-%d %H:%M:%S UTC')
                    
                    cookies.append({
                        '浏览器': 'Firefox',
                        '域名': host,
                        'Cookie名称': name,
                        '明文值': value,
                        '创建时间': convert_firefox_time(creationTime),
                        '最后访问时间': convert_firefox_time(lastAccessed),
                        '过期时间': convert_firefox_time(expiry)
                    })
                
                conn.close()
            except Exception as e:
                print(f"Firefox处理出错: {str(e)}")
            finally:
                os.unlink(tmp_db_path)
    
    if not profile_found:
        print("Firefox配置文件未找到")
    return cookies

# 主函数
if __name__ == "__main__":
    # 定义各Chromium浏览器路径模板,可自行添加其他浏览器
    chromium_browsers = [
        ("Chrome", r"AppData\Local\Google\Chrome\User Data\Default\Cookies"),
        ("Edge", r"AppData\Local\Microsoft\Edge\User Data\Default\Cookies"),
        ("Brave", r"AppData\Local\BraveSoftware\Brave-Browser\User Data\Default\Cookies"),
        # Opera示例: ("Opera", r"AppData\Roaming\Opera Software\Opera Stable\Cookies")
    ]
    
    all_cookies = []
    for browser_name, path_template in chromium_browsers:
        all_cookies.extend(get_chromium_cookies(browser_name, path_template))
    
    all_cookies.extend(get_firefox_cookies())
    
    # 打印明文Cookie
    for idx, cookie in enumerate(all_cookies, 1):
        print(f"===== Cookie [{idx}] =====")
        print(f"浏览器: {cookie['浏览器']}")
        print(f"域名: {cookie['域名']}")
        print(f"名称: {cookie['Cookie名称']}")
        print(f"明文值: {cookie['明文值']}")
        print(f"创建时间: {cookie['创建时间']}")
        print(f"最后访问时间: {cookie['最后访问时间']}")
        print(f"过期时间: {cookie['过期时间']}\n")

关键说明

  • 文件锁定解决:通过复制Cookie数据库到临时文件再访问,避免浏览器占用导致的权限问题
  • Chromium加密解密:读取Local State文件中的加密密钥,用DPAPI解密后再通过AES-GCM解密Cookie值
  • 多浏览器支持:适配Chrome、Edge、Brave等Chromium浏览器的默认路径,可自行扩展其他Chromium内核浏览器路径
  • Firefox处理:默认无主密码时可直接读取明文Cookie;若设置了主密码,需额外添加解密逻辑

内容的提问来源于stack exchange,提问作者crazky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:05:45