使用 Python 搜刮亚马逊产品数据

评论: 0

从亚马逊等电子商务巨头获取数据对于市场分析、定价策略和产品研究至关重要。这些数据可以通过网络抓取(一种从网站上提取大量信息的方法)来收集。然而,亚马逊严格保护其数据,因此传统的刮擦技术往往无效。在本综合指南中,我们将深入探讨从亚马逊收集产品数据的方法,并讨论规避该平台强大的反抓取系统的策略。我们将探讨如何使用 Python、代理和高级刮擦技术来帮助克服这些挑战,并高效地获取您的业务或研究目的所需的数据。

创建 Python 脚本以抓取亚马逊数据

要成功地从亚马逊网站上抓取数据,您可以遵循下面概述的结构化算法。这种方法可确保您高效、准确地检索到所需信息。

步骤 1: 向亚马逊产品页面发送 HTTP 请求:

  • 利用请求库启动针对亚马逊产品页面的 HTTP GET 请求;
  • 从 HTTP 响应中捕获原始 HTML 内容,为解析做好准备。

步骤 2: 解析 HTML 内容

  • 使用 lxml 库解析接收到的原始 HTML 内容;
  • 分析 HTML,找到想要提取的特定数据点;
  • 执行 XPath 查询,从 HTML 结构中精确锁定并提取这些数据点。

步骤 3: 存储数据:

  • 提取必要的数据后,将其保存为 CSV 或 JSON 等可访问格式,以便于分析和与其他应用程序集成。

处理潜在的路障

亚马逊采用了多种措施来阻止刮擦行为,包括连接速度限制、验证码集成和 IP 屏蔽。用户可以采取对策来规避这些障碍,例如使用高质量的代理服务器。

对于广泛的刮擦活动,可以采用先进的 Python 技术来获取大量产品数据。这些技术包括标题填充和 TLS 指纹技术,它们有助于躲避检测并确保成功提取数据。

这些步骤将在文章接下来的章节中进行解释,我们将看到使用 Python 3.12.2 的实际执行情况

先决条件

要启动网络搜刮项目,我们首先要使用 lxml 库(用于解析 HTML)和 requests 库(用于管理指向亚马逊网络服务器的 HTTP 请求)设置一个基本的搜刮器。

我们的重点是从亚马逊产品页面中提取产品名称、价格和评分等基本信息。我们还将展示高效解析 HTML 和管理请求的技术,确保精确有序地提取数据。

为了维护项目的依赖关系并避免冲突,建议为网络搜索工作创建一个单独的虚拟环境。建议使用 "venv "或 "pyenv "等工具来创建虚拟环境。

安装第三方程序库

您需要以下第三方 Python 库:

1. requests

用于发送 HTTP 请求和检索网络内容。它通常用于网络搜刮和与网络 API 交互。

安装:

 pip install requests

2. lxml

一个用于解析和处理 XML 和 HTML 文档的库。它常用于网络搜索和处理网页中的结构化数据。

安装:

 pip install lxml

导入必要的程序库

在这里,我们需要导入刮板运行所需的库。其中包括用于处理 HTTP 请求的 request 库、用于处理 CSV 文件操作的 CSV 库、用于生成随机值和进行随机选择的随机库、用于解析原始 HTML 内容的 lxml 库,以及用于类型提示的 Dict 和 List。

 import requests
import csv
import random
from lxml import html
from typing import Dict, List

从 CSV 文件读取输入内容

以下代码片段读取名为 amazon_product_urls.csv 的 CSV 文件,其中每一行都包含亚马逊产品页面的 URL。代码会遍历这些行,从每一行中提取 URL,并将它们追加到一个名为 URL 的列表中。

 with open('amazon_product_urls.csv', 'r') as file:
    reader = csv.DictReader(file)
    for row in reader:
        urls.append(row['url'])

HTTP 请求头和代理

请求头在 HTTP 请求中扮演着重要角色,提供复杂的客户端和请求信息。在进行刮擦时,复制授权用户标题非常重要,这样可以避免被检测到,并轻松获取想要的信息。通过模仿常用标题,刮擦程序可以避免检测技术,确保数据提取的一致性,同时保持道德标准。

