第一版:Python爬虫+CSV存储,3天崩溃的教训

去年接了个播客品牌的舆情监控项目,要抓5个平台的提及数据。我图省事,用Scrapy 2.9写了爬虫,输出直接怼CSV。每个平台配了3个代理IP,从快代理买的动态IP套餐,请求间隔设成2.5秒,想着慢慢爬总不会出问题。结果跑了72小时,服务器直接OOM,ssh都连不上,兜底一句硬重启才救回来。查日志一看,只抓了37条有效记录——其中23条还是重复的。

崩溃原因我排查了一整天:Scrapy的Item Pipeline默认把所有数据缓存到内存,CSV Feed Exporter写入频率太低,默认每隔4096条才flush一次。我抓的数据量虽然不大,但5个平台并发跑,每个平台还开了2个并发请求,总共10个spider实例在跑。每个实例的response对象、item对象全堆在内存里,Python的垃圾回收又慢,堆到1.2GB的时候系统撑不住了。

血的教训:别用CSV存实时数据,这玩意儿只适合小批量手动导出。老老实实上MySQL 8.0,建表语句长这样:

CREATE TABLE podcast_mentions (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    platform VARCHAR(20) NOT NULL COMMENT '平台: apple/spotify/xiaoyuzhou/ximalaya/netease',
    episode_id VARCHAR(64) NOT NULL COMMENT '播客节目ID',
    mention_text TEXT COMMENT '提及文本',
    mention_time DATETIME NOT NULL COMMENT '提及时间',
    keyword_hit VARCHAR(128) COMMENT '命中的关键词',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_platform_time (platform, mention_time),
    INDEX idx_keyword_hit (keyword_hit(64)),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

索引策略我摸了两轮才定下来:联合索引idx_platform_time按平台和提及时间排序,覆盖了90%的查询场景——按平台查最新数据。idx_keyword_hit用前缀索引64个字符,因为关键词最长也就50个汉字,够用了。实测从CSV切到MySQL后,同样跑3天,抓了2846条有效记录,内存占用稳定在180MB左右。别问我为什么当初不直接用数据库,问就是图省事,结果多花了一周重写。

第二版:nginx反代+百度sitemap推送,日抓取1200次的稳定方案

第一版被百度爬虫扒烂之后,我直接换了整套架构。nginx 1.24.0反代,后面挂了5台阿里云ECS(2核4G),后端用FastAPI 0.104.0。别问我为啥不用Flask,FastAPI的异步处理能扛住百度的并发抓取,实测在每秒80个请求时响应时间稳定在120ms以内。

sitemap.xml这块儿我踩了大坑。一开始一个sitemap.xml扔了15000条URL,百度爬虫只抓前2000条就跑了。后来我拆成30个分片,每个分片500条URL,用百度站长平台的实时推送接口去提交——不是被动等爬虫来,是主动喂给它。索引率从41%直接飙到76%,这个数字我盯着看了三天才敢信。

nginx配置里最关键的是这几个参数:worker_connections设成2048,gzip on,HTTP/2一定要开。HTTP/2在百度移动端爬虫的抓取效率能提升30%以上,实测首字节时间从3.2s降到0.8s。别用HTTP/1.1硬扛,爬虫并发连接数一上去就报503。

抓取频率从每小时1次提到每15分钟1次,这个改动是我跟百度站长平台的接口日志对照了两个月才确定下来的。15分钟正好卡在百度爬虫的刷新窗口内,再频繁了会被限流,再低了索引跟不上。去年给一个教育站做的时候,这么调完日抓取量从300次涨到1200次,稳定跑了4个月没掉过。

避坑清单

  • sitemap分片数量别超过50个,百度索引器会怀疑你刷量
  • 实时推送接口每天限额50000次,别超了,超了封24小时
  • 2核4G的ECS扛不住每秒200个并发请求,别想着省钱
  • HTTP/2必须配合gzip用,否则抓取效率反而下降10%左右

第三版:接入AI引擎(GEO优化),日抓取冲到2300次

去年12月Google和百度几乎同时上线AI摘要生成功能,我拿手上一个播客站做了测试。传统爬虫抓取的页面,在AI引擎里的索引率只有23%,这意味着AI生成答案时,77%的内容压根没被考虑。

我直接上了@type=PodcastEpisode的JSON-LD结构化数据。核心字段是duration(精确到秒)、transcript(全文对话文本)、mentions(标注了品牌名和人名)。实测发现,transcript字段的字符数必须超过3000字,低于这个阈值AI引擎会标记为“信息不足”。

同时给百度站长平台和Google Search Console提交了AI友好型sitemap。URL格式我改成这样:https://xxx.com/episode/20231215/ai-tools-mention-0.35,末尾的0.35代表关键词密度,我控制在0.3-0.5之间。时间戳精确到日,方便AI引擎按时间权重排序。

5天后看数据,Google AI索引率从23%干到89%,百度AI引擎日抓取从400次涨到1100次。最狠的是第三天,Google AI直接冲到了2300次,把服务器带宽干到报警,我连夜加了限流。

这个方案有个坑:JSON-LD里加了@id字段后,AI引擎会把不同时间戳的页面当成独立实体,导致重复抓取。我调了3天才摸清楚,必须用sitemap:lastmod去重,保证URL时间戳变动不超过24小时。

避坑清单

  • JSON-LD的duration字段用ISO 8601格式,别用HH:MM:SS
  • sitemap里URL时间戳和页面实际发布时间差不能超过2小时
  • transcript字段低于3000字,AI引擎直接忽略

避坑清单:4个必须做的配置和一个不该花的钱

去年我给一个品牌舆情站搭播客监测,第一周就被Apple Podcasts封了三个IP。查日志发现全是机房IP惹的祸——播客平台对数据中心的请求特征太敏感了。我花了2800元/月买Oxylabs住宅代理池(静态ISP套餐),成功率直接从34%跳到92%。别跟我一样图便宜用机房IP,白名单里至少备50个住宅IP轮换,每个IP发完10次请求就换。

百度站长平台那个抓取设置也是个坑。默认的’极速抓取’模式等于给反爬系统送人头——我调了三天才发现,这个模式会让爬虫在5秒内连续请求同一域名,播客平台直接返回503。去后台找到抓取设置,把开关拨到’智能抓取’,再手动把抓取间隔设为120秒。实测关掉极速后,被封率从17%降到0.3%。

API速率限制这玩意儿各家不一样。Apple Podcasts的Search API我测出来是10次/分钟,超过就返回429加IP禁封15分钟。Spotify的Web API给到20次/分钟,但如果你用Client Credentials流程,实际会被限到15次/分钟左右。小宇宙最宽松,30次/分钟,但凌晨时段会降到10次。我写了个限流器,用token bucket算法,Apple那边设8次/分钟留余量,跑了大半年没翻车。

兜底一句说那个不该花的钱。我试过3家AI播客监测SaaS,月费加起来6000多块,什么”智能语义分析”“自动标注提及”,全是噱头。实测数据延迟全部超过24小时——有个客户凌晨上了新节目,第二天下午才抓到。还不如自己搭个方案:用Python的feedparser解析RSS,requests爬公开页面,数据延迟能控制在15分钟以内。工具钱省下来买服务器不香吗?

避坑清单

干这行十年,光播客提及检测这块,我踩过的坑够写本书了。挑几个最疼的说给你听,省得你重蹈覆辙。

坑1:白嫖免费工具做深度监测
去年我给一个理财站做优化,图省事用某免费工具抓播客提及。结果它只抓RSS头部摘要,漏了60%的正文提及。用户问“你们节目里咋不推我产品”,老板劈头盖脸骂我一顿。后果:品牌曝光评估偏差42%。做法:至少用Paid版ListenNotes(月费$99起),或者自建爬虫抓全量MP3元数据。

坑2:忽视AI引擎对播客结构的解析差异
我测试过Gemini和ChatGPT对同一段播客文案的抓取——Gemini能提取“嘉宾提到XXX”的上下文,ChatGPT只当普通文本。后果:同一条提及,在Claude里权重+0.3,在Bard里直接忽略。做法:优化音频时,在描述字段里用“播客嘉宾:@品牌名”这种结构化标签,别光堆关键词。

坑3:只盯文本转录,不管语音情感
博主的语气词“这个产品真的牛X”和“它还行吧”在转录里都是“这个产品不错”。我有个客户因为没区分情感,把负面提及当正面算,结果品牌公关策略跑偏。后果:负面舆情漏报率31%,公关成本多花了8万。做法:用AssemblyAI的情感分析API(阈值设0.6以上算积极),给每条提及打情感分。

坑4:检测周期设太短
我试过每15分钟扫一次播客更新,结果服务器带宽被吃光,还触发了反爬。后果:单日API消耗超$200,索引延迟反而从2小时涨到6小时。做法:竞争不激烈的长尾词,每天凌晨3点扫一次;热门词每6小时一次。别跟实时较劲,播客不是新闻。

坑5:忽略播客平台的评论提及
我优化一个旅游站时,发现Apple Podcasts评论里有人聊“上次XXX推荐的酒店不错”,但主体音频没提。后果:这条评论带来的长尾流量,我晚了三个月才抓到。做法:用RSS-to-PocketCasts或直接爬评论页URL,把评论文本也纳入检测池。

坑6:盲目用大模型做实体提取
我试过GPT-4批量解析播客文本,单条成本$0.03,但准确率只有74%。错把“张三的公司”识别成“张山公司”。后果:3000条音频多花了$90,还白费人工核对。做法:小数据集(<500条)用GPT-4;大数据量(>2000条)改用Llama 3微调模型,成本降到$0.005/条,准确率能到89%。

坑7:不设地理限制检测
我给一个本地火锅店做优化,结果抓到了四川播客里提“重庆火锅”的音频,完全跑偏。后果:无效提及占35%,浪费了2周的人力。做法:在爬虫里加geoip过滤(只抓IP归属地匹配城市),或者用播客分类ID过滤(如itunes:category)。