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
相关产品推荐
相关产品推荐

