【问题标题】:HTMLAgilityPack and XPath TargetHTMLAgilityPack 和 XPath 目标
【发布时间】:2016-04-20 09:43:22
【问题描述】:

我有以下 HTML:

<table>
    <tr>
        <td><a href="#">Tournament Name</a>
            <br /> Tournament Address </td>
    </tr>

    <tr>
        <td><a>View Available Space and Book Online</a></td>
    </tr>

    <tr>
        <td>
            <em>Event Cost:</em> $$$
        </td>

        <td> Date and Time </td>
    </tr>

    <tr>

        <td>
            <p>
                <strong>
                    <img title="Boy's Teams can enter this tournament" />
                    <img  title="Girl's Teams can not enter this tournament" />
                    <img  title="Disabled Teams can not enter this tournament" />
                </strong>
            </p>
        </td>

        <td>
            TimeFrame
        </td>

    </tr>

     <tr>
       <td>
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image.gif" />
            <img src="image...." />
            <img src="image...." />
            <img src="image...." />
            <img src="image...." />
        </td>
    </tr>
</table>

(这个表格在页面上重复了很多次)。

我正在尝试提取锦标赛名称。

我有以下 C# 代码:

namespace AcademyScraper
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }


        private void saveBtn_Click(object sender, EventArgs e)
        {

            string url = "http://www.reddishvulcans.com/uk_tournament_database.asp";
            var Webget = new HtmlWeb();
            var doc = Webget.Load(url);

            var root = doc.DocumentNode;
            var nodes = root.Descendants();

            HtmlNodeCollection tableCollection = doc.DocumentNode.SelectNodes("//div[@class='infobox']/table");

            for (Int32 i = 0; i < tableCollection.Count(); i++)
            {
            HtmlNode tournamentName = tableCollection[i].SelectSingleNode("/tr[1]/td/a");

            MessageBox.Show(tournamentName.InnerText);
            // I get an exception here

            }

        }


    }
}

我遇到的问题是,无论我尝试什么,我似乎都无法定位包含锦标赛名称的标签。如果我这样做MessageBox.Show(tableCollection[i].OuterHTML);,表格内容将在消息框中很好地呈现,没有任何问题。但是,每当我尝试获取锦标赛名称时,都会出现参考异常。基于HTML我认为应该是对的。

【问题讨论】:

    标签: c# xpath web-scraping html-agility-pack


    【解决方案1】:

    也许你可以尝试这样的事情(我创建了一个控制台应用来尝试):

     private void saveBtn_Click(object sender, EventArgs e)
        {
    
            string url = "http://www.reddishvulcans.com/uk_tournament_database.asp";
            var Webget = new HtmlWeb();
            var doc = Webget.Load(url);
            var aTags = doc.DocumentNode.SelectNodes("//div[@class='infobox']/table/tr/td[1]/a");
    
            foreach (var tag in aTags)
            {
                Console.WriteLine(tag.InnerText);
            }
    
            Console.ReadLine();
        }
    

    【讨论】:

      【解决方案2】:

      以下 XPath 似乎适合我:

      //div[@class='infobox']/table/tr/td[br]/a
      

      控制台应用演示:

      string url = "http://www.reddishvulcans.com/uk_tournament_database.asp";
      var Webget = new HtmlWeb();
      var doc = Webget.Load(url);
      
      //print top 10 result just for the sake of demo
      var result = doc.DocumentNode
                      .SelectNodes("//div[@class='infobox']/table/tr/td[br]/a")
                      .Take(10);
      foreach (HtmlNode node in result)
      {
          Console.WriteLine(node.InnerText);
      }
      

      输出:

      The North West Junior Champions League 2016
      PLAY AT CHELSEA - STAMFORD BRIDGE FOOTBALL TOURNAMENT 2016
      PLAY AT FC BARCELONA -  CAMP NOU FOOTBALL TOUR 2016 - THE EUROPA CUP
      Silverdale Soccersevens XIX
      NORTH HALIFAX MINI SOCCER TOURNAMENT 2016
      Halton & District JFL Mini Soccer Tournament
      Colwyn Bay FC Junior Tournament
      GMCJFC Pat Mangan Festival of Football 2016
      Fred England Trophy
      Fred England Trophy
      

      【讨论】:

        【解决方案3】:

        你有一个与网络var doc = Webget.Load(url); 合作的任务,它可以做一些时间,但你在main thread -> 冲突中得到了它。您需要在其他线程中运行网络任务。注意MessageBox.Show(tournamentName.InnerText); 是 UI 线程(主线程),您应该在 INVOKE 委托中运行它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-22
          • 2013-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多