You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Curl抓取亚马逊搜索结果的商品链接及详情数据?

亚马逊商品列表及详情抓取的PHP实现优化

原代码的核心问题

  1. 商品链接选择器不精准:原XPath //a[contains(@class, "a-link-normal")]会匹配大量非商品链接(比如导航栏、广告入口、排序选项等),导致无效请求。
  2. CURL资源重复初始化:每次请求详情页都重新创建CURL句柄,浪费资源且效率低下。
  3. 未处理重复链接:可能抓取到同一商品的多个重复链接,增加不必要的请求。
  4. 反爬应对不足:仅设置User-Agent不足以绕过亚马逊的反爬机制,容易被拦截。
  5. 详情页元素选择器单一:亚马逊的价格、库存等元素ID/Class会根据商品类型(促销、自营等)变化,原代码的选择器无法覆盖所有情况。

优化后的实现代码

<?php
declare(strict_types = 1);

// 初始化CURL句柄,复用资源
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => 'gzip, deflate',
    CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_MAXREDIRS => 5,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_COOKIEJAR => './amazon_cookies.txt', // 保存Cookie,模拟会话
    CURLOPT_COOKIEFILE => './amazon_cookies.txt',
    CURLOPT_REFERER => 'https://www.amazon.com/'
]);

// 1. 抓取搜索页商品链接
$searchUrl = 'https://www.amazon.com/s?k=beauty';
$html = curl_exec($ch);
if($html === false) {
    die("CURL请求搜索页失败: " . curl_error($ch));
}

$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML($html);
libxml_clear_errors();
$xpath = new DOMXPath($domd);

// 精准匹配商品卡片内的链接
$linkNodes = $xpath->query('//div[@data-component-type="s-search-result"]//a[@class="a-link-normal s-no-outline"]/@href');
$linksToScrape = [];
if ($linkNodes->length > 0) {
    foreach ($linkNodes as $node) {
        $url = $node->nodeValue;
        // 处理相对链接,过滤非商品链接
        if (strpos($url, '/dp/') !== false || strpos($url, '/gp/product/') !== false) {
            if (strpos($url, 'https://') !== 0) {
                $url = 'https://www.amazon.com' . $url;
            }
            // 去重:提取商品ASIN作为标识
            preg_match('/(dp|gp\/product)\/([A-Z0-9]{10})/', $url, $matches);
            if (isset($matches[2])) {
                $asin = $matches[2];
                $linksToScrape[$asin] = $url;
            }
        }
    }
}

// 限制抓取数量(可选)
$linksToScrape = array_slice($linksToScrape, 0, 10);

// 2. 遍历商品链接抓取详情
foreach ($linksToScrape as $asin => $link) {
    echo "商品链接: {$link}\n";

    curl_setopt($ch, CURLOPT_URL, $link);
    $detailHtml = curl_exec($ch);
    if($detailHtml === false) {
        echo "CURL请求详情页失败: " . curl_error($ch) . "\n\n";
        continue;
    }

    $detailDom = new DOMDocument();
    libxml_use_internal_errors(true);
    $detailDom->loadHTML($detailHtml);
    libxml_clear_errors();
    $detailXpath = new DOMXPath($detailDom);

    // 商品名称
    $productNameNode = $detailXpath->query('//span[@id="productTitle"]');
    $productName = $productNameNode->length > 0 ? trim($productNameNode->item(0)->nodeValue) : '未获取到';
    echo "商品名称: {$productName}\n";

    // 库存状态
    $stockNode = $detailXpath->query('//div[@id="availability"]//span[@class="a-size-medium a-color-success"] | //div[@id="availability"]//span[@class="a-size-medium a-color-price"]');
    $stock = $stockNode->length > 0 ? trim($stockNode->item(0)->nodeValue) : '未获取到';
    echo "库存状态: {$stock}\n";

    // 价格(兼容促销价、常规价)
    $priceNode = $detailXpath->query('//span[@id="priceblock_dealprice"] | //span[@id="priceblock_ourprice"] | //span[@class="a-price-whole"]');
    $price = $priceNode->length > 0 ? trim($priceNode->item(0)->nodeValue) : '未获取到';
    echo "价格: {$price}\n";

    // 商品主图
    $imageNode = $detailXpath->query('//img[@id="landingImage"]/@src | //img[@data-a-dynamic-image]/@src');
    $image = $imageNode->length > 0 ? $imageNode->item(0)->nodeValue : '未获取到';
    // 处理动态图片链接(JSON格式)
    if (strpos($image, '{') !== false) {
        $imageJson = json_decode($image, true);
        $image = !empty($imageJson) ? key($imageJson) : '未获取到';
    }
    echo "商品图片: {$image}\n";

    // 分类(取最后一个面包屑)
    $categoryNodes = $detailXpath->query('//div[@id="wayfinding-breadcrumbs_feature_div"]//a[@class="a-link-normal a-color-tertiary"]');
    $category = $categoryNodes->length > 0 ? trim($categoryNodes->item($categoryNodes->length - 1)->nodeValue) : '未获取到';
    echo "分类: {$category}\n";

    // 商品描述(兼容APlus和基础描述)
    $descNode = $detailXpath->query('//div[@id="aplus"] | //div[@id="productDescription"]');
    $description = $descNode->length > 0 ? trim(strip_tags($descNode->item(0)->nodeValue)) : '未获取到';
    echo "商品描述: {$description}\n\n";
}

// 关闭CURL资源
curl_close($ch);
?>

关键优化点说明

  • 精准链接匹配:通过data-component-type="s-search-result"定位商品卡片,只抓取包含/dp/或/gp/product/的有效商品链接,并通过ASIN去重。
  • CURL资源复用:只初始化一次CURL句柄,通过curl_setopt动态修改URL,提升请求效率。
  • 增强反爬策略:添加Cookie持久化、Referer、跟随跳转等配置,模拟真实浏览器行为。
  • 兼容多场景元素选择:价格、库存等元素使用多选择器匹配,覆盖亚马逊不同类型商品的页面结构。
  • 动态图片处理:解析亚马逊的动态图片JSON数据,提取高清主图链接。

后续自动翻页实现思路

亚马逊搜索页的下一页链接位于//a[@class='s-pagination-item s-pagination-next']/@href,可在抓取完当前页链接后,判断该元素是否存在:

  1. 如果存在下一页链接,拼接完整URL后重复执行搜索页抓取逻辑。
  2. 使用循环控制翻页次数,避免无限请求。

内容的提问来源于stack exchange,提问作者Siyah Panda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:40:23