HtmlParser解析思路汇总
HTMLParser使用方式汇总(适用C# JAVA):
1. Lexer模式:
2. NodeFilter模式
3. NodeVisitor模式
-----------------------------------------涯上月灬指香专用分割线---------------------------------------------
1. HTMLParser解析的数据来源:
WebClient webclient = new WebClient();
String htmlContent = webclient.DownloadString("https://www.baidu.com/");
2. (Lexer模式)
使用依据: 该模式对整体数据负责,会返回一个线性的Node节点序列:
使用方式:
Lexer lexer = new Lexer(htmlContent);
Parser parser = new Parser();
parser.Lexer = lexer;
NodeList nodelist = parser.Parse(null); //开始解析,返回一个所有节点的线性序列
int size = nodelist.Size();
Console.WriteLine("扫描节点数:" + nodelist.Size());
for (int i = 0; i < size; i++)
{
INode node = nodelist.ElementAt(i);
Console.WriteLine(node.ToString());
}
Console.WriteLine("扫描结束");
3. (NodeFilter模式)
使用依据: 根据NodeFilter的要求过滤出符合要求的Node,只对结果负责
使用方式:
Parser parser = new Parser();
parser.InputHTML = htmlContent;
NodeList nodelist = parser.Parse(new NodeClassFilter(typeof(Winista.Text.HtmlParser.Tags.ImageTag))); //指定过滤出的标签为<Img>
for (int i = 0; i < nodelist.Size(); i++)
{
ImageTag node = (ImageTag)nodelist.ElementAt(i);
Console.WriteLine("href = {0}", node.ImageURL);
}
//如果没有你需要的过滤节点类型,可自定义节点过滤器
NodeList nodelist = parser.Parse(new CustomNodeFilter());
for (int i = 0; i < nodelist.Size(); i++)
{
INode node = nodelist.ElementAt(i);
Console.WriteLine(node.GetText());
}
class CustomNodeFilter : NodeFilter
{
public bool Accept(INode node) //自定义过滤器的条件
{
if(node is MetaTag)
{
MetaTag tag = (MetaTag)node;
if(tag.GetAttribute("title") != null)
{
return true;
}
}
return false;
}
}
Ps:
(继承树)
(Tags 类型图)
4. (NodeVisitor模式)
使用条件: 需要了解Parser解析过程,该模式对过程负责
使用方式:
Parser parser = new Parser();
parser.InputHTML = htmlContent;
parser.VisitAllNodesWith(new CustomNodeVIsitor());
class CustomNodeVIsitor: NodeVisitor
{
public override void BeginParsing() //当开始解析Html时回调
{
Console.WriteLine("开始解析Html页面");
}
public override void VisitTag(ITag tag) //当访问到一对标签的开始标签时回调 ,像<html>...</html> 中的<html>
{
Console.WriteLine("开始解析TAG" + tag.TagName);
}
public override void VisitEndTag(ITag tag) //当访问到一对标签的结束标签时回调, 像<html>...</html>中的</html>
{
Console.WriteLine("结束解析TAG" + tag.TagName);
}
public override void VisitStringNode(IText string_Renamed) //当访问到文本标签时回调, 像<div>我是内容</div>中的“我是内容”就是一个文本标签
{
Console.WriteLine("扫描到文本标签了");
}
public override void VisitRemarkNode(IRemark remark) //当访问到注释标签时,回调
{
Console.WriteLine("扫描到注释标签了");
}
}