如何用Curl抓取亚马逊搜索结果的商品链接及详情数据?
亚马逊商品列表及详情抓取的PHP实现优化
原代码的核心问题
- 商品链接选择器不精准:原XPath
//a[contains(@class, "a-link-normal")]会匹配大量非商品链接(比如导航栏、广告入口、排序选项等),导致无效请求。 - CURL资源重复初始化:每次请求详情页都重新创建CURL句柄,浪费资源且效率低下。
- 未处理重复链接:可能抓取到同一商品的多个重复链接,增加不必要的请求。
- 反爬应对不足:仅设置User-Agent不足以绕过亚马逊的反爬机制,容易被拦截。
- 详情页元素选择器单一:亚马逊的价格、库存等元素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,可在抓取完当前页链接后,判断该元素是否存在:
- 如果存在下一页链接,拼接完整URL后重复执行搜索页抓取逻辑。
- 使用循环控制翻页次数,避免无限请求。
内容的提问来源于stack exchange,提问作者Siyah Panda
相关产品推荐
相关产品推荐

