如何使用 Python 搜刮 Booking.com 数据

评论: 0

在本文中,我们将演示如何使用 Python 从 Booking.com 网站收集数据。我们将获取的信息包括但不限于酒店名称、评级、价格、位置地址及其描述。所提供的代码允许您通过解析 HTML 内容和提取嵌入的 JSON 数据来检索酒店页面的数据。

安装所需程序库

在运行代码从 Booking.com 搜刮数据之前,您需要安装必要的 Python 库。以下是安装所需依赖项的方法:

  1. Requests 库:用于向网站发送 HTTP 请求并获取网页的 HTML 内容。
  2. LXML 库:用于解析 HTML 内容并使用 XPath 提取数据。
  3. JSON:用于处理 JSON 数据的内置 Python 模块。
  4. CSV:内置 Python 模块,用于将刮擦数据写入 CSV 文件。

要安装必要的库,可以使用 pip:


pip install requests lxml

您只需要这些外部库,其余的(json、csv)都已预装在 Python 中。

了解 URL 和数据结构

在从 Booking.com 抓取数据时,了解网页的结构和要提取的数据类型非常重要。Booking.com 上的每个酒店页面都包含 JSON-LD 形式的嵌入式结构化数据,这种格式允许轻松提取名称、位置和定价等详细信息。我们将抓取这些数据。

逐步刮擦流程

由于 Booking.com 是一个动态网站,并实施了打击自动操作的措施,因此我们将使用适当的 HTTP 标头和代理来确保无缝刮擦,而不会有阻塞的风险。

使用标头发送 HTTP 请求

标头可在浏览器中模拟用户会话,防止被 Booking.com 的反搜索系统检测到。如果没有正确配置的标头,服务器可以轻松识别自动脚本,这可能会导致 IP 屏蔽或验证码挑战。

为避免被 Booking.com 的反捕获机制拦截,我们将使用自定义标题来模拟合法用户浏览网站。以下是您如何使用正确的标头发送 HTTP 请求:


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)

代理人的重要性

在对 Booking.com 等网站进行搜刮时,使用代理是必要的,因为这些网站会对请求率进行严格限制或跟踪 IP 地址。代理有助于在不同的 IP 地址之间分配请求负载,从而防止阻塞。为此,可以使用免费代理和付费代理服务,前者通过用户名和密码或 IP 地址进行验证。在我们的示例中,我们使用的是后一种方式。


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

解析 HTML 并提取 JSON 数据

发送请求后,我们使用 lxml 解析 HTML 内容,以找到包含酒店详细信息的嵌入式 JSON-LD 数据。这一步是从网页中提取结构化数据,包括酒店名称、价格、位置等。


parser = fromstring(response.text)

# 提取嵌入式 JSON 数据
embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
json_data = json.loads(embeded_jsons[0])

提取酒店信息

获得解析后的 JSON 数据后,我们就可以提取相关字段,如酒店名称、地址、评级和价格。下面是从 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()")

# 将数据添加到 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
})

将数据保存为 CSV

提取数据后,我们可以将其保存为 CSV 文件,以便进一步分析:


# 处理完所有 URL 后,将数据写入 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)
    
    # 编写页眉
    writer.writeheader()
    
    # 写入数据行
    writer.writerows(all_data)

完整代码

以下是所有部分的完整代码:


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

# 要搜索的酒店 URL 列表
urls_list = [
    "Https link", 
    "Https link"
]

# 初始化一个空列表,以保存所有搜刮到的数据
all_data = []

proxies = {
    'http': ''
}

# 循环浏览每个 URL 以获取数据
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, proxies=proxies)
    
    # 解析 HTML 内容
    parser = fromstring(response.text)
    
    # 提取嵌入式 JSON 数据
    embeded_jsons = parser.xpath('//script[@type="application/ld+json"]/text()')
    json_data = json.loads(embeded_jsons[0])

    # 从 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()")
    
    # 将数据添加到 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
    })

# 处理完所有 URL 后,将数据写入 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)
    
    # 编写页眉
    writer.writeheader()
    
    # 写入数据行
    writer.writerows(all_data)

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

本文介绍了如何使用 Python 从 Booking.com 抓取酒店数据。我们强调了使用适当的 HTTP 标头和代理绕过反抓取措施的重要性。提取的数据可以保存在 CSV 文件中,以便进一步分析。在对网站进行抓取时,请务必查看服务条款,以免违反规定。

评论:

0 评论