Cạo dữ liệu danh sách Airbnb với Python

Bình luận: 0

Đạt được quyền truy cập vào dữ liệu Airbnb là rất quan trọng để phân tích thị trường bất động sản, nghiên cứu động lực giá cho thuê, tiến hành phân tích cạnh tranh và đánh giá đánh giá và xếp hạng. Điều này có thể được thực hiện bằng cách cạo dữ liệu web. Tuy nhiên, việc truy cập dữ liệu này có thể là thách thức vì việc cạo có thể vi phạm các điều khoản sử dụng của trang web.

Tiếp theo, chúng tôi sẽ khám phá một hướng dẫn từng bước về cách phát triển một cạp web để trích xuất dữ liệu từ danh sách Airbnb bằng Python và Selenium. Hướng dẫn này cũng sẽ đề cập đến cách tránh các khối và hạn chế tiềm năng do nền tảng áp đặt.

Hiểu kiến ​​trúc của trang web của Airbnb

Bước đầu tiên trong việc tạo ra một cái cạo web là hiểu cách truy cập các trang web mà bạn quan tâm, vì cấu trúc của các trang web thường có thể thay đổi. Để làm quen với cấu trúc của một trang web, bạn có thể sử dụng các công cụ nhà phát triển của trình duyệt để kiểm tra HTML của trang web.

Để truy cập các công cụ nhà phát triển, nhấp chuột phải vào trang web và chọn Kiểm tra trên mạng hoặc sử dụng phím tắt:

  • CTRL+SHIFT+I cho Windows;
  • Option + ⌘ + I Trên Mac.

Mỗi thùng chứa danh sách được bọc trong một phần tử div với thuộc tính sau: class = "g1qv1ctd.

1.png

Bằng cách nhấp vào "Vị trí" và gõ "London, UK", chúng tôi có thể truy cập vị trí được cung cấp ở London. Trang web đề nghị thêm ngày nhận phòng và nhận phòng. Nó cho phép họ tính giá của các phòng.

2.png

URL cho trang này sẽ trông giống như thế này:

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"

Từ trang tìm kiếm, chúng tôi sẽ loại bỏ các thuộc tính sau của dữ liệu liệt kê sản phẩm:

  • Danh sách URL;
  • Tiêu đề;
  • Mô tả;
  • Xếp hạng;
  • Giá;
  • Thông tin danh sách bổ sung (không có giường và ngày có sẵn).

3.png

Hướng dẫn từng bước về xây dựng chương trình cạo Airbnb

Để bắt đầu quét web cho dữ liệu Airbnb, bạn cần thiết lập môi trường phát triển của mình trước. Đây là các bước để làm điều đó:

Bước 1: Tạo môi trường ảo

Môi trường ảo cho phép bạn cô lập các gói Python và sự phụ thuộc của chúng cho các dự án khác nhau. Điều này giúp ngăn ngừa xung đột và đảm bảo rằng mỗi dự án có các phụ thuộc chính xác được cài đặt.

Tạo môi trường ảo trên Windows

Mở dấu nhắc lệnh với các đặc quyền quản trị viên và chạy lệnh sau để tạo môi trường ảo mới có tên “venv”:

python -m venv venv

Kích hoạt môi trường ảo:

venv\Scripts\activate

Tạo môi trường ảo trên MacOS/Linux

Mở thiết bị đầu cuối và chạy lệnh sau để tạo môi trường ảo mới có tên “venv”:

sudo python3 -m venv venv

Kích hoạt môi trường ảo:

source venv/bin/activate

Để hủy kích hoạt môi trường ảo, chỉ cần chạy lệnh sau:

deactivate

Bước 2: Cài đặt các thư viện cần thiết

Bây giờ bạn đã thiết lập một môi trường ảo, bạn có thể cài đặt các thư viện cần thiết.

