C# 如何在web浏览器上阻止图像

C# 如何在web浏览器上阻止图像,c#,winforms,webbrowser-control,image,C#,Winforms,Webbrowser Control,Image,我正在用WebBrowser构建一个C#应用程序,并试图找出一种阻止图像的方法,即在加载网站时不显示图像(以便网站更容易加载) 我试图删除标记,方法是通过webBrowser1.DocumentText获取标记,并使用Regex.Replace删除图像,但当我使用代码时,它会显示一个带有aaa的空白页。有没有更好的方法删除图像?非常感谢您的帮助 代码: var html_source = webBrowser1.DocumentText; var newOne = Regex.Replace(h

我正在用
WebBrowser
构建一个C#应用程序,并试图找出一种阻止图像的方法,即在加载网站时不显示图像(以便网站更容易加载)

我试图删除
标记,方法是通过
webBrowser1.DocumentText
获取标记,并使用
Regex.Replace
删除图像,但当我使用代码时,它会显示一个带有
aaa
的空白页。有没有更好的方法删除图像?非常感谢您的帮助

代码:

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

为此,您可以使用延迟加载技术。请参见编辑

找到了一个完整的项目,这可能会帮助你。在此示例中,有一个使用webBrowser COM组件的用户控件。正如我在最初的回答中所写,我认为不可能阻止.net Framework WebBrowser加载图像。在浏览器控件接收到纯html文本后,您需要访问以下级别以拦截加载图像

。。。最模糊和最重要的部分 该控件是IDispatch\u Invoke\u处理程序()。。。如何实现IDispatch::Invoke限制IE显示的内容(如图像、ActiveX控件、Java)。 我发现如果在中添加IDispatch_Invoke_Handler()方法 您的代码的COM分派标识符为-5512,这就完成了任务 给你。一个非常模糊的答案,但效果很好

原创

你可以试试这个

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事件以在 新文档完成加载。当文档完成事件时 发生时,新文档已完全加载,这意味着您可以访问 通过文档、文档文本或文档流显示其内容 财产


我不认为您可以使用.net Framework中的webBrowser控件来实现这一点。

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

您需要的:

  • :基于Chromium引擎的.net控件
  • :一个http内存代理,允许您监视http通信
  • :根据您选择的解决方案,HAP可以帮助您以比正则表达式更可靠的方式动态更改html内容的DOM
我选择使用Awesomium,因为它提供了比现成的web浏览器控件多得多的功能。在我的例子中,它允许我定义要使用的代理,而不是系统范围的设置

Fiddler内核用于拦截通信。它的API提供了拦截/篡改/的方法。。。当发出请求时。在我的例子中,我只是将响应主体转发给我的业务类,但在您的例子中,您应该能够根据mime类型进行筛选,以更改HTML DOM(使用HTML功能包!!!)或返回图像的非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"]
            );

    }
}
正如我在评论中所说,您可以使用另一个事件处理程序来完成。这取决于您的需求(请阅读fiddler core SDK以获取帮助)

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

您可以尝试以下方法:

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

webbrowser控件使用与internet explorer相同的设置

您可以轻松禁用图像,但请注意,这将影响internet explorer,以及您的webbrowser控件(和其他使用internet explorer功能的程序)

要禁止加载图像,请执行以下操作:

1.)打开集成资源管理器

2.)转到“工具”>“互联网选项”

3.)转到“高级”选项卡

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

此更改的效果存储在注册表i beleive中,因此您也应该能够通过编程方式对其进行编辑。但是,请记住,它将不仅仅影响您的应用程序

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

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

您可能需要非贪婪+?量词:“
Ahhh!用正则表达式解析HTML!一个勇敢的尝试,但不是开箱即用的东西。。。事实上相当复杂,所以我投了反对票,对不起。@Steve B,我们正在使用C#windows窗体的web控件。但面临性能问题。考虑使用无铬抓取页面。它会优化性能吗?
HtmlElementCollection elc = WebBrowser1.Document.GetElementsByTagName("img");
foreach (HtmlElement el in elc)
{
   if (el.GetAttribute("src") != null)
   {
       el.SetAttribute("src", "");
   }
}