перейти к содержанию

Как очистить данные с Realtor.com: подробное руководство

Realtor.com — один из самых популярных веб-сайтов по продаже недвижимости, содержащий данные о миллионах объектов недвижимости, выставленных на продажу и в аренду, по всей территории Соединенных Штатов. Для специалистов в сфере недвижимости, инвесторов и специалистов по обработке данных информация на сайте Realtor.com является ценным ресурсом. Однако ручной поиск и агрегирование данных с сайта может занять чрезвычайно много времени.

В этом подробном руководстве мы рассмотрим процесс программного сбора данных с сайта Realtor.com с использованием Python и Selenium. Мы также увидим, как использовать сервис ScrapingBee для решения CAPTCHA и расширить ваши усилия по очистке сайта Realtor.com. В результате у вас будет полнофункциональный парсер Realtor.com, который вы сможете адаптировать под свои нужды в данных.

Настройка среды Python

Прежде чем мы начнем писать код, вам необходимо убедиться, что у вас установлен Python и несколько ключевых библиотек. В этом руководстве предполагается, что вы используете Python 3.6+. Если у вас еще нет Python, вы можете загрузить установщик для Windows, macOS или Linux по адресу python.org.

Когда Python готов к работе, создайте новую папку для вашего проекта очистки. Внутри этой папки создайте новый файл Python, например realtor_scraper.py.

Теперь откройте терминал или командную строку, перейдите в папку вашего проекта и выполните следующие команды, чтобы установить необходимые пакеты Python:

pip install selenium
pip install undetected-chromedriver

Это установит:

  1. Selenium — набор инструментов для автоматизации браузера, который мы будем использовать для взаимодействия с Realtor.com.
  2. undetected-chromedriver — оптимизированная версия ChromeDriver от Selenium, которая помогает избежать обнаружения ботов.

Получение страниц Realtor.com с помощью Selenium

Selenium позволяет нам запускать браузер и управлять им с помощью кода. В этом руководстве мы будем использовать Google Chrome. Добавьте следующий код в ваш файл Python:

import undetected_chromedriver as uc

driver = uc.Chrome()

driver.get("https://www.realtor.com/realestateandhomes-search/Miami_FL")

Этот код запускает Chrome (используя undetected_chromedriver, чтобы замаскировать тот факт, что мы автоматизируем браузер) и переходит на страницу результатов поиска Realtor.com для Майами, Флорида.

Вы можете изменить URL-адрес, чтобы загружать результаты для любого местоположения. Просто замените Miami_FL с желаемым сокращением города и штата, например New-York_NY or Chicago_IL.

Запустив этот код, вы должны увидеть открытое окно Chrome и загрузить страницу списков недвижимости Realtor.com в Майами.

Анализ структуры страницы Realtor.com

Чтобы извлечь данные со страницы, нам необходимо определить соответствующие элементы HTML и способы их уникального расположения. Инструменты разработчика браузера упрощают эту задачу.

В Chrome щелкните правой кнопкой мыши любой список на странице и выберите «Проверить», чтобы открыть инструменты разработчика. На панели «Элементы» вы можете увидеть HTML-структуру страницы.

    <img src="/blog/web-scraping-realtor/listing-inspect.png" alt="Inspecting listing HTML">

Исследуя HTML, мы видим, что каждый листинг содержится в li элемент с атрибутом data-testid="result-card", Внутри этих lis, различные точки данных, которые мы хотим извлечь (цена, кровати, ванны и т. д.), содержатся в элементах с data-label атрибутов.

Например, цена указана в span data-label="pc-price", хотя адрес находится в div data-label="pc-address".

Извлечение данных листинга с помощью Selenium

Вооружившись этой информацией о структуре страницы, мы можем использовать селекторы Selenium и CSS для поиска и извлечения нужных нам данных.

Во-первых, давайте возьмем все отдельные списки на странице:

from selenium.webdriver.common.by import By

listings = driver.find_elements(By.CSS_SELECTOR, ‘li[data-testid="result-card"]‘)

find_elements() возвращает список всех элементов, соответствующих данному селектору. Здесь мы используем селектор атрибутов CSS, чтобы найти все li элементы с data-testid of "result-card", которые соответствуют отдельным спискам.

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

