Cách quét dữ liệu Booking.com bằng Python

Bình luận: 0

Trong bài viết này, chúng tôi sẽ trình diễn cách thu thập dữ liệu từ trang web Booking.com với Python. Chúng tôi sẽ có được thông tin bao gồm, nhưng không giới hạn, tên khách sạn, xếp hạng, giá, địa chỉ vị trí và mô tả của chúng. Mã được cung cấp cho phép bạn lấy dữ liệu từ các trang khách sạn bằng cách phân tích nội dung HTML và trích xuất dữ liệu JSON nhúng.

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

Trước khi chạy mã để xóa dữ liệu từ Booking.com, bạn sẽ cần cài đặt các thư viện Python cần thiết. Đây là cách bạn có thể cài đặt các phụ thuộc cần thiết:

  1. Requests Thư viện: Điều này được sử dụng để gửi các yêu cầu HTTP đến trang web và tìm nạp nội dung HTML của các trang.
  2. LXML Thư viện: Điều này được sử dụng để phân tích nội dung HTML và trích xuất dữ liệu bằng XPath.
  3. JSON: Mô-đun Python tích hợp được sử dụng để xử lý dữ liệu JSON.
  4. CSV: Mô-đun Python tích hợp được sử dụng để ghi dữ liệu được quét vào tệp CSV.

Để cài đặt các thư viện cần thiết, bạn có thể sử dụng pip:


pip install requests lxml

Đây là những thư viện bên ngoài duy nhất bạn cần, và phần còn lại (JSON, CSV) được cài đặt sẵn với Python.

Hiểu cấu trúc URL và dữ liệu

Khi lấy dữ liệu từ Booking.com, điều quan trọng là phải hiểu cấu trúc của trang web và loại dữ liệu bạn muốn trích xuất. Mỗi trang khách sạn trên Booking.com chứa dữ liệu có cấu trúc nhúng dưới dạng JSON-LD, một định dạng cho phép dễ dàng trích xuất các chi tiết như tên, vị trí và giá cả. Chúng tôi sẽ lấy dữ liệu này.

Quá trình cạo từng bước

Vì Booking.com là một trang web động và thực hiện các biện pháp để chống lại các hành động tự động, chúng tôi sẽ sử dụng các tiêu đề và proxy HTTP thích hợp để đảm bảo cạo liền mạch mà không có nguy cơ chặn.

Gửi các yêu cầu HTTP với các tiêu đề

Các tiêu đề bắt chước một phiên người dùng trong trình duyệt và ngăn chặn phát hiện bằng các hệ thống chống xẹp của Booking.com. Nếu không có các tiêu đề được cấu hình đúng, máy chủ có thể dễ dàng xác định các tập lệnh tự động, có thể dẫn đến các thách thức chặn IP hoặc CAPTCHA.

Để tránh bị chặn bởi các cơ chế chống xẹp của Booking.com, chúng tôi sẽ sử dụng các tiêu đề tùy chỉnh để mô phỏng người dùng hợp pháp duyệt trang web. Đây là cách bạn có thể gửi yêu cầu HTTP với các tiêu đề thích hợp:


import requests
from lxml.html import fromstring

urls_list = ["https links"]

for url in urls_list:
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'accept-language': 'en-IN,en;q=0.9',
        'cache-control': 'no-cache',
        'dnt': '1',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Linux"',
        'sec-fetch-dest': 'document',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'none',
        'sec-fetch-user': '?1',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
    }

    response = requests.get(url, headers=headers)

Tầm quan trọng của proxy

Sử dụng proxy là cần thiết khi các trang web cạo như Booking.com, áp dụng giới hạn tỷ lệ yêu cầu nghiêm ngặt hoặc theo dõi địa chỉ IP. Proxy giúp phân phối tải các yêu cầu trên các địa chỉ IP khác nhau, ngăn chặn các khối. Với mục đích này, cả proxy miễn phí và dịch vụ proxy trả phí với xác thực theo tên người dùng và mật khẩu hoặc địa chỉ IP có thể được sử dụng. Trong ví dụ của chúng tôi, chúng tôi sử dụng tùy chọn sau.


proxies = {
    'http': '',
    'https': ''
}
response = requests.get(url, headers=headers, proxies=proxies)

Phân tích HTML và trích xuất dữ liệu JSON

Sau khi gửi yêu cầu, chúng tôi phân tích nội dung HTML bằng LXML để xác định dữ liệu JSON-LD nhúng có chứa chi tiết khách sạn. Bước này trích xuất dữ liệu có cấu trúc từ trang web bao gồm tên khách sạn, giá, địa điểm, v.v.


parser = fromstring(response.text)

# Trích xuất dữ liệu JSON nhúng
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])

Trích xuất thông tin khách sạn

Khi chúng tôi có dữ liệu JSON được phân tích cú pháp, chúng tôi có thể trích xuất các trường liên quan như tên khách sạn, địa chỉ, xếp hạng và giá cả. Dưới đây là mã để trích xuất thông tin khách sạn từ JSON:


