Руководство по Selenium: Web Scraping с Selenium и Python
Представьте, какие возможности откроются перед вами, если вы автоматизируете всю нудную деятельность в интернете, такую как ежедневная проверка первых результатов в Google по ключевым запросам, или загрузка кучи разных файлов с разных сайтов. В данном разделе мы научимся пользоваться Selenium вместе с Python. Selenium – это инструмент для веб скрейпинга, имитирующий деятельность пользователя в интернете. К примеру, вы можете использовать Selenium для автоматических запросов в Google и чтения результатов, или заходить в ваши аккаунты в социальных сетях, имитировать пользователя для теста ваших веб приложений. А также многое другое, что вам нужно постоянно делать в интернете. Возможности безграничны!
Важно: Каждый код в этом разделе был протестирован на Python 2.7 и Python 3.4.
Установка и использование Selenium
Selenium – это пакет Python который может быть установлен при помощи pip. Рекомендую установить его в виртуальной среде (используя virtualenv и virtualenvwrapper).
Чтобы установить Selenium, вам нужно ввести следующее:
pip install selenium
В этом разделе мы инициализируем драйвер Firefox, вы можете установить его, скачав исходники geckodriver. Если вы хотите работать в Chrome или IE, вы найдете всю нужную информацию у них на github.
Установка geckodriver драйвер для Firefox
для начинающих этот момент может быть первой проблемой, вроде как Selenium установлен но вот примеры из интернета не работают. Проблема заключается в отсутствии драйверов.
Первым делом скачиваем исходники драйвера geckodriver в моем случае это "geckodriver-v0.15.0-linux64.tar.gz" у меня Ubuntu.
wget https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-linux64.tar.gz tar -xvzf geckodriver-v0.15.0-linux64.tar.gz sudo chmod +x geckodriver sudo mv geckodriver /usr/local/bin
Более подробно про установку можно прочитать на английском сайте документации. Там и список всех доступных драйверов под разные браузеры.
Начнем работу!
После установки Selenium и Firefox(geckodriver), создайте файл Python под названием selenium_script.py. Теперь приступаем к инициализации браузера при помощи Selenium:
import time
from selenium import webdriver
driver = webdriver.Firefox()
time.sleep(5)
driver.quit()
Таким образом, код инициализировал браузер Firefox, и закрывает его спустя 5 секунд.
Что если мы перейдем в Google и поищем что-нибудь?
Web Scraping в Google при помощи Selenium
Давайте создадим скрипт, который загружает главную страницу Google, и создает запрос "Selenium":
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
def init_driver():
driver = webdriver.Firefox()
driver.wait = WebDriverWait(driver, 5)
return driver
def lookup(driver, query):
driver.get("http://www.google.com")
try:
box = driver.wait.until(EC.presence_of_element_located(
(By.NAME, "q")))
button = driver.wait.until(EC.element_to_be_clickable(
(By.NAME, "btnK")))
box.send_keys(query)
button.click()
except TimeoutException:
print("Box or Button not found in google.com")
if __name__ == "__main__":
driver = init_driver()
lookup(driver, "Selenium")
time.sleep(5)
driver.quit()
Что есть в данном коде:
1. Функция init_driver инициализирует экземпляр драйвера;
- Создает экземпляр драйвера;
- Добавляет функцию WebDriverWait в качестве атрибута драйвера, так что доступ к нему станет намного проще. Эта функция используется для того, чтобы дать драйверу подождать 5 секунд, перед следующим действием;
2. Функция lookup берет два аргумента: драйвер и запрос (строка);
- Это открывает поисковую страницу Google;
- Затем ждет, пока будет найден элемент окна запроса, а также кнопку для нажатия. Обратите внимание на то, что мы используем функцию WebDriverWait именно для того, чтобы дождаться появления этих элементов;
- Оба элементы были обнаружены по наименованию. Другими вариантами их поиска были бы ID, XPATH, TAG_NAME, CLASS_NAME, CSS_SELECTOR.
- Далее, запрос отправляется в элемент окна запроса, после чего кнопка поиска нажимается;
- Если окно запроса или кнопка небыли найдены, в пределах наших пяти секунд, возникает TimeoutException;
3. Следующий оператор является условным выражением, которое истинно только тогда, когда скрипт запускается напрямую. Это предотвращает запуск следующих операторов при импорте этого файла;
- Далее драйвер инициализируется и запускается функция lookup, которая будет искать в Google слово "Selenium";
- Ожидаем 5 секунд, чтобы увидеть результат, после чего мы выходим из драйвера.
И наконец, запустите свой код с:
python selenium_script.py
Сработало? Если у вас появилась ошибка ElementNotVisibleException, читайте далее.
Как выявить ElementNotVisibleException
Недавно был изменен поиск Google, поэтому вначале Google показывает эту страницу:
И после того, как вы начали вводить свой запрос, кнопка запроса смещается в верхнюю часть окна:
Что ж, на самом деле она не двигается. Старая кнопка стала невидимой, а новая все еще видна (по этой причине и возникает ошибка, когда вы нажимаете на старую кнопку: она невидима!). Мы можем обновить функцию lookup в нашем коде, чтобы выявить ошибку:
from selenium.common.exceptions import ElementNotVisibleException
def lookup(driver, query):
driver.get("http://www.google.com")
try:
box = driver.wait.until(EC.presence_of_element_located(
(By.NAME, "q")))
button = driver.wait.until(EC.element_to_be_clickable(
(By.NAME, "btnK")))
box.send_keys(query)
try:
button.click()
except ElementNotVisibleException:
button = driver.wait.until(EC.visibility_of_element_located(
(By.NAME, "btnG")))
button.click()
except TimeoutException:
print("Box or Button not found in google.com")
Элемент button.click(), который и вызывал ошибку, находится внутри оператора try. Если ошибка возникла, мы взглянем на следующую кнопку, при помощи visibility_of_element_located, чтобы убедиться в том, что нужный нам элемент видим, после чего нажимаем на кнопку. Если в какой-либо момент, какой-либо элемент не будет найден в течение 5 секунд, ошибка TimeoutException возникнет и будет выявлена двумя последними строками кода. Обратите внимание на то, что название кнопки “btnK” , а название новой кнопки - “btnG”.
Финальный вид кода
Демонстрируя возможные ошибки в работе, мы исправляли код по ходу работы. Если у вас возникли ошибки при выполнении наших советов то вот вам окончательный вид нашего примера. Если и этот код не работает, то пишите в комментариях - разберемся.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import ElementNotVisibleException
def init_driver():
driver = webdriver.Firefox()
driver.wait = WebDriverWait(driver, 5)
return driver
def lookup(driver, query):
driver.get("http://www.google.com")
try:
box = driver.wait.until(EC.presence_of_element_located(
(By.NAME, "q")))
button = driver.wait.until(EC.element_to_be_clickable(
(By.NAME, "btnK")))
box.send_keys(query)
try:
button.click()
except ElementNotVisibleException:
button = driver.wait.until(EC.visibility_of_element_located(
(By.NAME, "btnG")))
button.click()
except TimeoutException:
print("Box or Button not found in google.com")
if __name__ == "__main__":
driver = init_driver()
lookup(driver, "Selenium")
time.sleep(5)
driver.quit()
Список методов в Selenium
Подводя итоги, я создал таблицу с основными методами, которые нам потребуются:
# Импорт модулей и инициализация драйвера
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.wait = WebDriverWait(driver, 5)
# Ожидание элементов.
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
element = driver.wait.until(
EC.presence_of_element_located(
EC.element_to_be_clickable(
EC.visibility_of_element_located(
(By.NAME, "name")
(By.ID, "id")
(By.LINK_TEXT, "link text")
(By.PARTIAL_LINK_TEXT, "partial link text")
(By.TAG_NAME, "tag name")
(By.CLASS_NAME, "class name")
(By.CSS_SELECTOR, "css selector")
(By.XPATH, "xpath")
)
)
# Выявляем и ловим ошибки.
from selenium.common.exceptions import
TimeoutException
ElementNotVisibleException
Внимание: это не файл Python, не пытайтесь запустить или импортировать его! Спасибо за внимание, надеюсь, эта статья вам очень помогла.
Спасибо очень помогло наконец открылся браузер!!!
на странице сайта нужно вставлять фотографии, можно ли это как-то автоматизировать?
Спасибо за статью!
не находит кнопочку :( просто не находит
в мене метод click() не працює можете допомогти
Спасибо за статью!
Добрый вечер! Ситуация следующая: нужно найти все id в тегах на странице, и вывести их. Каким образом это можно было бы реализовать? Сайт: вайлдберис. Спасибо!