前言这个标题的写法会让人以为「照着抄一段代码就能把淘宝商品抓下来」。实际情况恰好相反淘宝这类电商平台用通用爬虫去抓既不合规、也几乎没有可行性。它的 robots.txt 与用户协议对通用抓取有严格限制具体限制内容请以你自己实际查到的 robots.txt 和协议为准页面的商品数据大量由脚本动态加载并且平台有一整套针对异常访问的识别与处置机制。所以这篇「小实例」的正确写法不是教你写一段能和风控对抗的代码而是把合规的那条路走一遍先判断能不能抓不能抓就走开放平台的正规接口实在只是练手就换成练习站点。有几句需要直说。本文不提供、也不演示任何绕过登录、绕过验证码、绕过风控的做法——包括但不限于伪造登录态、破解签名、模拟完整浏览器指纹来规避识别。这类「技术」即便写出来也是把你和平台都置于风险之中。本文只讲三件合规的事怎么判断一个站点让不让你抓官方开放接口的调用形态长什么样在不能抓的情况下怎么用练习数据把采集流程练熟。代码基于 Python 3Python 2.7 已于 2020 年 1 月 1 日停止维护老教程里的print语句、urllib2、dict.iteritems()都要按 Python 3 的写法重写。一、先判断「能不能抓」再谈「怎么抓」任何采集任务的第一步都是一个布尔判断目标站点让不让抓。标准库里的urllib.robotparser.RobotFileParser就是干这个的set_url(robots_url)设定 robots.txt 地址read()抓取并解析can_fetch(useragent, url)返回布尔值。对电商平台这一步的结论往往就是「不允许」——那结论就是不抓而不是「换个 UA 再试试」。要注意分清两种情况服务器上根本没有 robots.txt标准库按 RFC 9309 视为「没有规则」和服务器出错、取不到 robots.txt应当保守地假定禁止。后者稳妥的做法是暂停等下次重试成功再说而不是趁机开抓。除了 robots.txt还要看用户协议。robots.txt 表达的是「爬虫礼仪」协议与著作权法表达的是「让你做与不让你做」后者优先级更高。二、合规路径走开放平台电商平台通常会为开发者提供开放平台Open Platform接口申请应用、拿到 appkey 与 appsecret按平台规定的算法对请求参数做签名再调用接口获取结构化数据。这条路的特点是有明确的授权与配额你抓什么、抓多少都是约定好的数据是结构化的 JSON不用解析 HTML平台会限流超额会被拒绝——这是设计不是障碍。一个通用的带签名参数的 GET 请求长这样具体签名算法、参数名、接口地址以开放平台官方文档为准环节做什么注意组装参数把 appkey、时间戳、接口名、业务参数等放一个字典参数名以文档为准排序拼接按平台规定对参数排序、拼接成待签名字符串顺序错则验签失败生成签名用 appsecret 配合平台指定的哈希算法算出 sign私钥绝不能进前端或公开仓库发起请求拼成 URL 或放进请求体发出遵守平台限流解析响应响应是 JSON用json.loads解析先判断错误字段再取数据生成签名属于防御侧的正当用法标准库里hashlib提供各种哈希hmac提供基于密钥的消息认证码比如hmac.new(key, msg, hashlib.sha256).hexdigest()需要做恒定时间比较时用hmac.compare_digest而不是用。具体用哪个算法、拼串顺序如何一律以平台文档为准不要凭印象拼。三、只是练手换成练习数据如果你的目的只是学会「请求—解析—落盘」这条链路完全没必要去碰真实平台的边界。两条更合适的路径用专门为练习搭建的站点例如quotes.toscrape.com这类站点页面结构稳定、明确用于教学用自己构造的 JSON 或本地 HTML 文件把解析和落盘逻辑练熟。下面这个「小实例」就按这条思路写它先老老实实检查 robots.txt发现不允许就退出然后演示怎么处理一份开放接口返回的 JSON这里用本地字符串模拟因为你拿到的应当是授权接口的数据最后输出规整的记录。实战合规前提下的完整小实例# 适用于 Python 3.8import jsonimport urllib.parseimport urllib.requestimport urllib.robotparserUA taobao-api-demo/0.1 (contact: demoexample.net)def robots_allowed(url):parts urllib.parse.urlsplit(url)robots_url urllib.parse.urlunsplit((parts.scheme, parts.netloc, /robots.txt, , ))parser urllib.robotparser.RobotFileParser()parser.set_url(robots_url)try:parser.read()except Exception:return False # 读不到就按不允许处理return parser.can_fetch(UA, url)def call_open_api(base_url, params, timeout15):带签名参数的 GET 调用骨架。注意签名算法参数排序、拼接格式、哈希方式由开放平台文档规定这里只演示把参数编码后发出去这一形态sign 需要你按文档生成。query urllib.parse.urlencode(sorted(params.items()))req urllib.request.Request(base_url ? query, headers{User-Agent: UA})with urllib.request.urlopen(req, timeouttimeout) as resp:charset resp.headers.get_content_charset() or utf-8return resp.read().decode(charset, errorsreplace)def parse_items(payload):把接口返回的 JSON 转成规整记录。data json.loads(payload)records []for item in data.get(items, []):records.append({title: item.get(title, ).strip(),price: item.get(price, ),sold: int(item.get(sold, 0)),})return recordsdef main():target https://www.taobao.com/if not robots_allowed(target):print(robots.txt 不允许抓取该站点改用官方开放接口或练习数据。)return# 只有 robots 允许、且已获得平台授权时才应该调用真实接口# payload call_open_api(BASE, {appkey: ..., sign: ..., ...})# 下面用一段本地 JSON 演示解析逻辑无需联网。payload json.dumps({items: [{title: 示例商品 A, price: 39.90, sold: 128},{title: 示例商品 B, price: 199.00, sold: 7},]}, ensure_asciiFalse)for record in parse_items(payload):print(%-10s %8s 已售 %d % (record[title], record[price], record[sold]))if __name__ __main__:main()跑起来后如果 robots.txt 判定不允许程序会打印提示并主动退出——这个「主动退出」就是本实例最重要的行为。剩下的parse_items演示的是通用能力不管数据来自官方接口还是你自己的文件JSON 到记录的转换逻辑都是一样的。注意json.dumps(..., ensure_asciiFalse)让中文以汉字本身呈现json.loads则把文本还原成字典与列表。常见坑点1. 把「能不能抓」当成技术问题❌ 看到 robots.txt 禁止就开始研究怎么伪装。 ✅ robots.txt 禁止就是不抓。合规问题没有技术解法。2. 用脚本去对抗风控❌ 研究验证码、指纹、登录态的绕过手法。 ✅ 需要平台数据就申请开放平台权限本文不提供任何对抗性代码。3. appsecret 写死在会被公开的地方❌ 把密钥硬编码进开源仓库或前端页面。 ✅ 密钥放环境变量或配置中心不进版本库泄露了立刻在平台重置。4. 用比较签名❌if got_sign expect_sign:—— 普通比较可能提前返回理论上可被计时攻击利用。 ✅ 用hmac.compare_digest(a, b)做恒定时间比较。5. 猜测签名算法❌ 凭印象拼一个「参数排序 md5(secretbufsecret)」就当通用公式用。 ✅ 不同平台算法不同以该平台官方文档为准用文档给的样例自测。6. 无限流地调接口❌ 循环里不设间隔把配额瞬间打满。 ✅ 遵守平台的速率约定对限流错误退避后重试。7. 把授权数据再分发❌ 通过开放接口拿到数据后转手公开售卖。 ✅ 平台授权的是「你按约定使用」不是「你自由处置」使用范围以协议为准。8. 拿练习站当真站练❌ 在练习站上调通了就以为能原样套到电商平台。 ✅ 练习站结构简单稳定真实平台数据形态、鉴权、限流完全不同别把两件事混为一谈。总结场景合规做法明确不做的事想抓电商平台商品页走开放平台接口申请授权不抓、不绕过风控robots.txt 禁止抓取停止不换 UA 硬闯需要登录/付费的内容放弃不伪造登录态只是想练技术用练习站或本地数据不拿真实平台当靶子调用开放接口按文档签名、限流、比签名用compare_digest不硬编码密钥、不猜算法写「淘宝爬虫」这样一个实例真正学到的不是某段代码而是一个判断顺序先合规、再授权、最后才是技术。当 robots.txt 说不当内容需要登录当平台提供了官方接口——这些信号出现时正确的做法都已经定了。把精力放在拿到授权之后的数据处理上才是这段代码值得保留的部分。