Автор оригинала: Angelos Chalaris (Chalarangelo).
Я уже некоторое время собирался создать веб-скребок с использованием Python и Selenium , но так и не удосужился до этого. Несколько ночей назад я решил попробовать. Каким бы сложным это ни казалось, было чрезвычайно легко написать код, чтобы захватить несколько красивых изображений из Unsplash .
Ингредиенты для простого скребка для изображений
- Python (3.6.3 или новее)
- Pycharm (Издание сообщества просто отлично)
pip install requests Pillow selenium
- водитель геккона (инструкции см. ниже)
- Mozilla Firefox (как будто у вас его не было установлено)
- Рабочее подключение к Интернету (очевидно)
- 30 минут вашего времени (возможно, меньше)
Рецепт простого скребка для изображений
Все установлено и готово? Хорошо! Я объясню, что делает каждый из этих ингредиентов, когда мы будем продвигаться вперед с нашим кодом.
Первое, что мы будем использовать, – это Selenium webdriver в сочетании с драйвером gecko , чтобы открыть окно браузера, которое выполняет нашу работу за нас. Чтобы начать работу, создайте проект в Pycharm , загрузите последнюю версию драйвера gecko для вашей операционной системы, откройте сжатый файл и перетащите файл geckodriver в папку вашего проекта. Драйвер Gecko-это в основном то, что позволяет Selenium получить контроль над Firefox, поэтому он нужен нам в папке вашего проекта, чтобы иметь возможность использовать браузер.
Следующее, что мы хотим сделать, – это фактически импортировать веб-драйвер из Selenium в наш код и подключиться к нужному URL-адресу. Так что давайте сделаем именно это:
from selenium import webdriver # The URL we want to browse to url = "https://unsplash.com" # Using Selenium's webdriver to open the page driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url)
Окно Firefox с дистанционным управлением
Довольно просто, да? Если вы все сделали правильно, вы уже прошли трудную часть, и вы должны увидеть окно браузера, похожее на то, которое показано на приведенном выше изображении.
Далее мы должны прокрутить вниз , чтобы можно было загрузить больше изображений, прежде чем мы сможем их загрузить. Мы также хотим подождать несколько секунд , на случай, если соединение медленное и изображения не полностью загружены. Поскольку Unsplash построен с React, ожидание около 5 секунд кажется щедрым таймфреймом, поэтому мы должны сделать именно это, используя пакет time
. Мы также хотим использовать некоторый код Javascript для прокрутки страницы — для этого мы будем использовать window.scrollTo ()
. Собрав все это вместе, вы должны в конечном итоге получить что-то вроде этого:
import time from selenium import webdriver url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) # Scroll page and wait 5 seconds driver.execute_script("window.scrollTo(0,1000);") time.sleep(5)
После тестирования приведенного выше кода вы увидите, что браузер немного прокручивает страницу вниз. Следующее, что нам нужно сделать, – это найти изображения, которые мы хотим загрузить с веб-сайта. Покопавшись в коде, который генерирует React, я понял, что мы можем использовать селектор CSS , чтобы специально ориентироваться на изображения в галерее страницы. Конкретный макет и код страницы могут измениться в будущем, но на момент написания я мог бы использовать селектор #gridMulti img
, чтобы получить все элементы , которые появлялись на моем экране.
Мы можем получить список этих элементов , используя find_elements_by_css_selector ()
, но нам нужен атрибут src
каждого элемента. Итак, мы можем перебрать список и захватить их:
import time from selenium import webdriver url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) driver.execute_script("window.scrollTo(0,1000);") time.sleep(5) # Select image elements and print their URLs image_elements = driver.find_elements_by_css_selector("#gridMulti img") for image_element in image_elements: image_url = image_element.get_attribute("src") print(image_url)
Теперь, чтобы на самом деле получить изображения, которые мы нашли. Для этого мы будем использовать запросы
и часть пакета PIL
, а именно Изображение
. Мы также хотим использовать BytesIO
из io
для записи изображений в папку ./images/
, которую мы создадим в папке нашего проекта. Итак, чтобы собрать все это вместе, нам нужно отправить запрос HTTP GET на URL-адрес каждого изображения, а затем , используя Image
и BytesIO
, мы сохраним изображение , которое мы получим в ответе. Вот один из способов сделать это:
import requests import time from selenium import webdriver from PIL import Image from io import BytesIO url = "https://unsplash.com" driver = webdriver.Firefox(executable_path=r'geckodriver.exe') driver.get(url) driver.execute_script("window.scrollTo(0,1000);") time.sleep(5) image_elements = driver.find_elements_by_css_selector("#gridMulti img") i = 0 for image_element in image_elements: image_url = image_element.get_attribute("src") # Send an HTTP GET request, get and save the image from the response image_object = requests.get(image_url) image = Image.open(BytesIO(image_object.content)) image.save("./images/image" + str(i) + "." + image.format, image.format) i += 1
Это почти все, что вам нужно, чтобы загрузить кучу бесплатных изображений. Очевидно, что если вы не хотите создать прототип дизайна и вам просто нужны случайные изображения, этот маленький скребок не очень полезен. Поэтому я потратил некоторое время, чтобы улучшить его, добавив еще несколько функций:
- Аргументы командной строки , позволяющие пользователю указать поисковый запрос , а также числовое значение для прокрутки, которое позволяет странице отображать больше изображений для загрузки.
- Настраиваемый селектор CSS.
- Настраиваемые папки результатов , основанные на поисковых запросах.
- Полные HD – изображения путем обрезки URL-адреса миниатюр по мере необходимости.
- Именованные изображения, основанные на их URL-адресах.
- Закрытие окна браузера в конце процесса.
Вы можете (и, вероятно, должны) попробовать реализовать некоторые из этих функций самостоятельно. Полнофункциональная версия веб-скребка доступна здесь . Не забудьте загрузить драйвер gecko отдельно и подключить его к вашему проекту, как указано в начале статьи.
Ограничения, Соображения и будущие улучшения
Весь этот проект был очень простым доказательством концепции, чтобы увидеть, как выполняется очистка веб-страниц, а это означает, что есть много вещей, которые можно сделать, чтобы улучшить этот маленький инструмент:
- Не кредитовать первоначальных загрузчиков изображений – довольно плохая идея. Селен определенно способен обойти это, так что каждое изображение поставляется с именем автора.
- Драйвер Gecko не должен помещаться в папку проекта, а должен устанавливаться глобально и быть частью системной переменной
PATH
. - Функциональность поиска может быть легко расширена, чтобы включить несколько запросов, так что процесс загрузки большого количества изображений может быть упрощен.
- Браузер по умолчанию может быть изменен с Firefox на Chrome или даже PhantomJS , что было бы намного лучше для такого проекта.