zoukankan      html  css  js  c++  java
  • 基于HSharp 使用C#反序列化HTML并获取HTML中的特定内容

    最近有一个项目,要把别人网站上一些数据扒下来。(其实就是一个查课表)

    通过HTTP GET得到网页HTML源码倒是不难……难点在于这个网页内容非常混乱,有的时候格式都会发生变化。

    我最开始用Python做,可以直接把网页建立Dom。最简单的方法还是用jQuery,轻轻松松就可以把网站上的特定内容处理掉。

    但这个项目是用ASP.Net结合C#语言做的。我找了很多方案,都很费劲。

    下面这几个方案都是挺费劲的示例……告诉大家不要学啊

    方案一:根据网站建立对应的类。然后过XML反序列化

    这个方法很作死,首先建立对应的类就够建一整天的。坑爹在C#是强类型的语言。没法直接对着这个对象操作。只能先建立类。

    好像有一些库可以让这个过程稍微舒服点。比如xpath。

    方案二:自己用String的substring和正则表达式这些处理HTML

    这样写确实可行。但我写的正则表达式和Substring实在太难维护了。代码丑陋不堪,效率低下,还经常神之Exception。

    一个比较高效的方案

    最后我还是找到了一个比较可行的方法。大概方法是用到了一个叫做HSharp的库。用来以一种弱类型语言的处理方式来应用在C#,处理HTML。

    HSharp在Github上的主页:https://github.com/Obisoft2017/HSharp

    看上去还是蛮不错的。开源免费,源码也很短。

    类似的库也有HTMLagility。那个要复杂不少。C#自带一个Document,那个比较官方,但依赖WebBrowser对象,而且……速度慢的一笔。

    我主要用它进行HTML“反序列化”了。

    (严格意义上它的工作方式不是强类型的反序列化,而是把各个标签都塞进了字典里。起码这样还是可以查询了)

    首先在VS的PM里执行命令:

    1 Install-Package Obisoft.HSharp 

    然后直接使用它的HtmlConvert.DeserializeHtml方法来反序列化HTML。官网的示例都挺清楚。

    using Obisoft.HSharp.Models;
    using System;
    
    namespace Obisoft.HSharp
    {
        class Example
        {
            public static void Main(string[] args)
            {
                var NewDocument = HtmlConvert.DeserializeHtml($@"
    <html>
    <head>
        <meta charset={""utf-8""}>
        <meta name={""viewport""}>
        <title>Example</title>
    </head>
    <body>
        Some Text
        <table>
            <tr>OneLine</tr>
            <tr>TwoLines</tr>
            <tr>ThreeLines</tr>
        </table>
        Other Text
    </body>
    </html>");
                Console.WriteLine(NewDocument["html"]["head"]["meta",0].Properties["charset"]);
                Console.WriteLine(NewDocument["html"]["head"]["meta",1].Properties["name"]);
                foreach (var Line in NewDocument["html"]["body"]["table"])
                {
                    Console.WriteLine(Line.Son);
                }
        }
    }

    在上面代码中,反序列化了HTML,并对这段HTML的两个meta的charset和name属性值进行了打印。然后遍历了table的所有元素,打印了元素的内容。

    输出结果:

    utf-8
    viewport
    OneLine
    TwoLines
    ThreeLines
    

    回到项目

    我试了试反序列化一个真实的网站。这里拿Obisoft的主页举例子吧。他们的网站属于很复杂很复杂的了。

    这里假想要获取他们网站中随意一个数值。这里我获取一下他页面上一个普通数字:

    仔细检查他们代码后,这个数字出现在第5个section标签下面N重div的迭代里的一个span里。编写代码:

                var WebSiteResult = HtmlConvert.DeserializeHtml(new Uri("http://www.obisoft.com.cn/"));
                Console.WriteLine(NeuAaoResult["html"]["body"]["section", 5]["div"]["div"]["div"]["div"]["div"]["div", 2]["span"].Son);

    果然,程序成功输出了10. 速度还是挺快的。

    考虑到这个库确实挺好用而且足够强大。准备研究研究,去写一些接口。它好像还有挺多方法,应该也可以构建HTML。

  • 相关阅读:
    VysorPro助手
    Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
    Play 2D games on Nexus 6P running Android N7.1.1 with Daydream View VR headset
    Native SBS for Android
    ADB和Fastboot最新版的谷歌官方下载链接
    How do I install Daydream on my phone?
    Daydream Controller手柄数据的解析
    蓝牙BLE传输性能及延迟分析
    VR(虚拟现实)开发资源汇总
    Android(Java)控制GPIO的方法及耗时分析
  • 原文地址:https://www.cnblogs.com/mma2017/p/MMA.html
Copyright © 2011-2022 走看看