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

如何用C#与Html Agility Pack解析网页表格并提取指定字段?

解决方案

兄弟,你碰到的doc里找不到目标表格的问题,多半是网站拦截了默认WebClient的请求(比如检查请求头里的User-Agent),返回的内容不是完整的页面。先把请求部分修复好,再用LINQ解析表格数据就没问题了。

1. 完善WebClient请求,拿到完整页面

默认的WebClient没设置模拟浏览器的请求头,很多网站会把它当成爬虫,返回简化甚至空白的内容。我们给它加上必要的请求头:

using System.Net;
using HtmlAgilityPack;

using (WebClient webClient = new WebClient())
{
    // 模拟Chrome浏览器的请求头,让网站认为是正常用户访问
    webClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
    webClient.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
    webClient.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.5");
    
    string page = webClient.DownloadString("http://www.freeproxylists.net/?c=&pt=&pr=HTTP&a%5B%5D=1&a%5B%5D=2&u=40");
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(page);
    
    // 接下来解析表格
}

2. 用LINQ解析表格为嵌套列表

这个网站的代理数据在class="DataGrid"的表格里,表头正好对应你需要的字段。我们用LINQ跳过表头行,提取每行的单元格内容:

// 定位目标表格
var targetTable = doc.DocumentNode.SelectSingleNode("//table[@class='DataGrid']");
if (targetTable == null)
{
    MessageBox.Show("没找到目标代理表格,请检查请求是否正常");
    return;
}

// 用LINQ将表格行转为嵌套列表
var proxyDataList = targetTable.SelectNodes(".//tr")
    .Skip(1) // 跳过第一行表头
    .Where(row => row.SelectNodes(".//td").Count >= 8) // 确保每行有足够的单元格,避免索引越界
    .Select(row => 
    {
        var cells = row.SelectNodes(".//td");
        return new List<string>
        {
            cells[0].InnerText.Trim(), // IP Address
            cells[1].InnerText.Trim(), // Port
            cells[2].InnerText.Trim(), // Protocol
            cells[3].InnerText.Trim(), // Anonymity
            cells[4].InnerText.Trim(), // Country
            cells[5].InnerText.Trim(), // Region
            cells[6].InnerText.Trim(), // City
            cells[7].InnerText.Trim()  // Uptime
        };
    })
    .ToList();

// 测试输出,验证数据是否正确
foreach (var proxy in proxyDataList)
{
    Console.WriteLine($"IP: {proxy[0]} | Port: {proxy[1]} | 匿名度: {proxy[3]}");
}

额外小贴士

  • 如果还是拿不到表格,那可能网站用了JS动态加载数据,这时候就得换Selenium这类工具模拟浏览器加载页面了。不过目前这个网站的第一页数据是静态的,加对请求头就能解决。
  • 别频繁请求网站,容易被封IP,记得加个请求间隔。
  • 其实用实体类存储数据比嵌套列表更方便维护,比如定义个ProxyInfo类:
public class ProxyInfo
{
    public string IpAddress { get; set; }
    public string Port { get; set; }
    public string Protocol { get; set; }
    public string Anonymity { get; set; }
    public string Country { get; set; }
    public string Region { get; set; }
    public string City { get; set; }
    public string Uptime { get; set; }
}

然后LINQ里返回new ProxyInfo { IpAddress = cells[0].InnerText.Trim(), ... },代码可读性会高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:07:43