0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

把淘宝店铺详情搬进 MySQL:PHP 爬虫全链路实战(2025 版)

刘大雷 来源:jf_82280871 作者:jf_82280871 2025-10-16 17:31 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、为什么要自己爬店铺详情?

选品:直播团队需要「店铺评分、粉丝数、上新频率」快速筛选靠谱供应商

竞品:同一类目,对手店铺突然涨粉 10w,第一时间预警

数据训练:店铺简介 + 评分 → 做多模态情感分类

投资:提前发现「高评分+低粉丝」潜力店,谈供应链合作

官方 taobao.shop.get 需要企业资质,个人 99% 被卡;网页端「店铺主页」公开可见,走网页派依旧是最低成本方案。下面用纯 PHP 把「店铺主页 → 基础信息 → 商品列表 → 落库 → 飞书播报」一次撸完。

二、技术选型(全部开源)

wKgZPGjwuteAeFh4AABp6DI8PT0747.png

三、0 环境搭建(Linux / Win / mac 通用)

bash

# 1. 安装 PHP 8.2+ 扩展
sudo dnf install php php-cli php-curl php-dom php-mbstring php-pdo php-mysqlnd

# 2. 安装 Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# 3. 创建项目
mkdir taobao-shop-php && cd taobao-shop-php
composer init --no-interaction --require="php:>=8.2"
composer install

四、核心流程:6 步闭环(全部代码可跑)

① 找入口:店铺主页 + 签名算法(2025-10 有效)

店铺主页:

https://shop{m}.taobao.com/shop/shop_index.htm?shop_id={shop_id}

店铺内所有商品接口(JSONP):

https://shop.m.taobao.com/shop/shopItemSearch.jsonp?shopId={shop_id}¤tPage={page}&pageSize=20&callback=jsonp123

返回:

JavaScript

jsonp123({"total":1523,"items":[{...}]})

签名逻辑(与详情页同款):

php

function sign(string $raw): string {
    return strtoupper(md5($raw));
}

调用前拼字符串:t + "&12574478&" + data + "&",其中 t 为毫秒时间戳。

② 网络层:GuzzleHttp 7 + 连接池

php

< ?php
require 'vendor/autoload.php';
use GuzzleHttpClient;
use GuzzleHttpPool;
use GuzzleHttpPsr7Request;

class ShopClient {
    private Client $http;
    private int $qps = 15; // 令牌桶

    public function __construct() {
        $this- >http = new Client([
            'timeout' => 10,
            'headers' => [
                'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
                'Referer' => 'https://shop.taobao.com/'
            ]
        ]);
    }

    public function fetchIndex(int $shopId): array {
        $url = "https://shop.taobao.com/shop/shop_index.htm?shop_id={$shopId}";
        $html = $this->http->get($url)->getBody()->getContents();
        return $this->parseIndex($html, $shopId);
    }

    public function fetchItems(int $shopId, int $page = 1): array {
        $this->rateLimit(); // 限速
        $callback = 'jsonp' . microtime(true);
        $data = json_encode(['shopId' => $shopId, 'currentPage' => $page], JSON_UNESCAPED_SLASHES);
        $t = (string) (microtime(true) * 1000);
        $sign = sign($t . "&12574478&" . $data . "&");

        $url = "https://shop.m.taobao.com/shop/shopItemSearch.jsonp?" . http_build_query([
            'shopId' => $shopId,
            'currentPage' => $page,
            'pageSize' => 20,
            'callback' => $callback,
            't' => $t,
            'sign' => $sign
        ]);

        $jsonp = $this->http->get($url)->getBody()->getContents();
        $json = preg_replace('/^jsonpd+(|)$/m', '', $jsonp);
        return $this->parseItems(json_decode($json, true), $shopId);
    }

