Playwrite(Proxy和指纹库)

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

https://cheapproxy.net/

只用firefox

代码

from playwright.async_api import async_playwright
import asyncio
import time
async def main():
    async with async_playwright() as playwright:
        browser = await playwright.firefox.launch(
            proxy={
                'server': 'http://74.x1.x1.xx:xxx',
                'username': '0a06ab468ab8xxxxxx',
                'password': '5070cd44e888xxxx',
            },
            headless=False  # 改成 False,就能看到浏览器界面
        )
        context = await browser.new_context()
        page = await context.new_page()

        # 访问一个测试 IP 的网站,验证代理是否生效
        await page.goto("https://httpbin.org/ip")
        html_content = await page.content()
        time.sleep(10000)
        print(html_content)

        await context.close()
        await browser.close()

asyncio.run(main())

指纹库的代码

from playwright.async_api import async_playwright
from playwright_stealth import Stealth
import asyncio
import time

async def main():
    async with Stealth().use_async(async_playwright()) as playwright:
        browser = await playwright.chromium.launch(
            headless=False,
            proxy={
                'server': 'http://74.xx.xx.xx:xxx',
                'username': '0a06ab468ab80exxxxx',
                'password': '5070cd44e88xxxxx',
            }
        )

        context = await browser.new_context(
            viewport={"width":1920, "height":1080},  # 屏幕分辨率伪装
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                       "AppleWebKit/537.36 (KHTML, like Gecko) "
                       "Chrome/145.0.0.0 Safari/537.36"
        )

        # 注入脚本伪装硬件信息
        await context.add_init_script("""
        // CPU 核心数伪装
        Object.defineProperty(navigator, 'hardwareConcurrency', {
            get: () => 8
        });

        // 内存大小伪装
        Object.defineProperty(navigator, 'deviceMemory', {
            get: () => 4
        });

        // 外设数量伪装
        navigator.mediaDevices.enumerateDevices = async () => {
            return [
                { kind: "audioinput", label: "Fake Microphone", deviceId: "mic1" },
                { kind: "audiooutput", label: "Fake Speaker", deviceId: "spk1" },
                { kind: "videoinput", label: "Fake Camera", deviceId: "cam1" }
            ];
        };

        // 电池状态伪装
        navigator.getBattery = async () => {
            return {
                charging: false,
                chargingTime: 0,
                dischargingTime: 3600,
                level: 0.55
            };
        };

        // 蓝牙支持伪装
        Object.defineProperty(navigator, 'bluetooth', {
            get: () => ({ fake: true })
        });
        
        // ========== Canvas 指纹随机化 ==========
        const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
        HTMLCanvasElement.prototype.toDataURL = function(type) {
            const result = originalToDataURL.apply(this, arguments);
            // 添加微小的随机噪声
            if (type && type.startsWith('image/')) {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                canvas.width = 1;
                canvas.height = 1;
                ctx.fillStyle = 'rgba(0,0,0,' + (Math.random() * 0.01) + ')';
                ctx.fillRect(0, 0, 1, 1);
            }
            return result;
        };
        
        const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
        CanvasRenderingContext2D.prototype.getImageData = function() {
            const imageData = originalGetImageData.apply(this, arguments);
            // 随机微调像素
            if (imageData.data && imageData.data.length > 0) {
                const idx = Math.floor(Math.random() * (imageData.data.length / 4)) * 4;
                imageData.data[idx] = (imageData.data[idx] + Math.floor(Math.random() * 2)) % 256;
            }
            return imageData;
        };
        
        // ========== WebGL 指纹随机化 ==========
        const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
        WebGLRenderingContext.prototype.getParameter = function(parameterCode) {
            // 随机化供应商和渲染器
            if (parameterCode === 37445) {
                return 'Intel Inc.';
            }
            if (parameterCode === 37446) {
                return 'Intel Iris OpenGL Engine';
            }
            return originalGetParameter.apply(this, arguments);
        };
        
        // WebGL2
        if (WebGL2RenderingContext) {
            const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
            WebGL2RenderingContext.prototype.getParameter = function(parameterCode) {
                if (parameterCode === 37445) {
                    return 'Intel Inc.';
                }
                if (parameterCode === 37446) {
                    return 'Intel Iris OpenGL Engine';
                }
                return originalGetParameter2.apply(this, arguments);
            };
        }
        
        // ========== 插件列表伪装 ==========
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5]
        });
        
        // ==========MimeType伪装 ==========
        Object.defineProperty(navigator, 'mimeTypes', {
            get: () => []
        });
        """)

        # 禁用图片和CSS加载,大幅提升速度
        await context.route("**/*.{png,jpg,jpeg,gif,svg,ico,webp}", lambda route: route.abort())
        await context.route("**/*.css", lambda route: route.abort())
        
        # 跳过分析脚本和广告
        await context.route("**/*analytics*.js", lambda route: route.abort())
        await context.route("**/*googletagmanager*.js", lambda route: route.abort())
        
        # 允许视频(如果需要看视频)
        # await context.route("**/*.mp4", lambda route: route.continue_())
        
        page = await context.new_page()

        # 验证 stealth 生效
        webdriver = await page.evaluate("navigator.webdriver")
        print(f"navigator.webdriver = {webdriver}")  # 应该是 undefined/False

        await page.goto("https://www.deviceinfo.me/")
        await page.wait_for_timeout(1000)
        await page.goto("https://ip111.cn/")
        await page.wait_for_timeout(1000)
        await page.goto("https://www.youtube.com/")
        await page.wait_for_timeout(1000)

        print(await page.title())
        time.sleep(10000)
        await browser.close()

