当前位置:编程学习 > C#/ASP.NET >>

【百分结贴】能完美判断网页是否全部加载完毕吗?

C#内置的WebBrowser控件不能准确判断网页什么时候最终装载完毕,有高手帮我借鉴这个帖子通过延迟、记录再对比的方式做过测试,但也没找到好的效果,一般情况都是10个里面有两个不行。
谁有办法直接判断网页是否加载完毕(包括页面中的frame和js)? --------------------编程问答-------------------- --------------------编程问答-------------------- 谁写过类似的程序? --------------------编程问答-------------------- 为什么必须要加载完毕?


--------------------编程问答-------------------- 主要是需要递归判断所有框架网页是否都加载完毕。

另外一些网页使用了ajax会导致不断刷新数据,这样的网页似乎永远也不会加载完毕。 --------------------编程问答-------------------- 既然是使用asp.net,那么微软已经为我们做了判断
1).net3.5,参见:
http://msdn.microsoft.com/zh-cn/library/bb310952(v=vs.90).aspx
2).net4.0,参见:
http://msdn.microsoft.com/zh-cn/library/bb310952.aspx
3)如果是早期的.net框架,可以自行加载最新的microsoftAjaxLibrary
  获取最新版本,参见:
  http://ajaxcontroltoolkit.codeplex.com/
  换句话说,即便是不使用asp.net,
  我们仍然可以通过引入这个84k的js库,获得一个强大的客户端框架的支持 --------------------编程问答-------------------- http://blog.sina.com.cn/s/blog_67ce56040100m5h6.html
--------------------编程问答-------------------- 谢谢各位!
我把代码贴出来,请帮我修改调试一下(截取目标页面http://z.firefoxchina.cn的快照,图标和广告等时有时无,应该是网页没有加载完毕造成的):
Version=2.0.0.0
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
    
    </div>
    </form>
</body>
</html>

Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.IO;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        Bitmap bmp = HtmlToImg.GetHtmlToImg("http://z.firefoxchina.cn", 800, 600, 800, 600);
        MemoryStream stream = new MemoryStream();
        bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        byte[] buff = stream.ToArray();
        //保存图片
        FileStream fs = new FileStream(Server.MapPath(DateTime.Now.ToString("HHmmss") + ".png"), FileMode.Create);
        stream.WriteTo(fs);
        stream.Close();
        fs.Close();
    }
}

HtmlToImage.cs
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
/// <summary>
/// 生成网页快照
/// </summary>
public class HtmlToImg
{
    Bitmap m_Bitmap;
    string m_Url;
    int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth, m_ThumbnailHeight;
    public HtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
    {
        m_Url = Url;
        m_BrowserHeight = BrowserHeight;
        m_BrowserWidth = BrowserWidth;
        m_ThumbnailWidth = ThumbnailWidth;
        m_ThumbnailHeight = ThumbnailHeight;
    }
    public static Bitmap GetHtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
    {
        HtmlToImg thumbnailGenerator = new HtmlToImg(Url, BrowserWidth, BrowserHeight, ThumbnailWidth, ThumbnailHeight);
        return thumbnailGenerator.GenerateHtmlToImgImage();
    }
    public Bitmap GenerateHtmlToImgImage()
    {
        Thread m_thread = new Thread(new ThreadStart(_GenerateHtmlToImgImage));
        m_thread.SetApartmentState(ApartmentState.STA);
        m_thread.Start();
        m_thread.Join();
        return m_Bitmap;
    }
    private void _GenerateHtmlToImgImage()
    {
        WebBrowser m_WebBrowser = new WebBrowser();
        m_WebBrowser.ScrollBarsEnabled = false;
        m_WebBrowser.Navigate(m_Url);
        m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
        while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();
        m_WebBrowser.Dispose();
    }
    private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser m_WebBrowser = (WebBrowser)sender;
        m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
        m_WebBrowser.ScrollBarsEnabled = false;
        m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
        m_WebBrowser.BringToFront();
        m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
        m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
    }
}
--------------------编程问答-------------------- 网上搜索,有很多思路,但是不知道如何实现。谁给直接修改代码啊?实在不行改成延迟截图也行! --------------------编程问答-------------------- public Form2()
        {
            InitializeComponent();
           
            XMLHTTP http = new XMLHTTP();
            http.open("GET", "http://z.firefoxchina.cn", false, null, null);
            http.send(null);           
            Image bitmap = new Bitmap(800, 600);
     
            if (http.status == 200)//加载完成。。。
            {
                
                byte[] buff = (Byte[])http.responseBody;
                System.IO.FileStream stmFile = new System.IO.FileStream("d:/1.html", System.IO.FileMode.CreateNew);
                stmFile.Write(buff, 0, buff.Length);
                stmFile.Close();           
            }
        } --------------------编程问答-------------------- XMLHTTP http = new XMLHTTP();
