我需要创建一个html解析器,给定一个博客网址,它会返回一个列表,其中包含页面中的所有帖子。
我无法使用其rss Feed,因为我需要确切了解用户的样子,如果它有任何广告,图片等,相比之下,某些博客只有其内容的摘要和Feed这一切,反之亦然。
无论如何,我已经制作了一个下载其Feed,并在html中搜索类似内容的内容,它对某些博客非常有效,但对其他博客则无效。
我认为我不能创建一个适用于它解析的100%博客的解析器,但我想尽可能做到最好。
最佳方法应该是什么?查找id属性等于“post”,“content”的标签?寻找p标签?等等等......
提前感谢您的帮助!
答案 0 :(得分:2)
我认为你不会在这方面取得成功。您可能能够解析一个博客,但如果博客引擎更改了内容,它将不再起作用。我也认为你不能写一个通用的解析器。你甚至可能部分成功,但这将是一个空灵的成功,因为在这种情况下一切都是如此容易出错。如果您需要内容,则应使用RSS。如果你需要存储(只是存储)它的外观,你也可以这样做。但按照它看起来的方式解析?我没有看到具体的成功。
答案 1 :(得分:1)
使用HTML Agility包。它是为此而制作的HTML解析器。
答案 2 :(得分:1)
“最好的可能”原来是“最合理的”,你可以定义什么是合理的。您可以通过查看常见的博客工具(WordPress,LiveJournal等)如何生成他们的页面以及专门针对每个博客的代码来获取大量博客。
一般情况是一个非常棘手的问题,因为每个博客工具都有自己的格式。您可以使用“标准”标识符(如“帖子”,“内容”等)来推断事物,但这是值得怀疑的。
您也会遇到广告问题。很多广告都是使用JavaScript生成的。因此,下载页面将只提供JavaScript代码而不是生成的HTML。如果您确实要识别广告,则必须确定生成广告的JavaScript代码。或者,您的程序必须执行JavaScript才能创建最终的DOM。然后你面临一个与上述类似的问题:弄清楚某些特定的HTML是否是一个广告。
有一些启发式方法有些成功。查看Identifying a Page's Primary Content以获取类似问题的答案。
答案 3 :(得分:0)
我刚刚为我们公司使用wordpress的博客做了类似的事情。这对我们有好处,因为我们的wordress博客多年来没有变化,但其他人都是正确的,如果你的html变化很大,解析就变成了一个麻烦的解决方案。
以下是我的建议:
使用Nuget安装RestSharp和HtmlAgilityPack。然后下载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; }
}
}
祝你好运,
埃里克