CoderCastrov logo
CoderCastrov
Анализ данных

Парсинг отзывов Google Maps на Python

Парсинг отзывов Google Maps на Python
просмотров
5 мин чтение
#Анализ данных

Парсинг последних отзывов с использованием BeautifulSoup и Selenium

В этой статье я хотел бы поделиться с вами некоторыми знаниями о том, как применять парсинг данных с использованием библиотек Python Selenium и BeautifulSoup: комбинация этих двух инструментов позволяет определить набор API для сбора данных с практически любого веб-сайта.

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

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

После этого небольшого предупреждения, давайте начнем!


Давайте начнем с инструментов.

Anaconda

Anaconda - это фреймворк, который помогает поддерживать зависимости библиотек Python для каждого проекта прозрачным образом, используя концепцию виртуальных окружений: вы создаете окружение, устанавливаете каждую библиотеку внутри него и активируете/деактивируете окружение в зависимости от ваших потребностей, не вмешиваясь в зависимости других проектов. Вы можете скачать его здесь.

Этот инструмент не является обязательным, его можно заменить любой библиотекой для виртуальных окружений (например, virtualenv), но он может быть полезен, если вы хотите добавить дополнительные шаги, такие как очистка данных, анализ данных и машинное обучение в конце представленного здесь пайплайна. Кроме того, вы также можете установить описанные библиотеки с помощью pip.

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

Selenium

Selenium - это фреймворк, созданный для автоматического тестирования веб-приложений: его API позволяет симулировать клики, прокрутку и любое другое взаимодействие, которое происходит на веб-сайте. Поэтому он чрезвычайно полезен для парсинга веб-сайтов: клики и прокрутка вызывают изменения на странице, которая загружает дополнительные данные (или другие типы данных).

Библиотека написана на Java, Python, C#, JavaScript и многих других языках: в этой статье мы будем использовать реализацию на Python для загрузки целевой веб-страницы и генерации всех необходимых взаимодействий для получения дополнительной информации.

Чтобы установить Selenium, выполните команду:

conda install -c conda-forge selenium

Нам также нужно установить webdriver браузера, который мы хотим использовать. WebDriver - это программное обеспечение, которое автоматически запускает экземпляр браузера, над которым будет работать Selenium.

Я решил выбрать Google Chromedriver, который вы можете скачать здесь, но любой драйвер должен работать хорошо.

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

BeautifulSoup

BeautifulSoup - это встроенная библиотека Python, которая разбирает HTML и XML файлы: она помогает навигироваться по узлам дерева, получать доступ к атрибутам и свойствам очень интуитивным способом.

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

Чтобы установить библиотеку в нашу среду conda, выполните команду:

conda install -c anaconda beautifulsoup4

Ну, теперь мы должны быть готовы начать определение нашего модуля парсинга!

Целевой пример покажет, как собрать последние отзывы Google Maps: мы определим парсер, который переходит на определенную точку интереса (POI) и извлекает ее последние отзывы.

1. Инициализация

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

options = Options()
options.add_argument("--lang=en")
driver = webdriver.Chrome(chrome_options=options)

2. Ввод URL

Затем нам нужно указать целевую страницу: так как мы хотим собрать отзывы с Google Maps, мы выбираем достопримечательность и получаем URL, который напрямую указывает на отзывы. На этом этапе драйвер просто открывает страницу.

URL такого типа довольно сложен: нам нужно вручную скопировать его из браузера в переменную и передать его драйверу.

url = [https://www.google.it/maps/place/Pantheon/@41.8986108,12.4746842,17z/data=!3m1!4b1!4m7!3m6!1s0x132f604f678640a9:0xcad165fa2036ce2c!8m2!3d41.8986108!4d12.4768729!9m1!1b1](https://www.google.it/maps/place/Pantheon/@41.8986108,12.4746842,17z/data=!3m1!4b1!4m7!3m6!1s0x132f604f678640a9:0xcad165fa2036ce2c!8m2!3d41.8986108!4d12.4768729!9m1!1b1)driver.get(url)

3. Нажмите на кнопки меню

Теперь мы хотим извлечь последние отзывы, в то время как настройки страницы по умолчанию показывают самые релевантные отзывы. Нам нужно нажать на меню "Сортировка" и затем на вкладку "Самые новые".

Здесь Selenium (и навыки программирования) действительно пригодятся: нам нужно найти кнопку, нажать на нее, а затем нажать на вторую кнопку. Для этой цели я использовал методы поиска XPath, предоставляемые Selenium: это может быть проще, чем поиск с помощью CSS, благодаря также Chropath, расширению для браузера, которое добавляет интерпретатор XPath в инструменты разработчика браузера.

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

Тестирование выражения XPath для первой кнопки Тестирование выражения XPath для второй кнопки

К сожалению, этого недостаточно. Веб-сайт Google Maps (как и многие другие современные веб-сайты) в основном реализован с использованием AJAX: многие части сайта загружаются асинхронно, что означает, что кнопки могут не загрузиться, если Selenium ищет их сразу после загрузки страницы.

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

Код для этой части выглядит следующим образом:

wait = WebDriverWait(driver, 10)
menu_bt = wait.until(EC.element_to_be_clickable(
                       (By.XPATH, '//button[[@data](http://twitter.com/data)-value=\'Sort\']'))
                   )  
menu_bt.click()
recent_rating_bt = driver.find_elements_by_xpath(
                                     '//div[[@role](http://twitter.com/role)=\'menuitem\']')[1]
recent_rating_bt.click()
time.sleep(5)

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

4. Извлечение данных

И, наконец, мы подошли к целевым данным - отзывам. Мы отправляем страницу в парсер BeautifulSoup, который помогает найти правильные HTML-теги, div-ы и свойства.

Вначале мы определяем обертывающий div для отзыва: метод find_all создает список элементов div, которые соответствуют определенным свойствам. В нашем случае список содержит div-ы отзывов, присутствующих на странице.

response = BeautifulSoup(driver.page_source, 'html.parser')
rlist = response.find_all('div', class_='section-review-content')

Для каждого отзыва мы парсим его информацию: рейтинг (звезды), текстовое содержимое (если доступно), дату отзыва, имя рецензента, идентификатор отзыва.

id_r = r.find('button', 
              class_='section-review-action-menu')['data-review-id']
username = r.find('div', 
                  class_='section-review-title').find('span').texttry:
    review_text = r.find('span', class_='section-review-text').text
except Exception:
    review_text = Nonerating = r.find('span', class_='section-review-stars')['aria-label']
rel_date = r.find('span', class_='section-review-publish-date').text

5. Прокрутка

И наконец: страница уже загрузила 20 отзывов, но остальные не доступны без прокрутки вниз страницы.

Прокрутка не является прямой функцией в Selenium API, но они позволяют выполнять JavaScript-код и применять его к определенному элементу страницы: мы определяем объект div, который может быть прокручен, и запускаем простую строку JS-кода для прокрутки вниз страницы.

scrollable_div = driver.find_element_by_css_selector(
 'div.section-layout.section-scrollbox.scrollable-y.scrollable-show'
                     )
driver.execute_script(
               'arguments[0].scrollTop = arguments[0].scrollHeight', 
                scrollable_div
               )

Как вы можете видеть, в этом кратком руководстве я попытался объяснить основные элементы для парсинга отзывов с Google Maps, но те же самые концепции применимы к многим современным веб-сайтам. Сложность высока, и я не рассмотрел все детали здесь: если вы хотите получить полный пример, проверьте мой репозиторий на Github здесь.

Спасибо за чтение. Дайте мне знать, что вы об этом думаете и если у вас есть какие-либо вопросы!