CoderCastrov logo
CoderCastrov
Selenium

Автоматизация веб-парсинга с использованием Selenium и Python

Автоматизация веб-парсинга с использованием Selenium и Python
просмотров
9 мин чтение
#Selenium
Table Of Content

Об авторе: Привет, меня зовут Лукас Пекено Стерзек. Мне интересны автоматизация и Data Science. Надеюсь, вам понравится этот статья, и, если возможно, оставьте отзыв, чтобы я мог создавать еще лучшие статьи в будущем.

Что такое Python: Python - это широко используемый язык программирования, который может легко анализировать данные, автоматизировать задачи и создавать все, что ваша фантазия может вообразить. Он легко изучается, поэтому часто является входной точкой для многих программистов. Если вы хотите узнать больше о нем, я подготовил две статьи, которые помогут вам установить Python на Windows и Linux. Эти статьи не являются моими.

Что такое Selenium: Библиотека Python, которая позволяет симулировать взаимодействие с веб-браузером (драйвером). Поскольку многие из наших повседневных задач связаны с веб-браузером, здесь у нас есть большой потенциал для автоматизации повседневных задач.


Sumário:

1º Passo — Установка библиотеки Selenium в Python

Для установки библиотеки просто введите в терминале:

pip install selenium

Если вы используете среду conda, введите "conda install selenium", если вы находитесь в Linux, введите "sudo install selenium".

2º Passo — Установка веб-драйвера ChromeDriver (Chromium)

Selenium нуждается в веб-драйвере для интеграции, поэтому я расскажу о использовании драйвера Chrome, то есть драйвера, который позволяет Selenium использовать интерфейс браузера Chrome и взаимодействовать с элементами веб-страницы.

Чтобы установить ChromeDriver, вы можете использовать библиотеку chromedriver-autoinstaller с помощью команды

pip install chromedriver-autoinstaller

Если хотите, вы также можете скачать ChromeDriver вручную с официального сайта, но вам нужно знать, какая версия Chrome у вас установлена. Для этого перейдите в Настройки > О Google Chrome > Версия X.

Примечание: Также существуют веб-драйверы для Microsoft Explorer и Mozilla Firefox, но я никогда не использовал их для таких автоматизаций.

3-й шаг — Настройка начального кода

Здесь мы начнем код, чтобы затем создать переменную, которая будет содержать веб-браузер. Обратите внимание, что перед созданием объекта, который содержит веб-браузер, нам нужно вызвать путь/path, в данном случае это будет chromedriver-autoinstaller.install(), но если вы используете ручную установку, я приведу пример ниже, как должно быть объявлено.

# Импорт библиотек
from selenium import webdriver
import chromedriver_autoinstaller
path = chromedriver_autoinstaller.install()

# Дополнительные строки
import os
dir_path = os.getcwd()
profile = os.path.join(dir_path, "profile", "wpp")
options = webdriver.ChromeOptions()
options.add_argument(r"user-data-dir={}".format(profile))

# Создание браузера (с дополнительными строками)
navegador = webdriver.Chrome(options=options, executable_path=path)

# Создание браузера (без дополнительных строк)
# navegador = webdriver.Chrome(executable_path=path)

Дополнительные строки: Я решил добавить эти "Дополнительные строки", но что они делают? Они просто сохраняют информацию (кэш), которую ваш браузер, открытый через Selenium, будет использовать, что может быть очень полезно, когда вы, например, хотите сохранить вход на сайты, такие как Telegram, Youtube, Medium, Github, Kaggle, E-mail, Whatsapp или любой другой сайт, к которому вы планируете получить доступ.

После завершения вышеуказанного этапа при запуске кода будет открыт пустой браузер/webdriver в соответствии с изображением выше.

Примечание: Если по какой-либо причине вам нужно было скачать chromedriver вручную, вам нужно будет указать путь к нему в "executable_path", ниже я приведу пример:

# РУЧНАЯ ЗАГРУЗКА CHROMEDRIVER

from selenium import webdriver

# Переменная с путем к chromedriver
path = r'C:\Users\lucaspequenosterzeck\Downloads\chromedriver.exe'

import os
dir_path = os.getcwd()
profile = os.path.join(dir_path, "profile", "wpp")
options = webdriver.ChromeOptions()
options.add_argument(r"user-data-dir={}".format(profile))

navegador = webdriver.Chrome(options=options, executable_path=path)

4-й шаг - Основные интеграции с браузером

