Python ile Airbnb listeleme verilerini kazıma

Yorumlar: 0

Airbnb verilerine erişim elde etmek, emlak piyasasını analiz etmek, kira fiyat dinamiklerini araştırmak, rekabet analizi yapmak ve incelemeleri ve derecelendirmeleri değerlendirmek için çok önemlidir. Bu, web verilerini kazıyarak gerçekleştirilebilir. Ancak, kazıma işlemi sitenin kullanım koşullarını ihlal edebileceğinden bu verilere erişmek zor olabilir.

Ardından, Python ve Selenium kullanarak Airbnb listelerinden veri almak için bir web kazıyıcının nasıl geliştirileceğine dair adım adım bir kılavuz inceleyeceğiz. Bu kılavuz aynı zamanda platform tarafından uygulanan potansiyel engellerden ve kısıtlamalardan nasıl kaçınılacağını da kapsayacaktır.

Airbnb'nin web sitesinin mimarisini anlama

Bir web kazıyıcı oluşturmanın ilk adımı, web sitelerinin yapısı sıklıkla değişebildiğinden, ilgilendiğiniz web sayfalarına nasıl erişeceğinizi anlamaktır. Bir sitenin yapısına aşina olmak için, web sayfasının HTML'sini incelemek üzere tarayıcının geliştirici araçlarını kullanabilirsiniz.

Geliştirici Araçlarına erişmek için web sayfasına sağ tıklayın ve "İncele "yi seçin veya kısayolu kullanın:

  • CTRL+SHIFT+I Windows için;
  • Option + ⌘ + I Mac üzerinde.

Her liste konteyneri, aşağıdaki niteliğe sahip bir div öğesine sarılır: class="g1qv1ctd".

1.png

"Konum "a tıklayıp "Londra, İngiltere" yazarak Londra'da sunulan konuma erişebiliriz. Web sitesi check-in ve check-out tarihlerini eklemeyi öneriyor. Bu da oda fiyatlarını hesaplamalarını sağlıyor.

2.png

Bu sayfanın URL'si aşağıdaki gibi görünecektir:

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"

Arama sayfasından, ürün listeleme verilerinin aşağıdaki özelliklerini kazıyacağız:

  • Listeleme URL'si;
  • Başlık;
  • Açıklama;
  • Rating;
  • Fiyat;
  • Ek İlan Bilgileri (Yatak sayısı ve müsait tarihler).

3.png

Airbnb kazıma programı oluşturmak için adım adım kılavuz

Airbnb verileri için web kazıma işlemine başlamak için önce geliştirme ortamınızı kurmanız gerekir. İşte bunu yapmak için adımlar:

Adım 1: Sanal bir ortam oluşturma

Sanal ortamlar, Python paketlerini ve bağımlılıklarını farklı projeler için izole etmenize olanak tanır. Bu, çakışmaları önlemeye yardımcı olur ve her projenin doğru bağımlılıklara sahip olmasını sağlar.

Windows üzerinde sanal bir ortam oluşturma

Yönetici ayrıcalıklarına sahip bir komut istemi açın ve "venv" adında yeni bir sanal ortam oluşturmak için aşağıdaki komutu çalıştırın:

python -m venv venv

Sanal ortamı etkinleştirin:

venv\Scripts\activate

MacOS/Linux üzerinde sanal bir ortam oluşturma

Bir terminal açın ve "venv" adında yeni bir sanal ortam oluşturmak için aşağıdaki komutu çalıştırın:

sudo python3 -m venv venv

Sanal ortamı etkinleştirin:

source venv/bin/activate

Sanal ortamı devre dışı bırakmak için aşağıdaki komutu çalıştırmanız yeterlidir:

deactivate

Adım 2: Gerekli kütüphanelerin yüklenmesi

Artık sanal bir ortamınız olduğuna göre, gerekli kütüphaneleri yükleyebilirsiniz.

