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

Qt中QJsonArray数据量不稳定:请求返回非JSON内容排查

问题根源分析与解决建议

兄弟,我帮你捋捋这个问题的核心原因,结合你提到的C#测试发现部分请求返回HTML的情况,主要是这几点:

1. 接口的防爬/限流机制被触发

很多公开接口都会对高频、批量的请求做限制,你在短时间内遍历a-z的单字符+双字符组合发起请求,很容易被服务器判定为爬虫行为。这种情况下,服务器不会返回预期的JSON数据,而是返回HTML页面(比如人机验证页、限流提示页),但HTTP状态码还是200——这就导致reply->error()始终返回NoError(因为传输层面没出错),但内容完全不符合JSON格式,自然解析失败,对应请求的数据就没存入list,最终每次运行的元素数量不稳定(毕竟服务器的限流触发时机可能有随机性)。

2. JSON解析失败未被捕获处理

你大概率没对QJsonDocument::fromJson的结果做有效性校验。当传入HTML内容时,fromJson会返回一个无效的QJsonDocument(doc.isNull()为true),但如果你的代码没判断这个状态,直接跳过数据添加逻辑,那这部分请求的数据就丢失了。而且因为每次触发限流的请求数量不一样,所以list的元素数量每次都有差异。

3. 异步请求的并发/生命周期问题(次要可能)

如果你的Request函数是异步实现的,而main函数里循环发起请求时没做同步处理,可能导致部分请求的reply还没处理完,程序就已经继续执行后续逻辑,甚至提前退出,这也会导致部分数据没被正确存入list。不过你提到reply->error()都是NoError,这个可能性相对前两个要小,但也值得排查。


针对性解决建议

  • 给请求加间隔,降低触发限流的概率:在循环发起请求的地方,加入短延迟,比如:
    QThread::msleep(300); // 每次请求间隔300毫秒,可根据接口实际情况调整
    
  • 严格校验JSON解析结果:解析前先判断返回内容的有效性,示例代码:
    QByteArray data = reply->readAll();
    // 先粗略判断是否为JSON格式
    if (!data.startsWith('[') && !data.startsWith('{')) {
        qDebug() << "非JSON响应,查询串:" << queryStr;
        qDebug() << "响应内容片段:" << data.left(200);
        return;
    }
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isArray()) {
        qDebug() << "JSON解析失败,查询串:" << queryStr;
        return;
    }
    // 正常解析数组并存入list
    
  • 检查响应头的Content-Type:通过响应头判断是否是JSON,避免无效解析:
    QVariant contentType = reply->header(QNetworkRequest::ContentTypeHeader);
    if (!contentType.toString().contains("application/json")) {
        qDebug() << "响应类型不是JSON,跳过解析";
        return;
    }
    
  • 异步请求需确保全部处理完成:如果用异步请求,建议用QEventLoop等待每个请求完成,或者维护一个请求计数器,等所有请求都处理完再结束程序,避免数据丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:37:19