Uzyskanie dostępu do danych z Airbnb jest kluczowe dla analizy rynku nieruchomości, badania dynamiki cen wynajmu, przeprowadzania analiz konkurencyjnych oraz oceny recenzji i ocen. Można to osiągnąć poprzez zbieranie danych z sieci (web scraping). Jednak dostęp do tych danych może być wyzwaniem, ponieważ zbieranie danych może naruszać warunki korzystania z serwisu.
Następnie omówimy krok po kroku, jak opracować program do zbierania danych z ofert Airbnb przy użyciu Python i Selenium. Przewodnik ten obejmie również, jak unikać potencjalnych blokad i ograniczeń narzucanych przez platformę.
Pierwszym krokiem w tworzeniu programu do zbierania danych jest zrozumienie, jak uzyskać dostęp do stron internetowych, które nas interesują, ponieważ struktura stron internetowych może się często zmieniać. Aby zapoznać się ze strukturą strony, można skorzystać z narzędzi deweloperskich przeglądarki, aby sprawdzić HTML strony internetowej.
Aby uzyskać dostęp do narzędzi deweloperskich, kliknij prawym przyciskiem myszy na stronie internetowej i wybierz "Zbadaj" lub użyj skrótu:
Każdy kontener oferty jest opakowany w element div z następującym atrybutem: class="g1qv1ctd".
Klikając na "lokalizację" i wpisując "Londyn, UK", możemy uzyskać dostęp do ofert w Londynie. Strona sugeruje dodanie dat zameldowania i wymeldowania, co pozwala na obliczenie ceny pokoi.
URL tej strony będzie wyglądać mniej więcej tak:
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"
Na stronie wyników wyszukiwania będziemy zbierać następujące atrybuty danych z ofert:
Aby rozpocząć zbieranie danych z Airbnb, najpierw należy skonfigurować środowisko programistyczne. Oto kroki, jak to zrobić:
Środowiska wirtualne pozwalają na izolowanie pakietów Python i ich zależności dla różnych projektów. Pomaga to zapobiec konfliktom i zapewnia, że każdy projekt ma zainstalowane odpowiednie zależności.
Otwórz wiersz polecenia z uprawnieniami administratora i uruchom następujące polecenie, aby utworzyć nowe środowisko wirtualne o nazwie “venv”:
python -m venv venv
Aktywuj środowisko wirtualne:
venv\Scripts\activate
Otwórz terminal i uruchom następujące polecenie, aby utworzyć nowe środowisko wirtualne o nazwie "venv":
sudo python3 -m venv venv
Aktywacja środowiska wirtualnego:
source venv/bin/activate
Aby dezaktywować środowisko wirtualne, wystarczy uruchomić następujące polecenie:
deactivate
Po skonfigurowaniu środowiska wirtualnego można zainstalować niezbędne biblioteki.
W aktywowanym środowisku wirtualnym uruchom następujące polecenie, aby zainstalować wymagane biblioteki:
pip install selenium beautifulsoup4 lxml seleniumwire
Selenium wymaga sterownika do połączenia z wybraną przeglądarką. W tym przewodniku użyjemy przeglądarki Chrome. Upewnij się jednak, że zainstalowałeś odpowiedni WebDriver dla wybranej przeglądarki.
Po pobraniu upewnij się, że sterownik jest umieszczony w katalogu dostępnym przez zmienną środowiskową PATH systemu. Pozwoli to Selenium znaleźć sterownik i kontrolować przeglądarkę.
Na początku pliku Pythona zaimportuj biblioteki Seleniumwire i BeautifulSoup. Można to zrobić w następujący sposób:
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
Zaimportujemy również biblioteki `random`, `time` i `csv` dla różnych narzędzi.
Następnie definiujemy listę serwerów proxy, aby uniknąć zablokowania przez Airbnb. Podczas próby wysłania żądania bez proxy premium, możesz napotkać odpowiedź "Odmowa dostępu".
Serwer proxy można skonfigurować w następujący sposób:
# Lista pełnomocników
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",
]
Upewnij się, że zastąpiłeś "Your_proxy_IP_Address" i "Your_proxy_port" rzeczywistym adresem proxy uzyskanym od sprzedawcy proxy, a także zastąpiłeś wartości "username" i "password" swoimi rzeczywistymi poświadczeniami.
Rotacja serwerów proxy jest kluczowym aspektem web scrapingu. Strony internetowe często blokują lub ograniczają dostęp botom i scraperom, gdy otrzymują wiele żądań z tego samego adresu IP. Obracając różnymi adresami IP proxy, można uniknąć wykrycia, pojawić się jako wielu organicznych użytkowników i ominąć większość środków zapobiegających skrobaniu zaimplementowanych na stronie internetowej.
Aby ustawić rotację proxy, zaimportuj bibliotekę "random". Definiujemy również funkcję `get_proxy()`, aby wybrać proxy z naszej listy. Funkcja ta losowo wybiera proxy z listy proxy przy użyciu metody random.choice() i zwraca wybrane proxy.
def get_proxy():
return random.choice(proxies)
Następnie definiujemy główną funkcję o nazwie `listings()`. To tutaj skonfigurujemy nasz "ChromeDriver". Ta funkcja używa Selenium do nawigacji po stronie z listą nieruchomości, czeka na załadowanie strony i analizuje HTML za pomocą 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"
) # Zastąp ścieżką do ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Dostosuj na podstawie czasu ładowania strony
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
Tutaj zaczynamy od wybrania losowego serwera proxy i skonfigurowania opcji proxy. Opcje te zostaną wykorzystane do skonfigurowania webdrivera do korzystania z serwera proxy. Następnie ustawiamy opcje Chrome. Dodajemy argument --headless, aby uruchomić przeglądarkę w trybie headless, co oznacza, że przeglądarka będzie działać w tle bez graficznego interfejsu użytkownika.
Następnie należy zainicjować webdriver z usługą, opcjami seleniumwire i opcjami Chrome. Webdriver jest następnie używany do nawigacji do podanego adresu URL. Dodajemy czas uśpienia wynoszący 8 sekund, aby umożliwić całkowite załadowanie strony, a następnie analizujemy zwrócony kod HTML za pomocą Beautiful Soup. Po zakończeniu parsowania zamykamy webdriver.
Po pomyślnym uzyskaniu zawartości HTML, następnym krokiem jest wyodrębnienie odpowiednich danych dla każdej oferty. Korzystając z BeautifulSoup, możemy łatwo poruszać się po strukturze HTML i zlokalizować elementy zawierające informacje o ofercie.
Najpierw identyfikujemy wszystkie elementy oferty na stronie. Elementy te zawierają interesujące nas dane, takie jak adres URL oferty, tytuł, opis, ocena, cena i dodatkowe informacje.
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
Ten kod wykorzystuje metodę find_all() BeautifulSoup do zlokalizowania wszystkich elementów div z klasą "g1qv1ctd". Elementy te reprezentują poszczególne oferty na stronie Airbnb. Następnie przechodzi przez każdy z tych elementów, aby wyodrębnić odpowiednie dane.
Dla każdego znalezionego elementu oferty wyodrębniamy adres URL oferty.
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
Tutaj szukamy w naszym obiekcie "soup" znacznika kotwicy z klasą "rfexzly". Jeśli znajdzie ten element, wyodrębnia atrybut "href" (który zawiera względny adres URL) i dołącza go do podstawowego adresu URL, aby utworzyć pełny adres URL listy. Jeśli element nie zostanie znaleziony, przypisuje pusty ciąg znaków, aby uniknąć błędów.
Najpierw wyodrębnimy adres URL dla każdej oferty. Pozwoli nam to później odwiedzić poszczególne strony ofert, jeśli zajdzie taka potrzeba.
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
Tytuł jest zawarty w elemencie "div" z klasą "t1jojoys". Pobieramy zawartość tekstową tego elementu, usuwając wszelkie początkowe i końcowe białe znaki. Jeśli element nie zostanie znaleziony, zapisywany jest pusty ciąg znaków.
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
Podobnie jak w przypadku wyodrębniania tytułu, kod ten znajduje element span z klasą "t6mzqp7". Następnie wyodrębniamy i czyścimy zawartość tekstową tego elementu, która zawiera krótki opis oferty.
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
Jak widać w powyższym kodzie, element span z klasą "ru0q88m" przechowuje wartość ratingu. Wyodrębniamy tę wartość, usuwając wszelkie niepotrzebne białe znaki.
Na koniec wyodrębniamy cenę oferty.
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
Ten kod lokalizuje element z klasą "_1y74zjx" w bieżącym listing_element. Jeśli ten element, który zazwyczaj zawiera informacje o cenie, zostanie znaleziony, jego zawartość tekstowa zostanie wyodrębniona, wyczyszczona i dołączona do "za noc", aby utworzyć bardziej informacyjny ciąg ceny.
Niektóre oferty mogą zawierać dodatkowe informacje, które możemy wyodrębnić.
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 ""
)
Szukamy elementu span z atrybutem aria-hidden="true", aby znaleźć wszelkie dodatkowe informacje na temat oferty. Po wyodrębnieniu wszystkich istotnych danych z każdego elementu oferty, dołączamy zebrane dane do listy ofert.
listings.append(listing_data)
Po przetworzeniu wszystkich ofert zwracamy listę ofert, z których każda jest reprezentowana jako słownik zawierający wyodrębnione dane.
return listings
Po pomyślnym zeskrobaniu danych ze stron z ofertami Airbnb, kolejnym ważnym krokiem jest przechowywanie tych cennych informacji do przyszłej analizy i odniesienia. Do tego zadania wykorzystujemy bibliotekę csv. Otwieramy plik CSV w trybie zapisu i tworzymy obiekt csv.DictWriter. Następnie zapisujemy nagłówek i dane do pliku.
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}")
Oto kompletny kod, którego użyliśmy w tym samouczku:
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
# Lista pełnomocników
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"
) # Zastąp ścieżką do ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Dostosuj na podstawie czasu ładowania strony
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
listings = []
# Znajdź wszystkie elementy listy na stronie
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
# Wyodrębnij dane z każdego elementu listy
listing_data = {}
# Listing URL
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
# Tytuł
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
# Opis
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
# Ocena
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
# Cena
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
# Dodatkowe informacje o ofercie
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 ""
)
# Dołącz dane listy do listy
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}")
Ta część kodu zapewnia, że zeskrobane dane są przechowywane w pliku CSV o nazwie "proxy_web_listings_output.csv".
Wyniki naszego scrapera są zapisywane w pliku CSV o nazwie "proxy_web_listings_output.csv", jak pokazano poniżej.
Ten przewodnik skutecznie wyjaśnia, jak skrobać dane z ofert Airbnb za pomocą Pythona, umożliwiając wyodrębnienie kluczowych szczegółów, takich jak ceny, dostępność i recenzje. Podkreśla znaczenie korzystania z serwerów proxy i ich rotacji, aby zapobiec zablokowaniu przez środki antybotowe Airbnb.
Komentarze: 0