Теперь, когда у вас есть браузер, готовый к использованию с помощью Selenium, вот несколько основных методов взаимодействия:

В нашем коде мы обращаемся к "браузеру" как к веб-драйверу, который использует Selenium.

GET

Метод get позволяет выбранному окну перейти на определенный сайт, например, если мы хотим перейти на сайт YouTube, мы напишем следующий код:

navegador.get("https://www.youtube.com")

QUIT

Метод для закрытия браузера.

navegador.quit()

REFRESH

Метод refresh позволяет перезагрузить браузер:

navegador.refresh()

Помимо двух вышеуказанных методов навигации, также существуют .back() и .forward(), которые соответственно возвращаются назад и перемещаются вперед в навигации по страницам в соответствии с историей навигации.

FIND_ELEMENT

Одним из ключевых инструментов в автоматизации является способ нахождения элементов, чтобы затем взаимодействовать с нужными полями. Для этого мы используем метод .find_element(), а также его вариант .find_elements(). Постарайтесь не путать их! Второй вариант написан во множественном числе, потому что он возвращает список элементов, соответствующих вашему фильтру, в то время как первый возвращает только один элемент.

Ниже мы продолжим работу внутри YouTube и используем .find_element() для получения текста, содержащегося в первом видео, которое появляется в качестве рекомендации для вас:

from selenium.webdriver.common.by import By

navegador.find_element(By.ID, value='video-title').text

# Outuput: 'Dua Lipa, Coldplay, Martin Garrix & Kygo, The Chainsmokers Style - Feeling Me [Vol.2]'

Как показано выше, код возвращает 'текст', присутствующий в выбранном элементе на странице YouTube. Если вы хотите узнать, откуда взялись значения полей 'By', 'value' и '.text', вот некоторые пояснения:

О методе By: Мы импортировали 'By' из 'selenium.webdriver.common.by', чтобы ссылаться на элементы на сайте. В этот раз я использовал 'By.ID', потому что 'value', на который я ссылался, является идентификатором на сайте. О значении 'value': Чтобы узнать, что на сайте YouTube есть идентификатор 'video-title', я нажал клавишу F12, если вы используете Chrome, или щелкнул правой кнопкой мыши на любом элементе сайта и выбрал опцию 'Inspect'. Затем я нашел нужный элемент. О '.text': Поскольку .find_element() относится к элементу, я использовал дополнение .text, чтобы указать коду, что я хочу только текст выбранного элемента.

FIND_ELEMENTS

Теперь, используя приведенный выше пример, что если мы хотим получить все названия видео, которые отображаются на YouTube? Мы можем сделать это, используя .find_elements():

from selenium.webdriver.common.by import By

# Элемент, содержащий все заголовки видео
videos = navegador.find_elements(By.ID, value='video-title')

# Итерация по каждому элементу в videos и вывод его текста
for elemento in videos: print(elemento.text)

Взаимодействие с элементами

После выбора элемента на странице с помощью .find_element(), мы можем взаимодействовать с ним. В предыдущем примере мы использовали атрибут .text для извлечения текста из элемента, но мы также можем щелкнуть по нему или ввести что-то в выбранный элемент. Ниже приведены примеры каждого типа взаимодействия:

  • Взаимодействие типа "Клик"
navegador.find_element(By.ID, value='video-title').click()

Этот код выполнит "клик" на первом видео, которое появится.

  • Взаимодействие типа "Ввод"
campo_busca = '/html/body/ytd-app/div[1]/div/ytd-masthead/div[4]/div[2]/ytd-searchbox/form/div[1]/div[1]/div/div[2]/input'

navegador.find_element(By.XPATH,
                       value=campo_busca).send_keys('Тест Selenium')

Этот код заставит Selenium ввести содержимое, указанное в скобках .send_keys(). Обратите внимание, что для этого мы использовали By.XPATH. Ниже я постараюсь пояснить, что такое XPath и как его можно найти на сайте.

Примечание: Чтобы нажать специальные клавиши, мы импортируем Keys из selenium.webdriver.common.keys и используем его внутри send_keys().

5-й шаг — XPATH

Поскольку я часто использую этот метод выбора, я решил оставить отдельный шаг для описания XPath. Согласно Википедии, "XPath - это язык запросов (Query Language) для выбора узлов XML-документа. Кроме того, XPath может использоваться для вычисления значений (например, строк, чисел или логических значений) из содержимого XML-документа. XPath был определен Консорциумом Всемирной паутины...". Иными словами, это язык, с помощью которого вы можете выбирать элементы на веб-сайте, и Selenium принимает этот выбор, чтобы мы могли указать, на какой элемент или элементы мы хотим ссылаться.

