C#递归算法在提取网页数据中的应用
临沂第一中学 邰思童
摘要:随着信息技术的迅速发展,互联网已成为社会、经济、文化、教育、娱乐等各个方面的重要组成部分。现代的人们越来越依赖互联网获取信息。但网络世界包罗万象,各种数据混杂一起,如何帮助我们避开不相关的信息干扰,正确提取出网页正文从中抽取我们需要的信息呢?本文介绍一种对常用网页文件的预处理方法,该方法能够通过解析网页文件的结构,从中提取出网页数据以供处理。并把这些抽取出的信息进行分类、整理等二次加工。对于Web数据清洗、文档自动摘要的形成以及文档分类等诸多领域的应用都是非常有意义的。此方法对HTML文件的解析不仅可以用于提取出HTML文件的主体文本,也可以用于得到HTML文件中其他的元素的内容。
关键词:C#递归算法;HTML 页面;HtmlAgilityPack;HttpWebRequest;
在互联网的世界中信息是通过Web网页形式呈现给我们的,为了获取到我们需要的信息资料,需要通过搜索引擎的帮助才能达到目的。近几年来,出现了多种基于Web的信息检索工
具,如比较出名的Google、Yahoo、百度等搜索引擎工具,这些工具的出现极大地方便了人们对信息的获取,能够解决我们部分问题,但由于它们都是基于字符串匹配和词义相似原理进行信息查询,因此得到的查询结果会很多,甚至包含了重复的内容。
    特别是我们在特定的网站并且已经知道网页格式的情况下,需要重复点击链接来获取资料时,本文的方法能起到很好的作用。
1 网页分析
1.1 HTML简介   
    浏览器加载并运行 HTML 页面时,会创建 DOM 树结构这个模型。并且 DOM 树结构模型会被存储在浏览器的内存中。
    DOM是Document Object Model文档对象模型的缩写。根据W3C DOM规范,DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面中其他的标准组件。
    简单理解,DOM解决了Netscape的JavaScript和 Microsoft的JavaScript之间的冲突,给
予web设计师和开发者一个标准的方法,让他们来访问他们站点中的数据、脚本和表现层对象。
    例如下面这段代码是一个简单的 HTML 页面源代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>示例页面</title>
    </head>
    <body>
    <h2>这是一个示例页面</h2>
    <p title="我是一个p标签">这是一个段落内容.</p>
    </body>
    </html>   
    DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中导航寻特定信息。
    分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树或基于对象的。
   
导航页源码    通过上面的 DOM 树结构,我们可以看到,Document 对象是作为 DOM 树结构的入口。再根据 DOM 树结构的特点,我们就可以定位到 HTML 页面中任意一个元素、属性或
文本内容。   
1.2 HtmlAgilityPack   
    HtmlAgilityPack是一个基于.Net的、第三方免费开源的微型类库,主要用于在服务器端解析html文档(在B/S结构的程序中客户端可以用Javascript、jquery解析html)。
    HtmlAgilityPack为网页提供了标准的DOM API和XPath导航。使用WebBrowser和HttpWebRequest下载的网页可以用Html Agility Pack来解析。
    请点击HtmlAgilityPack.1.4.0下载,解压后到HtmlAgilityPack.dll,把它添加到项目中。或者有安装Nuget的话,可以直接查安装即可。    下载后解压缩后有3个文件,这里只需要将其中的HtmlAgilityPack.dll(程序集)、l引入解决方案中即可使用。HtmlAgilityPack.dll中的类都位于HtmlAgilityPack命名空间。   
    HtmlDocument表示一个完整的HTML文档。用Load方法加载网页。
    HtmlAgilityPack中定位节点基本上都用Xpath表达式,例如:获取网页title:doc.DocumentNode.SelectSingleNode("//title").InnerText;
2 算法设计及实现
2.1 递归算法
    递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。
    一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数)。
    在编写递归调用的函数的时候,一定要把对简单情境的判断写在最前面,以保证函数调用在检查到简单情境的时候能够及时地中止递归,否则,你的函数可能会永不停息的在那里递归调用了。   
    利用HtmlAgilityPack分析网页指定的id,调用递归函数,查所有符合条件的a链接。
    public void GetUniversity(string parent, string value, string text)
    {
        stringnewurl = BoxA.Text + value;
        stringhtmlStr = GetHtmlStr(newurl, "UTF8");
        if (htmlStr != "")
        {
            HtmlAgilityPack.HtmlDocumenthtmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(htmlStr);
            HtmlNodetableNode = htmlDoc.DocumentNode.SelectSingleNode("//table[@id='YKTabCon2_10']");
            HtmlAgilityPack.HtmlDocumenthtmltable = new HtmlAgilityPack.HtmlDocument();
            htmltable.LoadHtml(tableNode.OuterHtml.Trim());
            textBoxD.Text = tableNode.OuterHtml.Trim();
            Application.DoEvents();
            HtmlNode div = htmltable.DocumentNode.SelectSingleNode("//div[@id='cnt1']");
            if (div != null)
            {
                HtmlAgilityPack.HtmlNodeCollectionhtmlNodes = div.SelectNodes("//ul/li/a");
                if (htmlNodes == null || htmlNodes.Count == 0)
                {
                    ListItemListItem = new ListItem(parent, value, text);
                    University.Add(ListItem);
                }
                else
                {
                    foreach (var node in htmlNodes)
                    {
                        string Value = node.Attributes["href"].Value;
                        string Text = node.InnerText.Trim();
                        GetUniversity(text, Value, Text);
                    }
                }
            }
            else
            {
                ListItemListItem = new ListItem(parent, value, text);
                University.Add(ListItem);
            }
        }
    }
2.2 获取网页
    C# 通常使用WebClient、WebBrowser或者HttpWebRequest/HttpWebResponse三种方法获取网页内容,本文使用WebRequest获取网页
    HttpWebRequest类主要利用HTTP 协议和服务器交互,通常是通过 GET 和 POST 两种方式来对数据进行获取和提交。
    WebRequest request = WebRequest.Create(url);          //实例化WebRequest对象
    WebResponse response = request.GetResponse();          //创建WebResponse对象
    Stream datastream = response.GetResponseStream();      //创建流对象
    Encoding ec = Encoding.Default;
    if (encoding == "UTF8")
    {
        ec = Encoding.UTF8;
    }
    else if (encoding == "Default")
    {
        ec = Encoding.Default;
    }
    StreamReader reader = new StreamReader(datastream, ec);
    htmlStr = reader.ReadToEnd();                          //读取数据
    reader.Close();
    datastream.Close();
    response.Close();
3 结束语
    通过本文提供的方法能初步获取到网页资料,在固定格式的网页结构和内容的情况下,能够准确地提取出HTML 文档的主题内容,是自动、可靠和通用的方法。本方法基于HTML规范,提取后的网页内容和结构与源网页一致,需要对数据进一步的分析整理后才能形成需要的数据格式。
参考书目:
[1]《这就是搜索引擎-核心技术详解》张俊林电子工业出版社
[2] 《搜索引擎技术基础》刘弈清华大学出版社

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。