Selenium Python
Selenium Python
Но есть ещё третий способ, мой любимый, - это менеджер контекста with/as. С этим способом
нам вообще не нужно думать о том, когда закрывать браузер, менеджер контекста делает это
за нас в тот момент, когда это нужно. ..................................................................................................... 22
Некоторые проблемы WebDriver (из сети и личного опыта):............................................................... 23
3.3 Разница основных методов поиска элемента ..................................................................................... 24
.find_element() и find_elements() .............................................................................................. 24
Как всё таки быть, если нам нужен каждый второй или третий элемент на странице ?............... 25
3.4 Задачи по материалу ................................................................................................................................ 27
3.4.1 ................................................................................................................................................................. 27
3.4.2.................................................................................................................................................................. 27
3.4.3 Сопоставьте значения из двух списков ........................................................................................ 27
3.4.4 Введите численный ответ ................................................................................................................ 27
3.4.5 Введите численный ответ ................................................................................................................ 28
3.4.6 ................................................................................................................................................................. 28
3.4.7 ................................................................................................................................................................. 29
3.4.8 ................................................................................................................................................................. 29
3.4.9 ................................................................................................................................................................. 30
3.4.10 ............................................................................................................................................................... 31
3.4.11 ............................................................................................................................................................... 32
4. Опции и аргументы .......................................................................................................................................... 32
4.1 Запуск браузера с расширениями .......................................................................................................... 32
4.2 Запуск браузера в скрытом режиме ...................................................................................................... 36
Преимущества запуска браузера в фоновом режиме. ......................................................................... 36
4.3 Перенос профиля с основного браузера Chrome в браузер под управлением Selenium ............. 37
4.4 Proxy и Selenium.......................................................................................................................................... 38
5. Основные методы ........................................................................................................................................... 40
5.1 Основные методы Selenium..................................................................................................................... 40
5.2 Cookies ......................................................................................................................................................... 42
Куки чаще всего используются для:......................................................................................................... 42
Существует два вида cookie: ...................................................................................................................... 42
5.3 Cookies на практике .................................................................................................................................. 42
.get_cookies() ........................................................................................................................................ 42
.get_cookie(name_cookie) ................................................................................................................. 43
document.body.scrollHeight ............................................................................................................ 52
window.innerHeight ....................................................................................................................................... 53
.scrollTo(0,document.body.scrollHeight)" ...................................................................................................... 53
.get_window_size() .............................................................................................................................. 68
.title_is(title) ................................................................................................................................... 82
.title_contains(title) ..................................................................................................................... 82
8.4 Задачи ..................................................................................................................................................... 83
8.4.1.................................................................................................................................................................. 83
8.4.2.................................................................................................................................................................. 83
8.4.3.................................................................................................................................................................. 84
8.4.4.................................................................................................................................................................. 84
Документация и другие ресурсы вне курса
Неофициальная документация https://selenium-python.readthedocs.io/getting-
started.html
Его перевод https://habr.com/ru/post/250921/
1 Начало
1.1 Введение в Selenium
Selenium - это бесплатная и открытая библиотека для
автоматизированного тестирования веб-приложений и автоматизации действий в
браузере.
Selenium - поддерживает все основные браузеры, но в этом курсе, мы будет говорить
только про браузер Chrome т.к. он является самым популярным браузером на планете. К
тому же использование других браузеров отличается только способом
установки webdriver'а.
!
2 Установка Selenium и WebDriver
Установка Selenium ничем не отличается от установки других модулей в python.
Установка: pip install selenium
А вот что касается WebDriver, тут дела обстоят немного сложнее.
1) Установка WebDriver
Для начала нам необходимо выяснить версию вашего браузера chrome, для этого
введите в строке поиски поиска chrome://version/
Скопируйте код, ниже и запустите у себя в IDE, если окно браузера открылось и там
загрузился stepik.org то поздравляю вас, установка выполнена успешна.
from selenium import webdriver
url = 'https://stepik.org/'
browser = webdriver.Chrome()
browser.get(url)
Комментарии учащихся:
*****
Второй набор методов поиска называется локаторами и полностью эквивалентен
первому набору методов по функционалу.
Перед использованием локатора нам необходимо его импортировать:
from selenium.webdriver.common.by import By
Локаторы - Играют очень важную роль при работе с Selenium. Они обеспечивают
путь к веб-элементам, которые необходимы для автоматизации определенных действий,
таких как клик, ввод, установка флага и др.
• By.ID – поиск по уникальному атрибуту id элемента;
• By.CSS_SELECTOR –поиск элементов с помощью правил на основе CSS;
• By.XPATH – поиск элементов с помощью языка запросов XPath;
• By.NAME – поиск по атрибуту name элемента;
• By.TAG_NAME – поиск по названию тега;
• By.CLASS_NAME – поиск по атрибуту class элемента;
• By.LINK_TEXT – поиск ссылки с указанным текстом. Текст ссылки должен быть
точным совпадением;
• By.PARTIAL_LINK_TEXT – Поиск ссылки по частичному совпадению текста.
Локаторы мы используем с помощью двух универсальных
методов find_element() который возвращает ровно один элемент который был найден
первым, и второй find_elements() который возвращаем список найденных элементов.
Сравним два способа. Найдём на странице, кнопку Купить с id="sale_button" и
совершим по ней клик.
Вариант 1. .find_element_by_id("sale_button")
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://parsinger.ru/html/watch/1/1_1.html')
button = browser.find_element_by_id("sale_button").click()
Вариант 2. .find_element(By.ID, "sale_button")
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://parsinger.ru/html/watch/1/1_1.html')
button = browser.find_element(By.ID, "sale_button").click()
Думаю разница понятна, выбирайте какой из методов поиска выбрать лично вам, и
поехали дальше.
3.1.2 Поиск элементов на странице
ps. Все примеры выполнены в браузерe Chrome.
Элементы можно находить при помощи тегов, селекторов css, атрибутов и значения
атрибута.
Например:
• id="name_id" - по идентификатору;
• class="name_class" - по имени класса;
• div - по имени тега;
• href="link" - по атрибуту;
• name="item" - по значению атрибута.
Откройте страницу в своём браузере и откройте инструмент разработчика f12,
затем откройте панель поиска по дереву HTML командой ctrl+f, для закрепления знаний
мы будем тренироваться искать элементы в браузере, затем в разделе selenium мы
перейдём к написанию парсеров, используютcя знания из этого модуля.
Поиск по #id
# - базовый селектор, который помогаем выбирать элемент по значению
атрибута id , не забывайте что id являются уникальным объектом на странице,
т.е. id может быть использован только для одного тега в HTML документа.
У нас на странице есть определённое количество тегов с уникальными id , для
поиска по id используется синтаксис #значение_атрибута т.е в нашем
случае #brand . Потренируйтесь писать поиск по id самостоятельно на других тегах, так
же можно использовать аналогичный синтаксис с квадратными
скобками, [id='brand'] сделает то же самое что и #brand , только потребует
написания большего количества символов, какой способ выбирать, решать вам.
Поиск по .class
. - базовый селектор который помогает выбирать элемент по имени класса
Аналогично мы ищем элементы по классу используя знак
точки. .имя_класса или .description , используя поиск по классу, мы находим все
элементы с данным классом. Мы с таким же успехом можем использовать синтаксис с
квадратными скобками [class="headers"]
В этом примере оба тега <p> имею одинаковый класс "text" . Для того чтобы
получить тег у которого родитель с классом "author" нам и потребуется составной
селектор.
' ' (пробел) выбирает элементы, которые находятся внутри указанного элемента
(вне зависимости от уровня вложенности).
.author .text - это означает что мы ищем class c значением атрибута author ,
а пробел указывает что нужно искать внутри этого тега, тег с классом "text" .
Элемент .text потомок элемента .author , потомок может находиться на любом
уровне вложенности от элемента .author и между ними может быть сколько угодно
других тегов.
Или второй пример, мы хотим извлечь конкретный элемент при помощи составного
селектора
.container .price_box p сайт
(этот пример не сработает на сайте тренажёре, т.к. размещён тут для наглядности.)
Искомый элемент имеет 5 классов row user user-top nav-bottom margin-
bottom , мы находим элемент всего по двум классам. Важно помнить об этой
особенности и указывать более конкретный составной селектор, чтобы в наш поиск не
попадали лишние элементы.
3.1.4 Поиск элементов при помощи XPath
Когда мы не можем найти уникальный селектор для необходимого нам элемента, на
помощь приходит поиск по XPath, поиск атрибута по его пути.
XPath - очень мощный и гибкий инструмент, в то же время и очень опасный.
1. Во-первых, XPath помогает писать сложные запросы поиска элементов.
2. Во-вторых, если разработчик сайта вдруг решил изменить порядок элементов
на странице, то весь код парсера может сломаться, т.к. искомый элемент будет не найден.
XPath - оспользует и древовидную структуру документа. Проверять XPath запросы
можно точно так же как и простые css селекторы - в консоли разработчика.
1. XPath всегда начинается с символа / или //
Символ / аналогичен символу > в CSS-селекторе, а символ // — пробелу.
• element1/element2 — выбирает элементы element2, являющиеся прямыми
потомками element1;
• element1//element2 — выбирает элементы element2, являющиеся потомками
element1 любой степени вложенности.
Разница состоит в том, что в XPath, когда мы начинаем запрос с символа /, мы
должны указать элемент, являющийся корнем нашего документа. Корнем всегда будет
элемент с тегом <html> . Пример: /html/body/header
Мы можем начинать запрос и с символа //. Это будет означать, что мы хотим найти
всех потомков корневого элемента без указания корневого элемента. В этом случае для
поиска того же хедера, мы можем выполнить запрос //header , так как других
заголовков у нас нет.
browser = webdriver.Chrome()
browser.get('http://parsinger.ru/html/watch/1/1_1.html')
button = browser.find_element(By.ID, "sale_button")
time.sleep(2)
button.click()
time.sleep(2)
browser.quit()
Если ошибка произойдёт во время выполнения кода до команды .quit() ,
сеанс WebDriver не будет закрыт должным образом и файлы не будут удалены из памяти.
А для того, чтобы гарантированно код завершил свою работу
командой browser.quit() , мы будем использовать конструкцию try/finally .
Если код падает с ошибкой, весь код после finally: будет гарантированно
выполнен.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
try:
browser = webdriver.Chrome()
browser.get('http://parsinger.ru/html/watch/1/1_1.html')
button = browser.find_element(By.ID, "sale_button")
time.sleep(2)
button.click()
time.sleep(2)
finally:
browser.quit()
Но есть ещё третий способ, мой любимый, - это менеджер контекста with/as. С этим
способом нам вообще не нужно думать о том, когда закрывать браузер, менеджер
контекста делает это за нас в тот момент, когда это нужно.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
with webdriver.Chrome() as browser:
browser.get('http://parsinger.ru/html/watch/1/1_1.html')
button = browser.find_element(By.ID, "sale_button")
time.sleep(2)
button.click()
time.sleep(2)
Выполните эти три примера у себя в терминале, чтобы посмотреть как всё работает.
И вы увидите что всё работает одинакого, и не будет никакой разницы, поэтому выбирайте
понравившийся вариант.
Так же есть два похожих метода, которые новички иногда путают между собой, о
которых самое время поговорить. это browser.close() и browser.quit() , не глядя
дальше по тексту сможете ответить в чём отличие?
browser.close() - Закрывает текущее окно браузера если во время работы вы
открыли новое окно\вкладку
browser.quit() - Закрывает все окна, вкладки, процессы вебдрайвера которые
были запущены во время сессии.
Некоторые проблемы WebDriver (из сети и личного опыта):
• Поведение Selenium может отличаться в разных браузерах;
• Иногда возникают сложности с поиском элементов (XPath и другие методы
иногда просто не работают, хотя должны);
• Необъяснимые падения драйвера прямо посреди работы скрипта;
• Взаимодействие возможно только с активной вкладкой браузера, драйвер
позволяет открывать новые вкладки и новые окна, но не позволяет одновременно в них
работать.
3.3 Разница основных методов поиска элемента
.find_element() и find_elements()
Методы .find_element() и find_elements() вы будете использовать всегда при
написании ваших парсеров с помощью selenium. Поэтому нужно понимать как с ними
работать.
У нас есть сайт, у которого структура дерева HTML очень простая. На странице есть
100 блоков <div="text"> , в котором 3 тега <p> которые не имеют ни class , ни id . Мы
решили что нам необходимо собрать каждый первый элемент <p> .мы могли бы пройти в
цикле и использовать срезы, как мы делаем с простыми списками, наверняка подумали
мы.
url = 'http://parsinger.ru/selenium/3/3.html'
with webdriver.Chrome() as browser:
browser.get(url)
link = browser.find_element(By.CLASS_NAME, 'text')
print(type(link))
url = 'http://parsinger.ru/selenium/3/3.html'
with webdriver.Chrome() as browser:
browser.get(url)
link = browser.find_element(By.CLASS_NAME, 'text')
print(link)
>>> <selenium.webdriver.remote.webelement.WebElement
(session="a7cb2c979d456b7cae336e5eafa4ad6b", element="c2651e50-25a3-41bb-ad8d-
5a259929bbfe")>
Мы видим что возвращаемый объект, это элемент selenium, который между прочим,
не поддерживает срезы. Давайте попытаемся получить элемент [0] у этого объекта, и
посмотрим на результат.
from selenium import webdriver
from selenium.webdriver.common.by import By
url = 'http://parsinger.ru/selenium/3/3.html'
with webdriver.Chrome() as browser:
browser.get(url)
link = browser.find_element(By.CLASS_NAME, 'text')
print(link[0])
url = 'http://parsinger.ru/selenium/3/3.html'
with webdriver.Chrome() as browser:
browser.get(url)
link = browser.find_element(By.CLASS_NAME, 'text')
print(link.text)
>>> 191817
121314
151715
Как всё таки быть, если нам нужен каждый второй или третий элемент на странице ?
Мы всегда можем решить эту задачу при помощи XPath.
.find_element(By.XPATH, "//div[@class='text']/p[2]" - вернёт нам второй
элемент <p> , первого найденного элемента <div class="text"> .
.find_elements(By.XPATH, "//div[@class='text']/p[2]" - Соответственно
вернёт все найденные элементы <p> расположенные на вторых позиция, во всех
найденных <div class="text">
3.4 Задачи по материалу
3.4.1
3.4.2
Вставьте правильный импорт локатора By.
from selenium.webdriver.common.by import By
url = 'http://parsinger.ru/selenium/2/2.html'
url = 'https://parsinger.ru/selenium/2/2.html'
try:
browser = webdriver.Chrome()
browser.get(url)
link_to_click = browser.find_element(By.PARTIAL_LINK_TEXT, '16243162441624')
link_to_click.click()
result = browser.find_element(By.ID, 'result')
print(result.text)
finally:
browser.quit()
3.4.6
1. Откройте сайт;
2. Извлеките данные из каждого тега <p>;
3. Сложите все значения, их всего 300 шт;
4. Напишите получившийся результат в поле ниже.
РЕШЕНИЕ
from selenium import webdriver
from selenium.webdriver.common.by import By
3.4.7
1. Откройте сайт;
2. Извлеките данные из каждого второго тега <p> ;
3. Сложите все значения, их всего 100 шт;
4. Напишите получившийся результат в поле ответа.
РЕШЕНИЕ
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.common.by import By
3.4.8
1. Откройте сайт;
2. Установите все чек боксы в положение checked при помощи selenium и
метода click() ;
3. Когда все чек боксы станут активны, нажмите на кнопку;
4. Скопируйте число которое появится на странице;
5. Результат появится в <p id="result">Result</p> ;
6. Вставьте число в поле для ответа.
РЕШЕНИЕ
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
Задача
1. Откройте сайт;
2. Установите все чек боксы в положение checked при помощи selenium и
метода click() ;
3. Должны быть установлены те чек боксы, значение value="" которых, есть в
списке numbers ;
4. Когда все необходимые чек боксы станут checked , кнопка станет активной, нажмите
на неё и скопируйте результат
5. Результат появится в <p id="result">Result</p> ;
6. Вставьте число в поле для ответа.
numbers = [1, 2, 3, 4, 8, 9, 11, 12, 13, 14, 15, 16, 17, 22, 23, 28, 29,
33, 34, 38,
39, 43, 44, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 68,
69, 73,
74, 78, 79, 83, 84, 88, 89, 91, 92, 97, 98, 101, 104, 108, 109, 113, 114,
118,
119, 123, 124, 128, 129, 131, 132, 137, 138, 140, 141, 144, 145, 148,
149, 153,
154, 158, 159, 163, 164, 165, 168, 169, 171, 172, 177, 178, 180, 181,
184, 185,
187, 188, 189, 190, 192, 193, 194, 195, 197, 198, 199, 200, 204, 205,
206, 207,
208, 209, 211, 212, 217, 218, 220, 221, 224, 225, 227, 228, 229, 230,
232, 233,
234, 235, 237, 238, 239, 240, 245, 246, 247, 248, 249, 251, 252, 253,
254, 255,
256, 257, 258, 260, 261, 264, 265, 268, 269, 273, 274, 278, 279, 288,
289, 291,
292, 293, 294, 295, 296, 297, 300, 301, 302, 303, 304, 305, 308, 309,
313, 314,
318, 319, 328, 329, 331, 332, 339, 340, 341, 342, 343, 344, 345, 346,
348, 349,
353, 354, 358, 359, 368, 369, 371, 372, 379, 380, 385, 386, 408, 409,
411, 412,
419, 420, 425, 426, 428, 429, 433, 434, 438, 439, 444, 445, 446, 447,
448, 451,
452, 459, 460, 465, 466, 467, 468, 469, 470, 472, 473, 474, 475, 477,
478, 479,
480, 485, 486, 487, 488, 491, 492, 499, 500, 505, 506, 508, 509, 513,
514, 518, 519]
РЕШЕНИЕ
import time
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.common.by import By
number = [1, 2, 3, 4, 8, 9, 11, 12, 13, 14, 15, 16, 17, 22, 23, 28, 29, 33, 34, 38,
39, 43, 44, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 68, 69, 73,
74, 78, 79, 83, 84, 88, 89, 91, 92, 97, 98, 101, 104, 108, 109, 113, 114, 118,
119, 123, 124, 128, 129, 131, 132, 137, 138, 140, 141, 144, 145, 148, 149, 153,
154, 158, 159, 163, 164, 165, 168, 169, 171, 172, 177, 178, 180, 181, 184, 185,
187, 188, 189, 190, 192, 193, 194, 195, 197, 198, 199, 200, 204, 205, 206, 207,
208, 209, 211, 212, 217, 218, 220, 221, 224, 225, 227, 228, 229, 230, 232, 233,
234, 235, 237, 238, 239, 240, 245, 246, 247, 248, 249, 251, 252, 253, 254, 255,
256, 257, 258, 260, 261, 264, 265, 268, 269, 273, 274, 278, 279, 288, 289, 291,
292, 293, 294, 295, 296, 297, 300, 301, 302, 303, 304, 305, 308, 309, 313, 314,
318, 319, 328, 329, 331, 332, 339, 340, 341, 342, 343, 344, 345, 346, 348, 349,
353, 354, 358, 359, 368, 369, 371, 372, 379, 380, 385, 386, 408, 409, 411, 412,
419, 420, 425, 426, 428, 429, 433, 434, 438, 439, 444, 445, 446, 447, 448, 451,
452, 459, 460, 465, 466, 467, 468, 469, 470, 472, 473, 474, 475, 477, 478, 479,
480, 485, 486, 487, 488, 491, 492, 499, 500, 505, 506, 508, 509, 513, 514, 518, 519]
3.4.10
Выпадающие списки
Работа с выпадающими списками практически ничем не отличается от работы с чек
боксами или полями.
Для того чтобы получить значение любого элемента из выпадающего списка, мы
может использовать привычные нам методы поиска элемента.
В нашем случае на нашем сайте все элементы выпадающего списка, могут быть
спокойно найдены по тегу, метод By.TAG_NAME нам в этом поможет.
from selenium import webdriver
from selenium.webdriver.common.by import By
>>> 98016191141
Задача
1. Открываем сайт с помощью selenium;
2. Получаем значения всех элементов выпадающего списка;
3. Суммируем(плюсуем) все значения;
4. Вставляем получившийся результат в поле на сайте;
5. Нажимаем кнопку и копируем длинное число;
6. Вставляем конечный результат в поле ответа.
РЕШЕНИЕ
from selenium.webdriver.common.by import By
from selenium import webdriver
3.4.11
1. Откройте сайт при помощи selenium;
2. Решите уравнение на странице;
3. Найдите и выберите в выпадающем списке элемент с числом, которое у вас
получилось после решения уравнения;
4. Нажмите на кнопку;
5. Скопируйте число и вставьте в поле ответа.
РЕШЕНИЕ
from selenium.webdriver.common.by import By
from selenium import webdriver
4. Опции и аргументы
4.1 Запуск браузера с расширениями
Чтобы запустить браузер с предустановленным на него расширением, нам для
начала необходимо это расширение подготовить. В Chrome существует магазин
расширений, надеюсь об этом все знают и хоть раз в жизни пользовались им.
Давайте найдём расширение которое помогает определять координаты курсора.
Которое кстати поможет решить одну из задачек. Называется coordinates и скачать его
можно по ссылке, установите его привычным образом.
Для того чтобы подготовить расширение должным образом, нам необходимо его
упаковать. Для этого запустим Chrome и перейдем в раздел
расширений chrome://extensions ("Меню" → "Настройки" → "Расширения") → далее,
отметим чекбокс (флажок) "Режим разработчика" → "Упакованное расширение"
(скриншот) укажем путь куда необходимо сохранить расширение. → "ОК".
options_chrome = webdriver.ChromeOptions()
options_chrome.add_extension('coordinates.crx')
options_chrome = webdriver.ChromeOptions()
options_chrome.add_argument('--headless')
>>>
https://passport.yandex.ru/auth?origin=home_yandexid&retpath=https%3A%2F%2Ffanyv88.com%3A443%2Fhttps%2Fyand
ex.ru&backpath=https%3A%2F%2Ffanyv88.com%3A443%2Fhttps%2Fyandex.ru
options_chrome = webdriver.ChromeOptions()
options_chrome.add_argument('user-data-
dir=C:\\Users\\user\\AppData\\Local\\Google\\Chrome\\User Data')
with webdriver.Chrome(options=options_chrome) as browser:
url = 'https://yandex.ru/'
browser.get(url)
time.sleep(10)
url = 'https://2ip.ru/'
with webdriver.Chrome() as browser:
browser.get(url)
print(browser.find_element(By.ID,
'd_clip_button').find_element(By.TAG_NAME, 'span').text)
time.sleep(5)
>>> 95.27.00.01
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
proxy = ['8.210.83.33:80']
url = 'https://2ip.ru/'
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % proxy)
browser.set_page_load_timeout(5)
proxy_list.remove(PROXY)
except Exception as _ex:
print(f"Превышен timeout ожидания для - {PROXY}")
continue
В этом примере, есть список прокси proxy_list , по которому мы итерируемая в
цикле for , передавая на каждой итерации в переменную PROXY , следующий IP из этого
списка. В этом примере мы применили конструкцию try/except, чтобы наш скрипт не падал
с ошибкой, и продолжал работать. Если не обернуть код в try/except, мы после каждого
истёкшего timeout= будем получать ошибку: Message: unknown error:
net::ERR_TUNNEL_CONNECTION_FAILED .
timeout в Selenium применяется методом .set_page_load_timeout(5) где цифра 5
длительность в секундах.
p.s. Если вы найдёте работающий прокси, то этот код напечатает вам его в консоль
=)
5. Основные методы
•
• webdriver.forward() - вернутся вперёд, равнозначно стрелочке "вперёд" в
браузере;
•
• webdriver.refresh() - обновляет активную страницу в браузере, равнозначно
стрелочке обновить;
•
• webdriver.get_screenshot_as_file("../file_name.jpg") - ожидает полной
загрузки страницы и сохраняет скриншот в указанной папке. Возвращает False, если есть
ошибка ввода-вывода, иначе возвращает True;
• webdriver.save_screenshot("file_name.jpg") - ожидает полной загрузки
страницы и сохраняет скриншот в папке с проектом;
• webdriver.get_screenshot_as_png() - сохраняет скриншот в виде двоичных
данных, которые можно передать или сохранить в файл в конструкторе with/as ;
• webdriver.get_screenshot_as_base64() -после загрузки страницы, получает
скриншот текущего окна в виде строки в кодировке base64. Полезно во встроенных
изображениях в HTML;
• webdriver.get("http://example_url.ru") - метод получает ссылку которая
откроется в браузере;
• webdriver.quit() - метод разрывает все соединения установленные браузеров,
очищает после себя оперативную память;
• webdriver.close() - закрывает текущую вкладку;
• webdriver.execute_script("script_code") - исполняет на странице
переданный JavaScript код;
• webdriver.execute_async_script("script_code" , *args ) - асинхронно
выполняет код JavaScript на странице;
• webdriver.set_page_load_timeout() - устанавливает timeout ожидания
загрузки страницы после чего выбрасывает исключение;
• webdriver.find_element("element" or "locator- By.") - возвращает
первый найденный элемент соответствующий локатору или элементу;
• webdriver.find_elements("element" or "locator- By.") -
возвращает resultSet найденных элементов, с ним можно работать как со списком;
• webdriver.get_window_position() - возвращает позицию открытого окна
браузера, возвращается словарь {'x': 10, 'y': 50} ;
• webdriver.maximize_window() - разворачивает текущее окно;
•
• webdriver.minimize_window() - сворачивает текущее окно;
•
• webdriver.fullscreen_window() - максимизирует активное окно браузера,
аналогично нажатию клавиши F11;
• webdriver.get_window_size() - получает текущий размер окна браузера + рамки
окна и панель управления браузера, возвращает словарь {'width': 945, 'height': 1020} ;
• webdrive.set_window_size(800,600) - устанавливает высоту и ширину
браузера;
• webdriver.get_cookies() - возвращает словарь с cookies;
• webdriver.get_cookie(name_cookie) - возвращает набор cookie по его имени;
• webdriver.add_cookie(cookie_dict) - добавляет cookie к вашему текущему
сеансу;
• webdriver.delete_cookie(name_cookie) - удаляет cookie с заданным именем;
• webdriver.delete_all_cookies() - удаляет все файлы cookie в рамках
текущего сеанса;
• webdriver.implicitly_wait(10) - устанавливает неявное ожидание поиска
элемента, или для команды завершения;
• webdriver.click(webelement) - совершает клик по выбранному элементу,
клик возможен только по интерактивному элементу.
5.2 Cookies
Ку́ки (cookie, букв. — «печенье») - небольшой фрагмент данных, отправленный веб-
сервером и хранимый на компе пользователя. Когда вы открываете сайт, сервер
отправляет вашему браузеру данные которые хранятся в его памяти.
Куки чаще всего используются для:
• Аутентификации пользователя;
• Хранение личных настроек на сайте, к примеру тёмная тема или сохранение товаров
в корзине если вы не залогинились на сайте ;
• Отслеживание состояния сеанса доступа пользователя;
• Сведения статистики о пользователях;
• Хранения информации о местоположении пользователя и IP-адресе;
• Клики и переходы;
• версию операционной системы и браузера;
• И многое другое.
«Cookies не являются персональными данными, так как в законе сказано что
персональные данные — это информация, позволяющая идентифицировать человека.
Даже фамилия, имя и отчество могут не являться персональными данными, если
требуются дополнительные сведения, чтобы определить личность человека. Не говоря
уже о cookies».
Существует два вида cookie:
• Сессионные(временные) - это те куки которые хранят в себе информацию которая
актуальна ближайшее время, к примеру к таким данным можно отнести записи форм, полей, время
пребывание на сайте. Чаще всего они существуют пока вы находитесь на сайте и удаляются как
только вы его покидаете;
• Постоянные - это те куки которые могут хранится в вашем браузере очень долго,
например логин от вашей учётной записи на сайте или другие данные которые связаны с вашей
учётной записью. Это может быть данные о вашем местоположении в учётной записи гугла.
Что бы увидеть какие cookie сохраняет сайт в вашем браузере, вам нужно открыть
инструмент разработчика клавишей F12;
В Selenium мы можем получить доступ ко всем cookie сразу в виде словаря, либо к
конкретному полю, об этом в следующий степах.
5.3 Cookies на практике
.get_cookies()
В коде ниже использован метод .get_cookies() который получает список
всех cookie на странице. Выполните код ниже у себя в терминале.
from pprint import pprint
from selenium import webdriver
>>>
[{'domain': '.yandex.ru',
'expiry': 1685518907,
'httpOnly': False,
'name': '_ym_d',
'path': '/',
'sameSite': 'None',
'secure': True,
'value': '1653982908'},
...
{'domain': '.yandex.ru',
'expiry': 1656574906,
'httpOnly': False,
'name': 'yandex_gid',
'path': '/',
'sameSite': 'None',
'secure': True,
'value': '239'}]
.get_cookie(name_cookie)
В отличии от первого метода, этот метод находит возвращает cookie по его имени,
для того чтобы определить имя есть 2 способа.
• Способ №1 - этот способ не очень надёжен, т.к. с "живого" браузера данные
в cookies могут отличаться в зависимости от открытой сессии. Но если ваш код не зависит от
параметров сессии то можно получить имена cookie именно в браузере;
• Способ №2 - мы можем в цикле for/in итерироваться по списку cookie который мы
получили с помощью метода .get_cookies() . Этим способом мы можем получить не только
имя cookie но и его значение;
• from selenium import webdriver
•
• with webdriver.Chrome() as webdriver:
• webdriver.get('https://yandex.ru/')
• cookies = webdriver.get_cookies()
• for cookie in cookies:
• print(cookie['name']) # или cookie['value'] чтобы получить их
значение
• >>>
• _ym_d, _ym_isad, _ym_uid, my, gdpr, _yasc, i, is_gdpr, yuidss
• yabs-frequency, is_gdpr_b, yandexuid, yp, mda, ymex, yandex_gid
•
• Когда мы знаем имена всех cookie на странице мы можем получить нужные нам данные
по ключу. Мы помним что .get_cookies() возвращает список словарей. Если вы посмотрите на
первый пример с кодом, вы увидите что в cookie хранится время экспирации 'expiry': 1685518907 ,
т.е. истечения срока жизни cookie. Пример кода ниже, поможет нам извлечь конкретное значение
из cookie.
• from selenium import webdriver
•
• with webdriver.Chrome() as webdriver:
• webdriver.get('https://yandex.ru/')
• print(webdriver.get_cookie('_ym_uid')['expiry'])
•
• >>>1685520499
5.4 Добавление cookie
webdriver.add_cookie(cookie_dict)
Все мы когда то чистили браузер от печенек( cookie), наверное каждый начинающий
программист знает, что если очистить cookie то настройки сайта слетят, слетит учётная
запись, тёмная тема перестанет загружаться по умолчанию, сайт вдруг перестанет
приветствовать вас по имени. Всем понятно зачем чистить куки, а вот зачем их добавлять
в браузер? Добавляем мы их по обратной причине. Когда мы работаем с Selenium мы не
всегда можем использовать один профиль браузера в нескольких сриптах. В таких
случаях мы можем либо создать ещё несколько профилей, либо использовать
одни cookie на все скрипты.
.add_cookie(cookie_dict) - это метод который добавляет cookie в ваш браузер.
Принимает словарь, но с определёнными ограничениями, мы не можем передать
в cookie что попало. В браузере есть заранее подготовленные поля в которые мы можем
передавать данные.
Доступные поля для cookie, посмотреть их можно в любом браузере, эти поля
доступны для передаче их в словаре, как формировать словарь мы поговорим ниже.
• "name" - устанавливает имя cookie файла;
• "value" - устанавливает значение cookie, это значение может либо
идентифицировать пользователя, либо содержать любую другую служебную информацию;
• "expires" и "max-age" - определяет срок жизни cookie, после истечении этого
срока cookie будет удалён из памяти браузера, если не указывать эти значения,
содержимое cookie будет удалено после закрытия браузера ;
• "path" - указывает путь к директории на сервере, для которой будут
доступны cookie , чтобы cookie были доступны по всему домену необходимо указать / ;
• "domain" - хранит в себе информацию о домене или поддомене которые имеет
доступ к этой cookie, если необходимо чтоб cookie были доступны по всему домену и всем
поддоменом, указывается базовый домен, к примеру www.example.ru;
• "secure" - указывает серверу что cookie должны передавать только по
защищённому https-соединению;
• "httponly" - параметр запрещает доступ к cookie посредством API браузера
• document.cookie . Предотвращает кражи cookie посредством XSS-атак. Если флаг
установлен True, вы сможете получить доступ к этой cookie только через браузер в том числе и
через Selenium;
• "samesite" - ограничивает передачу cookie между сайтами, предотвращает
кражу cookie посредством XSS-атак. Имеет 3 состояния;
• samesite=none - на передачу cookie нет никаких ограничений;
• samesite=lax - разрешает передачу только безопасным HTTP методом;
• samesite=strict или samesite - самое строгое состояние, которое запрещает
отправку cookie на другие сайты.
Запустите код ниже у себя в терминале, поиграйтесь с параметрами, посмотрите на
результат, найдите изменения в браузере.
import time
from pprint import pprint
from selenium import webdriver
cookie_dict = {
'name': 'any_name_cookie', # Любое имя для cookie
'value': 'any_value_cookie', # Любое значение для cookie
'expiry': 2_000_000_000, # Время жизни cookie в секундах
'path': '/', # Директория на сервере дял которой
будут доступны cookie
'domain': 'parsinger.ru', # Информация о домене и поддомене для
которых доступны cookie
'secure': True, # or False # Сигнал браузера о том что передать
cookie только по защищённому HTTPS
'httpOnly': True, # or False # Ограничивает достук к cookie по
средствам API
'sameSite': 'Strict', # or lax or none # Ограничение на передачу
cookie между сайтами
}
5.6.2
1. Откройте сайт с помощью Selenium;
2. На сайте есть определённое количество секретных cookie;
3. Ваша задача получить все значения и суммировать их;
4. Полученный результат вставить в поле для ответа.
РЕШЕНИЕ
from selenium import webdriver
5.6.3
1. Откройте сайт с помощью Selenium;
2. Ваша задача получить все значения cookie с чётным или кратным 10 числа после "_" и
суммировать их;
3. Полученный результат вставить в поле для ответа.
РЕШЕНИЕ
from selenium import webdriver
5.6.5 Задача
5.6.6 Перекрытие элементов. Запуск JS
РЕШЕНИЕ
from selenium import webdriver
from selenium.webdriver.common.by import By
url = 'http://parsinger.ru/scroll/4/index.html'
res = []
with webdriver.Chrome() as browser:
browser.get(url)
for x in browser.find_elements(By.CLASS_NAME, "btn"):
browser.execute_script("return arguments[0].scrollIntoView(true);", x)
x.click()
res.append(int(browser.find_element(By.ID, 'result').text))
print(sum(res))
6. Скроллинг страниц
6.1 способ 1 execute_script() Прокрутка страницы
Полоса прокрутки представляет собой тонкую длинную часть на краю дисплея
компьютера. Используя полосу прокрутки, мы можем просматривать весь контент или
всю страницу, прокручивая ее вверх-вниз или влево-вправо с помощью мыши.
Самый простой способ прокрутки страницы по пикселю, это использования
метода execute_script() который выполняет код javascript на странице. К
примеру window.scrollBy(0,5000) прокрутит страницу вниз на 5000 пикселей.
Можете проверить на этом сайте
window.scrollBy(X, Y);
• X - смещение в пикселях по горизонтали;
• Y - смещение в пикселях по вертикали.
import time
from selenium import webdriver
document.body.scrollHeight
return document.body.scrollHeight вернёт значение высоты основного элемента
на странице - body
import time
from selenium import webdriver
>>>81000
window.innerHeight
81000 пикселей имеет в высоту наш сайт. Для того чтобы вычислить высоту
видимой области сайта, используется скрипт
Используется код window.innerHeight для получения высоты
или window.innerWidth для получения ширины видимой области
from selenium import webdriver
>>> 887
.scrollTo(0,document.body.scrollHeight)"
887 пикселей имеет видимая часть нашего сайта. Иногда необходимо чтобы
требуемый элемент находился в видимой области, т.к. методы .click() , .send_keys() и
другие. Не могут быть совершены если элемент не находится в видимой области экрана.
Так же, если вам необходимо совершить скроллинг в самый низ к последнему
пикселю одним из самых простых способов, то используйте
скрипт "window.scrollTo(0,document.body.scrollHeight)"
import time
from selenium import webdriver
Запустите этот код у себя в терминале и увидите, что этот код поочерёдно
выделяет(берёт в фокус) все <input> на странице. Наш сайт тренажёр довольно
примитивен и отдаёт весь список тегов <input> разом.
Для понимания следующего примера, откройте любой степ на степике, у которого
более 100 комментариев, и попробуйте пролистать к самому последнему комментарию.
Вы увидите несколько загрузок с сервера. Приведённый выше пример с
циклом for обработал бы только первые 17 элементов, т.к. они были загружены при
открытии страницы. Для того чтобы решить эту проблему и обрабатывать все
подгружаемые элементы, давайте модифицируем этот код.
import time
from selenium.webdriver import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
list_input = []
while True:
input_tags = [x for x in browser.find_elements(By.TAG_NAME,
'input')]
for tag_input in input_tags:
if tag_input not in list_input:
tag_input.send_keys(Keys.DOWN)
tag_input.click()
time.sleep(1)
list_input.append(tag_input)
Мы совсем чуть-чуть усложнили этот код = ).
Мы добавили бесконечный цикл while для того, чтобы добраться абсолютно до
всех элементов на странице, в этом коде отсутствует условие прерывание бесконечного
цикла, но об этом поговорим дальше.
[x for x in browser.find_elements(By.TAG_NAME, 'input')] генерирует список
из всех найденных на странице элементов, тегов <input> , при каждой новой загрузке
данных с сервера.
list_input.append(tag_input) , в конце цикла for , добавляет элемент в
список list_input , который мы создали для того, чтобы хранить все элементы, с
которыми уже взаимодействовали, чтобы не взаимодействовать с ним дважды.
if tag_input not in list_input: это условие проверяет, есть ли элемент в
контрольном списке list_input , если элемент отсутствует, то совершаем
взаимодействие tag_input.click()
Запустите последний пример у себя в терминале и понаблюдайте за происходящим,
всё куда проще чем кажется.
Доступные к применению клавиши
ADD ALT ARROW_DOWN
EQUALS ESCAPE F1
F2 F3 F4
F5 F6 F7
F8 F9 HELP
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform(
)
Когда мы пишем код, мы можем синтаксически разрывать цепочку, ведь каждое
написанное действие хранится в очереди объекта ActionChains.
menu = driver.find_element(By.CSS_SELECTOR, ".nav")
hidden_submenu = driver.find_element(By.CSS_SELECTOR, ".nav #submenu1")
action = ActionChains(driver)
time.sleep(1)
action.move_to_element(menu)
time.sleep(1)
action.click(hidden_submenu)
time.sleep(1)
action.perform()
Для примера, чтобы переместится к определённому элементу и кликнуть по нему, мы
напишем следующий код
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
result = []
with webdriver.Chrome() as browser:
browser.get('http://parsinger.ru/scroll/2/')
6.5.2
1. Откройте сайт сайт с помощью Selenium;
2. Ваша задача, получить числовое значение id="число" с каждого
тега <input> который при нажатии вернул число;
3. Суммируйте все значения и отправьте результат в поле ниже.
На целевом сайте 300 тегов. Чтобы сэкономить вам время, мы позаботились о мини
версии сайта, на нём всего 10 тегов. При правильном решении задачи, на тестовом сайте
получившийся результат будет равен 18
РЕШЕНИЕ
from selenium.webdriver import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
result = []
with webdriver.Chrome() as browser:
browser.get('http://parsinger.ru/scroll/3/')
print(sum(result))
6.5.3
1. Откройте сайт с помощью Selenium;
2. На сайте есть список из 100 элементов, которые генерируются при скроллинге;
3. В списке есть интерактивные элементы, по которым можно осуществить скроллинг
вниз;
1. Используйте Keys.DOWN или .move_to_element() ;
4. Цель: получить все значение в элементах, сложить их;
5. Получившийся результат вставить в поле ответа.
Подсказка:
Элементы могут грузится медленнее чем работает ваш код, установите задержки.
Подумайте над условием прерывания цикла, последний элемент в списке
имеет class="last-of-list"
РЕШЕНИЕ
from selenium.webdriver import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
url = 'http://parsinger.ru/infiniti_scroll_1/'
with webdriver.Chrome() as browser:
browser.get(url)
time.sleep(1)
count = 0
checking = []
result = []
while True:
input_list = [x for x in browser.find_element(By.ID, 'scroll-
container').find_elements(By.TAG_NAME, 'input')]
6.5.4
Для скроллинга окна используйте .scroll_by_amount(delta_x, delta_y)
1. Откройте сайт с помощью Selenium;
2. На сайте есть список из 100 элементов, которые генерируются при скроллинге;
3. Необходимо прокрутить окно в самый низ;
4. Цель: получить все значение в элементах, сложить их;
5. Получившийся результат вставить в поле ответа.
РЕШЕНИЕ
import time
6.5.5
1. Откройте сайт с помощью Selenium
2. На сайте есть 5 окошек с подгружаемыми элементами, в каждом по 100 элементов;
3. Необходимо прокрутить все окна в самый низ;
4. Цель: получить все значение в каждом из окошек и сложить их;
5. Получившийся результат вставить в поле ответа.
РЕШЕНИЕ
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
start = time.time()
url = 'http://parsinger.ru/infiniti_scroll_3/'
options_chrome = webdriver.ChromeOptions()
options_chrome.add_extension('coordinates.crx')
result = []
while True:
ActionChains(browser).scroll(85, 275, 85, 275).perform()
ActionChains(browser).scroll(280, 300, 280, 300).perform()
ActionChains(browser).scroll(480, 300, 480, 300).perform()
ActionChains(browser).scroll(680, 320, 680, 320).perform()
ActionChains(browser).scroll(900, 300, 900, 300).perform()
catch_last_elem = [x for x in browser.find_element(By.ID, 'scroll-
container_5').find_elements(By.TAG_NAME, 'span') if x.get_attribute('class')]
if catch_last_elem:
[result.append(int(x.text)) for x in browser.find_element(By.CLASS_NAME,
'main').find_elements(By.TAG_NAME, 'span')]
break
print(sum(result))
print(f'Time is running{time.time() - start}')
7. Окна и вкладки
7.1 Вкладки в браузере
При работе в браузере, мы можем открывать новые вкладки и работать в них. Мы
можем открыть любое количество вкладок одновременно, но работать мы можем только
в активной. Мы можем переключаться между вкладками, получить их title, проходить по
вкладкам в цикле, получить их дескрипторы, практически всё то, что вы делаете вручную.
Вам может понадобится собрать данные со второй вкладки, не отвлекаясь на
первую. Или сайт который вы парсите ,открывает ссылки в новой вкладке, такое
происходит если у ссылок есть атрибут target="_blank" .
Дескриптор - это идентификатор вкладки браузера, в Opera и Chrome дескрипторы
выглядят одинаково, CDwindow-8696D8A3F222B281BB03FC1EC259B251, а в Firefox они
выглядят немного иначе, d8e0e954-bf72-4eae-a63e-5ea404c3b0eb. Дескрипторы - это те
сущности которые помогают нам манипулировать вкладками.
• .current_window_handle - возвращает дескриптор текущей вкладки;
• .window_handles - возвращает список всех дескрипторов открытых вкладок;
• .switch_to.window(window_handles[0]) - переключает фокус между
вкладками.
Запустите код ниже, чтобы посмотреть как он работает. Этот код открывает первую
вкладку методом .get("URL") далее, открывает ещё 3 вкладки
методом .execute_script() и в после этого печатает все дескрипторы открытых
вкладок.
import time
from selenium import webdriver
with webdriver.Chrome() as browser:
result = []
browser.get('http://parsinger.ru/blank/2/1.html')
time.sleep(1)
browser.execute_script('window.open("http://parsinger.ru/blank/2/2.html",
"_blank1");')
browser.execute_script('window.open("http://parsinger.ru/blank/2/3.html",
"_blank2");')
browser.execute_script('window.open("http://parsinger.ru/blank/2/4.html",
"_blank3");')
time.sleep(2)
print(browser.window_handles)
browser.execute_script('window.open("http://parsinger.ru/blank/2/1.html",
"_blank1");')
browser.execute_script('window.open("http://parsinger.ru/blank/2/2.html",
"_blank2");')
browser.execute_script('window.open("http://parsinger.ru/blank/2/3.html",
"_blank3");')
browser.execute_script('window.open("http://parsinger.ru/blank/2/4.html",
"_blank4");')
for x in range(len(browser.window_handles)):
#reversed(range(len(browser.window_handles))) Для итерирования по порядку
browser.switch_to.window(browser.window_handles[x])
for y in browser.find_elements(By.CLASS_NAME, 'check'):
y.click()
Для того чтобы лучше понять как происходит итерирование по вкладкам, я создал
следующий пример, запустите код ниже у себя в терминале, и попытайтесь понять, как
происходит итерирование. Так же обратите внимание на то, что вкладка с именем data; не
возвращает своего имени, т.к. не содержит тега <title> .
import time
from selenium import webdriver
with webdriver.Chrome() as browser:
time.sleep(1)
browser.execute_script('window.open("http://parsinger.ru/blank/0/1.html",
"_blank1");')
browser.execute_script('window.open("http://parsinger.ru/blank/0/2.html",
"_blank2");')
browser.execute_script('window.open("http://parsinger.ru/blank/0/3.html",
"_blank3");')
browser.execute_script('window.open("http://parsinger.ru/blank/0/4.html",
"_blank4");')
browser.execute_script('window.open("http://parsinger.ru/blank/0/5.html",
"_blank5");')
browser.execute_script('window.open("http://parsinger.ru/blank/0/6.html",
"_blank6");')
for x in range(len(browser.window_handles)):
browser.switch_to.window(browser.window_handles[x])
time.sleep(1)
print(browser.execute_script("return document.title;"),
browser.window_handles[x])
Получаем title вкладки
title - это то что содержится в HTML тегах <title>Текст на вкладке</title> и то что
отображается на вкладке браузера.
Для того чтобы получить имя вкладки т.е. её title , используется
метод .execute_script("return document.title;") в который мы передали
код Javascript, который возвращает имя вкладки.
Запустите код ниже, у себя в терминале. Этот код откроет степик, и напечатает вам в
консоли title вкладки.
import time
from selenium import webdriver
with webdriver.Chrome() as browser:
browser.get('http://parsinger.ru/window_size/1/')
browser.set_window_size(1200, 720)
time.sleep(5)
Рабочая область сайта в данном случае будет равна x:1184px, y:587px, не путайте с
общим размером окна браузера.
• 16px занимают боковые границы браузера левая и правая;
• 133px занимает верхняя панель управления браузера и нижняя граница.
•
Учитывайте эту особенность при написании кода для будущих парсеров и решения
задач.
.get_window_size()
Для получения размеров окна браузера используется метод .get_window_size() , у
него есть метод .get() , который принимает 2
параметра 'height' и 'width' соответственно они возвращают высоту и ширину окна
браузера.
>>> 720
1200
При вызове метода .get_window_size() в ответ мы получим словарь, который
содержит ширину и высоту окна браузера.
Как и при работе с любым словарём, мы можем получить доступ к ширине или
высоте по ключу ["width"] и ["height"] .
>>> 1200
720
•
2. Prompt - запрашивает у пользователя ввод каких-либо текстовых данных, содержит
кнопки "ОК" и "Отмена";
•
3. Confirm - выводит окно с вопросом, содержит кнопки "ОК" и "Отмена".
•
Модальное окно Alert
Код ниже, выполнит клик на кнопку с id="alert" вызвав тем самым модальное
окно alert, переключит на него свой фокус функцией browser.switch_to.alert и в принте
распечатает содержимое title этого окна.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
РЕШЕНИЕ
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
РЕШЕНИЕ
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
7.4.3
1. Откройте сайт при помощи Selenium;
2. На сайте есть список пин-кодов и только один правильный;
3. Для проверки пин-кода используйте кнопку "Проверить"
4. Ваша задача, найти правильный пин-код и получить секретный код;
5. Вставьте секретный код в поле для ответа.
РЕШЕНИЕ
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
7.4.4
• Откройте сайт с помощью selenium;
• Необходимо открыть окно таким размером, чтобы рабочая область страницы
составляла 555px на 555px;
• Учитывайте размеры границ браузера;
• Результат появится в id="result" ;
• Вставьте полученный результат в поле для ответа.
РЕШЕНИЕ
from selenium import webdriver
from selenium.webdriver.common.by import By
with webdriver.Chrome() as browser:
browser.get('http://parsinger.ru/window_size/1/index.html')
browser.set_window_size(555 + 16, 555 + 133)
print(browser.find_element(By.ID, 'result').text)
7.4.5
• Откройте сайт с помощью selenium;
• У вас есть 2 списка с размерами size_x и size_y;
• При сочетании размеров из этих списков, появится число;
• Результат появится в id="result" ;
• Скопируйте результат в поле для ответа.
ps. При написании кода, учитывайте размер рамок браузера.
window_size_x = [516, 648, 680, 701, 730, 750, 805, 820, 855, 890, 955,
1000]
window_size_y = [270, 300, 340, 388, 400, 421, 474, 505, 557, 600, 653,
1000]
РЕШЕНИЕ
from selenium.webdriver.common.by import By
from selenium import webdriver
url = 'http://parsinger.ru/window_size/2/index.html'
size_x = [516, 648, 680, 701, 730, 750, 805, 820, 855, 890, 955, 1000]
size_y = [270, 300, 340, 388, 400, 421, 474, 505, 557, 600, 653, 1000]
with webdriver.Chrome() as browser:
browser.get(url)
for x in size_x:
for y in size_y:
browser.set_window_size(16 + x, 133 + y)
try:
res = browser.find_element(By.ID, 'result').text
if res:
print(res)
except:
pass
7.4.6
Для этой задачи потребуется код с прошлого степа.
• Откройте сайт с помощью selenium;
• У вас есть 2 списка с размера окон size_x и size_y;
• Цель: определить размер окна, при котором, в id="result" появляется число;
• Результат должен быть в виде словаря {'width': size_x, 'height': size_y}
ps. При написании кода, учитывайте размер рамок браузера.
Размеры рамок могут зависеть от вашего разрешения и масштабирования экрана.
Задача составлена при 100% масштабировании, масштабирование можно проверить в
настройках дисплея.
window_size_x = [516, 648, 680, 701, 730, 750, 805, 820, 855, 890, 955,
1000]
window_size_y = [270, 300, 340, 388, 400, 421, 474, 505, 557, 600, 653,
1000]
На вход ожидается словарь {'width': 000, 'height':000} где размеры указаны без учёта
размеров рамок браузера, т.е. необходимо указать размер рабочей области браузера.
РЕШЕНИЕ
from selenium.webdriver.common.by import By
from selenium import webdriver
url = 'https://parsinger.ru/window_size/2/index.html'
size_x = [516, 648, 680, 701, 730, 750, 805, 820, 855, 890, 955, 1000]
size_y = [270, 300, 340, 388, 400, 421, 474, 505, 557, 600, 653, 1000]
for x in size_x:
for y in size_y:
browser.set_window_size(16 -2 + x, 133 - 1 + y)
try:
res = browser.find_element(By.ID, 'result').text
if res:
print(res, {'width': x, 'height': y})
except:
pass
7.4.7
1. Откройте сайт с помощью Selenium;
2. На сайте есть 10 buttons, каждый button откроет сайт в новой вкладке;
3. Каждая вкладки имеет в title уникальное число;
4. Цель - собрать числа с каждой вкладки и суммировать их;
5. Полученный результат вставить в поле для ответа.
РЕШЕНИЕ
7.4.8
sites = ['http://parsinger.ru/blank/1/1.html',
'http://parsinger.ru/blank/1/2.html', 'http://parsinger.ru/blank/1/3.html',
'http://parsinger.ru/blank/1/4.html',
'http://parsinger.ru/blank/1/5.html', 'http://parsinger.ru/blank/1/6.html',]
РЕШЕНИЕ
import math
from selenium import webdriver
from selenium.webdriver.common.by import By
result = []
with webdriver.Chrome() as browser:
for x in range(1, 7):
blank =
browser.execute_script(f'window.open("http://parsinger.ru/blank/1/{x}.html",
"_blank{x}");')
tabs = browser.window_handles
for z in range(len(tabs) - 1):
if not browser.execute_script("return document.title;"):
browser.close()
browser.switch_to.window(browser.window_handles[z])
browser.find_element(By.CLASS_NAME, 'checkbox_class').click()
result.append(math.sqrt(int(browser.find_element(By.ID, 'result').text)))
8.Ожидания. Явное и неявное
8.1 Явное и неявное ожидание, Selenium Waits (Implicit
Waits)
Ни один современный сайт не обходится без JavaScript, когда вы сёрфите по
интернету, вы часто его встречаете плавно появляющиеся элементы на странице,
элементы которые появляются при скроллинге или при полной загрузки страницы,
вариаций использования JS очень много.
К этому уроки у вас уже есть определённый опыт написания скриптов на Selenium. Я
уверен вы сталкивались с тем что элемент который вы ищите, ещё не загрузился или ещё
не доступен для взаимодействия с ним.
Давайте немного модифицируем код выше, таким образом, чтобы он работал без
ошибок. Применим неявные ожидания, как они работают мы поговорим в следующих
степах и так же порешаем задачки по ним.
Запустите эти два примера у себя в IDE чтоб сравнить результат работы.
.title_is(title)
.title_contains(title)
8.4.1
1. Откройте сайт при помощи Selenium;
2. На сайте есть кнопка, которая становится активной после загрузки страницы с рандомной
задержкой, от 1 до 3 сек;
3. После нажатия на кнопку, в title начнут появляться коды, с рандомным временем, от 0.1 до
0.6 сек;
4. Ваша задача успеть скопировать код из id="result" , когда title будет
равен "345FDG3245SFD";
5. Вставить появившийся код в поле для ответа.
РЕШЕНИЕ
8.4.2
1. Откройте сайт при помощи Selenium;
2. На сайте есть кнопка, которая становится активной после загрузки страницы с рандомной
задержкой, от 1 до 3 сек;
3. После нажатия на кнопку, в title начнут появляться коды, с рандомным временем, от 0,1 до
0.6 сек;
4. В этот раз второй раз на кнопку кликать не нужно, а нужно получить title целиком, если
часть title ="JK8HQ"
5. Используйте метод title_contains(title) с прошлого урока;
6. Вставьте полный текст заголовка который совпадает с частью заголовка из условия.
РЕШЕНИЕ
ps. Вы конечно можете и в ручную найти элемент с этим классом, но кого вы обманите?
РЕШЕНИЕ
8.4.4
А это задача для тех кто всё таки решил перехитрить прошлую задачу и решил её вручную.
А для всех остальных, задача максимально проста, запустить тот же самый код из
прошлой задачи, но на другом url и с другим class.
РЕШЕНИЕ