吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1194|回复: 8
收起左侧

[资源求助] CSDN文章解锁(vip免费)

[复制链接]
sair0117 发表于 2025-11-27 19:14
25吾爱币
CSDN文章解锁(vip免费)求帮助,
https://blog.csdn.net/2501_93442133/article/details/152172943

最佳答案

查看完整内容

从 0 到 1,用 Python 写一套“会呼吸”的 1688 商品详情爬虫 原创 于 2025-09-27 17:53:05 发布 · 597 阅读 · 10 · 17 · CC 4.0 BY-SA版权 文章标签: #python #爬虫 #开发语言 一、为什么要“会呼吸”的爬虫? 1688 的反爬策略一直在升级: 2024 年 6 月之前,只验证 User-Agent ; 2024 年 8 月,加入滑块 + 行为验证; 2025 年 3 月,全面启用 x5sec 参数与 acsign 签名; 2025 年 9 ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lyh7733 发表于 2025-11-27 19:14
从 0 到 1,用 Python 写一套“会呼吸”的 1688 商品详情爬虫
原创

于 2025-09-27 17:53:05 发布
·
597 阅读
·

10
·
17
·
CC 4.0 BY-SA版权
文章标签:
#python
#爬虫
#开发语言


一、为什么要“会呼吸”的爬虫?
1688 的反爬策略一直在升级:

2024 年 6 月之前,只验证 User-Agent ;

2024 年 8 月,加入滑块 + 行为验证;

2025 年 3 月,全面启用 x5sec 参数与 acsign 签名;

2025 年 9 月,搜索列表页全部走 mtop 接口,cookie 有效期缩短到 15 min。

传统“一把梭”的静态爬虫早已阵亡。
本文给出的方案 = “Selenium 过滑块” + “API 签名直调” + “异步池控速” + “失败重试/断点续跑”——让程序像人一样“呼吸”:慢、稳、可恢复。

二、技术选型
模块        方案        理由
动态渲染        Selenium 4.11        自动下载 chromedriver,支持 headless=New,内存↓30%
签名破解        自建加密函数        把官方 JavaScript 翻译成 Python,免去调用 Node 子进程
并发控速        asyncio + aiohttp        单进程 500 协程,QPS≈120,峰值 1688 不弹验证码
数据缓存        sqlite + redis        支持“中断续采”,重复 SKU 自动跳过
代理/指纹        2c 住宅代理 + selenium-stealth        指纹随机化,封 IP 率 <0.5%
三、整体架构图
┌--------------┐     ┌-------------┐     ┌-------------┐
│ 种子 URL 池   │----&#9658;│ 签名/滑块层  │----&#9658;│ 异步下载层   │
└--------------┘     └-------------┘     └-------------┘
        │                     │                     │
        ▼                     ▼                     ▼
┌--------------┐     ┌-------------┐     ┌-------------┐
│ 失败重试队列 │&#9668;----│ 解析/清洗层  │&#9668;----│ 落地存储层   │
└--------------┘     └-------------┘     └-------------┘
全链路耗时:单条详情 0.8~1.2 s,日采 8 万 SKU 稳定运行。

四、分步代码实战
环境:Python 3.11,Win/Mac/Linux 通用

bash

# 一键安装依赖
pip install selenium==4.11.0 aiohttp aiofiles pandas sqlite3 redis selenium-stealth
1. 过滑块拿 cookie(仅需一次,15 min 内复用)
Python

# slide_login.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium_stealth import stealth
import time, json, pickle

def get_valid_cookie():
    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--no-sandbox")
    driver = webdriver.Chrome(service=Service(), options=options)
    stealth(driver,
            languages=["zh-CN", "zh"],
            vendor="Google Inc.",
            platform="Win32",
            webgl_vendor="Intel Inc.",
            renderer="Intel Iris OpenGL Engine",
            fix_hairline=True)

    driver.get("https://login.1688.com")
    input("【人工】完成滑块登录后,按回车继续...")
    cookies = driver.get_cookies()
    with open("cookies.pkl", "wb") as f:
        pickle.dump(cookies, f)
    driver.quit()
    print("cookie 已保存,15 min 内有效")