asyncio.run(main())

Firefox反检测完整代码

from playwright.async_api import async_playwright
from playwright_stealth import Stealth
import asyncio
import time

async def main():
    async with Stealth().use_async(async_playwright()) as playwright:
        browser = await playwright.firefox.launch(
            headless=False,
            proxy={
                'server': 'http://74.81.xxx.xxx:823',
                'username': '0a06ab468ab80e3exxxx__cr.kr',
                'password': '5070cd44e888xxxx',
            }
        )

        context = await browser.new_context(
            viewport={"width":1920, "height":1080},
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0",
            timezone_id="Asia/Seoul",
            locale="ko-KR",
            permissions=["geolocation"],
            extra_http_headers={
                "Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7"
            }
        )

        # 注入脚本伪装硬件信息
        await context.add_init_script("""
        // CPU 核心数伪装
        Object.defineProperty(navigator, 'hardwareConcurrency', {
            get: () => 8
        });

        // 内存大小伪装
        Object.defineProperty(navigator, 'deviceMemory', {
            get: () => 4
        });

        // 外设数量伪装
        navigator.mediaDevices.enumerateDevices = async () => {
            return [
                { kind: "audioinput", label: "Fake Microphone", deviceId: "mic1" },
                { kind: "audiooutput", label: "Fake Speaker", deviceId: "spk1" },
                { kind: "videoinput", label: "Fake Camera", deviceId: "cam1" }
            ];
        };

        // 电池状态伪装
        navigator.getBattery = async () => {
            return {
                charging: false,
                chargingTime: 0,
                dischargingTime: 3600,
                level: 0.55
            };
        };

        // 蓝牙支持伪装
        Object.defineProperty(navigator, 'bluetooth', {
            get: () => ({ fake: true })
        });
        
        // ========== Canvas 指纹随机化 ==========
        const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
        HTMLCanvasElement.prototype.toDataURL = function(type) {
            const result = originalToDataURL.apply(this, arguments);
            // 添加微小的随机噪声
            if (type && type.startsWith('image/')) {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                canvas.width = 1;
                canvas.height = 1;
                ctx.fillStyle = 'rgba(0,0,0,' + (Math.random() * 0.01) + ')';
                ctx.fillRect(0, 0, 1, 1);
            }
            return result;
        };
        
        const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
        CanvasRenderingContext2D.prototype.getImageData = function() {
            const imageData = originalGetImageData.apply(this, arguments);
            // 随机微调像素
            if (imageData.data && imageData.data.length > 0) {
                const idx = Math.floor(Math.random() * (imageData.data.length / 4)) * 4;
                imageData.data[idx] = (imageData.data[idx] + Math.floor(Math.random() * 2)) % 256;
            }
            return imageData;
        };
        
        // ========== WebGL 指纹随机化 ==========
        const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
        WebGLRenderingContext.prototype.getParameter = function(parameterCode) {
            // 随机化供应商和渲染器
            if (parameterCode === 37445) {
                return 'Intel Inc.';
            }
            if (parameterCode === 37446) {
                return 'Intel Iris OpenGL Engine';
            }
            return originalGetParameter.apply(this, arguments);
        };
        
        // WebGL2
        if (WebGL2RenderingContext) {
            const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
            WebGL2RenderingContext.prototype.getParameter = function(parameterCode) {
                if (parameterCode === 37445) {
                    return 'Intel Inc.';
                }
                if (parameterCode === 37446) {
                    return 'Intel Iris OpenGL Engine';
                }
                return originalGetParameter2.apply(this, arguments);
            };
        }
        
        // ========== AudioContext 伪造 ==========
        const originalAudioContext = window.AudioContext;
        const originalWebkitAudioContext = window.webkitAudioContext;
        
        // 创建伪造的 AudioContext
        function createFakeAudioContext() {
            const ctx = originalAudioContext ? new originalAudioContext() : new originalWebkitAudioContext();
            
            // 伪造 getChannelData - 添加随机噪声
            const originalGetChannelData = ctx.createBufferSource ? ctx.getChannelData : null;
            if (ctx.getChannelData) {
                ctx.getChannelData = function(channel) {
                    const data = originalGetChannelData.call(this, channel);
                    // 添加微小随机噪声
                    for (let i = 0; i < data.length; i += 100) {
                        data[i] += (Math.random() - 0.5) * 0.0001;
                    }
                    return data;
                };
            }
            
            // 伪造 AnalyserNode
            if (ctx.createAnalyser) {
                const originalCreateAnalyser = ctx.createAnalyser;
                ctx.createAnalyser = function() {
                    const analyser = originalCreateAnalyser.call(this);
                    
                    // 伪造 getByteFrequencyData
                    const originalGetByteFrequencyData = analyser.getByteFrequencyData;
                    analyser.getByteFrequencyData = function(array) {
                        const result = originalGetByteFrequencyData.call(this, array);
                        // 添加随机偏移
                        for (let i = 0; i < array.length; i++) {
                            array[i] = Math.max(0, Math.min(255, array[i] + Math.floor(Math.random() * 3) - 1));
                        }
                        return array;
                    };
                    
                    // 伪造 getFloatFrequencyData
                    const originalGetFloatFrequencyData = analyser.getFloatFrequencyData;
                    analyser.getFloatFrequencyData = function(array) {
                        const result = originalGetFloatFrequencyData.call(this, array);
                        // 添加随机偏移
                        for (let i = 0; i < array.length; i++) {
                            array[i] = array[i] + (Math.random() - 0.5) * 0.5;
                        }
                        return array;
                    };
                    
                    return analyser;
                };
            }
            
            return ctx;
        }
        
        // 替换 window 上的 AudioContext
        window.AudioContext = createFakeAudioContext;
        window.webkitAudioContext = createFakeAudioContext;
        
        // 同时禁用旧的
        Object.defineProperty(window, 'AudioContext', {
            get: () => createFakeAudioContext
        });
        Object.defineProperty(window, 'webkitAudioContext', {
            get: () => createFakeAudioContext
        });
        
        // ========== 移除自动化特征 ==========
        delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
        delete window.cdc_adoQpoasnfa76pfcZLmcfl_Object;
        delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
        delete window.cdc_adoQpoasnfa76pfcZLmcfl_Proxy;
        
        // 覆盖 navigator.webdriver
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
        
        // 移除 chrome.runtime
        if (window.chrome) {
            window.chrome.runtime = undefined;
        }
        
        // ========== WebRTC IP 泄露防护 ==========
        // 禁用 WebRTC
        window.RTCPeerConnection = undefined;
        window.webkitRTCPeerConnection = undefined;
        window.mozRTCPeerConnection = undefined;
        
        // 伪装 RTCPeerConnection
        window.RTCPeerConnection = function(config) {
            return {
                createOffer: function(success, error) {
                    success({
                        type: 'offer',
                        sdp: 'v=0\r\n' +
                             'o=- 123456789 2 IN IP4 127.0.0.1\r\n' +
                             's=-\r\n' +
                             't=0 0\r\n' +
                             'a=msid-semantic: WMS\r\n'
                    });
                },
                createAnswer: function(success, error) {
                    success({
                        type: 'answer',
                        sdp: 'v=0\r\n' +
                             'o=- 123456789 2 IN IP4 127.0.0.1\r\n' +
                             's=-\r\n' +
                             't=0 0\r\n'
                    });
                },
                setLocalDescription: function(desc, success, error) {
                    success();
                },
                setRemoteDescription: function(desc, success, error) {
                    success();
                },
                addIceCandidate: function(candidate, success, error) {
                    success();
                },
                close: function() {}
            };
        };
        
        window.webkitRTCPeerConnection = window.RTCPeerConnection;
        window.mozRTCPeerConnection = window.RTCPeerConnection;
        
        // 禁用 getUserMedia
        navigator.getUserMedia = undefined;
        navigator.webkitGetUserMedia = undefined;
        navigator.mozGetUserMedia = undefined;
        navigator.msGetUserMedia = undefined;
        
        // 禁用 enumerateDevices 返回真实设备信息
        if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
            navigator.mediaDevices.enumerateDevices = async () => {
                return [
                    { kind: "audioinput", label: "Microphone", deviceId: "default" },
                    { kind: "audiooutput", label: "Speaker", deviceId: "default" },
                    { kind: "videoinput", label: "Camera", deviceId: "default" }
                ];
            };
        }
        """)

        # 跳过分析脚本和广告(可选)
        # await context.route("**/*analytics*.js", lambda route: route.abort())
        # await context.route("**/*googletagmanager*.js", lambda route: route.abort())
        
        page = await context.new_page()

        # 验证 stealth 生效
        webdriver = await page.evaluate("navigator.webdriver")
        print(f"navigator.webdriver = {webdriver}")  # 应该是 undefined/False


        await page.goto("https://pixelscan.net/")
        #await page.goto("https://www.deviceinfo.me/")
        print(await page.title())
        time.sleep(10000)
        await browser.close()