data = []
for listing in listings:
    datum = {}

    # Price
    price = listing.find_element(By.CSS_SELECTOR, ‘span[data-label="pc-price"]‘).text
    datum[‘price‘] = price

    # Address
    address = listing.find_element(By.CSS_SELECTOR, ‘div[data-label="pc-address"]‘).text
    datum[‘address‘] = address

    # Beds
    try:
        beds = listing.find_element(By.CSS_SELECTOR, ‘li[data-label="pc-meta-beds"]‘).text
        datum[‘beds‘] = beds
    except:
        datum[‘beds‘] = None

    # Baths
    try:    
        baths = listing.find_element(By.CSS_SELECTOR, ‘li[data-label="pc-meta-baths"]‘).text
        datum[‘baths‘] = baths
    except:
        datum[‘baths‘] = None

    # Square Feet
    try:
        sqft = listing.find_element(By.CSS_SELECTOR, ‘li[data-label="pc-meta-sqft"]‘).text  
        datum[‘sqft‘] = sqft
    except:
        datum[‘sqft‘] = None

    data.append(datum)

Для каждого объявления li, мы используем find_element() чтобы найти дочерние элементы, содержащие целевые точки данных, по их data-label атрибуты. Мы извлекаем текст этих элементов и сохраняем его в словаре, который добавляется к текущему файлу. data .

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

В конце этого, data будет список словарей, каждый из которых содержит извлеченные данные для одного листинга:

[
    {
        ‘price‘: ‘$320,000‘, 
        ‘address‘: ‘9273 SW 227th St, Cutler Bay, FL 33190‘,
        ‘beds‘: ‘3 beds‘,
        ‘baths‘: ‘2 baths‘,
        ‘sqft‘: ‘1,441 sqft‘
    },
    {
        ‘price‘: ‘$1,150,000‘, 
        ‘address‘: ‘1024 Biscayne Blvd # UPH07, Miami, FL 33132‘,
        ‘beds‘: ‘1 bed‘,
        ‘baths‘: ‘2 baths‘, 
        ‘sqft‘: None
    },
    ...
]

Разбивка по страницам всех результатов поиска

Результаты поиска на сайте Realtor.com разбиты на страницы, и на каждой странице отображается ограниченное количество объявлений. Чтобы очистить все результаты, нам нужно перемещаться по страницам нашего скрипта.

К счастью, сайт Realtor.com предоставляет ссылку «Далее» для загрузки следующей страницы результатов. Нажимая на эту ссылку циклически, пока она не перестанет отображаться, мы можем очистить все результаты с разбивкой на страницы.

Вот как мы можем изменить наш скрипт для управления нумерацией страниц:

data = []

