Html解析器获取博客文章

本文关键字:文章 获取 Html | 更新日期: 2023-09-27 17:50:23

我需要创建一个html解析器,给定一个博客url,它返回一个列表,其中包含页面中的所有帖子。

  • 。如果一个页面有10个帖子,那么它应该返回一个包含10个div的列表,其中每个div包含h1 p

我不能使用它的rss提要,因为我需要确切地知道它对用户来说是什么样子的,如果它有任何广告,图像等,相比之下,一些博客只有其内容的摘要,而提要则有所有内容,反之亦然。

无论如何,我已经做了一个下载它的提要,并搜索类似的内容的html,它工作得很好,对一些博客,但不是对其他的。

我不认为我能使一个解析器对它所解析的博客100%有效,但我想尽可能做到最好。

最好的方法是什么?寻找标签,它的id属性等于"post","content"?寻找p标签?等等等等等等……

提前感谢您的帮助!

Html解析器获取博客文章

我认为你在这方面不会成功。您可能能够解析一个博客,但如果博客引擎更改了内容,它就不能再工作了。我也不认为您能够编写一个通用解析器。您甚至可能获得部分成功,但这将是一种虚无缥缈的成功,因为在这种情况下,一切都很容易出错。如果你需要内容,你应该选择RSS。如果您需要存储(只是存储)它的外观,您也可以这样做。但是通过它的外观来解析呢?我没看到具体的成功。

"Best possible"变成了"Best reasonable ",你可以定义什么是合理的。通过查看常见的博客工具(WordPress, LiveJournal等)如何生成页面,以及为每个页面专门编写的代码,你可以获得大量的博客。

一般情况是一个非常困难的问题,因为每个博客工具都有自己的格式。你也许可以使用"标准"标识符,如"post"、"content"等来推断事情,但这是值得怀疑的。

你在广告上也会遇到困难。很多广告都是用JavaScript生成的。因此,下载页面将只提供JavaScript代码,而不是生成的HTML。如果您真的想要识别广告,就必须识别生成广告的JavaScript代码。或者,您的程序将不得不执行JavaScript来创建最终的DOM。然后你就会面临一个类似于上面的问题:弄清楚某些特定的HTML是不是广告。

有些启发式方法是比较成功的。关于类似问题的答案,请查看识别页面's Primary Content。

使用HTML敏捷包。

我刚刚为我们公司使用wordpress的博客做了这样的事情。这对我们来说很好,因为我们的wordress博客已经好几年没变了,但是其他人是对的,如果你的html变化很大,解析就变成了一个麻烦的解决方案。

以下是我的建议:

使用Nuget安装RestSharp和htmllagilitypack。然后下载fizzler并将这些引用包含在您的项目中(http://code.google.com/p/fizzler/downloads/list)。

下面是我用来在我的网站上实现博客搜索的一些示例代码。

using System;
using System.Collections.Generic;
using Fizzler.Systems.HtmlAgilityPack;
using RestSharp;
using RestSharp.Contrib;
namespace BlogSearch
{
    public class BlogSearcher
    {
        const string Site = "http://yourblog.com";
        public static List<SearchResult> Get(string searchTerms, int count=10)
        {            
            var searchResults = new List<SearchResult>();
            var client = new RestSharp.RestClient(Site);
            //note 10 is the page size for the search results
            var pages = (int)Math.Ceiling((double)count/10);
            for (int page = 1; page <= pages; page++)
            {
                var request = new RestSharp.RestRequest
                                  {
                                      Method = Method.GET,
                                      //the part after .com/
                                      Resource = "page/" + page
                                  };
                //Your search params here
                request.AddParameter("s", HttpUtility.UrlEncode(searchTerms));
                var res = client.Execute(request);
                searchResults.AddRange(ParseHtml(res.Content));
            }
            return searchResults;
        }
        public static List<SearchResult> ParseHtml(string html)
        {            
            var doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);
            var results = doc.DocumentNode.QuerySelectorAll("#content-main > div");
            var searchResults = new List<SearchResult>();
            foreach(var node in results)
            {
                bool add = false;
                var sr = new SearchResult();
                var a = node.QuerySelector(".posttitle > h2 > a");
                if (a != null)
                {
                    add = true;
                    sr.Title = a.InnerText;
                    sr.Link = a.Attributes["href"].Value;
                }
                var p = node.QuerySelector(".entry > p");
                if (p != null)
                {
                    add = true;
                    sr.Exceprt = p.InnerText;
                }
                if(add)
                    searchResults.Add(sr);
            }
            return searchResults;
        }

    }
    public class SearchResult
    {
        public string Title { get; set; }
        public string Link { get; set; }
        public string Exceprt { get; set; }
    }
}

祝你好运,Eric