65.9K
CodeProject 正在变化。 阅读更多。
Home

网站快照

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (7投票s)

2008年8月14日

CPOL

4分钟阅读

viewsIcon

37998

一个用于拍摄网站图像快照的 Web 应用程序。

引言

我曾经很想知道如何制作一个网页,如果提供了另一个网页的 URL,就能截取该网页的快照。我为此搜索了很多,但最终只找到了一堆第三方组件。正是在这些页面上,我发现你的操作系统中实际上有一个内置的组件来处理网页浏览。而且,碰巧的是,这个组件作为 WebBrowser 控件被打包到你的 VS IDE (2005) 中;我的意思是,这个控件封装了这个组件提供的功能。

背景

这个项目可能与你之前做过的任何其他 Web 项目都不同。确切地说,它不仅仅是一个 Web 项目;它还是一个 Windows 应用程序项目。是的,你可能想知道为什么我们需要一个?拭目以待。

Windows 应用程序 (prjSnapShot)

这里是让我认为截取网页图像的过程是可能的链接。但是你需要进行这个项目并根据你的需要进行调整。这很容易理解。你所需要的只是一个停靠在 Windows Form 上的 WebBrowser 控件,然后是下面的代码让你开始。它几乎与我参考的项目相似,但我做了一些更改以适应我的需要。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Snapshot
{
    //This is my windows form class
    public partial class browserForm : Form
    {
        public browserForm()
        {
            InitializeComponent();
        }

        //private variables for properties
        private string _URL;
        private Bitmap docImg;
        private bool DownloadingComplete;        

        //this property accepts a URL.
        public string URL
        {
            get
            {
                return _URL;
            }
            set
            {
                _URL = value;
            }
        }

        //function that fetches the image and return a System.Drawing.Image
        //representation of it.
        public Image GetSnapshot()
        {
            if (_URL == null)
                throw new Exception("No input url given");
            if (_URL.Contains("http://") == false)
                throw new Exception("Invalid url input. No http prefix was found");
            docImg = new Bitmap(this.Width, this.Height);
            Control ctrl = wbCtrl;

            wbCtrl.Navigate(_URL);

            //blocking until downloading complete
            while (!DownloadingComplete)
                Application.DoEvents();          

            return System.Drawing.Image.FromHbitmap(docImg.GetHbitmap());
        }
        
        private void wbCtrl_DocumentCompleted
		(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            //Actual downloading done here.
            //Conversion to image is also done here.

            DownloadingComplete = true;
            Debug.Print("Download Completed @ " + DateTime.Now.ToString());
            docImg = new Bitmap(this.Width, this.Height);
            Control ctrl = wbCtrl;
            ctrl.DrawToBitmap(docImg, new Rectangle(wbCtrl.Location.X, wbCtrl.Location.Y,
                    wbCtrl.Width, wbCtrl.Height));
        }
    }
}

你可能需要运行这个项目几次;像我链接的文章中建议的那样,将其添加到另一个 Windows 项目中。整个过程的美妙之处在于,你实际上不会让这个表单可见!测试完成后,将项目转换为 DLL。我们将在下一个项目中添加它。

ASP.NET 项目

将上述 DLL 添加到此项目中。让我警告你,如果你试图在这个时候原样使用它,你可能会遇到很多问题。哦,顺便说一句,这个项目并没有“做”那么多。但是你必须了解一些概念。即 ASP.NET 引擎如何处理你的网页。这本身就是一个庞大的主题,但我只提几件事

  • 你的网页是在多线程单元 (MTA) 模型上执行的。我猜 ASP.NET 以这种方式运行以优化网页的加载。网页所需的资源由启动处理的线程处理。你不需要深入研究这个问题。但是,忽略这个事实可能会触发你的 Web 应用程序的异常。

在这里,你必须意识到,我们已经将一个 Windows 项目添加到一个 ASP.NET 项目中。大部分控件,甚至整个表单本身都在单线程单元 (STA) 模型上运行。因此,你会收到一个错误,说明类似线程不是 STA 的内容。

为了克服这个障碍,你所要做的就是将网页的页面AspCompat 页面属性设置为true。 ASP.NET 引擎将立即意识到必须在 STA 上处理此网页。事实上,我相信这过去是普通 ASP 页面被处理的方式。

下一个障碍是真正困扰你的东西。一切似乎都还好,但是你得到了一个奇怪的 COM 异常和一个看起来很奇怪的错误代码。有时,你第一次运行应用程序时一切顺利,但随后的每个请求都会抛出一个错误。搜索这个错误代码无济于事。你需要一些 COM 知识。但是,我不是这方面的专家,但我可以安全地告诉你,你必须告诉你的操作系统你已经完成了使用你的 COM 对象;否则,使用同一对象的其他应用程序可能会出现异常行为。因此,最终你在那里所见证的可能是 COM 没有被正确地取消引用。如果遇到这样的问题,请停止本地 Web 服务器(由 IDE 为你托管),然后重新启动它;在你的 IDE 中再次运行该项目。

Using the Code

我希望你已经理解了以上所有内容。现在使用代码就像这样简单

protected void btnGenerate_Click(object sender, EventArgs e)
{
    browserForm frm = new browserForm();
    frm.URL = txtURL.Text;
    System.Drawing.Image snapshot;
    snapshot = frm.GetSnapshot();
    snapshot.Save(Server.MapPath("snap.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
    frm.Dispose();
    Image1.ImageUrl = "snap.jpg";    
}

哦,而且我的所有 Web 表单都只有一个文本框、一个按钮和一个图像控件。

我想知道的事情

我还没有在生产环境中进行过这个练习。我正在考虑,也许,代码需要一些调整。但是如果你想玩这个,那么你非常欢迎!

历史

哇,在编辑了十年之后,我发表了我的第一篇文章!

© . All rights reserved.