while True:
    listings = driver.find_elements(By.CSS_SELECTOR, ‘li[data-testid="result-card"]‘)

    for listing in listings:
        # Extract data from each listing as shown in previous section
        ...

    try:
        next_link = driver.find_element(By.XPATH, ‘//a[@aria-label="Go to next page"]‘)
        next_link.click()
    except:
        break

Мы обертываем наш существующий код для извлечения данных из каждого листинга в while True петля. После обработки списков на текущей странице мы пытаемся найти ссылку «Далее» (определяемую по ее aria-label атрибут) и щелкните его, чтобы загрузить следующую страницу.

Если ссылка «Далее» не найдена, мы предполагаем, что достигли последней страницы результатов и break из цикла нумерации страниц.

Благодаря этой модификации наш скрипт теперь будет извлекать данные из всех списков на всех страницах результатов поиска.

Обработка CAPTCHA с помощью ScrapingBee

Если вы запустите парсер Realtor.com достаточно долго, вы, скорее всего, обнаружите страницу CAPTCHA. Это распространенная мера защиты от ботов, используемая веб-сайтами для предотвращения парсинга.

Решение CAPTCHA — сложная тема и зачастую требует платных услуг. Одним из таких сервисов является ScrapingBee, который предоставляет API для взаимодействия с веб-сайтами, включая решение CAPTCHA.

Вот как вы можете перенести сбор данных с сайта Realtor.com на ScrapingBee и избежать CAPTCHA и блокировки IP:

Сначала установите ScrapingBee Python SDK:

pip install scrapingbee

Затем зарегистрируйте учетную запись ScrapingBee на сайте https://app.scrapingbee.com/signup чтобы получить ключ API.

Теперь вы можете использовать ScrapingBee для парсинга сайта Realtor.com следующим образом:

from scrapingbee import ScrapingBeeClient

client = ScrapingBeeClient(api_key=‘YOUR_API_KEY‘)

response = client.get(
    ‘https://www.realtor.com/realestateandhomes-search/Miami_FL‘,
    params = {
        ‘extract_rules‘: {
            ‘listings‘: {
                ‘selector‘: ‘li[data-testid="result-card"]‘, 
                ‘type‘: ‘list‘,
                ‘output‘: {
                    ‘price‘: ‘span[data-label="pc-price"]‘,
                    ‘address‘: ‘div[data-label="pc-address"]‘, 
                    ‘beds‘: ‘li[data-label="pc-meta-beds"]‘,
                    ‘baths‘: ‘li[data-label="pc-meta-baths"]‘,
                    ‘sqft‘: ‘li[data-label="pc-meta-sqft"]‘
                }
            },
            ‘next_page‘: {
                ‘selector‘: ‘//a[@aria-label="Go to next page"]‘, 
                ‘output‘: ‘@href‘
            }
        },
        ‘wait_for‘: ‘ul.jsx-4195823979‘,
        ‘premium_proxy‘: ‘true‘
    }
)

data = response.json()

Этот код использует ScrapingBee extract_rules возможность указать селекторы CSS для данных, которые мы хотим извлечь. ScrapingBee будет обрабатывать JavaScript на странице (через wait_for параметр), извлеките данные в соответствии с нашими правилами и верните их в виде структурированного JSON.

ScrapingBee также незаметно управляет ротацией прокси и решением CAPTCHA, поэтому нам не нужно беспокоиться о блокировке нашего парсера.

Чтобы получить последующие страницы результатов, вы можете проверить наличие data[‘next_page‘] и если он существует, сделайте еще один запрос к ScrapingBee с этим URL-адресом, чтобы получить следующую страницу списков.

Масштабирование с помощью Scrapy

Для более сложных проектов парсинга вы можете рассмотреть возможность использования специальной платформы парсинга, такой как Scrapy.

Scrapy — мощная и расширяемая библиотека Python для создания веб-скраперов. Он предоставляет множество полезных функций «из коробки», таких как:

  • Встроенная поддержка создания и перехода по ссылкам для сканирования целых сайтов.
  • Надежный выбор и извлечение с использованием селекторов CSS и XPath.
  • Экспорт каналов для хранения очищенных данных в форматах JSON, CSV, XML и других форматах.
  • Регулирование и контроль вежливости, чтобы избежать перегрузки серверов
  • Промежуточное программное обеспечение для фильтрации запросов, обработки файлов cookie, аутентификации, сжатия и т. д.
  • Расширения для кэширования, сбора статистики, telnet-консолей и т. д.

Преобразование парсера Realtor.com на основе Selenium в Scrapy позволит вам значительно расширить свои усилия по парсингу. Вы можете легко распараллелить очистку, сохранить прогресс для приостановки и возобновления заданий, ротировать пользовательские агенты и IP-адреса и многое другое.

Заключение

В этом руководстве мы увидели, как собирать данные с сайта Realtor.com с помощью Python и Selenium. Ключевые шаги:

  1. Используйте Selenium для извлечения и рендеринга страниц
  2. Анализируйте HTML-код страницы, чтобы определить селекторы для целевых точек данных.
  3. Найдите и извлеките данные с помощью Selenium find_element(s) методы
  4. Управляйте нумерацией страниц, находя и нажимая ссылки «Далее».
  5. Интегрируйте ScrapingBee, чтобы избежать CAPTCHA и блокировки IP-адресов.
  6. Рассмотрите Scrapy для более масштабных, готовых к производству проектов парсинга.

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

Используя описанные здесь методы, вы сможете создать парсер Realtor.com для извлечения необходимых вам данных. Если у вас есть какие-либо вопросы или вы застряли на этом пути, не стесняйтесь обращаться к нам — мы всегда рады помочь с вашими проектами по парсингу веб-страниц!

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *