Python爬取亚马逊商品数据-多线程【附源码】

效果如下图:

Python爬取亚马逊商品数据-多线程【附源码】_第1张图片

Python爬取亚马逊商品数据-多线程【附源码】_第2张图片

代码用途说明(完整代码在后面)

核心功能

本代码用于自动化采集亚马逊平台商品数据,主要获取以下信息:

  • 商品分类:通过URL参数自动识别商品类别(如electronics/beauty)
  • 商品名称:精准提取商品标题
  • 用户评分:解析星级评分(4.5/5.0等)
  • 销售信息:获取近期销售数据

应用场景

  1. 市场调研:分析不同商品类别的市场竞争情况
  2. 价格监控:跟踪商品价格波动趋势
  3. 竞品分析:获取同类商品的用户评价数据
  4. 库存管理:通过销售数据预测热销商品

输出结果

生成标准Excel文件amazon_products.xlsx,包含完整商品数据字段


多线程原理详解

实现机制

with ThreadPoolExecutor(max_workers=6) as executor:
    futures = []
    for base_url in base_urls:
        for page in range(1, 6):
            url = base_url.format(page)
            futures.append(executor.submit(get_amazon_product, url))


  1. 线程池创建:通过ThreadPoolExecutor创建包含6个工作线程的池
  2. 任务分配:将每个页面URL封装为独立任务提交到线程池
  3. 异步执行:线程池自动分配空闲线程处理请求
  4. 结果收集:通过Future对象跟踪任务状态并获取返回数据

性能优化点

  1. 智能调度:相比单线程速度提升5-8倍
  2. 资源控制:限制最大线程数避免被封禁
  3. 错误隔离:单个页面请求失败不影响整体任务

关键技术细节

  1. 随机延迟机制:通过random.uniform(1,4)模拟人类操作间隔
  2. 请求头伪装:使用真实浏览器指纹降低被识别风险
  3. 分级异常处理:区分页面级错误和商品级错误

扩展思考与建议

反爬策略增强

  1. IP轮换:可集成代理服务提供商(如BrightData)
  2. 指纹伪装:定期更换浏览器指纹特征
  3. 验证码应对:接入第三方OCR识别服务

完整实现代码

import requests
from bs4 import BeautifulSoup
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
import time
import random
from urllib.parse import urlparse, parse_qs

# 伪装浏览器访问
headers = {
    'User-Agent': '',  # 替换为自己的User-Agent
    'Accept-Language': 'en-US,en;q=0.9'
}


def get_amazon_product(url):
    try:
        response = requests.get(url, headers=headers, timeout=15)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'lxml')
            products = []

            # 获取分类名称
            parsed_url = urlparse(url)
            query_params = parse_qs(parsed_url.query)
            category = query_params.get('k', ['Unknown'])[0]

            # 定位所有商品容器
            product_containers = soup.find_all('div', {'data-component-type': 's-search-result'})

            for container in product_containers:
                try:
                    # 商品名称
                    product_name_h2 = container.find('h2', {
                        'class': 'a-size-medium a-spacing-none a-color-base a-text-normal'
                    })
                    if product_name_h2:
                        # 提取 h2 内部的 span 文本
                        product_name = product_name_h2.find('span').text.strip()
                    else:
                        product_name = 'NA'
                    # print(product_name)

                    # 评分
                    rating_tag = container.find('span', {'class': 'a-icon-alt'})
                    rating = rating_tag.text.split()[0] if rating_tag else 'N/A'

                    # 销售额
                    sales_tag = container.find('span', class_='a-size-base s-underline-text')
                    sales = sales_tag.text.strip() if sales_tag else 'N/A'

                    products.append({
                        'Category': category,
                        'ProductName': product_name,
                        'Rating': rating,
                        'SalesInfo': sales
                    })
                except Exception as e:
                    print(f"解析商品失败: {str(e)[:50]}...")
                    continue

            print(f"从 {url} 成功提取 {len(products)} 个商品")
            return products
        else:
            print(f"请求失败: {url} (状态码: {response.status_code})")
            return []
    except Exception as e:
        print(f"严重错误: {str(e)[:50]}...")
        return []

def main():
    base_urls = [
        'https://www.amazon.com/s?k=electronics&page={}',
        'https://www.amazon.com/s?k=beauty&page={}'
    ]

    all_products = []

    # 多线程设置
    with ThreadPoolExecutor(max_workers=6) as executor:
        futures = []
        for base_url in base_urls:
            for page in range(1, 6):  # 每类爬取5页
                url = base_url.format(page)
                print(f"提交任务: {url}")
                futures.append(executor.submit(get_amazon_product, url))

                # 随机延迟(1-4秒)
                time.sleep(random.uniform(1, 4))

        # 收集结果
        for i, future in enumerate(futures, 1):
            try:
                result = future.result()
                if result:
                    all_products.extend(result)
                    print(f"已处理 {i}/{len(futures)} 个页面")
            except Exception as e:
                print(f"任务失败: {str(e)[:50]}...")

    # 保存数据
    if all_products:
        df = pd.DataFrame(all_products)
        df.to_excel('amazon_products.xlsx', index=False)
        print(f"成功保存 {len(df)} 条商品数据!")
    else:
        print("未获取到有效数据")


if __name__ == '__main__':
    main()

延伸学习建议

python爬虫从基础可参考本人前两篇技术笔记:

  1. 每日实战:Python爬取微博热榜数据存入Excel-CSDN博客
  2. 每日实战:python爬虫之网页跳转-以某博为例-CSDN博客

原创声明:本技术方案为实战经验总结,转载请注明出处。数据抓取行为可能违反平台政策,请谨慎使用!更多技术细节欢迎关注CSDN技术专栏

 

你可能感兴趣的:(python爬虫,python,爬虫,多线程,开发语言)