在 Python 中,如何使用保存的浏览器会话让 Selenium 无头地工作?

In Python, how do I make Selenium work headless with a Saved Browser Session?

我正试图绕过 web.whatsapp.com QR 扫描页面。这是我目前使用的代码:

options = webdriver.ChromeOptions();
options.add_argument('--user-data-dir=./User_Data')
driver = webdriver.Chrome(options=options)
driver.get('https://web.whatsapp.com/')

第一次尝试时,我必须手动扫描二维码,但在后来的尝试中,它不再要求输入二维码。

但是,如果我在添加此行 chrome_options.add_argument("--headless") 后尝试执行相同的操作,我会收到将 DevTools 活动端口写入文件的错误。我至少尝试了十几种不同的 google 搜索解决方案,但其中 none 有效。对此的任何帮助将不胜感激!谢谢。

到目前为止,尝试了一堆不同组合的不同参数,但没有任何效果:

options = Options() #decomment for local debugging
options.add_argument('--no-sandbox')
options.add_argument('--headless')
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-setuid-sandbox')
options.add_argument('--remote-debugging-port=9222')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')  # Last I checked this was necessary.
options.add_argument('start-maximized')
options.add_argument('disable-infobars')
options.add_argument('--user-data-dir=./User_Data')
driver = webdriver.Chrome('chromedriver.exe', options=options)

driver.get('https://web.whatsapp.com/')

最近我做了一个whatsapp bot,遇到了同样的问题。经过长时间的搜索,我想出了这个解决方案:

第一个问题是浏览器缓存内存,如果没有获取到浏览器apdata中缓存的二维码,它会一直等待扫描。

所以在我的程序中我使用了下面的函数得到:

def apdata_path():
    path = str(pathlib.Path().absolute())
    driver_path = path + "\chromedriver.exe"
    apdata = os.getenv('APPDATA')
    apdata_path = "user-data-dir=" + \
    re.findall(".+.\Dta\D", a)[0] + \
    r'Local\Chromium\User Data\Default\Default'
    apdata_path = apdata_path.replace("\", "\"*2)
    return apdata_path

在这里它找到第一个 apdata 路径 => C:\Users\AppData\ 然后我将路径的其余部分连接到缓存文件夹,在本例中我使用了 Chromium。在你的情况下它将是:

C:\Users\AppData\本地\Google\Chrome\用户Data\Default

可能有更好的方法来查找配置文件数据路径。找到它后我设置了驱动程序:

def chrome_driver(user_agent=0):
    usr_path = apdata_path()
    chrome_path = file_path() + '\Chromium 85\bin\chrome.exe'
    options = webdriver.ChromeOptions()
    options.binary_location = r"{}".format(chrome_path)
    if user_agent != 0:
        options.add_argument('--headless')
        options.add_argument('--hide-scrollbars')
        options.add_argument('--disable-gpu')
        options.add_argument("--log-level=3")
        options.add_argument('--user-agent={}'.format(user_agent))
    options.add_argument(usr_path)
    driver = webdriver.Chrome('chromedriver.exe', chrome_options=options)
    return driver

这里我遇到了另一个问题,即有时 Selenium 无法工作,因为 Whatsapp 有用户代理验证,以便能够验证浏览器版本是否兼容。我知道的不多所以我通过反复试验得出了这个结论,也许这不是真正的解释。但这对我有用。

因此,在我的 Bot 中,我创建了一个启动函数来获取用户代理并获取第一个 QR 扫描并将其保存在浏览器缓存中:

def whatsapp_QR():
    driver = chrome_driver()
    user_agent = driver.execute_script("return navigator.userAgent;")
    driver.get("https://web.whatsapp.com/")
    print("Scan QR Code, And then Enter")
    input()
    print("Logged In")
    driver.close()
    return user_agent

毕竟,我的机器人工作得很好,虽然不完美,但 运行 很顺利。我能够以无头模式在我的测试组中发送消息。

总而言之,获取 apdata 中的配置文件用户缓存以绕过 QR 码(但您需要 运行 它一次而不用无头来创建第一个缓存)。

然后获取用户代理以绕过 Wthatsapp 验证。所以整个选项集看起来像这样:

options.add_argument('--headless')
options.add_argument('--hide-scrollbars')
options.add_argument('--disable-gpu')
options.add_argument("--log-level=3")
options.add_argument('--user-agent={}'.format(user_agent)) # User agent for validation
options.add_argument(usr_path) #apdata user profile, to by pass QR code

usr_path = "user-data-dir=rC:\Users\\AppData\Local\Google\Chrome\User Data\Default"