Отримання доступу до даних Airbnb є важливим етапом під час аналізу ринку нерухомості. Це необхідно для дослідження цін на оренду житла та їхньої динаміки в рамках маркетингових кампаній, проведення конкурентного аналізу, оцінювання відгуків і рейтингів, і може бути досягнуто шляхом скрапінгу веб-даних. Однак доступ до цих даних може бути обмежений, оскільки скрапінг може порушувати правила використання сайту.
Далі покроково розглянемо, як розробити веб-скрапер для вилучення даних з оголошень на Airbnb за допомогою Python і Selenium, водночас уникнувши можливих блокувань і обмежень з боку платформи.
Перший крок у створенні веб-скрапера - розуміння того, як отримати доступ до веб-сторінок, які нас цікавлять, оскільки структура веб-сайтів може змінюватися з часом.
Щоб зрозуміти структуру сайту, ми можемо використовувати інструменти розробника браузера для вивчення HTML веб-сторінки. Для доступу до інструментів розробника ви можете натиснути правою кнопкою миші та вибрати пункт "Переглянути код елемента" або використовувати поєднання клавіш:
Зверніть увагу, що кожен контейнер з оголошенням на Airbnb обгорнутий в елемент "div" з певним атрибутом класу: class="g1qv1ctd".
Для прикладу, виберемо вкладку "location" і введемо "London, UK", таким чином отримавши доступ до пропозицій з розміщення в Лондоні. Веб-сайт запропонує додати дати заїзду та виїзду, що дає змогу розрахувати вартість проживання.
URL для цієї сторінки матиме приблизно такий вигляд:
url = "https://www.airbnb.com/s/London--United-Kingdom/homes?tab_id=home_tab&refinement_paths%5B%5D=%2Fhomes&flexible_trip_lengths%5B%5D=one_week&monthly_start_date=2024-01-01&monthly_length=3&price_filter_input_type=0&channel=EXPLORE&query=London%2C%20United%20Kingdom&place_id=ChIJdd4hrwug2EcRmSrV3Vo6llI&date_picker_type=calendar&source=structured_search_input_header&search_type=autocomplete_click"
Виходячи зі сторінки пошуку, ми будемо витягувати такі атрибути даних оголошень:
Перш ніж почати скрапінг, потрібно налаштувати середовище розробки. Ось кроки, які потрібно виконати:
Віртуальні середовища в Python - інструмент, який дає змогу ізолювати пакети та їхні залежності для різних проєктів. Використання віртуального середовища допомагає уникнути конфліктів між бібліотеками та забезпечує наявність усіх необхідних залежностей у рамках конкретного проєкту.
Відкрийте командний рядок з правами адміністратора і виконайте таку команду для створення нового віртуального середовища з ім'ям "venv":
python -m venv venv
Активуйте віртуальне середовище:
venv\Scripts\activate
Відкрийте термінал і виконайте таку команду, щоб створити нове віртуальне середовище з іменем "venv":
sudo python3 -m venv venv
Активуйте віртуальне середовище:
source venv/bin/activate
Щоб деактивувати віртуальне середовище, виконайте таку команду:
deactivate
Після налаштування віртуального середовища можна приступити до встановлення необхідних бібліотек для скрапінгу даних.
В активованому віртуальному середовищі виконайте таку команду:
pip install selenium beautifulsoup4 lxml seleniumwire
Для роботи з Selenium необхідний спеціальний драйвер, який буде здійснювати взаємодію з обраним браузером. У цьому посібнику ми будемо використовувати браузер Chrome, але важливо встановити відповідний WebDriver для обраного браузера. Після завантаження переконайтеся, що драйвер розташований у каталозі, який включено до змінної середовища PATH вашої операційної системи. Це дозволить Selenium автоматично знаходити драйвер і керувати браузером.
На початку Python-файлу імпортуйте Seleniumwire і BeautifulSoup, а також інші необхідні бібліотеки за допомогою таких команд:
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
import csv
import random
Ми також імпортуємо бібліотеки "random", "time" і "csv" для різних допоміжних функцій.
Далі ми завантажуємо список проксі, щоб уникнути блокування з боку Airbnb. Під час спроби надіслати запит без використання приватного проксі користувач може зіткнутися з відповіддю "Access Denied".
Налаштування проксі виконується таким чином:
# Список проксі-серверів
proxies = [
"username:password@Your_proxy_IP_Address:Your_proxy_port1",
"username:password@Your_proxy_IP_Address:Your_proxy_port2",
"username:password@Your_proxy_IP_Address:Your_proxy_port3",
"username:password@Your_proxy_IP_Address:Your_proxy_port4",
"username:password@Your_proxy_IP_Address:Your_proxy_port5",
]
Переконайтеся, що замінили "Your_proxy_IP_Address", "Your_proxy_port", а також "username" і "password" на актуальні дані.
Ротація проксі - ключовий елемент успішного веб-скрапінгу. Веб-сайти часто блокують доступ, коли помічають безліч запитів з однієї IP-адреси. Ротація різних проксі дає змогу замаскувати активність, імітуючи роботу безлічі звичайних користувачів і обійти анти-скрапінгові системи безпеки.
Для налаштування ротації проксі спочатку імпортуйте бібліотеку "random". Потім створіть функцію "get_proxy()", яка вибиратиме проксі з наданого списку випадковим чином, використовуючи метод "random.choice()", і повертатиме обраний проксі.
def get_proxy():
return random.choice(proxies)
Далі ми створюємо основну функцію під назвою "listings()". У цій функції налаштовується "ChromeDriver", також вона використовує Selenium для навігації сторінкою з оголошеннями про нерухомість, очікує на завантаження сторінки та аналізує HTML за допомогою Beautiful Soup.
def listings(url):
proxy = get_proxy()
proxy_options = {
"proxy": {
"http": f"http://{proxy}",
"https": f"http://{proxy}",
"no_proxy": "localhost,127.0.0.1",
}
}
chrome_options = Options()
chrome_options.add_argument("--headless")
s = Service(
"C:/Path_To_Your_WebDriver"
) # Замініть на ваш шлях до ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Настройте в зависимости от времени загрузки сайта
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
У цій функції спочатку обирається випадковий проксі та налаштовуються його опції, які надалі використовуються для конфігурації WebDriver. Далі налаштовуються опції Chrome, включно з аргументом "--headless", що дає змогу браузеру працювати у фоновому режимі без графічного інтерфейсу.
Потім WebDriver ініціалізується із зазначеними сервісом, опціями seleniumwire і Chrome, що, своєю чергою, використовується для переходу за заданим URL. Час очікування у 8 секунд дозволяє сторінці повністю завантажитися, після чого за допомогою Beautiful Soup проводиться аналіз повернутого HTML. Після завершення аналізу WebDriver закривається.
Наступний етап після отримання HTML-вмісту сторінки включає в себе витяг даних з кожного оголошення. Використовуючи бібліотеку BeautifulSoup, ми можемо ефективно здійснювати навігацію по структурі HTML і визначати елементи, що містять потрібну нам інформацію.
Для початку потрібно визначити всі елементи оголошення на сторінці, які містять необхідні нам дані: URL оголошення, заголовок, опис, рейтинг, ціну та іншу релевантну інформацію.
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
Цей код використовує метод "find_all()" бібліотеки BeautifulSoup для пошуку всіх елементів "div" із класом "g1qv1ctd". Ці елементи являють собою окремі оголошення на сторінці Airbnb. Потім скрипт перебирає кожен із цих елементів для вилучення відповідних даних.
Для кожного знайденого елемента оголошення проводиться витяг URL.
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
У цьому фрагменті коду ми досліджуємо об'єкт "soup" на предмет наявності тега анкора з класом "rfexzly". Якщо такий елемент знайдено, з нього витягується атрибут "href", що містить URL. Цей URL потім додається до базової адреси Airbnb для формування повного URL оголошення. У разі відсутності елемента присвоюється порожній рядок, щоб запобігти можливим помилкам у виконанні коду.
Сначала мы извлечем URL каждого объявления. Это позволит нам в дальнейшем посетить страницы каждого из этих объявлений, если это будет необходимо.
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
Далее, для извлечения заголовка объявления, мы обращаемся к элементу “div” с классом “t1jojoys”. Из этого элемента извлекается текстовое содержимое, при этом удаляются все начальные и конечные пробелы для чистоты данных. В случае отсутствия такого элемента в объявлении сохраняется пустая строка, чтобы избежать ошибок при обработке данных.
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
Так само, як і під час вилучення заголовка, цей код знаходить елемент "" з класом "t6mzqp7". Потім з цього елемента витягується і очищається текстовий вміст, який являє собою короткий опис оголошення.
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
Як видно з коду вище, елемент "span" із класом "ru0q88m" містить значення рейтингу. Ми витягуємо це значення, переконавшись, що зайві пробіли видалено.
Нарешті, ми витягуємо ціну оголошення.
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
Цей код знаходить елемент із класом "._1y74zjx" у поточному елементі оголошення. Якщо цей елемент, який зазвичай містить інформацію про ціну, знайдено, його текстовий вміст витягують, очищають і доповнюють фразою "per night", формуючи в такий спосіб більш інформативний рядок із ціною.
Деякі оголошення можуть містити додаткову інформацію, яку ми можемо отримати.
listing_info_element = listing_element.find("span", {"aria-hidden": "true"})
listing_data["Additional Listing information"] = (
listing_info_element.get_text(strip=True) if listing_info_element else ""
)
Ми шукаємо елемент "" з атрибутом aria-hidden="true" для пошуку додаткової інформації про оголошення. Після того як усі релевантні дані з кожного елемента оголошення витягнуто, ми додаємо зібрані дані до списку оголошень.
listings.append(listing_data)
Щойно всі оголошення оброблено, ми повертаємо список оголошень, де кожне оголошення представлено у вигляді словника, що містить витягнуті дані.
return listings
Після успішного збору даних зі сторінок оголошень Airbnb наступним важливим кроком є збереження цієї інформації для майбутнього аналізу та довідки. Для цього завдання ми використовуємо бібліотеку csv. Спочатку відкриваємо файл CSV у режимі запису і створюємо об'єкт csv.DictWriter. Потім ми записуємо заголовок і дані у файл.
airbnb_listings = listings(url)
csv_file_path = "proxy_web_listings_output.csv"
with open(csv_file_path, "w", encoding="utf-8", newline="") as csv_file:
fieldnames = [
"Listing URL",
"Title",
"Description",
"Rating",
"Price",
"Additional Listing information",
]
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
for listing in airbnb_listings:
writer.writerow(listing)
print(f"Data has been exported to {csv_file_path}")
Нижче представлено повну версію коду, що використовується під час цього туторіалу:
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
import csv
import random
# Список проксі-серверів
proxies = [
"username:password@Your_proxy_IP_Address:Your_proxy_port1",
"username:password@Your_proxy_IP_Address:Your_proxy_port2",
"username:password@Your_proxy_IP_Address:Your_proxy_port3",
"username:password@Your_proxy_IP_Address:Your_proxy_port4",
"username:password@Your_proxy_IP_Address:Your_proxy_port5",
]
def get_proxy():
return random.choice(proxies)
def listings(url):
proxy = get_proxy()
proxy_options = {
"proxy": {
"http": f"http://{proxy}",
"https": f"http://{proxy}",
"no_proxy": "localhost,127.0.0.1",
}
}
chrome_options = Options()
chrome_options.add_argument("--headless")
s = Service(
"C:/Path_To_Your_WebDriver"
) # Замініть на ваш шлях до ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Налаштуйте залежно від часу завантаження сайту
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
listings = []
# Знайдіть усі елементи оголошень на сторінці
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
# Витягніть дані з кожного елемента оголошення
listing_data = {}
# URL оголошення
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
# Заголовок
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
# Опис
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
# Рейтинг
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
# Ціна
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
# Додаткова інформація оголошення
listing_info_element = listing_element.find("span", {"aria-hidden": "true"})
listing_data["Additional Listing information"] = (
listing_info_element.get_text(strip=True) if listing_info_element else ""
)
# Додайте дані оголошення до списку
listings.append(listing_data)
return listings
url = "https://www.airbnb.com/s/London--United-Kingdom/homes?tab_id=home_tab&refinement_paths%5B%5D=%2Fhomes&flexible_trip_lengths%5B%5D=one_week&monthly_start_date=2024-01-01&monthly_length=3&price_filter_input_type=0&channel=EXPLORE&query=London%2C%20United%20Kingdom&place_id=ChIJdd4hrwug2EcRmSrV3Vo6llI&date_picker_type=calendar&source=structured_search_input_header&search_type=autocomplete_click"
airbnb_listings = listings(url)
csv_file_path = "proxy_web_listings_output.csv"
with open(csv_file_path, "w", encoding="utf-8", newline="") as csv_file:
fieldnames = [
"Listing URL",
"Title",
"Description",
"Rating",
"Price",
"Additional Listing information",
]
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
for listing in airbnb_listings:
writer.writerow(listing)
print(f"Data has been exported to {csv_file_path}")
Ця частина коду забезпечує збереження зібраних даних у файл CSV під назвою "proxy_web_listings_output.csv".
Результати роботи нашого скрапера зберігаються у файл CSV у форматі, показаному нижче на скріншоті.
Ця інструкція ефективна для вилучення даних з оголошень Airbnb за допомогою Python і дає змогу збирати важливу інформацію про нерухомість, включно з цінами, доступністю та відгуками. Використання проксі та налаштування їхньої ротації - важливий крок, щоб уникнути блокування з боку механізмів захисту Airbnb від ботів.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Коментарі: 0