Если вы хотите узнать больше о XPath, я подобрал две ссылки, которые могут вам помочь:

Escola de dados - INTRODUÇÃO AO XPATH PARA RASPAGEM DE DADOS EM HTML

w3schools - XPath Tutorial

Escola de dados на предоставленной выше ссылке представляет очень полную гифку, показывающую пошагово, как найти XPath на странице:

Авторство escoladedados.org. Доступно по ссылке выше

6-й шаг - Ожидание между шагами

Мы всегда должны учитывать, что код выполняется гораздо быстрее, чем браузер может загрузить элементы, которые мы изменяем. Поэтому очень полезно установить определенные или относительные интервалы в коде, где код будет ждать x секунд, прежде чем продолжить, или будет ждать, пока элемент x не появится, прежде чем продолжить программу.

Ожидание с определенным интервалом

Существуют и другие способы заставить код ждать x секунд, прежде чем продолжить, но мне нравится использовать встроенную библиотеку time.sleep для этого процесса.

from time import sleep

navegador.get("https://www.youtube.com")

sleep(3) # Подождите 3 секунды

campo_busca = '/html/body/ytd-app/div[1]/div/ytd-masthead/div[4]/div[2]/ytd-searchbox/form/div[1]/div[1]/div/div[2]/input'
navegador.find_element(By.XPATH,
                       value=campo_busca).click()

sleep(0.5) # Подождите полсекунды


navegador.find_element(By.XPATH,
                       value=campo_busca).send_keys('teste')

Ожидание с относительным интервалом

Для этого типа интервала мы будем использовать немного более изощренный метод, чем выше. Мы сделаем следующее:

Создадим бесконечный цикл с помощью while True, код будет выходить из цикла только если указанный нами элемент будет найден на странице. Чтобы выполнить эту проверку, мы создаем условие if, в котором мы подсчитываем количество элементов с помощью len(), которые возвращает find_elements().

from time import sleep

navegador.get("https://www.youtube.com")

ожидаемый_элемент = '//*[@id="thumbnail"]'

while True:
    sleep(1)
    if len(navegador.find_elements(By.XPATH, value=ожидаемый_элемент)) > 0: 
        sleep(2)
        break

поле_поиска = '/html/body/ytd-app/div[1]/div/ytd-masthead/div[4]/div[2]/ytd-searchbox/form/div[1]/div[1]/div/div[2]/input'
navegador.find_element(By.XPATH, value=поле_поиска).click()
sleep(0.5)
navegador.find_element(By.XPATH, value=поле_поиска).send_keys('тест')

Примечание: Даже после ожидания загрузки указанного выше элемента может быть, что другие элементы еще не загрузились, и в этом случае код вызовет ошибку. Чтобы предотвратить такую ​​ситуацию, мы добавляем sleep() перед break, таким образом, код будет ждать x секунд даже после нахождения запрашиваемого элемента.

7-й шаг - Создание циклов и пример с Selenium

Теперь, когда вы знаете, как выбирать элементы с помощью XPath и взаимодействовать с браузером, давайте попрактикуемся. Чтобы помочь вам в этом процессе, я предоставлю полный код на Python. Идея состоит в том, чтобы вы скопировали весь код и выполняли его на своей машине, чтобы научиться практически. Код будет выполнять следующие действия:

  • Поиск видео в строке поиска
  • Нажатие на первое видео
  • Нажатие на кнопку "Нравится"
  • Раскрытие описания видео
  • Перемотка до середины видео
  • Нажатие на кнопку "Поделиться", копирование ссылки и вставка ее в поле поиска
# Импорт библиотек
from selenium import webdriver
import chromedriver_autoinstaller
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import sleep
import os

# Установка chromedriver
path = chromedriver_autoinstaller.install()

# Необязательные строки ниже
dir_path = os.getcwd()
profile = os.path.join(dir_path, "profile", "wpp")
options = webdriver.ChromeOptions()
options.add_argument(r"user-data-dir={}".format(profile))

# Создание браузера (с необязательными строками)
navegador = webdriver.Chrome(executable_path=path)
sleep(1) # Подождите, пока браузер откроется

# Перейти на YouTube
navegador.get("https://www.youtube.com")

# Подождите, пока страница загрузится
wait_for_this_element = '//*[@id="contents"]'
while True:
    sleep(1)
    if len(navegador.find_elements(By.XPATH, value=wait_for_this_element)) > 0: 
        sleep(2)
        break