    private function parseIndex(string $html, int $shopId): array {
        $doc = new DOMDocument();
        @$doc->loadHTML($html);
        $xpath = new DOMXPath($doc);
        return [
            'shop_id' => $shopId,
            'shop_name' => trim($xpath->query("//h1[@class='shop-name']")->item(0)?->nodeValue ?? ''),
            'shop_score' => trim($xpath->query("//span[@class='shop-score']")->item(0)?->nodeValue ?? ''),
            'shop_fans' => trim($xpath->query("//span[@class='shop-fans']")->item(0)?->nodeValue ?? ''),
        ];
    }

    private function parseItems(array $root, int $shopId): array {
        $items = [];
        foreach ($root['items'] ?? [] as $i) {
            $items[] = [
                'shop_id' => $shopId,
                'item_id' => $i['itemId'],
                'title' => $i['title'],
                'price' => $i['price'],
                'pic_url' => $i['picUrl'],
                'sold' => $i['sold'] ?? 0,
                'comment_count' => $i['commentCount'] ?? 0,
                'created_at' => date('Y-m-d H:i:s', $i['created'] / 1000)
            ];
        }
        return $items;
    }

    private function rateLimit(): void {
        usleep(1000000 / $this->qps); // 微秒
    }
}

③ 并发池:Guzzle Pool + 进度条

php

public function fetchAllItems(int $shopId, int $maxPage = 200): array {
    $first = $this->fetchItems($shopId, 1);
    $totalPage = min(ceil(($first['total'] ?? 0) / 20), $maxPage);

    $requests = function () use ($shopId, $totalPage) {
        for ($p = 2; $p <= $totalPage; $p++) {
            yield new Request('GET', $this- >buildItemUrl($shopId, $p));
        }
    };

    $items = [];
    $pool = new Pool($this->http, $requests(), [
        'concurrency' => 15, // 令牌桶
        'fulfilled' => function ($response, $index) use (&$items, $shopId) {
            $jsonp = $response->getBody()->getContents();
            $json = preg_replace('/^jsonpd+(|)$/m', '', $jsonp);
            $items[] = $this->parseItems(json_decode($json, true), $shopId);
        },
        'rejected' => function ($reason, $index) {
            Log::error("Page $index failed: $reason");
        },
    ]);
    $pool->promise()->wait();
    return array_merge(...$items);
}

④ 落库:Laravel Eloquent 批量 + Redis 去重

sql

