L'accès aux données d'Airbnb est essentiel pour analyser le marché de l'immobilier, étudier la dynamique des prix de location, mener des analyses concurrentielles et évaluer les avis et les évaluations. Il est possible d'y parvenir en récupérant des données sur le web. Cependant, l'accès à ces données peut s'avérer difficile car le scraping peut violer les conditions d'utilisation du site.
Ensuite, nous allons explorer un guide étape par étape sur la façon de développer un scraper web pour extraire des données des annonces Airbnb en utilisant Python et Selenium. Ce guide expliquera également comment éviter les blocages et les restrictions potentiels imposés par la plateforme.
La première étape de la création d'un scraper web consiste à comprendre comment accéder aux pages web qui vous intéressent, car la structure des sites web peut souvent changer. Pour vous familiariser avec la structure d'un site, vous pouvez utiliser les outils de développement du navigateur pour inspecter le code HTML de la page web.
Pour accéder aux outils de développement, cliquez avec le bouton droit de la souris sur la page web et sélectionnez "Inspecter" ou utilisez le raccourci :
Chaque conteneur de liste est enveloppé dans un élément div avec l'attribut suivant : class="g1qv1ctd".
En cliquant sur "location" et en tapant "London, UK", nous pouvons accéder à la location proposée à Londres. Le site propose d'ajouter les dates d'arrivée et de départ. Cela permet de calculer le prix des chambres.
L'URL de cette page ressemblerait à ceci :
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"
À partir de la page de recherche, nous allons récupérer les attributs suivants des données de la liste de produits :
Pour commencer le web scraping des données Airbnb, vous devez d'abord configurer votre environnement de développement. Voici les étapes à suivre:
Les environnements virtuels vous permettent d'isoler les paquets Python et leurs dépendances pour différents projets. Cela permet d'éviter les conflits et de s'assurer que chaque projet dispose des bonnes dépendances.
Ouvrez une invite de commande avec des privilèges d'administrateur et exécutez la commande suivante pour créer un nouvel environnement virtuel nommé "venv" :
python -m venv venv
Activer l'environnement virtuel :
venv\Scripts\activate
Ouvrez un terminal et exécutez la commande suivante pour créer un nouvel environnement virtuel nommé "venv" :
sudo python3 -m venv venv
Activer l'environnement virtuel :
source venv/bin/activate
Pour désactiver l'environnement virtuel, il suffit d'exécuter la commande suivante :
deactivate
Maintenant que vous avez mis en place un environnement virtuel, vous pouvez installer les bibliothèques nécessaires.
Dans votre environnement virtuel activé, exécutez la commande suivante pour installer les bibliothèques requises :
pip install selenium beautifulsoup4 lxml seleniumwire
Selenium nécessite un pilote pour interfacer avec le navigateur choisi. Nous utiliserons Chrome pour ce guide. Cependant, assurez-vous d'avoir installé le pilote WebDriver approprié pour le navigateur de votre choix.
Une fois téléchargé, assurez-vous que le pilote est placé dans un répertoire accessible par la variable d'environnement PATH de votre système. Cela permettra à Selenium de trouver le pilote et de contrôler le navigateur.
Au début de votre fichier Python, importez les bibliothèques Seleniumwire et BeautifulSoup. Voici comment procéder :
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
Nous importerons également les bibliothèques `random`, `time` et `csv` pour divers utilitaires.
Ensuite, nous définissons une liste de proxys pour éviter qu'Airbnb ne les bloque. Si vous essayez d'envoyer une demande sans proxy premium, vous risquez d'obtenir une réponse "Accès refusé".
Vous pouvez configurer un proxy de la manière suivante :
# Liste des mandataires
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",
]
Veillez à remplacer "Your_proxy_IP_Address" et "Your_proxy_port" par l'adresse proxy réelle que vous avez obtenue auprès du vendeur de proxy et remplacez également les valeurs de "username" et "password" par vos informations d'identification réelles.
La rotation des proxys est un aspect crucial du web scraping. Les sites web bloquent ou restreignent souvent l'accès aux bots et aux scrapers lorsqu'ils reçoivent plusieurs requêtes provenant de la même adresse IP. En passant par différentes adresses IP de proxy, vous pouvez éviter d'être détecté, apparaître comme plusieurs utilisateurs organiques et contourner la plupart des mesures anti-scraping mises en œuvre sur le site web.
Pour mettre en place la rotation des mandataires, il faut importer la bibliothèque "random". Nous définissons également une fonction `get_proxy()` pour sélectionner un proxy dans notre liste. Cette fonction sélectionne aléatoirement un proxy dans la liste des proxies en utilisant la méthode random.choice() et renvoie le proxy sélectionné.
def get_proxy():
return random.choice(proxies)
Ensuite, nous définissons la fonction principale appelée `listings()`. C'est ici que nous allons mettre en place notre "ChromeDriver". Cette fonction utilise Selenium pour naviguer sur la page d'annonces immobilières, attend que la page se charge, et analyse le HTML en utilisant 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"
) # Remplacer par le chemin d'accès à ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Ajuster en fonction du temps de chargement du site web
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
Ici, nous commençons par sélectionner un proxy aléatoire et par configurer les options du proxy. Ces options seront utilisées pour configurer le webdriver afin qu'il utilise le serveur proxy. Ensuite, nous configurons les options de Chrome. Ajoutez l'argument --headless pour exécuter le navigateur en mode headless, ce qui signifie que le navigateur fonctionnera en arrière-plan sans interface utilisateur graphique.
Initialiser ensuite le pilote web avec le service, les options seleniumwire et les options Chrome. Le webdriver est alors utilisé pour naviguer vers l'URL donnée. Nous ajoutons un temps de sommeil de 8 secondes pour permettre à la page de se charger complètement, puis nous analysons le code HTML retourné à l'aide de Beautiful Soup. Une fois l'analyse terminée, le webdriver est fermé.
Une fois que vous avez réussi à obtenir le contenu HTML, l'étape suivante est d'extraire les données pertinentes pour chaque listing. En utilisant BeautifulSoup, nous pouvons facilement naviguer dans la structure HTML et localiser les éléments contenant les informations de l'annonce.
Tout d'abord, nous identifions tous les éléments de l'annonce sur la page. Ces éléments contiennent les données qui nous intéressent, telles que l'URL de l'annonce, le titre, la description, l'évaluation, le prix et les informations complémentaires.
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
Ce code utilise la méthode find_all() de BeautifulSoup pour localiser tous les éléments div avec la classe "g1qv1ctd". Ces éléments représentent des annonces individuelles sur la page Airbnb. Il parcourt ensuite chacun de ces éléments pour en extraire les données pertinentes.
Pour chaque élément d'inscription trouvé, nous extrayons l'URL de l'inscription.
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
Ici, nous recherchons dans notre objet "soupe" une balise d'ancrage de la classe "rfexzly". S'il trouve cet élément, il extrait l'attribut "href" (qui contient l'URL relative) et l'ajoute à l'URL de base pour créer l'URL complète de la liste. Si l'élément n'est pas trouvé, il attribue une chaîne vide pour éviter les erreurs.
Tout d'abord, nous allons extraire l'URL de chaque fiche. Cela nous permettra de visiter les pages individuelles des annonces plus tard, si nécessaire.
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
Le titre est contenu dans un élément "div" de classe "t1jojoys". Nous récupérons le contenu textuel de cet élément, en supprimant tout espace blanc de début ou de fin. Une chaîne vide est stockée si l'élément n'est pas trouvé.
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
Comme pour l'extraction du titre, ce code trouve un élément span avec la classe "t6mzqp7". Nous extrayons et nettoyons ensuite le contenu textuel de cet élément, qui contient une brève description de l'annonce.
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
Comme le montre le code ci-dessus, un élément span de classe "ru0q88m" contient la valeur de l'évaluation. Nous extrayons cette valeur en veillant à supprimer tout espace blanc inutile.
Enfin, nous extrayons le prix de l'annonce.
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
Ce code localise l'élément de la classe "_1y74zjx" dans le listing_element actuel. Si cet élément, qui contient généralement les informations sur le prix, est trouvé, son contenu textuel est extrait, nettoyé et complété par "par nuit" pour former une chaîne de prix plus informative.
Certaines listes peuvent contenir des informations supplémentaires que nous pouvons extraire.
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 ""
)
Nous recherchons un élément span avec l'attribut aria-hidden="true" pour trouver des informations supplémentaires sur l'annonce. Après avoir extrait toutes les données pertinentes de chaque élément de l'annonce, nous ajoutons les données collectées à une liste d'annonces.
listings.append(listing_data)
Une fois que toutes les inscriptions ont été traitées, nous renvoyons la liste des inscriptions, chacune étant représentée par un dictionnaire contenant les données extraites.
return listings
Après avoir réussi à récupérer les données des pages d'inscription d'Airbnb, l'étape suivante consiste à stocker ces informations précieuses pour les analyser et les consulter ultérieurement. Nous utilisons la bibliothèque csv pour cette tâche. Nous ouvrons un fichier CSV en mode écriture et créons un objet csv.DictWriter. Nous écrivons ensuite l'en-tête et les données dans le fichier.
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}")
Voici le code complet que nous avons utilisé pour ce tutoriel :
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
# Liste des mandataires
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"
) # Remplacer par le chemin d'accès à ChromeDriver
driver = webdriver.Chrome(
service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
)
driver.get(url)
time.sleep(8) # Ajuster en fonction du temps de chargement du site web
soup = BeautifulSoup(driver.page_source, "lxml")
driver.quit()
listings = []
# Trouver tous les éléments de la liste sur la page
listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:
# Extraire les données de chaque élément de la liste
listing_data = {}
# URL de l'inscription
URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
"https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)
# Titre
title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
title_element.get_text(strip=True) if title_element else ""
)
# Description
Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
Description_element.get_text(strip=True) if Description_element else ""
)
# Classement
rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
rating_element.get_text(strip=True) if rating_element else ""
)
# Prix
price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
f"{price_element.get_text(strip=True)} per night" if price_element else ""
)
# Informations complémentaires sur la liste
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 ""
)
# Ajouter les données du listing à la liste
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}")
Cette partie du code garantit que les données extraites sont stockées dans un fichier CSV nommé "proxy_web_listings_output.csv".
Les résultats de notre scraper sont enregistrés dans un fichier CSV appelé "proxy_web_listings_output.csv", comme indiqué ci-dessous.
Ce guide explique efficacement comment extraire des données des annonces Airbnb à l'aide de Python, ce qui permet d'extraire des détails clés tels que les prix, la disponibilité et les avis. Il souligne l'importance d'utiliser des proxies et de les faire tourner pour éviter d'être bloqué par les mesures anti-bots d'Airbnb.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Commentaires: 0