обзор
Я пишу много уроков для Envato Tuts +. Эти учебники имеют заголовки, которые должны следовать определенным правилам использования заглавных букв. Tuts + предоставляет нам, авторам, веб-инструмент, который берет текст заголовка и возвращает заголовок с правильной заглавной буквы. Когда я пишу свои учебные пособия, я пытаюсь войти в поток, и переключение на инструмент капитализации нарушает мой поток. Раньше я просто делал это и делал капитализацию сам.
Оказывается, я часто допускал ошибки, что вызывало дополнительную работу у редакторов Tuts +, которые должны были их исправить. Будучи программистом, я решил запрограммировать выход из проблемы. Я все еще пишу свои собственные заголовки, но когда я закончу, я запускаю небольшую программу на Python, которая анализирует мою статью, обнаруживает все заголовки, а затем запускает их с помощью инструмента капитализации Tuts + и правильно прописывает все заголовки.
Поскольку инструмент капитализации является веб-приложением, а не API, мне пришлось автоматизировать браузер, чтобы вызвать его и извлечь заглавные буквы. В этом уроке вы узнаете, как управлять браузером в Python с помощью Selenium и заставить его выполнять ваши ставки.
Как использовать заголовки
Заглавные буквы — это не ракетостроение, но и не тривиальное. Есть несколько стилей, с некоторым перекрытием и некоторыми вариациями. Это более или менее консенсус:
- Прописать все слова четырьмя или более буквами.
- Всегда пишите заглавными буквами первые и последние слова.
- Не используйте заглавные буквы: a, an, the.
- Не используйте короткие сочетания с заглавными буквами: и, или, ни, для, но, так, пока.
Тогда есть множество исключений и особых ситуаций (например, заголовок переходит на следующую строку). Но это все спорно. Даже если я решил написать свой собственный код с заглавной буквы, Tuts + уже выбрал их вкус, и мне нужно соответствовать их выбранному стилю.
Онлайн конвертер дел
Инструмент капитализации Tuts + является внутренним инструментом, предназначенным для использования только инструкторами Tuts +, поэтому я не могу использовать его в качестве демонстрации. Тем не менее, я нашел похожий инструмент под названием Title Case Converter . Это веб-приложение с большой текстовой областью, в которой вы можете ввести свой заголовок (или заголовок), кнопку преобразования, которую вы нажимаете, чтобы отправить форму, область вывода, которая отображается с правильно прописным заголовком, и, наконец, кнопка копирования, которая копирует преобразованный заголовок в буфер обмена.
План автоматизации инструмента капитализации
OK. Я собираюсь использовать онлайн конвертер дел, но нет API. Это не большая проблема. Я могу автоматизировать браузер и смоделировать пользователя, который вводит заголовок в поле ввода, нажимает кнопку конвертирования, ждет появления вывода, нажимает кнопку копирования и, наконец, вставляет заголовок с правильной прописной буквой из буфера обмена.
Первый шаг — выбрать браузер для автоматизации. Я выбрал Selenium WebDriver, который раньше успешно использовал. Остальная часть плана:
- Запустите браузер.
- Перейдите к URL-адресу онлайн-конвертера дел.
- Найдите все необходимые элементы.
- Заполните поле ввода.
- Отправьте форму.
- Ждите выхода.
- Нажмите кнопку копирования.
- Прочитайте заглавную букву из буфера обмена.
Полный исходный код можно найти на GitLab .
Введение в селен
Selenium автоматизирует браузеры с 2004 года. В 2008 году он объединился с проектом WebDriver, в котором рассматриваются некоторые ограничения исходного Selenium (например, работа в песочнице JavaScript).
Selenium по-прежнему предлагает оригинальный аромат Selenium под названием Selenium RC (Remote Control). Он также имеет IDE для написания автоматизированных наборов тестов и инструмент под названием Selenium Grid, который масштабирует Selenium RC для больших наборов тестов, которые должны работать в нескольких средах. Мы ограничимся программным доступом к браузеру через API WebDriver (он же Selenium 2).
Установка Selenium и веб-драйвера
Установка Selenium так же проста, как и pipenv selenium
. Если вы не знакомы с Pipenv, ознакомьтесь с « Пересмотром упаковки Python с помощью Pipenv» . Вам также нужен определенный веб-драйвер. Есть веб-драйверы для разных браузеров и серверных частей. Вы можете найти полный список на сайте Selenium .
Я выбрал веб-драйвер Chrome для этого урока. Вот последняя версия .
Это один zip-файл, который содержит один исполняемый файл (есть версии для Windows, macOS и Linux). После того, как вы загрузили его, распакуйте его и пройдите по пути.
Поздравляем! Теперь вы готовы использовать Selenium WebDriver из Python.
Запуск браузера
Selenium позволяет легко запускать браузер. Если у вас есть правильный веб-драйвер на вашем пути, вы просто импортируете модуль selenium.webdriver
и вызываете правильный метод для запуска вашего браузера:
1
2
3
|
from selenium import webdriver
driver = webdriver.Chrome()
|
Переход к URL
Если у вас есть объект драйвера, вы можете вызвать метод get()
чтобы перейти на любую веб-страницу. Вот как перейти к конвертеру титров:
1
|
driver.get(‘https://titlecaseconverter.com’)
|
Поиск элементов
Нам нужен способ найти элементы на странице, с которой вы хотите взаимодействовать. Самый простой способ — просмотреть веб-страницу в браузере и найти идентификаторы целевых элементов. На следующем скриншоте видно, что поле ввода имеет идентификатор «title»:
Кнопка конвертации не имеет идентификатора, но это не проблема, как вы скоро увидите. Вот код для поиска формы и текстовых полей по id:
1
|
input_field = driver.find_element_by_id(‘title’)
|
Если элемент, с которым вы хотите взаимодействовать, не имеет идентификатора, вы можете найти его, используя различные другие методы, такие как имя, имя класса или селектор CSS. Посмотреть все варианты в этом руководстве Selenium .
Например, чтобы найти кнопку конвертации, я использовал ее имя класса:
1
2
|
convertButton = \
driver.find_element_by_class_name(‘convertButton’)
|
Заполнение текстовых полей
Чтобы заполнить поле ввода, мы можем использовать метод send_keys()
нашего элемента поля ввода. Но сначала обязательно очистите его. В противном случае вы просто добавите к существующему тексту.
1
2
|
input_field.clear()
input_field.send_keys(heading)
|
Это было довольно легко.
Нажатие кнопок и отправка форм
Теперь пришло время отправить форму. Вы можете сделать это двумя способами:
- Найдите элемент формы на странице и вызовите его метод
submit()
. - Найдите кнопку конвертации и нажмите ее.
Я изначально отправил форму напрямую:
1
2
|
form = driver.find_element_by_css_selector(‘body > form’)
form.submit()
|
По какой-то причине это не работает. Там нет ошибки, но ничего не происходит. Я не тратил много времени на исследования, потому что весь смысл Selenium и этого урока в том, чтобы имитировать человека. Поэтому я использовал другой метод и просто нажал кнопку, которую нашел ранее:
1
|
convertButton.click()
|
Ожидание отправки формы
Онлайновый конвертер кейсов несколько необычен Поле вывода не существует изначально. После того, как вы нажмете кнопку «Преобразовать» и форма будет отправлена, выходные данные отображаются вместе с кнопкой «Копировать». Это означает, что нам нужно дождаться завершения отправки формы, прежде чем появится кнопка копирования, и мы можем щелкнуть ее, чтобы скопировать вывод в буфер обмена.
Селен покрыл тебя. Он поддерживает ожидание произвольных условий и тайм-аут, если они не материализуются. Вот код, который ждет кнопку копирования. Он создает объект WebDriverWait
с WebDriverWait
таймаутом. Затем он создает условие для присутствия элемента с именем класса copyButton
, а затем вызывает метод wait until()
объекта ожидания с условием.
1
2
3
|
wait = WebDriverWait(driver, 5)
buttonPresent = presence_of_element_located((By.CLASS_NAME, ‘copyButton’))
copyButton = wait.until(buttonPresent)
|
В результате после нажатия кнопки конвертирования он будет ждать, пока не появится кнопка копирования или не истечет время ожидания через пять секунд. Если все хорошо, он вернет элемент copyButton
.
Чтение заглавной буквы
Вы можете прочитать содержимое текстовых полей с помощью field.get_attribute('value')
. Но, как я уже упоминал ранее, онлайн-конвертер кейсов довольно необычен. Его выходные данные представляют собой вложенную структуру span и div, и когда вы наводите указатель мыши на каждую часть выходных данных, он говорит вам, почему он пишется с большой буквы или нет.
Я мог бы свернуть этот лабиринт и разобрать фактический заголовок, но есть более простой способ. Кнопка копирования копирует заголовок с заглавной буквы в буфер обмена. Мы можем просто нажать на кнопку и прочитать заголовок из буфера обмена. Я использовал модуль буфера обмена, который можно установить с pipenv install clipboard
. Приведенный ниже код очищает буфер обмена, копируя в него пустую строку, нажимает кнопку копирования и многократно читает буфер обмена, пока он не станет пустым.
1
2
3
4
5
6
|
clipboard.copy(»)
copyButton.click()
result = clipboard.paste()
while not result:
time.sleep(0.1)
result = clipboard.paste()
|
Использование всего документа уценки
OK. Мы можем использовать один заголовок. Я поместил весь этот код в одну функцию:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
def capitalize_heading(heading):
input_field = driver.find_element_by_id(‘title’)
input_field.clear()
input_field.send_keys(heading)
# form = driver.find_element_by_css_selector(‘body > form’)
# form.submit()
convertButton = \
driver.find_element_by_class_name(‘convertButton’)
convertButton.click()
# Wait for copy button to appear
wait = WebDriverWait(driver, 5)
buttonPresent = presence_of_element_located((By.CLASS_NAME,
‘copyButton’))
copyButton = wait.until(buttonPresent)
clipboard.copy(»)
copyButton.click()
result = clipboard.paste()
while not result:
time.sleep(0.1)
result = clipboard.paste()
return result
|
Теперь, вооружившись этой возможностью, мы можем разобрать целую статью и использовать все заголовки. Я пишу свои уроки в Markdown. Все мои заголовки начинаются с одного или нескольких хэшей (#).
Я определил вспомогательную функцию, которая берет строку и, если она содержит заголовок, правильно использует ее capitalize_heading()
используя функцию capitalize_heading()
и возвращает результат. Главное — убрать все ведущие хеши и пробелы и восстановить их позже. Мы не можем указывать заголовок пробелами, потому что это сбивает с толку онлайн конвертер дел
1
2
3
4
5
6
7
8
|
def capitalize_line(line):
tokens = line.split(‘#’)
heading = tokens[-1]
space_count = len(heading) — len(heading.lstrip())
spacing = heading[:space_count]
tokens[-1] = spacing + capitalize_heading(heading.lstrip())
result = ‘#’.join(tokens)
return result
|
На этом этапе мы можем использовать заголовок Markdown. Пришло время использовать весь документ по уценке. Этот код довольно прост: итерируйте по всем строкам, пишите с заглавной буквы каждую строку, начинающуюся с хеша, и возвращайте правильно прописной текст:
def capitalize_all_headings(markdown)
:
1
2
3
4
5
6
7
8
|
capitalized = []
lines = markdown.split(‘\n’)
for line in lines:
if line.startswith(‘#’):
line = capitalize_line(line)
print(line)
capitalized.append(line)
return ‘\n’.join(capitalized)
|
Основная функция берет входной документ Markdown, использует его заглавные буквы и сохраняет результат как «capitalized.md», который вы можете проверить и использовать. Единственное, с чем следует быть осторожным, это если ваш документ Markdown содержит не заголовочные строки, начинающиеся с хеша. Это может произойти, если вы возглавляете блоки кода, содержащие комментарии Python или bash.
Забавный факт — урок, который вы сейчас читаете, был написан с использованием этой программы.
Вывод
Автоматизация браузера позволяет программно управлять веб-приложениями, которые не предоставляют API. Это полезно в основном для заполнения форм и других интерактивных веб-действий (нажмите «Далее» в длинных лицензионных соглашениях?).
Selenium был в первую очередь предназначен для тестирования веб-приложений, но он отлично подходит для автоматизации любого взаимодействия на основе браузера. Если вы немного подумаете, вы можете найти множество веб-приложений, которые вы можете автоматизировать и сделать вашу жизнь проще.