asyncio.run(main())

谷歌反检测(Profile加载+全绿)但是不能打开google

from playwright.async_api import async_playwright
import asyncio
import os
import json
import random

CONFIG = {
    "profile_dir": "user_data/chrome_profile",
    "proxy": {
        'server': 'http://74.81.81.81:823',
        'username': '0a06ab468ab80e3e6d6c__cr.gb',
        'password': '5070cd44e888f480',
    },
    "fp": {
        "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
        "locale": "en-GB",
        "tz": "Europe/London",
        "screen": {"width": 1920, "height": 1080},
    }
}

COMPLETE_STEALTH = """
(() => {
    'use strict';
    
    // ===== 1. webdriver:更彻底的原型链级改写(不可配置) =====
    (function () {
        const define = (obj) => {
            try {
                Object.defineProperty(obj, 'webdriver', {
                    get: () => false,
                    configurable: false
                });
                return true;
            } catch (e) {
                return false;
            }
        };
        if (typeof Navigator !== 'undefined' && Navigator.prototype) {
            if (define(Navigator.prototype)) return;
        }
        if (typeof navigator !== 'undefined') {
            if (define(navigator)) return;
            const p = Object.getPrototypeOf(navigator);
            if (p) define(p);
        }
    })();
    
    // ===== 2. 移除 Playwright 特征 =====
    const toDelete = [
        'cdc_adoQpoasnfa76pfcZLmcfl_Array',
        'cdc_adoQpoasnfa76pfcZLmcfl_Object', 
        'cdc_adoQpoasnfa76pfcZLmcfl_Promise',
        'cdc_adoQpoasnfa76pfcZLmcfl_Proxy',
        '__playwright_init_script__'
    ];
    toDelete.forEach(key => {
        if (window[key]) delete window[key];
    });
    if (window.chrome) window.chrome.runtime = undefined;
    
    // ===== 3. 时区:重写 Intl 核心方法 =====
    Date.prototype.getTimezoneOffset = function() { return 0; };
    window.Intl = window.Intl || {};
    const originalDateTimeFormat = Intl.DateTimeFormat;
    Intl.DateTimeFormat = function(...args) {
        const dtf = new originalDateTimeFormat(...args);
        const originalResolved = dtf.resolvedOptions;
        dtf.resolvedOptions = function() {
            const opts = originalResolved.call(this);
            opts.timeZone = 'Europe/London';
            return opts;
        };
        return dtf;
    };
    Intl.DateTimeFormat.prototype.resolvedOptions = function() { return { timeZone: 'Europe/London' }; };
    
    // ===== 4. 语言/系统信息 =====
    Object.defineProperty(navigator, 'language', {value: 'en-GB', writable: false});
    Object.defineProperty(navigator, 'languages', {value: ['en-GB','en-US','en'], writable: false});
    Object.defineProperty(navigator, 'platform', { get: () => 'Win32' });
    Object.defineProperty(navigator, 'vendor', { get: () => '', configurable: false });
    Object.defineProperty(navigator, 'hardwareConcurrency', {value: 8, configurable: true});
    Object.defineProperty(navigator, 'deviceMemory', {value: 4, configurable: true});
    
    // ===== 5. MimeTypes/Plugins 伪装为空 =====
    const createEmptyList = function() {
        const arr = []; arr.length = 0;
        arr.item = function(i) { return null; };
        arr.namedItem = function(name) { return null; };
        return arr;
    };
    Object.defineProperty(navigator, 'mimeTypes', { get: createEmptyList, configurable: false });
    Object.defineProperty(navigator, 'plugins', { get: createEmptyList, configurable: false });
    
    // ===== 6. Canvas 指纹随机化 =====
    const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
    HTMLCanvasElement.prototype.toDataURL = function(type) {
        const result = originalToDataURL.apply(this, arguments);
        if (type && type.startsWith('image/')) {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = 1; canvas.height = 1;
            ctx.fillStyle = 'rgba(0,0,0,' + (Math.random() * 0.01) + ')';
            ctx.fillRect(0, 0, 1, 1);
        }
        return result;
    };
    const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
    CanvasRenderingContext2D.prototype.getImageData = function() {
        const imageData = originalGetImageData.apply(this, arguments);
        if (imageData.data && imageData.data.length > 0) {
            const idx = Math.floor(Math.random() * (imageData.data.length / 4)) * 4;
            imageData.data[idx] = (imageData.data[idx] + Math.floor(Math.random() * 2)) % 256;
        }
        return imageData;
    };
    
    // ===== 7. WebGL 指纹伪装 =====
    const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
    WebGLRenderingContext.prototype.getParameter = function(parameterCode) {
        if (parameterCode === 37445) return 'Intel Inc.';
        if (parameterCode === 37446) return 'Intel Iris OpenGL Engine';
        return originalGetParameter.apply(this, arguments);
    };
    if (WebGL2RenderingContext) {
        const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
        WebGL2RenderingContext.prototype.getParameter = function(parameterCode) {
            if (parameterCode === 37445) return 'Intel Inc.';
            if (parameterCode === 37446) return 'Intel Iris OpenGL Engine';
            return originalGetParameter2.apply(this, arguments);
        };
    }
    
    // ===== 8. 外设/电池伪装 =====
    navigator.mediaDevices.enumerateDevices = async () => {
        return [
            { kind: "audioinput", label: "Fake Microphone", deviceId: "mic1" },
            { kind: "audiooutput", label: "Fake Speaker", deviceId: "spk1" },
            { kind: "videoinput", label: "Fake Camera", deviceId: "cam1" }
        ];
    };
    navigator.getBattery = async () => { return { charging: false, chargingTime: 0, dischargingTime: 3600, level: 0.55 }; };
    
    // ===== 9. WebRTC 伪装 =====
    window.RTCPeerConnection = function(config) {
        return {
            createOffer: function(success, error) { success({ type: 'offer', sdp: 'v=0\r\no=- 123456789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=msid-semantic: WMS\r\n' }); },
            createAnswer: function(success, error) { success({ type: 'answer', sdp: 'v=0\r\no=- 123456789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n' }); },
            setLocalDescription: function(desc, success, error) { success(); },
            setRemoteDescription: function(desc, success, error) { success(); },
            addIceCandidate: function(candidate, success, error) { success(); },
            close: function() {}
        };
    };
    window.webkitRTCPeerConnection = window.RTCPeerConnection;
    
    // ===== 10. 权限伪装 =====
    const originalQuery = window.navigator.permissions?.query;
    if (originalQuery) {
        window.navigator.permissions.query = (parameters) => {
            const name = parameters.name || parameters;
            if (name === 'notifications') {
                return Promise.resolve({
                    state: Notification.permission,
                    onchange: null,
                    addEventListener: () => {},
                    removeEventListener: () => {},
                    dispatchEvent: () => false
                });
            }
            return originalQuery.apply(window.navigator.permissions, arguments);
        };
    }
    
    window.__complete_stealth_done = true;
})();
"""

