日期:2014-05-18  浏览次数:20588 次

在web项目中使用WebBrowser类-----给网站抓图
最近做一个WEB项目,其中要求有个功能就是程序能网页抓图,举个例子:
  在test.aspx页面上放一个TextBox和一个Button,TextBox用来输入要抓取的网页地址,然后按了Button之后,服务器要对前面输入的网址进行抓图,然后显示出来。我把抓图的业务逻辑做成一个类:
C# code
using System;
using System.Data;
using System.Windows.Forms;
using System.Drawing;

/// <summary>
/// WebSnap :网页抓图对象
/// </summary>
public class WebSnap2
{


    public WebSnap2()
    {
        //
        // TODO: 在此处添加构造函数逻辑
        //
    }

    /// <summary>
    /// 开始一个抓图并返回图象
    /// </summary>
    /// <param name="Url">要抓取的网页地址</param>
    /// <returns></returns>
    public Bitmap StartSnap(string Url)
    {
        WebBrowser myWB = this.GetPage(Url);
        Bitmap returnValue = this.SnapWeb(myWB);
        myWB.Dispose();
        return returnValue;
    }

    private WebBrowser GetPage(string Url)
    {
        WebBrowser myWB = new WebBrowser();
        myWB.ScrollBarsEnabled = false;
        myWB.Navigate(Url);
        while (myWB.ReadyState != WebBrowserReadyState.Complete)
        {
            System.Windows.Forms.Application.DoEvents();
        }
        return myWB;
    }

    private Bitmap SnapWeb(WebBrowser wb)
    {
        HtmlDocument hd = wb.Document;
        int height = Convert.ToInt32(hd.Body.GetAttribute("scrollHeight")) + 10;
        int width = Convert.ToInt32(hd.Body.GetAttribute("scrollWidth")) + 10;
        wb.Height = height;
        wb.Width = width;
        Bitmap bmp = new Bitmap(width, height);
        Rectangle rec = new Rectangle();
        rec.Width = width;
        rec.Height = height;
        wb.DrawToBitmap(bmp, rec);
        return bmp;
    }

}


然后在test.asp的button_click事件里面调用:
C# code

        WebSnap ws = new WebSnap();
        Bitmap bmp= ws.StartSnap(TextBox1.Text);
        System.IO.MemoryStream ms = new System.IO.MemoryStream();
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        Response.BinaryWrite(ms.GetBuffer());


经过测试确实可以抓图,因为不急着用,这个功能就暂时放下了。可是过了不久之后当我重新想使用这个功能的时候,却发现使用不了,一个字代码都没改过,还是那个test.aspx页面,还是那个按扭调用抓图,点了之后就提示:“当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”。 ”
网上找了好多资料,都说activex控件只能在单线程里面用,但是我的WEB程序是单线程的啊,而且为什么一开始可以用后来就用不了??

------解决方案--------------------
帮顶
------解决方案--------------------
我的WEB程序是单线程的啊
========================
错,不是单线程


可以试试HtmlThumbnailGrabber,也是一个组件
------解决方案--------------------
您将很高兴听到这样一个消息:仍然可以使用这些 STA 组件,而不需要更改任何代码。您需要做的工作只是在 ASP .NET 网页的 <%@Page> 标记中包含兼容性属性 aspcompat=true,如 <%@Page aspcompat=true Language=VB%>。使用此属性将强制网页以 STA 模式执行,从而确保您的组件可以继续正确运行。如果试图使用 STA 组件但没有指定此标记,运行时将会发生异常情况。

将此属性的值设置为 true 时,将允许网页调用 COM+ 1.0 组件,该组件需要访问非管理的 ASP 内置对象。可以通过 ObjectContext 对象进行访问。

如果将此标记的值设为 true,性能会稍微有些下降。建议只在确实需要时才这样做。
------解决方案--------------------
mark