if __name__ == "__main__":
    get_valid_cookie()
登录后 cookie 里关键字段: _m_h5_tk 、 _m_h5_tk_enc 、 x5sec ,后文 API 必须带。

2. 签名算法 Python 化(核心)
1688 的 mtop 接口需要 sign = md5(token&t&appKey&data) ,再把 + 替换 - , / 替换 _ 。

Python

# sign.py
import time, hashlib, urllib.parse

def make_sign(token: str, app_key: str, data: dict) -> str:
    t = str(int(time.time() * 1000))
    data_str = json.dumps(data, separators=(',', ':'), ensure_ascii=False)
    raw = f"{token}&{t}&{app_key}&{data_str}"
    sign = hashlib.md5(raw.encode()).hexdigest()
    return sign, t
把 token 从 cookie 里正则提取即可,30 行代码搞定,无需 Node。

3. 异步下载详情(aiohttp + 代理池)
Python

# fetcher.py
import aiohttp, asyncio, pickle, json, redis, pandas as pd
from sign import make_sign

POOL = redis.from_url("redis://localhost:6379/0", decode_responses=True)

async def fetch_detail(session, sku_id, semaphore):
    async with semaphore:
        cookie_jar = aiohttp.CookieJar()
        with open("cookies.pkl", "rb") as f:
            cookies = pickle.load(f)
        for c in cookies:
            cookie_jar.update_cookies({c['name']: c['value']}, "https://detail.1688.com")

        token = next(c["value"] for c in cookies if c["name"] == "_m_h5_tk").split("_")[0]
        app_key = "12574478"          # 固定
        data = {"detailV3Params": '{"id":"%s"}' % sku_id}
        sign, t = make_sign(token, app_key, data)

        url = ("https://h5api.m.1688.com/h5/mtop.1688.detail.getdetail/1.0/"
               f"?jsv=2.4.11&appKey={app_key}&t={t}&sign={sign}&api=mtop.1688.detail.getdetail&v=1.0"
               f"&data={urllib.parse.quote_plus(json.dumps(data))}")
        headers = {
            "user-agent": "Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36 Chrome/96.0.4664.45",
            "referer": f"https://detail.1688.com/offer/{sku_id}.html",
        }
        async with session.get(url, headers=headers, cookie_jar=cookie_jar) as resp:
            obj = await resp.json()
            if obj.get("ret")[0].startswith("SUCCESS"):
                return sku_id, obj["data"]
            else:
                return sku_id, None

async def bulk_fetch(sku_list, max_conn=200):
    semaphore = asyncio.Semaphore(max_conn)
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_detail(session, sid, semaphore) for sid in sku_list]
        return await asyncio.gather(*tasks)
代理池用法:把 session.get(..., proxy="http://user:pass@ip:port") 包一层即可。

4. 解析&落地(pandas + sqlite)
Python

# parser.py
import pandas as pd
import sqlite3, json, datetime

def parse_and_save(raw_list):
    records = []
    for sku_id, data in raw_list:
        if not data:
            continue
        d = data["data"]
        records.append({
            "sku_id": sku_id,
            "title": d["subject"],
            "price": float(d["price"]),
            "moq": int(d["moq"]),
            "sold": int(d.get("soldQuantity", 0)),
            "pics": "|".join([img["url"] for img in d["imageList"]]),
            "props": json.dumps({p["name"]: p["value"] for p in d["props"]}, ensure_ascii=False),
            "ts": datetime.datetime.now(),
        })
    df = pd.DataFrame(records)
    conn = sqlite3.connect("1688.db")
    df.to_sql("sku", conn, if_exists="append", index=False)
    print(">>> 入库", len(df))
字段完全对齐前文提到的 num_iid/title/price/props 等,方便后续直接 BI 分析。

