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

Dart中double.parse()抛出无效双精度异常的原因及解决方法

问题原因

double.parse 抛出异常触发崩溃,本质是传入的字符串经过逗号替换后,仍不符合Dart的double类型解析规则。爬取网页DOM拿到的价格文本普遍存在脏数据,仅替换逗号为小数点无法覆盖所有异常场景,常见触发场景包括:

  • 文本夹带货币符号、促销标签:如"€14,99"、"折扣价9,99",替换逗号后仍存在非数字类字符,直接解析报错
  • 千分位格式冲突:如"1,299.00"类带千分位逗号的价格,全量替换逗号为点会得到"1.299.00",出现多个小数点无法解析
  • 特殊空白字符:网页常携带不换行空格\xa0、零宽空格等特殊字符,普通trim()无法清除字符串中间夹杂的这类空白
  • 多价格拼接:同一个价格节点可能同时包含原价、折扣价两段文本,如"19,99 12,99",替换后为多段数字拼接格式,无法解析
  • 非数字占位:缺货、免费赠送的商品价格位置可能是"暂无库存"、"Free"这类纯文本,无有效数字
修复代码

不要直接使用double.parse处理外部爬取的不可靠数据,先做全量文本清洗,再用double.tryParse做容错,避免单条脏数据导致整个列表加载崩溃。

  1. 先实现通用价格清洗解析方法:
double? parseWebPrice(String rawText) {
  if (rawText.trim().isEmpty) return null;
  // 移除所有数字、逗号、小数点之外的字符(货币符号、文字、特殊空格全过滤)
  String cleaned = rawText.replaceAll(RegExp(r'[^0-9,.]'), '');

  // 区分千分位逗号和小数位逗号
  cleaned = cleaned.replaceAllMapped(RegExp(r',(\d{3})'), (match) {
    final remainStr = cleaned.substring(match.end);
    // 逗号后3位后没有其他数字分隔符,判定为千分位逗号,直接删除
    if (!remainStr.contains(RegExp(r'[,.]'))) {
      return match.group(1)!;
    }
    // 否则为小数分隔符,替换为点
    return '.${match.group(1)}';
  });

  // 处理多小数点异常,仅保留最后一个小数点作为小数分隔符
  if (cleaned.split('.').length > 2) {
    final parts = cleaned.split('.');
    cleaned = '${parts.sublist(0, parts.length - 1).join()}.${parts.last}';
  }

  return double.tryParse(cleaned);
}
  1. 替换原循环中的价格解析逻辑:
var content = parser.parse(doc);
var allBooks =
    content.querySelectorAll("div.facet__products div.prd-main-wrapper");
var prices = allBooks
    .map((e) => e.getElementsByClassName("prd-price")[0].text.trim())
    .toList();
 
for (int i = 0; i < allBooks.length; i++) {
  final price = parseWebPrice(prices[i]);
  // 解析失败时可根据业务需求给默认值,或打日志排查对应脏数据
  if (price == null) {
    print('价格解析异常,原始文本:${prices[i]}');
    continue;
  }
  var name = names[i].toString();
  var author = authors[i].toString();
  var img = imgs[i].toString();
  BookModel model = BookModel(name, author, img, price, "D.R");
  controller.books.add(model);
  print(allBooks);
}
调试建议
  • 定位具体异常值时,直接在解析前打印prices[i]的原始内容,可快速确认是哪类脏数据触发的问题
  • 如果你爬取的站点价格格式统一(比如仅用逗号做小数分隔符、无千分位规则),可以简化清洗逻辑,只保留过滤非数字字符的步骤即可
  • 所有来自网页爬取、用户输入的不可靠数据,做类型转换时优先用tryParse系列方法,不要直接用强转换方法,避免不必要的崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:21:28