CREATE TABLE tb_shop_detail (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  shop_id BIGINT NOT NULL,
  shop_name VARCHAR(100) NOT NULL,
  shop_score VARCHAR(20) NOT NULL,
  shop_fans VARCHAR(20) NOT NULL,
  item_id BIGINT NOT NULL,
  title VARCHAR(200) NOT NULL,
  price VARCHAR(30) NOT NULL,
  pic_url VARCHAR(500) NOT NULL,
  sold INT DEFAULT 0,
  comment_count INT DEFAULT 0,
  created_at DATETIME NOT NULL,
  UNIQUE KEY uk_item (item_id),
  INDEX idx_shop (shop_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

模型:

php

< ?php
namespace AppModels;

use IlluminateDatabaseEloquentModel;

class ShopDetail extends Model
{
    protected $table = 'tb_shop_detail';
    protected $fillable = [
        'shop_id','shop_name','shop_score','shop_fans',
        'item_id','title','price','pic_url','sold','comment_count','created_at'
    ];
    public $timestamps = false;
}

批量插入:

php

use IlluminateSupportFacadesDB;
use AppModelsShopDetail;

function bulkSave(array $rows): int
{
    $new = 0;
    foreach (array_chunk($rows, 1000) as $chunk) {
        $exists = Redis::command('sadd', ['item_id_set', ...array_column($chunk, 'item_id')]);
        $filtered = array_filter($chunk, fn($i) => $exists[$i['item_id']] ?? false);
        if ($filtered) {
            ShopDetail::insert($filtered);
            $new += count($filtered);
        }
    }
    return $new;
}

⑥ Docker 定时:每天 8 点飞书播报

Dockerfile

dockerfile

FROM php:8.2-cli
RUN apt-get update && apt-get install -y libcurl4-openssl-dev libssl-dev libzip-dev 
    && docker-php-ext-install pdo_mysql curl zip
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /app
COPY . .
RUN composer install --no-dev
CMD ["php","crawl.php"]

crontab

0 8 * * * docker run --rm -v /mnt/nas/shop:/app/storage taobao-shop-php

飞书推送(精简版)

php

function report(int $shopId, int $new): void {
    $body = json_encode([
        'msg_type' => 'text',
        'content'  => ['text' => "店铺 $shopId 新增 $new 条商品,已落库~"]
    ]);
    file_get_contents('https://open.feishu.cn/open-apis/bot/v2/hook/xxx', false, stream_context_create([
        'http' => ['method' => 'POST', 'header' => 'Content-Type: application/json', 'content' => $body]
    ]));
}

五、踩坑 & 反爬锦囊

JSONP 壳:正则为 ^jsonpd+(|)$,剥完再 json_decode

Referer:必须 https://shop.taobao.com/,否则 403

限速:单 IP 15 QPS 稳过,> 200/10min 必出滑块

代理池:青果云 1G ≈ 0.8 元,能跑 8 万页

重复:Redis item_id_set 秒级去重,内存省 90 %

六、结语

从店铺主页、JSONP 签名、Guzzle 并发、Eloquent 落库,到 Docker 定时 + 飞书群播报,一条完整的 PHP 闭环就打通了。
全部代码可直接扔进 PhpStorm / VSCode 跑通,改一行 shopId 就能薅任意店铺。
祝各位运营、产品、算法大佬爬得开心,爆单更开心!

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PHP
    PHP
    +关注

    关注

    0

    文章

    463

    浏览量

    28802
  • MySQL
    +关注

    关注

    1

    文章

    930

    浏览量

    29745
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    电商效率翻倍:用 OpenClaw 对接京东详情接口,一键抓取商品量信息

    完整数据,非常适合无货源铺货、竞品监控、选品比价、素材采集等场景。 一、接口核心能力 支持京东自营、第三方店铺、京东国际商品详情获取 一次返回 主图、SKU、价格、销量、详情图片、参数、店铺
    的头像 发表于 04-22 13:55 50次阅读

    电商效率翻倍:用 Open Claw 对接淘宝详情接口,一键抓取商品量信息

    Open Claw 封装的 淘宝商品详情接口(item_get) ,可以直接获取淘宝 / 天猫商品的 标题、主图、SKU、价格、销量、详情页素材、属性、发货信息 等
    的头像 发表于 04-21 16:56 329次阅读

    高效获取淘宝商品详情:API 开发实现链接解析的完整技术方案

    ​ 在电商数据应用、比价系统搭建、库存监控等场景中,通过 API 实现淘宝链接解析与商品详情获取是核心技术环节。但淘宝开放平台的权限限制、反爬虫机制及数据格式差异,常让开发者踩坑。本文
    的头像 发表于 04-13 16:23 121次阅读

    淘宝店铺所有商品接口

    获取 淘宝店铺所有商品 ,核心依赖 淘宝开放平台(TOP) 的官方 API。以下是最常用、最稳定的接口清单与使用说明: 一、核心商品列表接口(获取店商品) 1.
    的头像 发表于 04-08 14:39 243次阅读

    调用淘宝开放平台API获取店铺所有商品列表

    ​  在电商系统开发或数据分析场景中,有时需要批量获取淘宝店铺的所有商品信息。淘宝开放平台(Taobao Open Platform)提供了丰富的API接口供开发者使用,其中就包含获取店铺
    的头像 发表于 03-27 17:38 728次阅读
    调用<b class='flag-5'>淘宝</b>开放平台API获取<b class='flag-5'>店铺</b>所有商品列表

    接入淘宝店铺所有商品接口后

    一、基础价值:合规、高效、稳定获取量商品数据 合规无风险 :官方 API,彻底替代爬虫,避免账号风险与法律问题。 数据完整 :获取商品 ID、标题、价格、主图、销量、库存、类目、SKU、优惠
    的头像 发表于 03-09 17:30 893次阅读

    淘宝店铺量商品API接口技术实践指南

    在电商数字化运营与数据分析场景中,高效获取店铺量商品数据是核心需求之一。淘宝开放平台提供的店铺量商品API接口(核心接口:taobao.
    的头像 发表于 01-23 10:55 504次阅读

    1688店铺详情API使用指南

    等级、主营品类等核心数据。该接口为电商数据分析、店铺监控、供应对接、导购平台开发等场景提供了关键的数据支撑。本文将从 摘要、接口概述、Python 请求示例、结语 四个维度,详细介绍该 API 的使用方式。 一、摘要 1688 店铺
    的头像 发表于 12-19 10:20 1857次阅读

    # 深度解析:爬虫技术获取淘宝商品详情并封装为API的流程应用

    需求。本文将深入探讨如何借助爬虫技术实现淘宝商品详情的获取,并将其高效封装为API。 一、爬虫技术核心原理与工具 1.1 爬虫运行机制 网络
    的头像 发表于 11-17 09:29 472次阅读

    淘宝商品详情API接口技术解析与实战应用

    随着电商行业的快速发展,数据驱动的决策模式已成为企业核心竞争力的重要组成部分。淘宝作为国内领先的电商平台,其开放平台提供的商品详情API接口为开发者提供了获取商品维度数据的通道。本文从技术实现角度
    的头像 发表于 11-04 09:50 516次阅读

    揭秘淘宝详情 API 接口:解锁电商数据应用新玩法

    在电商的浩瀚宇宙中,淘宝无疑是一颗璀璨的巨星。对于开发者、电商从业者来说,获取淘宝商品的详细信息是一项常见且重要的需求。而淘宝详情 API 接口,就像是一
    的头像 发表于 09-29 14:30 534次阅读

    从 0 到 1:用 PHP 爬虫优雅地拿下京东商品详情

    PHP 语言 实现一个 可运行的京东商品爬虫 ,不仅能抓取商品标题、价格、图片、评价数,还能应对常见的反爬策略。全文附完整代码, 复制粘贴即可运行 。 一、为什么选择 PHP爬虫
    的头像 发表于 09-23 16:42 1060次阅读
    从 0 到 1:用 <b class='flag-5'>PHP</b> <b class='flag-5'>爬虫</b>优雅地拿下京东商品<b class='flag-5'>详情</b>

    淘宝商品详情 API 实战:5 大策略提升店铺转化率(附签名优化代码 + 避坑指南)

    ”“差评失控” 等转化率杀手。本文结合我对接 300 + 淘宝店铺实战经验,拆解 API 如何落地到动态定价、库存预警等 5 大场景,代码做了签名优化和错误处理,新手也能直接复用,避开 90% 的调用坑。 一、
    的头像 发表于 09-15 10:53 1132次阅读

    淘宝/天猫:通过商品详情API实现多店铺商品信息批量同步,确保价格、库存实时更新

    ​ 在电商运营中,管理多个淘宝或天猫店铺的商品信息(如价格和库存)是一项繁琐的任务。手动更新耗时耗力,且容易出错,导致价格不一致或库存超卖。通过淘宝/天猫开放平台提供的商品详情API,
    的头像 发表于 09-08 16:05 1400次阅读
    <b class='flag-5'>淘宝</b>/天猫:通过商品<b class='flag-5'>详情</b>API实现多<b class='flag-5'>店铺</b>商品信息批量同步,确保价格、库存实时更新

    淘宝 API 实现天猫店铺商品详情页智能优化

    ​ 在竞争激烈的电商环境中,天猫店铺的商品详情页是影响用户转化率的关键因素。通过淘宝开放平台提供的API,我们可以实现智能优化,提升用户体验和销售业绩。本文将从零开始,逐步介绍如何利用淘宝
    的头像 发表于 08-13 14:35 958次阅读
    用<b class='flag-5'>淘宝</b> API 实现天猫<b class='flag-5'>店铺</b>商品<b class='flag-5'>详情</b>页智能优化