CoderCastrov logo
CoderCastrov
Питон

Извлечение веб-данных во множестве с использованием Python

Извлечение веб-данных во множестве с использованием Python
просмотров
5 мин чтение
#Питон

Одним из преимуществ использования операционной системы Linux является наличие множества инструментов разработки, включая множество программ.

Существует бесчисленное количество форков популярных инструментов и библиотек программирования, которые даже начинающие разработчики найдут очень универсальными и интуитивно понятными, с хорошо задокументированными функциями и примерами использования, что является моим предпочтительным способом обучения.

А для всего остального есть Stack Overflow...

Я не могу сразу придумать способ получить выгоду от огромного количества информации, и я не обязательно верю, что информация - это сила, но извлекать ее весело.


Давайте рассмотрим несколько различных способов извлечения данных из веб-страниц на Python:

Selenium - мифическое безголовое чудовище.

Selectolax - самый быстрый из всех.

BeautifulSoup - возвращение к традиционному подходу.

Grab - еще один интуитивный подход с поддержкой аутентификации.

Я открываю свой код, и иногда легко застрять в одном способе выполнения задач, что не обязательно означает, что это лучший способ. Поэтому я решил рассмотреть четыре разных метода.

Во всех примерах я буду использовать разные методы извлечения одного и того же значения пиковой 24-часовой одновременной игры определенной видеоигры из сторонней базы данных Steam.

Также я буду измерять время выполнения скрипта, чтобы увидеть, какая из четырех библиотек выполняет задачу быстрее.


Selenium

Если вы предпочитаете полагаться на простой и интуитивно понятный синтаксис, то Selenium всегда является хорошим выбором.

Конечно, такая простота имеет свою цену в виде скорости, так как Selenium вместе с Chromedriver (который будет использоваться в примере) использует браузер для достижения своей цели.

Без лишних слов:

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import codetiming

t = codetiming.Timer(name="execTime")
t.start()

staticURL = 'https://steamdb.info/app/440/graphs/'

peakxPath = '/html/body/div[1]/div[1]/div[3]/div/div[2]/div[4]/ul/li[3]'

options = webdriver.ChromeOptions()
strategy = DesiredCapabilities().CHROME
strategy["pageLoadStrategy"] = "eager"

# Экспериментальные параметры для отключения загрузки изображений для ускорения работы Selenium
chrome_prefs = {}
options.experimental_options["prefs"] = chrome_prefs
chrome_prefs["profile.default_content_settings"] = {"images": 2}
chrome_prefs["profile.managed_default_content_settings"] = {"images": 2}


driver = webdriver.Chrome(options=options, desired_capabilities=strategy)

driver.get(staticURL)
peakPlayersElement = driver.find_element_by_xpath(peakxPath).text.split()

print(peakPlayersElement[0])
t.stop()
driver.quit()

Этот код позволяет получить количество игроков, достигнувших пика за 24 часа, и время выполнения скрипта.

86,919
Прошло времени: 1.7432 секунды

Таким образом, Selenium затратил 1.7432 секунды, чтобы дать нам нужное значение - пиковое количество одновременных игроков в игре Team Fortress 2.

Также отмечу:

В строке 14 установка стратегии страницы на "eager" указывает Selenium продолжать поиск значений без загрузки всей страницы.

Строки 19, 20 задают дополнительные параметры для отключения загрузки изображений на странице, так как нужное нам значение является строкой.

Однако я бы не использовал эти параметры, если бы целью было полное отображение HTML или выполнение действий, которые требуют изображений.

Я также остановил замер времени до закрытия экземпляра драйвера, так как он уже предоставил нам нужную информацию.

Selectolax

Теперь этот действительно не разочаровывает, если вам нужно масштабировать ваш проект для работы с большими объемами одновременно, чем Selectolax - это надежный выбор.

В этом случае потребовался дополнительный user agent, так как страница не очень дружелюбна к запросам на Python. Код довольно простой, с той разницей, что использовался CSS селектор для нахождения элемента.

import requests
from selectolax.parser import HTMLParser
import codetiming

t = codetiming.Timer(name="execTime")
t.start()

headers = {'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25'}

staticURL = 'https://steamdb.info/app/440/graphs/'
selector = '#graphs > ul > li:nth-child(3) > strong'

response = requests.get(staticURL, headers=headers)
pageHtml = response.text
tree = HTMLParser(pageHtml)

print(tree.css_first(selector).text())
t.stop()

Который выводит:

86,919
Elapsed time: 0.3130 seconds

Как мы видим, это довольно замечательное время, оно получило страницу, отобразило ее и распарсило наше значение за 0.3130 секунды. Целую секунду и полторы быстрее, чем Selenium и даже больше.

BeautifulSoup

Это, как правило, самый популярный выбор, когда дело доходит до парсинга веб-страниц на языке Python, код почти полностью повторяет код Selectolax с некоторыми изменениями в парсере HTML.

import requests
from bs4 import BeautifulSoup
import codetiming
import lxml

t = codetiming.Timer(name="execTime")
t.start()

headers = {'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25'}

staticURL = 'https://steamdb.info/app/440/graphs/'
selector = '#graphs > ul > li:nth-child(3) > strong'

response = requests.get(staticURL, headers=headers)
pageHtml = response.text

soup = BeautifulSoup(pageHtml, 'lxml')
SoupSelected = soup.select_one(selector).text

print(SoupSelected)

t.stop()

Дает нам

86,919
Elapsed time: 0.5421 seconds

Приблизительно в два раза медленнее, чем Selectolax, и в три раза быстрее, чем Selenium. Неплохо.

Парсинг

Почему бы вам не взять себе немного закусок и напитка, потому что это будет почти так захватывающе. Он предлагает множество функций, включая создание пользовательских пауков, возможно, предназначенных для более простого масштабирования ваших проектов по извлечению веб-данных. Теперь давайте проверим его.

import time
import requests
from grab import Grab
import codetiming

t = codetiming.Timer(name="execTime")
t.start()

staticURL = 'https://steamdb.info/app/440/graphs/'
peakxPath = '/html/body/div[1]/div[1]/div[3]/div/div[2]/div[4]/ul/li[3]'

g = Grab()
g.setup(headers={'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25'})

g.go(staticURL)

ourText = g.doc(peakxPath).text().split()
print(ourText[0])

t.stop()

Что привело к следующему результату:

86,919
Прошло времени: 1.5842 секунды

Почти так же быстро, как Selenium, и немного разочаровывающе, так как эта библиотека использует pyCurl, который является реализацией cURL на Python. Я ожидал, что Grab будет по крайней мере быстрее Selenium.

Однако мы сделаем исключение, так как Grab настолько функционален...

Вердикт

Selectolax - самый быстрый подход для получения необходимой информации, даже если он немного одномерный.

Если вам нужно что-то, что может обрабатывать многопроходной парсинг (то есть вход в систему, навигация по страницам, а затем извлечение данных), то лучше всего использовать что-то вроде Selenium или Grab.

Лично я обычно прибегаю к использованию Selenium из-за его простоты в использовании и возможности взаимодействия с веб-страницей разными способами.

Некоторые похвальные упоминания также заслуживают: Ruia, Scrapy

Спасибо за чтение этой статьи! Надеюсь, вы сможете воспользоваться ею в будущем.