Как внедрить веб-сессию WhatsApp, чтобы оставаться в системе с помощью селена?Python

Программы на Python
Ответить
Anonymous
 Как внедрить веб-сессию WhatsApp, чтобы оставаться в системе с помощью селена?

Сообщение Anonymous »

Я пытаюсь написать оболочку Python для селена для отправки и получения сообщений в WhatsApp Web. Однако я не хочу, чтобы людям приходилось сканировать QR-код аутентификации каждый раз, когда они запускают программу.
Из того, что я прочитал в Интернете, данные сеанса хранятся в indexeddb. с именем «wawc» и синхронизирует эти данные с локальным хранилищем. Я написал js-скрипты для извлечения ключей и значений IndexedDB и их внедрения в локальное хранилище и indexeddb при запуске. Кажется, что они работают, когда я смотрю на инструменты разработчика Chrome, но при перезагрузке страницы я получаю экран выхода из системы, а затем IndexedDB очищается.
Я видел, что некоторые люди обходятся без этого. это можно сделать, указав аргумент user-data-dir в ChromeOptions, но я предпочитаю делать это вручную, так как предпочитаю, чтобы пользовательские данные сохранялись только для web.whatsapp.com, а не для каких-либо других сайтов.
extract_session.js:

Код: Выделить всё

function requestPromise(request) {
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}

async function openDatabase(dbName) {
const request = indexedDB.open(dbName);
return requestPromise(request);
}

async function getAllFromStore(db, storeName) {
const transaction = db.transaction(storeName, "readonly");
const objectStore = transaction.objectStore(storeName);
return requestPromise(objectStore.getAll());
}

try {
const db = await openDatabase(arguments[0]);
const data = await getAllFromStore(db, arguments[1]);
return JSON.stringify(data);
} catch (error) {
console.log("Failed to extract session:", error)
return null;
}
inject_session.js:

Код: Выделить всё

function requestPromise(request) {
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}

async function openDatabase(dbName) {
const request = indexedDB.open(dbName);
return requestPromise(request);
}

async function putInStore(db, storeName, data) {
const transaction = db.transaction(storeName, "readwrite");
const objectStore = transaction.objectStore(storeName);
for (const item of data) {
const request = objectStore.put(item);
await requestPromise(request);
}
}

try {
const session = JSON.parse(arguments[2]);
const db = await openDatabase(arguments[0]);
await putInStore(db, arguments[1], session);
localStorage.clear()
for (const item of session) {
localStorage.setItem(item.key, item.value);
}
} catch (error) {
console.error("Failed to inject session:", error);
}
Минимальный код для воссоздания проблемы:

Код: Выделить всё

from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By

import os

def _handle_await(parent, locator, timeout, poll_freq):
try:
return WebDriverWait(parent,
timeout,
poll_frequency=poll_freq
).until(EC.presence_of_element_located(locator))
except TimeoutException:
return None

def await_element(parent, locator, timeout=0, poll_freq=0.05):

if timeout == 0:
while True:
res = _handle_await(parent, locator, timeout, poll_freq)
if res is not None:
return res
else:
return _handle_await(parent, locator, timeout, poll_freq)

QR_CODE = (By.CSS_SELECTOR, "canvas[role='img']")
LOGGED_IN = (By.CSS_SELECTOR, "div[title='Chats']")

options = ChromeOptions()

driver = Chrome(options=options)
driver.get("https://web.whatsapp.com/")

await_element(driver, QR_CODE)

if os.path.isfile("session.wa"):

js_code = open("inject_session.js", "r").read()
with open("session.wa", "r", encoding="utf-8") as file:
driver.execute_script(js_code, "wawc", "user", file.read())

driver.refresh()
input()

else:

await_element(driver, LOGGED_IN)

js_code = open("extract_session.js", "r").read()
session_data = driver.execute_script(js_code, "wawc", "user")

with open("session.wa", "w", encoding="utf-8") as file:
file.write(str(session_data))

input()
При первом запуске кода файл session.wa создается и выглядит нормально. После повторного запуска кода локальное хранилище и IndexedDB кажутся обновленными правильно, но после перезагрузки страницы я получаю этот экран:

И затем меня перенаправляют на главный экран web.whatsapp.com с QR-кодом для входа в систему. в.
Обновление 1: я начал изучать метод Execute_cdp_cmd для взаимодействия с CDP и установки значений IndexedDB и LocalStorage перед загрузкой веб-страницы. Это по-прежнему приводит к появлению страницы выхода из системы, которая предполагает, что нам не хватает данных сеанса, сохраняемых где-то еще, которые также необходимо внедрить.

Подробнее здесь: https://stackoverflow.com/questions/791 ... h-selenium
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»