5. 断点续采 + 失败重试
启动前把待采 SKU 写进 redis 集合 todo_set ,成功即刻 srem ,异常自动 rpush 到 retry_queue ,最大 3 次。

Python

# scheduler.py
import redis, random, asyncio
from fetcher import bulk_fetch
from parser import parse_and_save

POOL = redis.from_url("redis://localhost:6379/0", decode_responses=True)

def schedule():
    while True:
        sku_list = POOL.srandmember("todo_set", 500)
        if not sku_list:
            break
        sku_list = [s for s in sku_list if s]
        result = asyncio.run(bulk_fetch(sku_list))
        parse_and_save(result)
        for sku_id, data in result:
            if data:
                POOL.srem("todo_set", sku_id)
            else:
                retry = POOL.lpush("retry_queue", sku_id)
                if retry > 3:
                    POOL.srem("todo_set", sku_id)   # 超过 3 次放弃
        time.sleep(random.uniform(1, 3))            # 呼吸一下

if __name__ == "__main__":
    schedule()
实测 8 核 16 G 云主机,日采 8.2 万 SKU,峰值内存 1.4 G,CPU 35%,无验证码弹出。

五、常见问题 FAQ
cookie 只有 15 min 怎么办?
把 slide_login.py 包装成 API,用 playwright 无头模式每 10 min 重新登录一次,无缝切换。

想抓店铺“全部商品”列表?
店铺页也是 mtop.1688.shop.getShopOfferList 接口,签名方式完全一样,改 data={"page":i,"pageSize":20,"memberId":"xxx"} 即可。

会不会侵权?
1688 数据属于公开商品信息,未涉及个人信息, 仅限内部分析/选品 ,不要二次销售;robot.txt 禁止 /search/ 目录,但详情页 offer/*.html 未禁止,合规风险低。
建议加 2~3 s 随机延迟,白天 09-22 点限速 50%,子夜可跑满。

六、总结
静态 requests 时代已过去,动态签名 + 滑块验证才是 2025 主流;

Selenium 只负责“拿门票”,真正高效的是 aiohttp 批量调 API;

签名算法本地化,避免 Node 子进程性能损耗;

用 redis+sqlite 做“断点续采”,8 万 SKU/天稳稳跑;

代码全部开源在 GitHub(文末二维码),一键 python main.py 就能跑,真正 0 成本上手!

把这篇软文收藏起来,你就拥有了一套“会呼吸”的 1688 商品爬虫——
让它帮你选品、比价、监控竞品,把数据变成钱!

点击获取更多优质资料
jinkji 发表于 2025-11-27 19:47
文章已经转到飞书了:
https://pcnv19t5hy2p.feishu.cn/docx/KM3MdC6cZobi3yxpO4hcyj0NnTh?from=from_copylink

忘采纳
 楼主| sair0117 发表于 2025-11-27 20:22
jinkji 发表于 2025-11-27 19:47
文章已经转到飞书了:
https://pcnv19t5hy2p.feishu.cn/docx/KM3MdC6cZobi3yxpO4hcyj0NnTh?from=from_copy ...

没权限访问,已经申请了,备注52pojie
 楼主| sair0117 发表于 2025-11-27 20:46
jinkji 发表于 2025-11-27 19:47
文章已经转到飞书了:
https://pcnv19t5hy2p.feishu.cn/docx/KM3MdC6cZobi3yxpO4hcyj0NnTh?from=from_copy ...

用户855086的申请
lyh7733 发表于 2025-11-27 21:59
https://c.wss.cc/f/ikf6rwplzmb 复制链接到浏览器打开
 楼主| sair0117 发表于 2025-11-27 22:33
lyh7733 发表于 2025-11-27 21:59
https://c.wss.cc/f/ikf6rwplzmb 复制链接到浏览器打开

请问文章末尾是不是有个项目开源地址的二维码,这个下载的html没图片,谢谢,
sunnytian 发表于 2025-11-28 00:32
请问有佬做这种的技术网站吗
jinkji 发表于 2025-11-28 20:26

已同意,可以直接访问
返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-6-16 10:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表