# Поиск видео по названию "Rift (feat. Jenn Lucas)"
search_field = '/html/body/ytd-app/div[1]/div/ytd-masthead/div[4]/div[2]/ytd-searchbox/form/div[1]/div[1]/div/div[2]/input'
navegador.find_element(By.XPATH, value='//*[@id="search-input"]').click()
sleep(0.5)
navegador.find_element(By.XPATH, value=search_field).send_keys('Rift (feat. Jenn Lucas)')
sleep(0.5)
navegador.find_element(By.XPATH, value=search_field).send_keys(Keys.ENTER) # Метод Keys имитирует клавиатуру

# Подождите, пока элемент загрузится
wait_for_this_element = '//*[@id="thumbnail"]'
while True:
    sleep(1)
    if len(navegador.find_elements(By.XPATH, value=wait_for_this_element)) > 0: 
        sleep(2)
        break

# Загрузить все названия
video_titles = '//*[@id="video-title"]/yt-formatted-string'
search_results = navegador.find_elements(By.XPATH, value=video_titles)

# Нажмите на искомое название
for title in search_results:
    if title.text == 'Rift (feat. Jenn Lucas)': 
        title.click()
        break

# Подождите, пока страница видео загрузится
wait_for_this_element = '//*[@id="movie_player"]/div[20]'
while True:
    sleep(1)
    if len(navegador.find_elements(By.XPATH, value=wait_for_this_element)) > 0: 
        sleep(2)
        break

# Нажмите на кнопку "Нравится" видео
like_button = '//*[@id="segmented-like-button"]/ytd-toggle-button-renderer/yt-button-shape/button/yt-touch-feedback-shape/div/div[2]'
navegador.find_element(By.XPATH, value=like_button).click()
sleep(1)
like_window = '//*[@id="contentWrapper"]/ytd-modal-with-title-and-button-renderer'
navegador.find_element(By.XPATH, value=like_window).send_keys(Keys.ESCAPE) # Закрытие окна с запросом о входе
sleep(0.5)

# Раскрытие описания видео
show_more_option = '//*[@id="expand"]'
navegador.find_element(By.XPATH, value=show_more_option).click()
sleep(1)

# Нажмите на кнопку "Поделиться", скопируйте ссылку и вставьте ее в поле поиска
share_button = '//*[@id="top-level-buttons-computed"]/ytd-button-renderer/yt-button-shape/button/yt-touch-feedback-shape/div/div[2]'
navegador.find_element(By.XPATH, value=share_button).click()
sleep(1)
copy_share_link_button = '//*[@id="copy-button"]/yt-button-shape/button/yt-touch-feedback-shape/div/div[2]'
navegador.find_element(By.XPATH, value=copy_share_link_button).click()
sleep(0.5)
close_share_window = '/html/body/ytd-app/ytd-popup-container/tp-yt-paper-dialog/ytd-unified-share-panel-renderer/yt-icon-button/button/yt-icon'
navegador.find_element(By.XPATH, value=close_share_window).click()
sleep(1)
search_field = '/html/body/ytd-app/div[1]/div/ytd-masthead/div[4]/div[2]/ytd-searchbox/form/div[1]/div[1]/div/div[2]/input'
navegador.find_element(By.XPATH, value='//*[@id="search-input"]').click()
sleep(0.5)
navegador.find_element(By.XPATH, value=search_field).send_keys(Keys.CONTROL, 'V') # Имитация CTRL + V

sleep(1)
# Если есть реклама, пропустите ее
video_ad = '//*[@id="ad-text:7"]'
if len(navegador.find_elements(By.XPATH, value=video_ad)) > 0:
    navegador.find_element(By.XPATH, value=video_ad).click()
    sleep(3)

# Перемотка до середины видео
current_video = '//*[@id="movie_player"]'
navegador.find_element(By.XPATH, value=current_video).send_keys('5')
sleep(2)

# Перемотка до конца видео
current_video = '//*[@id="movie_player"]'
navegador.find_element(By.XPATH, value=current_video).send_keys('9')
sleep(5)

# Закрыть браузер
navegador.quit()

В конечном итоге, что я могу автоматизировать?

Это лишь некоторые из возможностей автоматизации, которые предлагают Selenium и Python. С навыками программирования и знанием Selenium вы можете автоматизировать многие другие задачи, связанные с взаимодействием с веб-сайтами.

Ссылки:

Selenium

Неофициальная документация Selenium