Hiểu các thư viện:

  • Selenium: Công cụ cạo web mạnh mẽ này cho phép bạn kiểm soát một trình duyệt web. Điều này cho phép bạn tương tác với các trang web, bao gồm nhấp vào các nút, điền vào biểu mẫu và điều hướng qua các trang như thể bạn là người dùng thực sự.
  • Seleniumwire: Thư viện này mở rộng selen bằng cách cho phép bạn chặn và kiểm tra các yêu cầu HTTP và tích hợp proxy với các hoạt động cạo của bạn. Điều này rất quan trọng vì selenium không có hỗ trợ proxy gốc.
  • BeautifulSoup4: Đây là một thư viện được thiết kế để phân tích các tệp HTML và XML. Nó giúp bạn trích xuất thông tin cụ thể từ các trang web một cách có cấu trúc và hiệu quả.
  • LXML: Một trình phân tích cú pháp HTML và XML nhanh và mạnh mẽ bổ sung cho người đẹp.

Trong môi trường ảo được kích hoạt của bạn, hãy chạy lệnh sau để cài đặt các thư viện cần thiết:

pip install selenium beautifulsoup4 lxml seleniumwire

Trình điều khiển Selen

Selenium yêu cầu trình điều khiển giao diện với trình duyệt đã chọn. Chúng tôi sẽ sử dụng Chrome cho hướng dẫn này. Tuy nhiên, vui lòng đảm bảo bạn đã cài đặt webDriver thích hợp cho trình duyệt mà bạn chọn.

Sau khi tải xuống, đảm bảo trình điều khiển được đặt trong thư mục có thể truy cập bằng biến môi trường đường dẫn của hệ thống của bạn. Điều này sẽ cho phép Selenium tìm trình điều khiển và điều khiển trình duyệt.

Bước 3: Nhập thư viện

Khi bắt đầu tệp Python của bạn, hãy nhập các thư viện Seleniumwire và BeautifulSoup. Đây là cách bạn làm điều đó:

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

Chúng tôi cũng sẽ nhập các thư viện `Random`,` Time` và `CSV` cho các tiện ích khác nhau.

Bước 4: Tích hợp proxy

Tiếp theo, chúng tôi xác định một danh sách các proxy để tránh bị Airbnb chặn. Khi cố gắng gửi một yêu cầu mà không có proxy cao cấp, bạn có thể gặp phải phản hồi "bị từ chối" truy cập ".

4.png

Bạn có thể thiết lập một proxy như sau:

# Danh sách các proxy
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",

]

Đảm bảo thay thế "your_proxy_ip_address" và "your_proxy_port" bằng địa chỉ proxy thực tế mà bạn có được từ proxy-seller và cũng thay thế các giá trị của tên người dùng và mật khẩu của bạn bằng thông tin thực tế của bạn.

Bước 5: Các proxy xoay vòng

Các proxy xoay là một khía cạnh quan trọng của việc cạo web. Các trang web thường chặn hoặc hạn chế quyền truy cập vào bot và bộ phế liệu khi họ nhận được nhiều yêu cầu từ cùng một địa chỉ IP. Bằng cách xoay qua các địa chỉ IP proxy khác nhau, bạn có thể tránh phát hiện, xuất hiện dưới dạng nhiều người dùng hữu cơ và bỏ qua hầu hết các biện pháp chống xơ cứng được thực hiện trên trang web.

Để thiết lập vòng quay proxy, hãy nhập thư viện ngẫu nhiên. Chúng tôi cũng xác định một hàm `get_proxy ()` để chọn proxy từ danh sách của chúng tôi. Hàm này chọn ngẫu nhiên một proxy từ danh sách các proxy bằng phương thức ngẫu nhiên.choice () và trả về proxy đã chọn.

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

Bước 6: Thiết lập WebDriver

Tiếp theo, chúng tôi xác định hàm chính gọi là `listings()`. Đây là nơi chúng tôi sẽ thiết lập bộ Chromedriver của chúng tôi. Chức năng này sử dụng selenium để điều hướng trang danh sách tài sản, chờ trang tải và phân tích HTML bằng súp đẹp.

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"
    )  # Thay thế bằng đường dẫn của bạn đến Chromedriver
    driver = webdriver.Chrome(
        service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
    )

    driver.get(url)

    time.sleep(8)  # Điều chỉnh dựa trên thời gian tải của trang web

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

    driver.quit()