--------------------------------

项目-鼠标右键-添加引用-com-Microsoft XML,V4.0 --------------------编程问答-------------------- 不好意思没仔细看,原来是b/s的项目,这类需求其实用c/s就好了,只要定时截图就ok了吧? --------------------编程问答-------------------- 谢谢!照着做了,可还是通不过:
项目-鼠标右键-添加引用-com-Microsoft XML,V4.0
提示:已经存在名为“Bin/Interop.MSXML2.dll”的文件。是否替换它?
选择:“是”
编译器错误信息: CS0246: 找不到类型或命名空间名称“XMLHTTP”(是否缺少 using 指令或程序集引用?)
源错误:行 16:         XMLHTTP http = new XMLHTTP();
引用 10 楼  的回复:
XMLHTTP http = new XMLHTTP();
--------------------------------

项目-鼠标右键-添加引用-com-Microsoft XML,V4.0
--------------------编程问答-------------------- http://download.csdn.net/detail/yeness/4473545

---------------------------------------------

发这里了,如果定时抓取,做个线程就好。。。 --------------------编程问答-------------------- 不是定时抓取,而是因为抓取的时候页面还没有全部打开,所以想延迟一下再截图。
已经下载了,为什么里面没有aspx后缀的文件啊?我加上了Default.aspx和Default.aspx.cs两个文件,添加了点击事件,也重复了“项目-鼠标右键-添加引用-com-Microsoft XML,V4.0”,但是运行依然出错,编译器错误信息: CS0246: 找不到类型或命名空间名称“XMLHTTP”(是否缺少 using 指令或程序集引用?)

引用 13 楼  的回复:
http://download.csdn.net/detail/yeness/4473545

---------------------------------------------

发这里了,如果定时抓取,做个线程就好。。。
--------------------编程问答-------------------- $(document).ready(){
 alert("加载完毕!");
} --------------------编程问答-------------------- 这个怎么用?是php吗?
请问该怎样用到我的代码里?
引用 15 楼  的回复:
$(document).ready(){
 alert("加载完毕!");
}
--------------------编程问答--------------------
引用 16 楼  的回复:
这个怎么用?是php吗?
请问该怎样用到我的代码里?


昏倒。

这是javascript! --------------------编程问答--------------------
引用 4 楼  的回复:
主要是需要递归判断所有框架网页是否都加载完毕。

另外一些网页使用了ajax会导致不断刷新数据,这样的网页似乎永远也不会加载完毕。

使用ajax加载,根本不是传统意义上的加载。假设它5秒种之后将一个图片切换到下一张,你的程序怎么知道要等待5秒种?

如果你们能想出那种连google、百度都不去做的所谓“抓取”逻辑,那么你们干脆就用一个进程打开一个页面延迟10分钟,然后再去访问 webbrowser.Document 里边的 HtmlElement 好了。 --------------------编程问答--------------------
引用 15 楼  的回复:
$(document).ready(){
 alert("加载完毕!");
}

