Рубрики
Без рубрики

30-минутный веб-скребок Python

Я собирался создать веб-скребок с использованием Python и Selenium (http://www.seleniumhq.org/) уже некоторое время, но до этого так и не дошло. Несколько ночей назад я решил попробовать….

Автор оригинала: 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 , что было бы намного лучше для такого проекта.