name = json_data['name']
location = json_data['hasMap']
priceRange = json_data['priceRange']
description = json_data['description']
url = json_data['url']
ratingValue = json_data['aggregateRating']['ratingValue']
reviewCount = json_data['aggregateRating']['reviewCount']
type_ = json_data['@type']
postalCode = json_data['address']['postalCode']
addressLocality = json_data['address']['addressLocality']
addressCountry = json_data['address']['addressCountry']
addressRegion = json_data['address']['addressRegion']
streetAddress = json_data['address']['streetAddress']
image_url = json_data['image']
room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")

# Nối dữ liệu vào danh sách all_data
all_data.append({
    "Name": name,
    "Location": location,
    "Price Range": priceRange,
    "Rating": ratingValue,
    "Review Count": reviewCount,
    "Type": type_,
    "Postal Code": postalCode,
    "Address Locality": addressLocality,
    "Country": addressCountry,
    "Region": addressRegion,
    "Street Address": streetAddress,
    "URL": url,
    "Image URL": image_url,
    "Room Types": room_types
})

Lưu dữ liệu vào CSV

Khi dữ liệu đã được trích xuất, chúng tôi có thể lưu nó vào tệp CSV để phân tích thêm:


# Sau khi tất cả các URL được xử lý, hãy ghi dữ liệu vào tệp CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Viết tiêu đề
    writer.writeheader()
    
    # Viết các hàng dữ liệu
    writer.writerows(all_data)

Hoàn thành mã

Ở đây, mã hoàn chỉnh kết hợp tất cả các phần:


import requests
from lxml.html import fromstring
import json
import csv

# Danh sách các url khách sạn để cạo
urls_list = [
    "Https link", 
    "Https link"
]

# Khởi tạo một danh sách trống để giữ tất cả các dữ liệu bị xóa
all_data = []

proxies = {
    'http': ''
}

# Vòng qua từng URL để cạo dữ liệu
for url in urls_list:
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'accept-language': 'en-IN,en;q=0.9',
        'cache-control': 'no-cache',
        'dnt': '1',
        'pragma': 'no-cache',
        'priority': 'u=0, i',
        'sec-ch-ua': '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Linux"',
        'sec-fetch-dest': 'document',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'none',
        'sec-fetch-user': '?1',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
    }

    # Gửi yêu cầu đến trang web
    response = requests.get(url, headers=headers, proxies=proxies)
    
    # Phân tích nội dung HTML
    parser = fromstring(response.text)
    
    # Trích xuất dữ liệu JSON nhúng
    embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
    json_data = json.loads(embeded_jsons[0])

    # Trích xuất tất cả các chi tiết khách sạn từ JSON
    name = json_data['name']
    location = json_data['hasMap']
    priceRange = json_data['priceRange']
    description = json_data['description']
    url = json_data['url']
    ratingValue = json_data['aggregateRating']['ratingValue']
    reviewCount = json_data['aggregateRating']['reviewCount']
    type_ = json_data['@type']
    postalCode = json_data['address']['postalCode']
    addressLocality = json_data['address']['addressLocality']
    addressCountry = json_data['address']['addressCountry']
    addressRegion = json_data['address']['addressRegion']
    streetAddress = json_data['address']['streetAddress']
    image_url = json_data['image']

    room_types = parser.xpath("//a[contains(@href, '#RD')]/span/text()")
    
    # Nối dữ liệu vào danh sách all_data
    all_data.append({
        "Name": name,
        "Location": location,
        "Price Range": priceRange,
        "Rating": ratingValue,
        "Review Count": reviewCount,
        "Type": type_,
        "Postal Code": postalCode,
        "Address Locality": addressLocality,
        "Country": addressCountry,
        "Region": addressRegion,
        "Street Address": streetAddress,
        "URL": url,
        "Image URL": image_url,
        "Room Types": room_types
    })

# Sau khi tất cả các URL được xử lý, hãy ghi dữ liệu vào tệp CSV
with open('booking_data.csv', 'w', newline='') as csvfile:
    fieldnames = ["Name", "Location", "Price Range", "Rating", "Review Count", "Type", "Postal Code", 
                  "Address Locality", "Country", "Region", "Street Address", "URL", "Image URL", "Room Types"]
    
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    
    # Viết tiêu đề
    writer.writeheader()
    
    # Viết các hàng dữ liệu
    writer.writerows(all_data)

print("Data successfully saved to booking_data.csv")

Bài viết này cho thấy cách cạo dữ liệu khách sạn từ Booking.com bằng Python. Chúng tôi nhấn mạnh tầm quan trọng của việc sử dụng các tiêu đề và proxy HTTP thích hợp để bỏ qua các biện pháp chống xẹp. Dữ liệu được trích xuất có thể được lưu trong tệp CSV để phân tích thêm. Khi cạo các trang web, luôn luôn kiểm tra các điều khoản dịch vụ để tránh vi phạm.

Bình luận:

0 Bình luận