Kütüphaneleri anlamak:

  • Selenium: Bu güçlü web kazıma aracı, bir web tarayıcısını programlı olarak kontrol etmenizi sağlar. Bu, düğmelere tıklamak, formları doldurmak ve sayfalarda gerçek bir kullanıcıymışsınız gibi gezinmek de dahil olmak üzere web sayfalarıyla etkileşime girmenizi sağlar.
  • Seleniumwire: Bu kütüphane, HTTP isteklerini yakalamanıza ve incelemenize ve proxy'leri kazıma işlemlerinizle entegre etmenize olanak tanıyarak Selenium'u genişletir. Selenium'un yerel proxy desteği olmadığı için bu çok önemlidir.
  • BeautifulSoup4: HTML ve XML dosyalarını ayrıştırmak için tasarlanmış bir kütüphanedir. Web sayfalarından belirli bilgileri yapılandırılmış ve verimli bir şekilde çıkarmanıza yardımcı olur.
  • lxml: BeautifulSoup'u tamamlayan hızlı ve sağlam bir HTML ve XML ayrıştırıcı.

Etkinleştirilmiş sanal ortamınızda, gerekli kütüphaneleri yüklemek için aşağıdaki komutu çalıştırın:

pip install selenium beautifulsoup4 lxml seleniumwire

Selenium sürücüleri

Selenium, seçilen tarayıcı ile arayüz oluşturmak için bir sürücü gerektirir. Bu kılavuz için Chrome kullanacağız. Ancak, lütfen seçtiğiniz tarayıcı için uygun WebDriver'ı yüklediğinizden emin olun.

İndirildikten sonra, sürücünün sisteminizin PATH ortam değişkeni tarafından erişilebilen bir dizine yerleştirildiğinden emin olun. Bu, Selenium'un sürücüyü bulmasını ve tarayıcıyı kontrol etmesini sağlayacaktır.

Adım 3: Kütüphaneleri içe aktarın

Python dosyanızın başında Seleniumwire ve BeautifulSoup kütüphanelerini içe aktarın. Bunu şu şekilde yaparsınız:

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

Ayrıca çeşitli yardımcı programlar için `random`, `time` ve `csv` kütüphanelerini de içe aktaracağız.

Adım 4: Proxy entegrasyonu

Ardından, Airbnb tarafından engellenmekten kaçınmak için bir proxy listesi tanımlıyoruz. Premium proxy olmadan bir istek göndermeye çalıştığınızda "Erişim Reddedildi" yanıtıyla karşılaşabilirsiniz.

4.png

Bir proxy'yi aşağıdaki şekilde ayarlayabilirsiniz:

# Vekillerin listesi
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" ve "Your_proxy_port" değerlerini Proxy-seller'dan aldığınız gerçek proxy adresiyle değiştirdiğinizden emin olun ve ayrıca "username" ve "password" değerlerini gerçek kimlik bilgilerinizle değiştirin.

Adım 5: Proxy'leri döndürme

Proxy'leri döndürmek web kazımanın çok önemli bir yönüdür. Web siteleri genellikle aynı IP adresinden birden fazla istek aldıklarında botların ve kazıyıcıların erişimini engeller veya kısıtlar. Farklı proxy IP adresleri arasında rotasyon yaparak, tespit edilmekten kaçınabilir, birden fazla organik kullanıcı olarak görünebilir ve web sitesinde uygulanan çoğu kazıma önleyici önlemi atlayabilirsiniz.

Proxy rotasyonunu ayarlamak için "random" Kütüphanesini içe aktarın. Ayrıca listemizden bir proxy seçmek için bir `get_proxy()` fonksiyonu tanımlarız. Bu fonksiyon random.choice() yöntemini kullanarak proxy listesinden rastgele bir proxy seçer ve seçilen proxy'yi döndürür.

def get_proxy():
    return random.choice(proxies)

Adım 6: WebDriver'ı Kurun

Ardından, `listings()` adlı ana fonksiyonu tanımlıyoruz. Burası "ChromeDriver "ımızı kuracağımız yerdir. Bu fonksiyon, emlak listeleri sayfasında gezinmek için Selenium'u kullanır, sayfanın yüklenmesini bekler ve Beautiful Soup kullanarak HTML'yi ayrıştırır.

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'a giden yolunuzla değiştirin
    driver = webdriver.Chrome(
        service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
    )

    driver.get(url)

    time.sleep(8)  # Web sitesinin yüklenme süresine göre ayarlayın

    soup = BeautifulSoup(driver.page_source, "lxml")

    driver.quit()