+1.
直接调用jquery搞定。方法最简单。 --------------------编程问答-------------------- 我想延迟500毫秒,该怎么做?
引用 18 楼  的回复:
引用 4 楼  的回复:
主要是需要递归判断所有框架网页是否都加载完毕。

另外一些网页使用了ajax会导致不断刷新数据,这样的网页似乎永远也不会加载完毕。

使用ajax加载,根本不是传统意义上的加载。假设它5秒种之后将一个图片切换到下一张,你的程序怎么知道要等待5秒种?

如果你们能想出那种连google、百度都不去做的所谓“抓取”逻辑,那么你们干脆就用一个进程打开一个页面延迟……
--------------------编程问答-------------------- 具体该怎样调用呢?
引用 19 楼  的回复:
引用 15 楼  的回复:
$(document).ready(){
alert("加载完毕!");
}

+1.
直接调用jquery搞定。方法最简单。
--------------------编程问答-------------------- \WinWEBImage\bin\Debug 下 WinWEBImage.exe 双击 在d盘根目录有一个抓取的图片 --------------------编程问答-------------------- 谢谢,看到了!
我是想在网页里实现。而且试了好多次,你的程序也没有抓全,左上角火狐图标和百度搜索下的广告时有时无,和我之前的抓取效果是一样的。
引用 22 楼  的回复:
\WinWEBImage\bin\Debug 下 WinWEBImage.exe 双击 在d盘根目录有一个抓取的图片
--------------------编程问答-------------------- 用JQuery 

$(document).ready(function(){ .....});

--------------------编程问答-------------------- 该怎么用啊?能帮我直接写到我的代码里吗?
谢谢!
引用 24 楼  的回复:
用JQuery 

$(document).ready(function(){ .....});
--------------------编程问答-------------------- webbrower 有一个加载完毕的 属性呀 --------------------编程问答--------------------         m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
        while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();
        m_WebBrowser.Dispose();
是这个吧?我代码里就用这个判断的,但是很不准确,常出问题。
引用 26 楼  的回复:
webbrower 有一个加载完毕的 属性呀
--------------------编程问答-------------------- 谁能改一下我的代码? --------------------编程问答--------------------

不知道说什么了。 js能解决的  去查查函数就行了 --------------------编程问答-------------------- 我在7楼贴出了全部代码。谁能直接修改代码解决啊?现在是思路有很多,但是就是无法实现!
引用 29 楼  的回复:
不知道说什么了。 js能解决的  去查查函数就行了
--------------------编程问答-------------------- 我不懂js,上面多次提到$(document).ready(),查了一下:
document.ready和onload的区别——JavaScript文档加载完成事件页面加载完成有两种事件,一是ready,表示文档结构已经加载完成(不包含图片等非文字媒体文件),二是onload,指示页面包含图片等文件在内的所有元素都加载完成。
我这里是不是该用onload啊?我在7楼贴出了全部网页代码,谁能帮我用js判断一下?
谢谢! --------------------编程问答-------------------- $(document).ready()
底层实现是通过setimeout 以几毫少的频率去判段DOM元素是否存在。
说白了是JQUERY封装一个判段DOC元素加载的一个方法
只要HTML标签加载出来
就会执行事件
ONLONAD是所有元素加载完成包含图片等文件。 --------------------编程问答-------------------- 应该是用document.onload判断所有元素都加载完成吧?我不会js,对net也不熟悉,你能帮我写进我的代码里吗?
引用 32 楼  的回复:
$(document).ready()
底层实现是通过setimeout 以几毫少的频率去判段DOM元素是否存在。
说白了是JQUERY封装一个判段DOC元素加载的一个方法
只要HTML标签加载出来
就会执行事件
ONLONAD是所有元素加载完成包含图片等文件。
--------------------编程问答-------------------- 看来要靠js解决了。谁写过这样的程序,帮我改改吧~~ --------------------编程问答-------------------- $(document).onload()?
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,