async def basic_check(page):
    return await page.evaluate("""() => ({
        webdriver: navigator.webdriver,
        userAgent: navigator.userAgent,
        platform: navigator.platform,
        language: navigator.language,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        chrome: !!window.chrome,
        stealth_done: !!window.__complete_stealth_done,
    })""")

async def human_behavior(page):
    await page.wait_for_timeout(random.randint(2000, 4000))
    for i in range(15):
        t = i / 14
        x = 500 + 900 * t + random.randint(-5, 5)
        y = 400 + 300 * t + random.randint(-5, 5)
        await page.mouse.move(x, y)
        await page.wait_for_timeout(random.randint(30, 80))
    await page.mouse.wheel(0, random.randint(100, 300))
    await page.wait_for_timeout(random.randint(200, 600))

async def main():
    profile_dir = CONFIG["profile_dir"]
    os.makedirs(profile_dir, exist_ok=True)

    async with async_playwright() as playwright:
        # ✅ 这里改成:直接用持久化上下文加载 profile
        context = await playwright.chromium.launch_persistent_context(
            user_data_dir=profile_dir,  # 🔥 核心:加载本地profile
            headless=False,
            proxy=CONFIG["proxy"],
            viewport=CONFIG["fp"]["screen"],
            user_agent=CONFIG["fp"]["ua"],
            timezone_id=CONFIG["fp"]["tz"],
            locale=CONFIG["fp"]["locale"],
            extra_http_headers={"Accept-Language": "en-GB,en;q=0.9"},
            permissions=[],
            args=[
                '--disable-blink-features=AutomationControlled',
                '--disable-features=IsolateOrigins,site-per-process,WebRTCHideLocalIpsWithMdns',
                '--disable-web-security',
                '--no-sandbox',
                '--disable-setuid-sandbox',
                '--disable-webrtc-hide-local-ips-with-mdns',
            ]
        )

        # 注入隐身脚本
        await context.add_init_script(COMPLETE_STEALTH)

        page = context.pages[0] if context.pages else await context.new_page()

        # 自检
        print("🔍 [注入后] 核心指纹:")
        check1 = await basic_check(page)
        print(json.dumps(check1, indent=2, default=str))

        await human_behavior(page)

        print("\n🌐 访问 pixelscan.net...")
        await page.goto("https://pixelscan.net/", wait_until="networkidle")
        await page.wait_for_timeout(15000)

        print("\n🔍 [站点加载后] 核心指纹:")
        check2 = await basic_check(page)
        print(json.dumps(check2, indent=2, default=str))

        await page.screenshot(path="debug_complete.png", full_page=True)
        print("\n📸 截图: debug_complete.png")

        print("\n📊 核心验证:")
        results = [
            ("webdriver", not check2.get('webdriver'), "✅" if not check2.get('webdriver') else "❌"),
            ("timezone", check2.get('timezone') == 'Europe/London', "✅" if check2.get('timezone') == 'Europe/London' else "❌"),
            ("chrome", check2.get('chrome') == True, "✅" if check2.get('chrome') else "❌"),
        ]
        for name, passed, icon in results:
            print(f"  {icon} {name}: {'PASS' if passed else 'FAIL'}")

        print("\n✅ Profile 已加载。按 Ctrl+C 退出...")
        await asyncio.Event().wait()
        await context.close()