代理在网络搜索中充当中间人,掩盖搜索者的 IP 地址,防止服务器检测和拦截。旋转代理允许您使用新的 IP 地址发送每个请求,以避免潜在的拦截。使用住宅或移动代理可以加强对反搜索措施的抵御能力,因为可以检测到真实的主机和提供商。

集成请求头和代理服务器与 IP 地址授权的代码:

 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',
    'dnt': '1',
    'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
   }
proxies = {'http': '', 'https': ''}

用户代理轮换

在这里,我们将创建一个用户代理集合列表,每次请求都将从中随机选择一个用户代理。实施头轮换机制,例如在每次请求后轮换用户代理,可以进一步帮助绕过僵尸检测措施。

 useragents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4591.54 Safari/537.36",
        "Mozilla/5.0 (Windows NT 7_0_2; Win64; x64) AppleWebKit/541.38 (KHTML, like Gecko) Chrome/105.0.1585 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.7863.44 Safari/537.36"
    ]
headers['user-agent'] = random.choice(useragnets)

向亚马逊的产品页面发出 HTTP 请求,并附上标题和代理服务器

向指定 URL 发送 HTTP GET 请求,并为请求指定自定义标题、30 秒超时和代理。

response = requests.get(url=url, headers=headers, proxies=proxies, timeout=30)

确定所需数据点的 XPath/选择器

所需数据点:标题、价格和评分。现在,让我们检查并识别截图中所示元素的相应 XPath 及其各自的数据点。

下面的截图显示了 Chrome DevTools 的 "Inspect "功能用于查找 XPath `//span[@id="productTitle"]/text()`,以便从亚马逊产品页面提取产品标题。

1.png

下面的截图显示了从亚马逊产品页面提取产品价格的 XPath `//div[@id="corePrice_feature_div"]/div/div/span/span/text()`。

2.png

截图显示了分别使用 XPath `//span[@id="acrPopover"]/@title'` 从亚马逊产品页面提取产品评分的结果。

3.png

创建一个字典,提供 XPath 表达式以从网页中提取特定信息:产品的标题、评级和价格。

xpath_queries = {'title': '//span[@id="productTitle"]/text()', 'ratings': '//span[@id="acrPopover"]/@title', 'price': '//span[@class="a-offscreen"]/text()'}

从 HTML 响应创建 lxml 分析器

下面的代码将从亚马逊服务器的 GET 请求中获取的 HTML 内容解析为结构化的树状格式,以便于导航和操作其元素和属性。

tree = html.fromstring(response.text)

提取所需数据

下面的代码片段使用 XPath 查询从解析的 HTML 树中提取数据,并将其赋值给具有指定键的字典。它检索 XPath 查询的第一个结果,并将其存储在 extracted_data 字典中给定的键下。

data = tree.xpath(xpath_query)[0].strip()
extracted_data[key] = data

将提取的数据保存为 CSV

以下代码将提取的数据字典中的数据写入名为 product_data.csv 的 CSV 文件。确保只有在文件为空时才写入标题行。如果文件不是空的,则将数据作为附加行添加到 CSV 文件中。通过该功能,可以用提取的新数据不断更新 CSV 文件,而不会覆盖现有文本。

 csv_file_path = 'product_data.csv'
fieldnames = ['title', 'ratings', 'price']
with open(csv_file_path, 'a', newline='') as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    if csvfile.tell() == 0:
        writer.writeheader()
    writer.writerow(extracted_data)

代码执行

请参考我们的完整代码,它将帮助您快速入门。代码结构合理,文档齐全,便于初学者使用。要执行此代码,用户必须在同一目录下拥有一个名为 "amazon_product_urls "的 CSV 文件。下面是 CSV 文件的结构:

4.png

import requests
import csv
import random
from lxml import html
from typing import Dict, List


def send_requests(
    url: str, headers: Dict[str, str], proxies: Dict[str, str]
) -> List[Dict[str, str]]:
    """
    向多个带标头和代理的 URL 发送 HTTP GET 请求。

    Args:
        urls (str): 发送请求的 URL。
        headers (Dict[str, str]): 包含请求标头的字典。
        proxies (Dict[str, str]): 包含代理设置的字典。

    Returns:
        Response: 包含每个 URL 响应数据的响应对象。
    """
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
        # 响应验证
        if len(response.text)> 10000:
            return response
        return None
    except Exception as e:
        print(f"Error occurred while fetching URL {url}: {str(e)}")


