C#如何通过GET请求获取含目录的维基百科页面提取浮点数输出JSON
C# 获取维基百科完整页面提取浮点数输出JSON实现方案
依赖准备
不需要引入过多冗余第三方包,仅需安装1个HTML解析组件即可:
- 通过NuGet安装
HtmlAgilityPack,用于解析HTML结构 - JSON序列化直接使用.NET内置的
System.Text.Json,无需额外依赖 - HTTP请求使用.NET内置的
HttpClient完成网络通信
核心实现逻辑
1. 发起HTTP请求获取完整页面
必须配置合法请求头,否则会被反爬规则拦截,直接请求目标页面的桌面版地址即可拿到包含目录、数学公式、特殊符号的完整HTML源码,无需调用片段类接口:
- 设置通用User-Agent,标注请求为个人学习用途
- 设置Accept头为
text/html,优先返回完整桌面版页面 - 响应内容自动解码,保留所有特殊字符、公式标签结构
核心代码片段:
// 全局复用HttpClient,避免端口耗尽 private static readonly HttpClient _httpClient = new HttpClient(); // 初始化请求头 _httpClient.DefaultRequestHeaders.Add("User-Agent", "CsharpPractice/1.0 (personal learning use)"); _httpClient.DefaultRequestHeaders.Accept.ParseAdd("text/html"); // 发起GET请求,替换为目标维基百科页面地址 var response = await _httpClient.GetAsync("https://<维基百科站点域名>/wiki/<目标页面条目名>"); response.EnsureSuccessStatusCode(); // 拿到完整HTML内容,包含目录、MathML公式、特殊符号等全部元素 string fullHtml = await response.Content.ReadAsStringAsync();
2. 解析HTML提取所有浮点数
加载完整HTML后,排除脚本、样式等非内容标签,遍历所有文本节点,通过正则匹配浮点数,覆盖正文、目录、公式注释、表格等所有位置的数值:
- 浮点数匹配正则使用
[-+]?\d+\.\d+([eE][-+]?\d+)?,可匹配普通小数、带正负号的小数、科学计数法格式的浮点数 - 自动跳过script、style、noscript等非用户可见内容标签
- 数学公式无论是MathML结构、LaTeX文本还是图片alt属性内容,都会被文本遍历逻辑覆盖,不会遗漏其中的浮点数
核心代码片段:
var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(fullHtml); // 移除不需要解析的非内容节点 htmlDoc.DocumentNode.Descendants() .Where(n => n.Name == "script" || n.Name == "style" || n.Name == "noscript") .ToList() .ForEach(n => n.Remove()); var floatResults = new List<double>(); const string floatPattern = @"[-+]?\d+\.\d+([eE][-+]?\d+)?"; var regex = new Regex(floatPattern, RegexOptions.Compiled); // 遍历所有文本节点匹配浮点数 foreach (var textNode in htmlDoc.DocumentNode.Descendants().Where(n => n.NodeType == HtmlNodeType.Text)) { var matches = regex.Matches(textNode.InnerText); foreach (Match match in matches) { if (double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double num)) { floatResults.Add(num); } } }
3. 序列化输出JSON
将提取结果整理为结构化对象,序列化为JSON格式输出即可,可选择输出到控制台或本地文件:
var output = new { PageTitle = htmlDoc.DocumentNode.SelectSingleNode("//title")?.InnerText ?? "Unknown", ExtractTime = DateTime.Now, FloatCount = floatResults.Count, FloatValues = floatResults }; // 序列化为格式化的JSON string jsonResult = JsonSerializer.Serialize(output, new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping // 避免特殊符号被转义为乱码 }); // 输出到控制台 Console.WriteLine(jsonResult); // 如需输出到文件,调用File.WriteAllText写入即可
注意事项
- 不要高频发起请求,遵守站点访问频率限制,练习场景下单次请求间隔不低于1秒即可
- 浮点数匹配规则可根据实际需求调整,比如增加千分位支持、调整科学计数法匹配范围
- 页面内的特殊符号、数学公式标签会完整保留在获取到的HTML源码中,如果需要后续单独处理公式,可直接通过对应CSS类名选择节点
- 不要使用移动端页面地址请求,否则会丢失完整目录结构
内容的提问来源于stack exchange,提问作者S Z
相关产品推荐
相关产品推荐

