【问题标题】:Reading multiple Div's with HtmlAgilityPack使用 HtmlAgilityPack 读取多个 Div
【发布时间】:2014-02-05 15:44:58
【问题描述】:

我试图从 2 个不同的 Div 中提取数据,但我只能从第一个 Div(城市)中获取数据。我以 wiki 页面中的代码设置为例,其中所有 li 元素来自 H2 id = citiesid = Other_destinations:

var xpathData = "//h2[span/@id='Cities' or @id='Other_destinations']" + "/following-sibling::ul[1]" + "/li";

然后我将 li 中的任何内容写入文本文档。

private void button1_Click(object sender, EventArgs e)
    {

        List<string> destinations = new List<string>();
        var xpathData = "//h2[span/@id='Cities' or @id='Other destinations']" + "/following-sibling::ul[1]" + "/li";

        WebClient web = new WebClient();
        String html = web.DownloadString("http://wikitravel.org/en/Germany");

        hap.HtmlDocument doc = new hap.HtmlDocument();
        doc.LoadHtml(html);

        using (StreamWriter write = new StreamWriter(@"C:\path\testText.txt"))
        { 
            foreach (hap.HtmlNode node in doc.DocumentNode.SelectNodes(xpathData)) 
            {

            string all = node.InnerText;

            //Writes to text file
            write.WriteLine(all);
            }
        }

      }

关于 'hap' 的注释,由于一些奇怪的冲突,我不得不使用 hap = HtmlAgilityPack;

感谢任何帮助/建议/指导!

【问题讨论】:

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


    【解决方案1】:

    更新了一个可行的解决方案
    所以现在的问题是一些国家有奇怪的标记。大多数 Div 设置为:

    <h2>
    <span id="cities"></span>
    </h2>
    <ul>
    <li>...</li>
    <li>...</li>
    ...
    </ul>
    <h2>
    ...
    </h2>
    

    但是,当我在 cmets 中提到它只从 Other_destinations div 中提取第一个 li 时,发生的事情是当前脚本只查看第一个 ul,然后是 div 中的 li。所以那个特定国家页面上的标记是这样的:

    <h2>
    <span id="Other_destinations"></span>
    </h2>
    <ul>
    <li>...</li>
    <li>...</li>
    ...
    </ul>
    <h2>
    <span id="Get_in"></span>
    </h2>
    

    更新的工作代码

    var xpathData = "//ul[preceding-sibling::h2[span/@id='Cities' or span/@id='Other_destinations'] and following-sibling::h2[span/@id='Get_in']]" + "/li";
    

    此查询仅用于从上述 HTML 格式的网页中获取 2 部分信息。一个重要的注意事项是文本需要被编码,否则它将打印到带有'-'作为'-'的文本。我为 web 客户端添加了这个编码:

    var web = new WebClient();
    web.Encoding = System.Text.Encoding.UTF8;
    String html = string.Empty;
    html = //get URL's
    

    文档的编码如下:

    var doc = new hap.HtmlDocument
    {
        OptionDefaultStreamEncoding = Encoding.UTF8
    };
    
    doc.LoadHtml(html);
    

    【讨论】:

    • 你可以使用这样的东西:xpath="//div[@id='div']/child::ul/li",我推荐你阅读this,真的很有用。如果您有更多问题,请发布它以正确回答。希望对你有帮助
    • 哦,对不起。当我找到解决方案时,我打算重新格式化它。我尝试使用 child 但它只返回一个空文本文档。
    • 看,发布这个问题,让我知道在 cmets 中可以显示我的代码,因为这里我不能发布大代码
    • @Vkt0r 我已经提交了一个新问题here。谢谢。
    • 以上答案来自here
    【解决方案2】:

    您的原始代码中的第二个 id 输入错误:

    var xpathData = "//h2[span/@id='Cities' or span/@id='Other_destinations']" + "/following-sibling::ul[1]" +
                            "/li";
    

    这是我使用的代码:

    var destinations = new List<string>();
    var xpathData = "//h2[span/@id='Cities' or span/@id='Other_destinations']" + "/following-sibling::ul[1]" +
                            "/li";
    
    var webClient = new WebClient();
    var html = webClient.DownloadString("http://wikitravel.org/en/Germany");
    
    // to control the encoding 
    var doc = new HtmlDocument
    {
        OptionDefaultStreamEncoding = Encoding.UTF8
    };
    
    doc.LoadHtml(html);
    
    using (var write = new StreamWriter("testText.txt"))
    {
       foreach (var node in doc.DocumentNode.SelectNodes(xpathData))
       {
           var all = node.InnerText;
    
           //Writes to text file
           write.WriteLine(all);
       }
    
    }       
    

    【讨论】:

    • 不错的收获!不幸的是,它并没有完全解决问题。现在它只会出去并抓住 Div 中的第一个 li...
    • 我已经测试了你的代码并且在我的机器上运行良好。我将用我的代码编辑我的答案。请运行它。
    • 嗯,你是对的。这段代码确实工作得很好。我已经更改了这部分正在使用的代码,它只从“Other_destinations”Div 中获取第一个 li……一定是在其他地方绊倒了……谢谢。
    • 我认为问题出在 WikiTravel 代码格式上。再次感谢!
    • 你可以在WebClient中指定编码,如果你也想
    猜你喜欢
    • 2016-04-21
    • 2017-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2018-09-11
    相关资源
    最近更新 更多