...
Емейл Маркетинг

Драматург: мої перші кроки з інструментом автоматизації браузера

Драматург: мої перші кроки з інструментом автоматизації браузера

У моїй попередній компанії я розробив пакетне завдання, яке відстежувало показники в соціальних мережах, таких як Twitter, LinkedIn, Mastodon, Bluesky, Reddit тощо. Потім я зрозумів, що можу скопіювати це для своєї власної «персони». Проблема полягає в тому, що деякі засоби масової інформації не надають API HTTP для потрібних мені показників. Ось показники, які мені потрібні в LinkedIn:

Інформаційна панель показників LinkedInІнформаційна панель показників LinkedIn

Я довго шукав, але не знайшов доступу до API для наведених вище показників. Довгий час я збирав показники вручну щоранку і нарешті вирішив автоматизувати це виснажливе завдання. Ось що я дізнався.

Контекст

Робота виконана на Python, тому я хочу залишатися в тому самому технічному стеку. Після швидкого дослідження я знайшов Playwright, інструмент автоматизації браузера з кількома мовними API, включаючи Python. Основним випадком використання Playwright є наскрізне тестування, але він також може керувати браузером поза контекстом тестування.

Я використовую Poetry для керування залежностями. Встановити Playwright так само просто:

poetry add playwright

На цьому етапі Playwright готовий до використання. Він пропонує два різних API, один синхронний і один асинхронний. Через мій варіант використання першого смаку більш ніж достатньо.

Мочу ноги

Мені подобається підходити до розвитку поступово.

Ось уривок API:

Витяг з моделі APIВитяг з моделі API

Це перетворюється на такий код:

from playwright.sync_api import Browser, Locator, Page, sync_playwright


with (sync_playwright() as pw):                                                        #1
    browser: Browser = pw.chromium.launch()                                            #2
    page: Page = browser.new_page()                                                    #3
    page.goto('https://www.linkedin.com/login')                                        #4
    page.locator('#username').press_sequentially(getenv('LINKEDIN_USERNAME'))          #5
    page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD'))          #5
    page.locator('button[type=submit]').press('Enter')                                 #6
    page.goto('https://www.linkedin.com/dashboard/')                                   #4
    metrics_container: Locator = page.locator('.pcd-analytic-view-items-container')
    metrics: List[Locator] = metrics_container.locator('p.text-body-large-bold').all() #7
    impressions = atoi(metrics[0].inner_text())                                        #8
    # Get other metrics
    browser.close()                                                                    #9
  1. отримати a playwright об'єкт.

  2. Запустіть екземпляр браузера. Доступно декілька типів браузерів; Я вибрав Chromium з примхи. Зверніть увагу, що ви повинні були встановити певний браузер раніше, тобто, playwright install --with-deps chromium.

    За замовчуванням відкривається браузер безголовий; воно не з'являється. Я б порадив запустити його видимо на початку для легшого налагодження: headless = True.

  3. Відкрийте нове вікно браузера.

  4. Перейдіть до нового місця.

  5. Знайдіть вказані поля введення та заповніть їх моїми обліковими даними.

  6. Знайдіть зазначену кнопку та натисніть її.

  7. Знайдіть все зазначені елементи.

  8. Отримайте внутрішній текст першого елемента.

  9. Закрийте браузер, щоб очистити.

Зберігання файлів cookie

Вищезазначене спрацювало, як очікувалося. Єдиним мінусом є те, що я отримував електронний лист від LinkedIn кожного разу, коли запускав сценарій:

Привіт Ніколас,

Ви успішно активували Запам'ятати мене на новому пристрої HeadlessChrome,

в , , . Дізнайтеся більше про те, як Запам’ятати мене працює на пристрої.

Я також познайомився з Фаб’єном Вошеллем на конференції JavaCro. Він спеціалізується на веб-збиранні та сказав мені, що більшість людей у ​​цій галузі використовують профілі браузера. Дійсно, якщо ви ввійдете в LinkedIn, ви отримаєте маркер автентифікації, збережений у вигляді файлів cookie, і вам не потрібно буде повторно автентифікувати його до закінчення терміну дії. На щастя, Playwright пропонує таку функцію launch_persistent_context метод.

Ми можемо замінити вищезазначене launch з наступним:

with sync_playwright() as pw:
    playwright_profile_dir = f'{Path.home()}/.social-metrics/playwright-profile'
    context: BrowserContext = pw.chromium.launch_persistent_context(playwright_profile_dir) #1
    try:                                                                               #2
        page: Page = context.new_page()                                                #3
        page.goto('https://www.linkedin.com/dashboard/')                               #4
        if 'session_redirect' in page.url:                                             #4
            page.locator('#username').press_sequentially(getenv('LINKEDIN_USERNAME'))
            page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD'))
            page.locator('button[type=submit]').press('Enter')
            page.goto('https://www.linkedin.com/dashboard/')
        metrics_container: Locator = page.locator('.pcd-analytic-view-items-container')
        # Same as in the previous snippet
    except Exception as e:                                                             #2
        logger.error(f'Could not fetch metrics: {e}')
    finally:                                                                           #5
        context.close()
  1. Playwright зберігатиме профіль у вказаній папці та повторно використовуватиме його під час серії.

  2. Покращити обробку винятків.

  3. The BrowserContext також може відкривати сторінки.

  4. Пробуємо перейти до приладової панелі. LinkedIn перенаправить нас на сторінку входу, якщо ми не пройшли автентифікацію; тоді ми можемо автентифікувати.

  5. Закрийте контекст незалежно від результату.

На цьому етапі нам потрібно лише пройти автентифікацію з обома обліковими даними вперше. Це залежить від наступних прогонів.

Адаптація до реальності

Я був здивований, побачивши, що код вище не працює надійно. Це спрацювало при першому запуску, а іноді і при наступних. Оскільки я зберігаю профіль веб-переглядача під час запусків, коли мені потрібно автентифікуватися, LinkedIn запитує лише пароль, а не ім’я для входу! Оскільки код намагається ввести логін, у цьому випадку це не вдається. Виправлення досить просте:

username_field = page.locator('#username')
if username_field.is_visible():
    username_field.press_sequentially(getenv('LINKEDIN_USERNAME'))
page.locator('#password').press_sequentially(getenv('LINKEDIN_PASSWORD'))

Висновок

Хоча я не експерт у Python, мені вдалося досягти того, чого я хотів, із Playwright. Я віддав перевагу використанню API синхронізації, тому що це полегшує розробку коду, і я не маю жодних вимог до продуктивності. Я використовував лише основні функції, запропоновані Playwright. Playwright дозволяє записувати відео в контексті тестів, що дуже корисно, коли тест не вдається під час виконання конвеєра CI.

Щоб піти далі:


Вперше опубліковано на сайті A Java Geek 19 січня 2024 року

Alex

About Author

Recommend – дізнавайтеся більше про події, що формують наше сьогодення. Найцікавіші новини України та світу, аналітика, тренди та ексклюзивні матеріали – все це на recommend.com.ua!

Отримуйте останні оновлення та великі пропозиції