Ở đây, chúng tôi bắt đầu bằng cách chọn một proxy ngẫu nhiên và thiết lập các tùy chọn proxy. Các tùy chọn này sẽ được sử dụng để định cấu hình webDriver để sử dụng máy chủ proxy. Tiếp theo, chúng tôi thiết lập các tùy chọn Chrome. Thêm đối số không đầu để chạy trình duyệt ở chế độ không đầu, điều đó có nghĩa là trình duyệt sẽ chạy ở chế độ nền mà không cần giao diện người dùng đồ họa.

Sau đó khởi tạo webDriver với dịch vụ, tùy chọn seleniumwire và các tùy chọn Chrome. WebDriver sau đó được sử dụng để điều hướng đến URL đã cho. Chúng tôi thêm thời gian ngủ là 8 giây để cho phép trang tải hoàn toàn, và sau đó phân tích HTML được trả lại bằng súp đẹp. Sau khi phân tích cú pháp được thực hiện, nó đóng WebDriver.

Bước 7: Tìm và trích xuất dữ liệu niêm yết

Khi bạn đã đạt được thành công nội dung HTML, bước tiếp theo là trích xuất dữ liệu liên quan cho mỗi danh sách. Sử dụng đẹp, chúng ta có thể dễ dàng điều hướng qua cấu trúc HTML và xác định vị trí các yếu tố chứa thông tin niêm yết.

Trích xuất các yếu tố liệt kê

Đầu tiên, chúng tôi xác định tất cả các yếu tố niêm yết trên trang. Các yếu tố này chứa dữ liệu mà chúng tôi quan tâm, chẳng hạn như URL niêm yết, tiêu đề, mô tả, xếp hạng, giá cả và thông tin bổ sung.

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

Mã này sử dụng phương thức find_all () của BeautifulSoup để xác định vị trí tất cả các phần tử div với lớp G1QV1CTD. Các yếu tố này đại diện cho danh sách riêng lẻ trên trang Airbnb. Sau đó, nó lặp qua từng yếu tố niêm yết này để trích xuất dữ liệu liên quan.

Trích xuất URL liệt kê

Đối với mỗi yếu tố niêm yết được tìm thấy, chúng tôi trích xuất URL của danh sách.

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

Ở đây, chúng tôi tìm kiếm trong đối tượng súp súp của chúng tôi cho một thẻ neo với lớp RF RFEXZLY. Nếu nó tìm thấy phần tử này, nó sẽ trích xuất thuộc tính 'href' (chứa URL tương đối) và nối nó vào URL cơ sở để tạo URL danh sách đầy đủ. Nếu phần tử không được tìm thấy, nó gán một chuỗi trống để tránh lỗi.

Trích xuất tiêu đề danh sách

Đầu tiên, chúng tôi sẽ trích xuất URL cho mỗi danh sách. Điều này sẽ cho phép chúng tôi truy cập các trang danh sách cá nhân sau nếu cần.

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

Tiêu đề được chứa trong một phần tử div Div với lớp T1Jojoys. Chúng tôi lấy lại nội dung văn bản của yếu tố này, tước bất kỳ khoảng trắng nào hoặc dấu vết dẫn đầu. Một chuỗi trống được lưu trữ nếu phần tử không được tìm thấy.

Trích xuất mô tả danh sách

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

Tương tự như trích xuất tiêu đề, mã này tìm thấy một phần tử nhịp với lớp "T6MZQP7". Sau đó, chúng tôi trích xuất và làm sạch nội dung văn bản của yếu tố này, trong đó có một mô tả ngắn về danh sách.

Trích xuất xếp hạng danh sách

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

Như đã thấy trong mã ở trên, một phần tử nhịp với lớp Ru Ru0Q88M, giữ giá trị xếp hạng. Chúng tôi trích xuất giá trị này, đảm bảo tước bất kỳ khoảng trắng không cần thiết nào.

