利用Webbrowser类实现超长网页的截屏的实现Word文档下载推荐.docx
- 文档编号:19852357
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:15
- 大小:20.99KB
利用Webbrowser类实现超长网页的截屏的实现Word文档下载推荐.docx
《利用Webbrowser类实现超长网页的截屏的实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《利用Webbrowser类实现超长网页的截屏的实现Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
在日后浏览的时候,如果是在一台没有联网的机器上,会出现两种情况。
一是:
由于保存了链接地址,于是会尝试读取这些地址,而这些地址又没法读取(没联网或者是链接地址失效),则会导致长时间的假死状态(尤其以IE保存的网页为甚);
二是:
由于缺失部分的文件(swf文件、CSS文件、JS文件等),导致页面的结构出现了变形(甚至是无法忍受的地步)。
这也就是为什么要截图的原因,图是静止的,不会出现上述的情况
还是要截图的,截超长网页的图的一种办法就是分开截图,截成若干个图
于是把之前的代码改写一下,把原来多次截图,后覆写到一张图片,改写为多次截图,把多个bitmap对象存入到一个对象
于是信心满满的尝试文章开始的网址,天啊,还是报错
在截超长网页的时候,在截60000+这部分的时候,Webbrowser类的DrawToBitmap函数就会报错,说是无效的参数。
无效的参数?
没道理呀,若是参数无效,在截0+和20000+的时候就会报错,怎么会到60000+的时候报错呢?
而且是每次到60000+都会报错,排除了系统随机性错误的问题(有时在截一些网页的时候,也会报参数无效的错误,但是重启软件后,就不会报错)
突然有一个想法,会不会是Webbrowser类的DrawToBitmap方法有资源没有释放,在同一个Webbrowser的实例中的DrawToBitmap方法执行完后,没有释放资源,所以当上面的代码尝试截取60000+的时候,超过了DrawToBitmap方法的资源限制,于是报了错误。
如果能尝试释放DrawToBitmap方法所占的资源是不是就可以呢?
在网上找了一圈后,没有发现释放DrawToBitmap方法所占的资源的问题。
这真是一个超级难题了。
有一个笨办法涌上心头。
一个Webbrowser实例不能解决超长网页的截图问题,多个Webbrowser实例能不能解决该问题呢?
将一个网页分成几个部分,每个部分分给一个Webbrowser实例去截图,最后将这些截图再存入到一个对象。
这样做的优点是:
如果成功,解决了超长网页的截图问题;
缺点是:
每个部分都分给一个Webbrowser类的实例去截图,每个实例都需要访问同一个网址,造成了重复访问,形成了资源浪费。
不过,目前最重要的是实现超长网页的截图。
于是,修改代码。
进行截图实验。
嗯。
这样终于成功了。
下面是修改后代码。
由于功能上的需要,我对代码进行了扩展
PublicClassclsCaptureWebSettings
PublicUrlAsString
PublicTimeOutAsInteger
PublicWidthAsInteger
PublicDelayAsInteger
PublicHtmlElementID()AsString={}
PublicSubNew(UrlAsString,OptionalDelayAsInteger=15,OptionalTimeOutAsInteger=180,OptionalWidthAsInteger=1024)
Me.Url=Url
Me.TimeOut=TimeOut
Me.Width=Width
Me.Delay=Delay
Me.HtmlElementID={}
EndSub
PublicSubNew(UrlAsString,IDAsString,OptionalDelayAsInteger=15,OptionalTimeOutAsInteger=180,OptionalWidthAsInteger=1024)
DimtS(0)AsString
tS(0)=ID
Me.HtmlElementID=tS
PublicSubNew(UrlAsString,ID()AsString,OptionalDelayAsInteger=15,OptionalTimeOutAsInteger=180,OptionalWidthAsInteger=1024)
Me.HtmlElementID=ID
EndClass
clsCaptureWebSettings类,截取网页的参数类,有如下的几个参数:
URL
网页截图的网址。
注:
有些网页要提供Cookies或者是Session才能访问,这部分目前还没有做到。
Delay
网页截图的延迟。
由于有部分网页会利用AJAX技术填充内容,而Webbrowser类又不能很好的判断AJAX技术的结束时刻,故统一一个延迟时间,等延迟时间结束以后再截图。
默认是15秒。
由于有的超长网页会交给几个Webbrowser类截图,每个Webbrowser类的延迟时间都是由Delay决定的,故在截超长网页的时候,会显得比较漫长,但是用了Delay参数以后,截图的效果好了很多。
TimeOut
网页截图的超时。
在访问某些网站的时候,由于种种原因,导致访问失败。
设置这个参数避免在访问失败的时候,程序陷入假死情况。
默认是180秒
Width
网页截图的宽度。
由于网页的布局都是竖式布局,故先指定宽度,再截图。
默认是1024,现今的网页基本上都兼容1024的宽度
HtmlElementID
网页截图中的目标ID。
我们在截网页的时候,有时特别想只截其中的一部分(例如,不想截取包含广告的部分),我们可以提供网页上的元素的ID,返回该元素在网页上的位置(Rectangle结构)。
该参数是字符串的数组,数组中每个元素就是网页上元素的ID。
注意:
程序中只返回能找到的元素的位置,如果没有找到,则直接忽略掉
PublicClassclsCaptureImages
Private_BmpAsList(OfBitmap)
Private_RectAsDictionary(OfString,Rectangle)
Private_HeightPerImageAsInteger
PublicSubNew()
Me.New(20000)
PublicSubNew(HeightPerImageAsInteger)
_HeightPerImage=HeightPerImage
_Bmp=NewList(OfBitmap)
_Rect=NewDictionary(OfString,Rectangle)
PublicSubAddBitmap(BmpAsBitmap)
_Bmp.Add(Bmp)
PublicSubAddRect(IDAsString,RAsRectangle)
If_Rect.ContainsKey(ID)=TrueThen
_Rect(ID)=R
Else
_Rect.Add(ID,R)
EndIf
PublicFunctionImageRect()AsRectangle
If_Bmp.Count=0ThenReturnNewRectangle(0,0,0,0)
DimWidthAsInteger=_Bmp(0).Width
DimHeightAsInteger=_HeightPerImage*(_Bmp.Count-1)+_Bmp(_Bmp.Count-1).Height
ReturnNewRectangle(0,0,Width,Height)
EndFunction
PrivateFunctionGetRectImage(RAsRectangle)AsBitmap
DimtBAsNewBitmap(R.Width,R.Height)
UsingtGAsGraphics=Graphics.FromImage(tB)
DimIAsInteger=Int(R.Y/_Bmp(0).Height)
DimJAsInteger=Int((R.Bottom-1)/_Bmp(0).Height)
DimKAsInteger
IfI=JThen
R.Y=R.YMod_Bmp(0).Height
tG.DrawImage(_Bmp(I),0,0,R,GraphicsUnit.Pixel)
DimtRAsRectangle=R
tR.Y=tR.YMod_Bmp(0).Height
tR.Height=_Bmp(0).Height-tR.Y
tG.DrawImage(_Bmp(I),0,0,tR,GraphicsUnit.Pixel)
DimtTopAsInteger=tR.Height
ForK=I+1ToJ-1Step1
tR=R
tR.Y=0
tR.Height=_Bmp(0).Height
tG.DrawImage(_Bmp(K),0,tTop,tR,GraphicsUnit.Pixel)
tTop+=tR.Height
Next
tR.Height=(tR.Bottom-1)Mod_Bmp(0).Height+1
tG.DrawImage(_Bmp(J),0,tTop,tR,GraphicsUnit.Pixel)
EndUsing
ReturntB
PublicFunctionRenderImage(RAsRectangle,HeightPerImageAsInteger)AsList(OfBitmap)
DimtRAsRectangle=ImageRect()
If_Bmp.Count=0OrElseR.IntersectsWith(tR)=FalseThenReturnNewList(OfBitmap)
R.Intersect(tR)
IfR.Equals(tR)=TrueAndAlsoHeightPerImage=_HeightPerImageThenReturn_Bmp
ReturnRenderImageBase(R,HeightPerImage)
PublicFunctionRenderImage(RAsRectangle)AsList(OfBitmap)
ReturnRenderImage(R,_HeightPerImage)
PublicFunctionRenderImage(HeightPerImageAsInteger)AsList(OfBitmap)
If_Bmp.Count=0ThenReturnNewList(OfBitmap)
IfHeightPerImage=_HeightPerImageThenReturn_Bmp
ReturnRenderImageBase(ImageRect,HeightPerImage)
PublicFunctionRenderImage()AsList(OfBitmap)
Return_Bmp
PrivateFunctionRenderImageBase(RAsRectangle,HeightPerImageAsInteger)AsList(OfBitmap)
tR.Height=HeightPerImage
DimBmpListAsNewList(OfBitmap)
DoWhileR.IntersectsWith(tR)=True
tR.Intersect(R)
BmpList.Add(GetRectImage(tR))
tR.Offset(0,HeightPerImage)
Loop
ReturnBmpList
PublicFunctionRenderImage(HeightPerImageAsInteger,ID1AsString)AsList(OfBitmap)
If_Rect.ContainsKey(ID1)=FalseThenReturnNewList(OfBitmap)
ReturnRenderImage(_Rect(ID1),HeightPerImage)
PublicFunctionRenderImage(ID1AsString)AsList(OfBitmap)
ReturnRenderImage(_Rect(ID1),_HeightPerImage)
PublicFunctionRenderImage(ID1AsString,ParamArrayID()AsString)AsList(OfBitmap)
ReturnRenderImage(_HeightPerImage,ID1,ID)
PublicFunctionRenderImage(HeightPerImageAsInteger,ID1AsString,ParamArrayID()AsString)AsList(OfBitmap)
DimHasRectAsBoolean=False
DimRAsRectangle
If_Rect.ContainsKey(ID1)=TrueThen
HasRect=True
R=_Rect(ID1)
DimIAsInteger
ForI=0ToID.Length-1
If_Rect.ContainsKey(ID(I))=TrueThen
IfHasRect=TrueThen
R=Rectangle.Union(R,_Rect(ID(I)))
R=_Rect(ID(I))
IfHasRect=FalseThenReturnNewList(OfBitmap)
ReturnRenderImage(R,HeightPerImage)
clsCaptureImages类,保存截图结果的类,由于超长网页不能截在一张图里,故用一个类保存截图的结果。
并提供一些扩展的功能
AddBitmap方法
PublicSubAddBitmap(BmpAsBitmap)
把截好的图片添加到类中
AddRect方法
PublicSubAddRect(IDAsString,RAsRectangle)
把ID对应的位置Rectangle添加到类中
RenderImage函数,返回图像的集合。
并可以根据某些参数定制图像集合。
例如:
只想获得某个Rectangle的范围的图像;
只想获得某个ID的元素的图像;
按照指定的高度划分图像集合等等。
如果我把截图放在Word里的话,最好每张的图片的高度不超过1200
返回值:
根据参数返回图像的集合List(OfBitmap)
它有如下的几个重载方式:
PublicFunctionRenderImage()AsList(OfBitmap)
不加修饰,直接把图像集合返回。
默认的图像集合中的每张图像的高度是20000
PublicFunctionRenderImage(RAsRectangle)AsList(OfBitmap)
返回指定区域R的截图图像集合。
程序会先计算整个图像的范围(利用ImageRect函数),然后返回的是R和ImageRect交集的图像集合,按照默认的高度(20000)划分每张图片
PublicFunctionRenderImage(HeightPerImageAsInteger)AsList(OfBitmap)
返回图像集合,每张图片的高度由HeightPerImage参数决定。
这个在将来要把图像放在Word里特别有用。
PublicFunctionRenderImage(RAsRectangle,HeightPerImageAsInteger)AsList(OfBitmap)
程序会先计算整个图像的范围(利用ImageRect函数),然后返回的是R和ImageRect交集的图像集合,按照参数HeightPerImage指定的高度划分每张图片的高度
PublicFunctionRenderImage(ID1AsString)AsList(OfBitmap)
返回指定ID1的元素所在位置的截图图像集合。
ID1所在的位置在之前的AddRect方法中添加到类中。
如果没有找到ID1对应的位置,则返回空的集合。
每张图像的高度由默认值(20000)决定
PublicFunctionRenderImage(HeightPerImageAsInteger,ID1AsString)AsList(OfBitmap)
返回指定ID1的元素所在位置的截图图像集合,每张图像的高度由HeightPerImage决定。
PublicFunctionRenderImage(ID1AsString,ParamArrayID()AsString)AsList(OfBitmap)
返回指定ID1和ID的元素所在位置的截图图像集合。
如果所有的ID指定的位置都不存在,返回空集合,否则返回存在的ID所在位置的并集所在位置的图像集合。
PublicFunctionRenderImage(HeightPerImageAsInteger,ID1AsString,ParamArrayID()AsString)AsList(OfBitmap)
每张图像的高度由HeightPerImage决定
PublicClassclsCaptureWebEx
PublicSharedFunctionCaptureWebEx(SettingsAsclsCaptureWebSettings)AsclsCaptureImages
Dim_ImagesAsNewclsCaptureImages
DimIAsInteger,JAsInteger
ConstWEB_HEIGHTAsInteger=20000
J=0
J=CaptureWebEx(_Images,Settings,J)
I=WEB_HEIGHT
DoWhileI<
J
CaptureWebEx(_Images,Settings,I)
I+=WEB_HEIGHT
Loop
Return_Images
EndFunction
PrivateSharedFunctionCaptureWebEx(_ImagesAsclsCaptureImages,_SettingsAsclsCaptureWebSettings,_CapTopAsInteger)AsInteger
Dim_BmpAsBitmap
Dim
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 利用 Webbrowser 实现 超长 网页