if __name__ == "__main__":
    asyncio.run(main())

能打开谷歌,firefox反检测(全绿+profile) 但是不能google登录

from playwright.async_api import async_playwright
import asyncio
import os
import random

# 🔥 核心:复刻真实英国Firefox用户的指纹(无手动篡改,无伪装痕迹)
REAL_FIREFOX_FP = {
    "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0",
    "locale": "en-GB",
    "tz": "Europe/London",
    "screen": {"width": 1920, "height": 1080},
    # 真人硬件指纹(从真实英国用户Firefox提取)
    "hardwareConcurrency": 8,
    "deviceMemory": 8,
    "platform": "Win32",
    "vendor": "",
    "product": "Gecko",
    "productSub": "20100101"
}

# 🔥 无篡改痕迹的脚本:只做「隐藏自动化标识」,不修改指纹(关键)
STEALTH_NO_MASK = """
(() => {
    // 1. 静默隐藏webdriver(无篡改痕迹)
    const navProto = Navigator.prototype;
    Object.defineProperties(navProto, {
        webdriver: {
            get: () => undefined,
            configurable: false,
            enumerable: false
        }
    });

    // 2. 关闭自动化协议(无篡改痕迹)
    delete window.marionette;
    delete window.__mozilla__;

    // 3. 保持原生指纹不变(核心:不修改language/platform等)
    // 所有指纹由Firefox原生配置提供,无手动修改痕迹
})();
"""

