Веб-скрейпинг

Иногда в своей работе я осуществляю веб-скрейпинг с помощью selenium, но этот инструмент работает слишком медленно.
Решение, казалось бы, лежит на поверхности, но в течение последних двух лет я не видел что его кто то использует.
Как вы, возможно, знаете, основная причина, по которой selenium работает медленно, — это парсер. Поэтому первое, что приходит на ум — это изменить парсер в selenium.
Чтобы показать вам, как это работает, я буду использовать seleniumс chromedriver, beautifulsoup4 и эту страницу в Википедии, которая содержит таблицу с некоторой информацией о штатах США.

Итак, для начала я сделал Python скрипт, который использует только selenium для извлечения данных из таблицы:

from datetime import datetime
from selenium import webdriver


def get_states():
    url = 'https://en.wikipedia.org/wiki/List_of_states_and_territories_of_the_United_States'
    driver = webdriver.Chrome()
    driver.get(url)

    rows = driver.find_element_by_xpath('//*[@id="mw-content-text"]/div/table[1]/tbody')\
        .find_elements_by_tag_name('tr')

    states = []

    for row in rows:
        cells = row.find_elements_by_tag_name('td')
        name = row.find_element_by_tag_name('th').text
        abbr = cells[0].text
        established = cells[-9].text
        population = cells[-8].text
        total_area_km = cells[-6].text
        land_area_km = cells[-4].text
        water_area_km = cells[-2].text

        states.append([
            name, abbr, established, population, total_area_km, land_area_km,
            water_area_km
        ])
    driver.quit()
    return states


if __name__ == '__main__':
    start = datetime.now()
    states = get_states()
    finish = datetime.now() - start
    print(finish)
Чистый selenium

Если вы запустите этот скрипт, вы увидите, что реализация заняла 27,177188 секунд.
Теперь давайте попробуем изменить стандартный парсер Selenium на BeautifulSoup. Просто получаем исходный код страницы и отправляем его в парсер BeautifulSoup:

bs_obj = BeautifulSoup(driver.page_source, 'html.parser')

В результате код веб-скрейпинга будет выглядеть следующим образом:

from datetime import datetime
from selenium import webdriver
from bs4 import BeautifulSoup as BSoup


def get_states():
    url = 'https://en.wikipedia.org/wiki/List_of_states_and_territories_of_the_United_States'
    driver = webdriver.Chrome()
    driver.get(url)

    bs_obj = BSoup(driver.page_source, 'html.parser')
    rows = bs_obj.find_all('table')[0].find('tbody').find_all('tr')

    states = []

    for row in rows:
        cells = row.find_all('td')
        name = row.find('th').get_text()
        abbr = cells[0].get_text()
        established = cells[-9].get_text()
        population = cells[-8].get_text()
        total_area_km = cells[-6].get_text()
        land_area_km = cells[-4].get_text()
        water_area_km = cells[-2].get_text()

        states.append([
            name, abbr, established, population, total_area_km, land_area_km,
            water_area_km
        ])
    driver.quit()
    return states


if __name__ == '__main__':
    start = datetime.now()
    states = get_states()
    finish = datetime.now() - start
    print(finish)
Веб-скрейпинг с BeautifulSoup

И после запуска мы видим… 07.664240 секунд! Результат в 3 раза быстрее!
Таким образом, Selenium является отличным инструментом, если вам нужно имитировать действия пользователя, но если вы работаете с большими или огромными массивами данных с веб-страниц, то лучший способ — делегировать эту задачу более быстрым анализаторам.