Trích xuất giá danh sách

Cuối cùng, chúng tôi trích xuất giá của danh sách.

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

Mã này định vị phần tử với lớp "_1Y74ZJX" trong danh sách hiện tại_element. Nếu phần tử này, thường chứa thông tin giá, được tìm thấy, nội dung văn bản của nó được trích xuất, làm sạch và được thêm vào "mỗi đêm" để tạo thành một chuỗi giá nhiều thông tin hơn.

Trích xuất thông tin danh sách bổ sung

Một số danh sách có thể có thông tin bổ sung mà chúng ta có thể trích xuất.

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

Chúng tôi tìm kiếm một phần tử nhịp với thuộc tính aria-hidden = "true" để tìm bất kỳ thông tin bổ sung nào về danh sách. Sau khi trích xuất tất cả dữ liệu liên quan từ mỗi yếu tố niêm yết, chúng tôi nối dữ liệu được thu thập vào danh sách danh sách.

listings.append(listing_data)

Khi tất cả các danh sách đã được xử lý, chúng tôi trả về danh sách các danh sách, mỗi danh sách được biểu diễn dưới dạng từ điển chứa dữ liệu được trích xuất.

return listings

Bước 8: Viết dữ liệu vào tệp CSV

Sau khi xóa dữ liệu thành công từ các trang niêm yết của Airbnb, bước quan trọng tiếp theo là lưu trữ thông tin có giá trị này để phân tích và tham khảo trong tương lai. Chúng tôi sử dụng thư viện CSV cho nhiệm vụ này. Chúng tôi mở một tệp CSV ở chế độ ghi và tạo đối tượng CSV.DictWriter. Sau đó chúng tôi viết tiêu đề và dữ liệu vào tệp.

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

Dưới đây là một mã hoàn chỉnh mà chúng tôi đã sử dụng cho hướng dẫn này:

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

# Danh sách các proxy
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"
    )  # Thay thế bằng đường dẫn của bạn đến Chromedriver
    driver = webdriver.Chrome(
        service=s, seleniumwire_options=proxy_options, chrome_options=chrome_options
    )

    driver.get(url)

    time.sleep(8)  # Điều chỉnh dựa trên thời gian tải của trang web

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

    driver.quit()

    listings = []

    # Tìm tất cả các yếu tố danh sách trên trang
    listing_elements = soup.find_all("div", class_="g1qv1ctd")

    for listing_element in listing_elements:
        # Trích xuất dữ liệu từ mỗi phần tử liệt kê
        listing_data = {}

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

        # Tiêu đề
        title_element = listing_element.find("div", class_="t1jojoys")
        listing_data["Title"] = (
            title_element.get_text(strip=True) if title_element else ""
        )

        # Sự miêu tả
        Description_element = listing_element.find("span", class_="t6mzqp7")
        listing_data["Description"] = (
            Description_element.get_text(strip=True) if Description_element else ""
        )

        # Xếp hạng
        rating_element = listing_element.find("span", class_="ru0q88m")
        listing_data["Rating"] = (
            rating_element.get_text(strip=True) if rating_element else ""
        )

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

        # Thông tin danh sách bổ sung
        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 ""
        )

        # Nối dữ liệu danh sách vào danh sách
        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}")

Phần này của mã đảm bảo rằng dữ liệu đã được lưu trữ trong tệp CSV có tên "Proxy_Web_Listings_Output.csv".

Kết quả

Kết quả của cạp của chúng tôi được lưu vào một tệp CSV có tên là Proxy_web_listings_output.csv, như được thấy dưới đây.

5.jpg

Hướng dẫn này giải thích hiệu quả cách cạo dữ liệu từ danh sách Airbnb bằng Python, cho phép trích xuất các chi tiết chính như giá cả, tính khả dụng và đánh giá. Nó nhấn mạnh tầm quan trọng của việc sử dụng proxy và xoay chúng để ngăn chặn bị chặn bởi các biện pháp chống BOT của Airbnb.

Bình luận:

0 Bình luận