async def main():
    profile_dir = "user_data/real_firefox_profile"
    os.makedirs(profile_dir, exist_ok=True)

    async with async_playwright() as playwright:
        # 🔥 启动原生Firefox(无任何指纹篡改配置)
        context = await playwright.firefox.launch_persistent_context(
            user_data_dir=profile_dir,
            headless=False,
            proxy={
                'server': 'http://74.81.81.81:823',
                'username': '0a06ab468ab80e3e6d6c__cr.gb',
                'password': '5070cd44e888f480',
            },
            # 🔥 核心:用原生配置匹配指纹,而非手动修改
            user_agent=REAL_FIREFOX_FP["ua"],
            locale=REAL_FIREFOX_FP["locale"],
            timezone_id=REAL_FIREFOX_FP["tz"],
            viewport=REAL_FIREFOX_FP["screen"],
            permissions=[],
            # 原生启动参数(无任何指纹修改)
            args=[
                "--start-maximized",
                "--no-remote",
                "--disable-private-browsing"
            ],
            # 🔥 原生Firefox偏好设置(模拟真实英国用户)
            firefox_user_prefs={
                # 系统级语言配置(无篡改痕迹)
                "intl.locale.requested": "en-GB",
                "intl.accept_languages": "en-GB,en",
                "general.useragent.locale": "en-GB",
                # 关闭自动化特征(无篡改痕迹)
                "marionette.enabled": False,
                "dom.webdriver.enabled": False,
                # 原生硬件配置(匹配真实用户)
                "browser.cache.disk.enable": True,
                "browser.cache.memory.enable": True,
                "network.cookie.cookieBehavior": 0,
                "browser.send_pings": False
            },
            # 禁用所有Playwright的自动化注入
            ignore_default_args=["--marionette", "--enable-automation"]
        )

        # 注入「无篡改痕迹」的反检测脚本
        await context.add_init_script(STEALTH_NO_MASK)

        page = await context.new_page()
        
        # 🔥 模拟真人操作节奏(关键:无机器人特征)
        await asyncio.sleep(random.uniform(1.5, 3.5))  # 随机延迟,更像真人
        print("🌐 以原生英国Firefox环境打开Google...")
        
        # 访问Google(无任何指纹修改,纯原生环境)
        await page.goto(
            "https://www.google.com",
            wait_until="domcontentloaded",
            timeout=60000
        )

        # 验证指纹(确认无篡改痕迹)
        fp_check = await page.evaluate("""
            ({
                webdriver: navigator.webdriver,
                language: navigator.language,
                platform: navigator.platform,
                hardwareConcurrency: navigator.hardwareConcurrency
            })
        """)
        print(f"✅ 指纹验证:{fp_check}")
        print("✅ Google加载完成!无指纹伪装痕迹")
        
        await asyncio.Event().wait()
        await context.close()

if __name__ == "__main__":
    asyncio.run(main())

123

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aaiier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值