Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Руководство по Selenium: Web Scraping с Selenium и Python

2 апреля 2017 г. Archy Просмотров: 52447 RSS 7 , , , ,

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 показывает эту страницу:

Web Scraping с Selenium и Python

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

Web Scraping с Selenium и Python

Что ж, на самом деле она не двигается. Старая кнопка стала невидимой, а новая все еще видна (по этой причине и возникает ошибка, когда вы нажимаете на старую кнопку: она невидима!). Мы можем обновить функцию 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, не пытайтесь запустить или импортировать его! Спасибо за внимание, надеюсь, эта статья вам очень помогла.

Комментариев: 7
  1. Спасибо очень помогло наконец открылся браузер!!!

  2. Богдан | 2018-05-22 в 16:28:18

    на странице сайта нужно вставлять фотографии, можно ли это как-то автоматизировать?

  3. Василий | 2018-09-21 в 12:06:15

    Спасибо за статью!

  4. не находит кнопочку :( просто не находит

  5. в мене метод click() не працює можете допомогти

  6. Спасибо за статью!

  7. Михаил | 2021-10-28 в 19:10:13

    Добрый вечер! Ситуация следующая: нужно найти все id в тегах на странице, и вывести их. Каким образом это можно было бы реализовать? Сайт: вайлдберис. Спасибо!