Burada, rastgele bir proxy seçerek ve proxy seçeneklerini ayarlayarak başlıyoruz. Bu seçenekler webdriver'ı proxy sunucusunu kullanacak şekilde yapılandırmak için kullanılacaktır. Ardından, Chrome seçeneklerini ayarlıyoruz. Tarayıcıyı başsız modda çalıştırmak için --headless argümanını ekleyin; bu, tarayıcının grafik kullanıcı arayüzü olmadan arka planda çalışacağı anlamına gelir.

Ardından webdriver'ı servis, seleniumwire seçenekleri ve Chrome seçenekleriyle başlatın. Webdriver daha sonra verilen URL'ye gitmek için kullanılır. Sayfanın tamamen yüklenmesine izin vermek için 8 saniyelik bir uyku süresi ekliyoruz ve ardından Beautiful Soup kullanarak döndürülen HTML'yi ayrıştırıyoruz. Ayrıştırma işlemi tamamlandıktan sonra webdriver kapatılır.

Adım 7: Listeleme verilerini bulma ve çıkarma

HTML içeriğini başarıyla elde ettikten sonra, bir sonraki adım her bir liste için ilgili verileri çıkarmaktır. BeautifulSoup'u kullanarak HTML yapısı içinde kolayca gezinebilir ve listeleme bilgilerini içeren öğeleri bulabiliriz.

Listeleme öğelerini çıkarma

İlk olarak, sayfadaki tüm listeleme öğelerini tanımlarız. Bu öğeler, listeleme URL'si, başlık, açıklama, derecelendirme, fiyat ve ek bilgiler gibi ilgilendiğimiz verileri içerir.

listing_elements = soup.find_all("div", class_="g1qv1ctd")
for listing_element in listing_elements:

Bu kod, "g1qv1ctd" sınıfına sahip tüm div öğelerini bulmak için BeautifulSoup'un find_all() yöntemini kullanır. Bu öğeler Airbnb sayfasındaki bireysel listeleri temsil eder. Daha sonra, ilgili verileri ayıklamak için bu listeleme öğelerinin her biri üzerinde döngüler gerçekleştirir.

Listeleme URL'sini çıkarma

Bulunan her liste öğesi için listenin URL'sini çıkarıyoruz.

URL_element = soup.find("a", class_="rfexzly")
listing_data["Listing URL"] = (
    "https://www.airbnb.com" + URL_element["href"] if URL_element else ""
)

Burada, "soup" nesnemiz içinde "rfexzly" sınıfına sahip bir bağlantı etiketi ararız. Bu öğeyi bulursa, 'href' niteliğini (göreli URL'yi içeren) çıkarır ve tam liste URL'sini oluşturmak için temel URL'ye ekler. Eleman bulunamazsa, hataları önlemek için boş bir dize atar.

Listeleme başlığını çıkarma

İlk olarak, her bir liste için URL'yi çıkaracağız. Bu, gerektiğinde daha sonra tek tek listeleme sayfalarını ziyaret etmemizi sağlayacaktır.

title_element = listing_element.find("div", class_="t1jojoys")
listing_data["Title"] = (
    title_element.get_text(strip=True) if title_element else ""
)

Başlık, "t1jojoys" sınıfına sahip bir "div" öğesi içinde yer alır. Bu öğenin metin içeriğini, baştaki veya sondaki boşlukları çıkararak alırız. Eleman bulunamazsa boş bir dize saklanır.

Listeleme açıklamasını çıkarma

Description_element = listing_element.find("span", class_="t6mzqp7")
listing_data["Description"] = (
    Description_element.get_text(strip=True) if Description_element else ""
)

Başlık çıkarma işlemine benzer şekilde, bu kod "t6mzqp7" sınıfına sahip bir span öğesi bulur. Ardından, bu öğenin listelemenin kısa bir açıklamasını içeren metin içeriğini çıkarır ve temizleriz.

Listeleme derecelendirmesini çıkarma

rating_element = listing_element.find("span", class_="ru0q88m")
listing_data["Rating"] = (
    rating_element.get_text(strip=True) if rating_element else ""
)

Yukarıdaki kodda görüldüğü gibi, "ru0q88m" sınıfına sahip bir span öğesi derecelendirme değerini tutar. Gereksiz boşlukları temizlediğimizden emin olarak bu değeri çıkarıyoruz.

Listeleme fiyatını çıkarma

Son olarak, listelemenin fiyatını çıkarıyoruz.

price_element = listing_element.select_one("._1y74zjx")
listing_data["Price"] = (
    f"{price_element.get_text(strip=True)} per night" if price_element else ""
)

Bu kod, geçerli listing_element içinde "_1y74zjx" sınıfına sahip öğeyi bulur. Tipik olarak fiyat bilgisini içeren bu öğe bulunursa, metin içeriği çıkarılır, temizlenir ve daha bilgilendirici bir fiyat dizesi oluşturmak için "gecelik" ile eklenir.

Ek listeleme bilgilerini çıkarma

Bazı listelerde çıkarabileceğimiz ek bilgiler olabilir.

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 ""
)

