You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web scraping长轮询场景下板球比分Telegram推送数据重复问题

板球比分重复推送问题诱因分析及解决方案

核心诱因

该问题并非仅由爬虫环节导致,竞态条件、前端请求逻辑、文件操作异常、源站数据波动都可能触发该问题,具体如下:

  • 并发竞态条件(最高概率):你的PHP代码对old_score.txt的读写没有加排他锁,且前端使用setInterval固定每1秒发送一次请求,不会等待上一次请求处理完成。如果出现上一次请求因爬虫抓取慢、Telegram接口响应慢延迟完成的情况,会出现多个PHP进程同时读取old_score.txt的场景:比如两个进程同时读取到旧值5 score,第一个进程抓取到新比分2 score推送完成后,还没来得及写入新值到文件,第二个进程如果刚好抓取到回退的5 score,就会触发第二次5 score的推送,同时覆盖已经写入的2 score。
  • 爬虫源站数据波动:板球官方网站可能存在临时比分修正的情况,比如记分员录入错误后短时间内回滚数据,你的爬虫刚好在数据波动的时间窗口抓取到了三次不同的比分,就会按照抓取顺序依次推送。此外如果源站CDN缓存异常,你请求时拿到了历史版本的页面,也会抓取到旧比分触发重复推送。
  • 文件写入失败:你的代码没有对file_put_contents的返回结果做校验,如果出现磁盘IO异常、文件权限不足的情况,新比分写入old_score.txt失败,下一次请求读取到的还是旧比分,只要此时抓取到的比分和历史推送过的比分一致,就会触发重复推送。
  • 请求重复触发:网络异常时浏览器会自动重试超时的GET请求,或者前端请求堆积时多个重复请求同时打到后端,都会放大并发竞态的问题,导致重复推送。

修复建议

  • 给old_score.txt的读写操作加flock排他锁,保证同一时间只有一个PHP进程可以操作该文件,避免竞态问题。
  • 把前端的setInterval改成setTimeout,每次Ajax请求完成(无论成功失败)后再间隔1秒发起下一次请求,避免请求堆积。
  • 增加file_put_contents的返回结果校验,写入失败时记录日志并重试,避免文件更新失败。
  • 增加比分防抖逻辑:连续两次爬虫请求拿到同一个新比分时,再触发推送,过滤源站临时的分数波动。

内容的提问来源于stack exchange,提问作者shakky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:09:00