为表数据解析格式错误的HTML

时间:2014-10-02 22:29:39

标签: c# regex parsing

我正在编写一个c#控制台应用程序来从外部html网页检索表信息。

Example web page:(chessnuts.org)

我想提取<td>datamatchopponent等所有result条记录 - 上面示例链接中的23行。

我无法控制此网页,遗憾的是格式不正确,因此我尝试的选项就像HtmlAgilityPackXML解析完全失败一样。我也为RegEx尝试过一个号码,但我对此的了解非常差,我在下面尝试了一个例子:

string[] trs = Regex.Matches(html, 
                             @"<tr[^>]*>(?<content>.*)</tr>", 
                             RegexOptions.Multiline)
                    .Cast<Match>()
                    .Select(t => t.Groups["content"].Value)
                    .ToArray();

这会返回所有<tr>的完整列表(包含我不需要的许多记录),但我无法从中获取数据。

更新

以下是我尝试使用HtmlAgilityPack的示例:

 HtmlDocument doc = new HtmlDocument();

        doc.LoadHtml(html);
        foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
        {

            foreach (HtmlNode row in table.SelectNodes("tr"))
            {
                foreach (HtmlNode cell in row.SelectNodes("td"))
                {
                    Console.WriteLine(cell.InnerText);
                }
            }
        } 

2 个答案:

答案 0 :(得分:1)

我认为您只需要修复HtmlAgilityPack次尝试。这对我来说很好:

// Skip the first table on that page so we just get results
foreach (var table in doc.DocumentNode.SelectNodes("//table").Skip(1).Take(1)) {
    foreach (var td in table.SelectNodes("//td")) {
        Console.WriteLine(td.InnerText);
    }
}

这会将结果表中的一堆数据(每行一列)转储到控制台。

答案 1 :(得分:0)

如果你想要一个完整的程序:)。我找了好几个小时。

类ReadHTML     {

    internal void ReadText()
    {
        try
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.RootFolder = Environment.SpecialFolder.MyComputer;//This causes the folder to begin at the root folder or your documents
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                string[] files = Directory.GetFiles(fbd.SelectedPath, "*.html", SearchOption.AllDirectories);//change this to specify file type
                SaveFileDialog sfd = new SaveFileDialog();// Create save the CSV
                //sfd.Filter = "Text File|*.txt";// filters for text files only
                sfd.FileName = "Html Output.txt";
                sfd.Title = "Save Text File";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    string path = sfd.FileName;
                    using (StreamWriter bw = new StreamWriter(File.Create(path)))
                    {
                        foreach (string f in files)
                        {

                            var html = new HtmlAgilityPack.HtmlDocument();
                            html.Load(f);
                            foreach (var table in html.DocumentNode.SelectNodes("//table").Skip(1).Take(1))//specify which tag your looking for
                            {
                                foreach (var td in table.SelectNodes("//td"))// this is the sub tag
                                {
                                    bw.WriteLine(td.InnerText);// this will make a text fill of what you are looking for in the HTML files
                                }
                            }

                        }//ends loop of files

                        bw.Flush();
                        bw.Close();
                    }
                }
                MessageBox.Show("Files found: " + files.Count<string>().ToString());
            }
        }

        catch (UnauthorizedAccessException UAEx)
        {
            MessageBox.Show(UAEx.Message);
        }
        catch (PathTooLongException PathEx)
        {
            MessageBox.Show(PathEx.Message);
        }
    }//method ends
}