Listeleme hakkında herhangi bir ek bilgi bulmak için aria-hidden="true" niteliğine sahip bir span öğesi arıyoruz. Her bir listeleme öğesinden ilgili tüm verileri çıkardıktan sonra, toplanan verileri bir listeleme listesine ekleriz.

listings.append(listing_data)

Tüm listeler işlendikten sonra, her biri çıkarılan verileri içeren bir sözlük olarak temsil edilen listelerin listesini döndürüyoruz.

return listings

Adım 8: Verileri bir CSV dosyasına yazma

Airbnb'nin Listeleme sayfalarından başarılı bir şekilde veri topladıktan sonra, bir sonraki önemli adım bu değerli bilgileri gelecekteki analiz ve referans için saklamaktır. Bu görev için csv kütüphanesini kullanıyoruz. Bir CSV dosyasını yazma modunda açıyoruz ve bir csv.DictWriter nesnesi oluşturuyoruz. Daha sonra başlığı ve verileri dosyaya yazıyoruz.

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}")

İşte bu eğitim için kullandığımız kodun tamamı:

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

# Vekillerin listesi
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'a giden yolunuzla değiştirin
    driver = webdriver.Chrome(
        service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
    )

    driver.get(url)

    time.sleep(8)  # Web sitesinin yüklenme süresine göre ayarlayın

    soup = BeautifulSoup(driver.page_source, "lxml")

    driver.quit()

    listings = []

    # Sayfadaki tüm listeleme öğelerini bulun
    listing_elements = soup.find_all("div", class_="g1qv1ctd")

    for listing_element in listing_elements:
        # Her listeleme öğesinden veri ayıklayın
        listing_data = {}

        # Listeleme URL'si
        URL_element = soup.find("a", class_="rfexzly")
        listing_data["Listing URL"] = (
            "https://www.airbnb.com" + URL_element["href"] if URL_element else ""
        )

        # Başlık
        title_element = listing_element.find("div", class_="t1jojoys")
        listing_data["Title"] = (
            title_element.get_text(strip=True) if title_element else ""
        )

        # Açıklama
        Description_element = listing_element.find("span", class_="t6mzqp7")
        listing_data["Description"] = (
            Description_element.get_text(strip=True) if Description_element else ""
        )

        # Değerlendirme
        rating_element = listing_element.find("span", class_="ru0q88m")
        listing_data["Rating"] = (
            rating_element.get_text(strip=True) if rating_element else ""
        )

        # Fiyat
        price_element = listing_element.select_one("._1y74zjx")
        listing_data["Price"] = (
            f"{price_element.get_text(strip=True)} per night" if price_element else ""
        )

        # Ek liste bilgileri
        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 ""
        )

        # Listeleme verilerini listeye ekle
        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}")

Kodun bu kısmı, kazınan verilerin "proxy_web_listings_output.csv" adlı bir CSV dosyasında saklanmasını sağlar.

Sonuçlar

Kazıyıcımızın sonuçları aşağıda görüldüğü gibi "proxy_web_listings_output.csv" adlı bir CSV dosyasına kaydedilir.

5.jpg

Bu kılavuz, Python kullanarak Airbnb listelerinden verilerin nasıl kazınacağını etkili bir şekilde açıklayarak fiyatlar, müsaitlik durumu ve yorumlar gibi önemli ayrıntıların çıkarılmasını sağlar. Airbnb'nin anti-bot önlemleri tarafından engellenmeyi önlemek için proxy kullanmanın ve bunları döndürmenin önemini vurgulamaktadır.

Yorumlar:

0 yorumlar