如何在Web浏览器上阻止图像

时间:2012-08-31 07:24:01

标签: c# winforms webbrowser-control image

我正在构建一个带有WebBrowser的C#应用​​程序,我正试图想出一种阻止图像的方法,即在网站加载时不显示它们(这样网站加载更容易)

我尝试通过<img>获取webBrowser1.DocumentText代码并使用Regex.Replace删除图片来删除aaa代码,但随后它显示了{{1}的空白页面当我使用代码时。有没有更好的方法来删除图像?非常感谢任何帮助。

代码:

var html_source = webBrowser1.DocumentText;
var newOne = Regex.Replace(html_source, "<img.*/>", "", RegexOptions.Multiline);
webBrowser1.DocumentText = newOne + "aaa";

更新

我尝试了以下代码(仅用于测试),但仍然只显示aaa

var html_source = webBrowser1.DocumentText;
webBrowser1.DocumentText = html_source + "aaa";

6 个答案:

答案 0 :(得分:4)

修改

在SO上找到了this question以及一个可以帮助您codeproject.com的完整项目。在此示例中,使用webBrowser COM组件有一个 userControl。正如我在原始回答中所写,我认为 可能阻止.net Framework WebBrowser加载图像。浏览器控件收到普通html文本后,您需要访问以下级别拦截加载图像

  

......最晦涩难懂的重要部分   控件是 IDispatch_Invoke_Handler()。 ...如何实现IDispatch :: Invoke   限制IE显示的内容(例如图像,ActiveX控件,Java)。   我发现如果你在中添加一个IDispatch_Invoke_Handler()方法   使用 COM调度标识符-5512的代码,这可以完成工作   为你。一个非常模糊的答案,但它运作良好....

<强> ORIGINAL

你可以试试这个

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
     Debug.WriteLine("documentCompleted");
     HtmlDocument doc = webBrowser1.Document;
     foreach (HtmlElement  imgElemt in doc.Images)
     {
         imgElemt.SetAttribute("src", "");
     }
}

但正如MSDN所说

  

处理DocumentCompleted事件以在接收时收到通知   新文档完成加载。当DocumentCompleted事件发生时   发生时,新文档已完全加载,这意味着您可以访问   其内容通过Document,DocumentText或DocumentStream   属性。

我认为您无法使用.net Framework中的webBrowser控件执行此操作。

答案 1 :(得分:4)

你可以试试这个:

private void webBrowser1_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
{
  if (webBrowser1.Document != null)
  {
     foreach (HtmlElement imgElemt in webBrowser1.Document.Images)
     {
        imgElemt.SetAttribute("src", "");
     }
   }
}

答案 2 :(得分:3)

webbrowser控件使用与Internet Explorer使用的相同设置。

您可以轻松禁用图片,但请注意它会影响Internet Explorer,以及您的webbrowser控件(以及其他使用Internet Explorer功能的程序)

禁用加载图片:

1。)打开integent explorer

2。)转到'工具'&gt; '互联网选项'

3。)转到“高级”标签

4.。)向下滚动,直到找到“显示图片”复选框,然后取消选中它(它位于“多媒体”部分)

此更改的效果存储在我相信的注册表中,因此您应该能够以编程方式编辑它。但请记住,它不仅仅会影响您的应用程序。

答案 3 :(得分:2)

最近,我要求拦截和分析webbrowser控件中的所有通信。我认为我使用的技术可以帮助你。

你需要什么:

  • Awesomium.Net:基于Chromium引擎的.net
  • 控件
  • Fiddler Core:一个http内存代理,允许您监控http通信。
  • HtmlAgility pack:根据您选择的解决方案,HAP可以帮助您以比正则表达式更加可靠的方式动态更改html内容的DOM。

我选择使用Awesomium,因为它提供了比开箱即用的Web浏览器控件更多的功能。在我的例子中,它允许我定义要使用的代理而不是系统范围的设置。

Fiddler Core用于拦截通信。它的API提供了在发出请求时拦截/篡改/ ...的方法。在我的情况下,我只是将响应主体转发到我的业务类,但在你的情况下,你应该能够过滤mime-type来改变HTML DOM(使用HtmlAgility包!!!!! )或返回图像的非200 http状态。

这是我使用的代码。我的应用程序是WPF,但您可以通过很少的努力使其适应winform:

public partial class App : Application
{
    static App()
    {
        // First, we set up the internal proxy
        SetupInternalProxy();
        // The we set up the awesomium engine
        SetupBrowser();
    }
    private static void SetupInternalProxy()
    {
        // My requirement is to get response content, so I use this event.
        // You may use other handlers if you have to tamper data.
        FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
        FiddlerApplication.Log.OnLogString += (o, s) => Debug.WriteLine(s);

        FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;

        //this line is important as it will avoid changing the proxy for the whole system.
        oFCSF = (oFCSF & ~FiddlerCoreStartupFlags.RegisterAsSystemProxy);

        FiddlerApplication.Startup(0, oFCSF);

    }
    private static void SetupBrowser()
    {
        // We may be a new window in the same process.
        if (!WebCore.IsRunning)
        {
            // Setup WebCore with plugins enabled.
            WebCoreConfig config = new WebCoreConfig
            {
                // Here we plug the internal proxy to the awesomium engine
                ProxyServer = "http://127.0.0.1:" + FiddlerApplication.oProxy.ListenPort.ToString(),
                // Adapt others options related to your needs
                EnablePlugins = true,
                SaveCacheAndCookies = true,
                UserDataPath = Environment.ExpandEnvironmentVariables(@"%APPDATA%\MyApp"),
            };
            WebCore.Initialize(config);
        }
        else
        {
            throw new InvalidOperationException("WebCore should be already running");
        }
    }
    // Here is the handler where I intercept the response
    private static void FiddlerApplication_AfterSessionComplete(Session oSession)
    {
        // Send to business objects
        DoSomethingWith(
            oSession.PathAndQuery,
            oSession.ResponseBody,
            oSession["Response", "Content-Type"]
            );

    }
}

正如我在评论中所说,您可以使用AfterSessionComplete的另一个事件处理程序。这取决于您的要求(阅读fiddler核心SDK以获得帮助)。

最后一句话:此代码从app类运行(相当于Winform中的Program类)。您可能需要使用消息传递系统或发布全局事件(小心内存泄漏)才能在Windows类中使用结果。您还必须知道AfterSessionComplete事件是从多个线程触发的,有时是同时触发的。您将使用某种类型的Invoking在UI线程中工作。

答案 4 :(得分:1)

HtmlElementCollection elc = WebBrowser1.Document.GetElementsByTagName("img");
foreach (HtmlElement el in elc)
{
   if (el.GetAttribute("src") != null)
   {
       el.SetAttribute("src", "");
   }
}

如果有任何元素可能包含图像,则它将位于img标记中。

答案 5 :(得分:0)

您可以使用延迟加载技术来实现此目的。见http://engineering.slideshare.net/2011/03/faster-page-loads-with-image-lazy-loading/