def extract_data_from_html(
    response, xpath_queries: Dict[str, str]
) -> Dict[str, List[str]]:
    """
    使用 XPath 查询从 HTML 内容中提取数据。

    Args:
        response (Response): 响应对象。
        xpath_queries (Dict[str, str]): 包含用于数据提取的 XPath 查询的字典。

    Returns:
        Dict[str, str]: 包含为每个 XPath 查询提取的数据的字典。
    """
    extracted_data = {}
    tree = html.fromstring(response.text)
    for key, xpath_query in xpath_queries.items():
        data = tree.xpath(xpath_query)[0].strip()
        extracted_data[key] = data
    return extracted_data


def save_to_csv(extracted_data: Dict[str, any]):
    """
   使用 DictWriter 将字典保存为 CSV 文件中的一行。

    Args:
        extracted_data (Dict[str, any]):代表一行数据的字典。
    """
    csv_file_path = "product_data.csv"
    fieldnames = ["title", "ratings", "price"]
    with open(csv_file_path, "a", newline="") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        if csvfile.tell() == 0:
            writer.writeheader()  # 仅在文件为空的情况下写入文件头
        writer.writerow(extracted_data)


def main():
    # 从 CSV 文件读取 URL
    urls = []
    with open("amazon_product_urls.csv", "r") as file:
        reader = csv.DictReader(file)
        for row in reader:
            urls.append(row["url"])

    # 定义请求标头
    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",
        "dnt": "1",
        "sec-ch-ua": '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "same-origin",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
    }

    useragents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4591.54 Safari/537.36",
        "Mozilla/5.0 (Windows NT 7_0_2; Win64; x64) AppleWebKit/541.38 (KHTML, like Gecko) Chrome/105.0.1585 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.7863.44 Safari/537.36"
        ]

    # 定义代理
    proxies = {"http": "IP:Port", "https": "IP:Port"}

   # 向 URL 发送请求
    for url in urls:
        # 标题中的用户代理轮换
        headers["user-agent"] = random.choice(useragnets)
        response = send_requests(url, headers, proxies)
        if response:
           # 从 HTML 内容中提取数据
            xpath_queries = {
                "title": '//span[@id="productTitle"]/text()',
                "ratings": '//span[@id="acrPopover"]/@title',
                "price": '//span[@class="a-offscreen"]/text()',
            }
            extracted_data = extract_data_from_html(response, xpath_queries)

            # 将提取的数据保存到 CSV 文件中
            save_to_csv(extracted_data)


if __name__ == "__main__":
    main()

通过 Python 搜索亚马逊的代理建议

不同的代理解决方案(包括数据中心 IPv4、旋转移动代理、ISP 代理和住宅代理)可用于不间断的数据提取。适当的轮换逻辑和用户代理用于模拟真实用户行为,而特殊代理则通过内部轮换和广泛的 IP 池支持大规模搜索。了解每种代理选项的利弊对于不间断地提取数据至关重要。

类型 优点 缺点
数据中心代理

高速、高性能。

成本效益高。

非常适合大量需求。

很容易被检测到并列入黑名单。

对反搜索或反僵尸系统不可靠。

住宅代理

由于采用了真实的住宅 IP,因此具有很高的合法性。

广泛的全球 IP 可用性,可用于特定地点的数据搜刮。

IP 轮换功能。

比数据中心代理更昂贵。

移动代理

高度合法的 IP。

有效避免拦截和验证提示。

比其他代理类型更昂贵。

由于依赖移动网络,速度比数据中心代理慢。

ISP 代理服务器

高度可靠的 IP。

比住宅 IP 更快。

有限的 IP 可用性。

IP 轮换不可用。

从亚马逊抓取产品数据需要精心准备,以便有效地避开平台的反抓取机制。利用代理服务器和 Python 可以高效处理数据,并有针对性地提取必要信息。在为网络抓取选择代理时,考虑性能、成本、服务器可靠性以及项目的具体要求等因素至关重要。采用动态代理并实施应对安全措施的策略,可以最大限度地降低被拦截的风险,并提高搜索过程的整体效率。

评论:

0 评论