• 利用WebBrowser类实现超长网页的截图


    在实际的工作中,有时我们需要对一些网页进行截图,一般的网页截图的代码如下(VB2010)

        Private Shared Function CaptureWeb(Settings As Object) As Object
            Dim _Settings As clsCaptureSettings = CType(Settings, clsCaptureSettings)
            Dim _Bmp As Bitmap = Nothing
    
            Using _Web As New WebBrowser
                _Web.ScrollBarsEnabled = False
                _Web.Width = _Settings.Width
    
                Dim _Time As Date = Now.AddSeconds(_Settings.TimeOut)
                _Web.Navigate(_Settings.Url)
    
                Do Until (_Web.ReadyState = WebBrowserReadyState.Complete) OrElse (Now > _Time)
                    Application.DoEvents()
                Loop
    
                _Web.Stop()
    
                If _Web.Document.Body Is Nothing Then
                    _Web.Height = 40
                Else
                    _Web.Height = _Web.Document.Body.ScrollRectangle.Height
                End If
    
                _Bmp = New Bitmap(_Web.Width, _Web.Height)
                Dim R As Rectangle = New Rectangle(0, 0, _Web.Width, _Web.Height)
                _Web.DrawToBitmap(_Bmp, R)
            End Using
            Return _Bmp
        End Function
    

    这段代码用到了辅助类clsCaptureSettings。这个类有3个字段:Url:要访问的网页的地址;Width:要截图的宽度,默认是1024;TimeOut:超时设置,默认是180秒;

    以上代码实现截图的关键就是两句话

    _Web.Height = _Web.Document.Body.ScrollRectangle.Height

    把WebBrowser的高度设置和网页高度一致

    _Web.DrawToBitmap(_Bmp, R)

    将WebBrowser类中的内容画到位图对象

    上面的代码经测试,会有如下的两个问题

    1、当WebBrowser的高度设置超过20000(是个约数,没有仔细测量过)时,DrawToBitmap方法会有一定几率失效,没法完成截图。而且,WebBrowser的高度越大,失效的几率越大。

    2、WebBrowser的高度也不是能无限设置的,其上限是65536,超过这个上限的时候,Webbrowser类会自动设置高度为65536,而当高度设置为65536时,DrawToBitmap方法失效的几率几乎是100%

    这样,上面的代码在截取超长网页的时候就会出现问题,几乎不能完成网页的截图。

    于是,需要改动代码。利用滚屏实现网页截图。

    实现滚屏的技术难点在于,一是如何通过代码滚动网页?通过查阅资料,用如下的代码即可。

    _Web.Document.Window.Parent.ScrollTo(X, Y)

    该代码将网页滚动到水平X,垂直Y的位置。

    二是,如何获得当前网页滚动的垂直位置?代码如下:

    _Web.Document.Body.Parent.ScrollTop

    因此,改进后的代码如下:

        Private Shared Function CaptureWeb(Settings As Object)As Object
            Dim
    _Settings As clsCaptureSettings = CType(Settings, clsCaptureSettings)
            Dim _Bmp As Bitmap =
    Nothing
            Dim
    i
    As Integer

            Const
    WEB_HEIGHT As Integer = 10000

            Using _Web As New
    WebBrowser
               
    _Web.ScrollBarsEnabled =
    False
               
    _Web.Width = _Settings.Width
                _Web.Height = WEB_HEIGHT

                Dim _Time As Date = Now.AddSeconds(_Settings.TimeOut)
                _Web.Navigate(_Settings.Url)

                Do Until (_Web.ReadyState = WebBrowserReadyState.Complete) OrElse (Now > _Time)
                    Application.DoEvents()
              
    Loop

               
    _Web.Stop()

                Dim _WebHeight
    As Integer
                If
    _Web.Document.Body
    Is Nothing Then
                   
    _WebHeight = 500
              
    Else
                   
    _WebHeight = _Web.Document.Body.ScrollRectangle.Height
              
    End If

               
    _Bmp = New Bitmap(_Web.Width, _WebHeight)
                Dim R As Rectangle = New Rectangle(0, 0, _Web.Width, WEB_HEIGHT)

                For i = 0 To _WebHeight - 1 Step WEB_HEIGHT
                    _Web.Document.Window.Parent.ScrollTo(0, i)
                    If _Web.Document.Body.Parent.ScrollTop = i
    Then
                       
    _Web.DrawToBitmap(_Bmp, R)
                        R.Offset(0, WEB_HEIGHT)
                  
    Else
                       
    R.Y = _Web.Document.Body.Parent.ScrollTop
                        _Web.DrawToBitmap(_Bmp, R)
                  
    End If
                Next

            End Using
            Return
    _Bmp
      
    End Function

    此改进后的代码相较之前的代码增加了滚动网页的代码,因此在截相同的网页的时候,效率会差点,但是可能截一些超长网页。

    什么地方会出线超长网页?很多大家不注意的地方,那就是论坛,一般论坛都是主题一个,每页的回复数是30个。这样,很容易整个网页的长度就超过65536了。用之前的代码是无法实现截图的,而用改进后的代码就可以实现这点。

  • 相关阅读:
    高并发的优化策略
    Linux Ctrl+c与ctrl+z的区别
    数据库连接池的工作原理
    JDBC数据库连接池原理
    JSP页面批量选择&全选操作&选择回显
    通过火狐谋智查询API
    通过console.log()打印window对象的属性、方法、事件
    制作 首页
    JavaScript 函数参数
    JavaScript 函数
  • 原文地址:https://www.cnblogs.com/grenet/p/2621482.html
Copyright © 2020-2023  润新知