• C#彻底解决Web Browser 跨域读取Iframes内容


    用C# winform的控件web browser 读取网页内容,分析一下数据,做一些采集工作。

    如果是同一个域名下面还是好办的,基本上用HtmlAgilityPack就完全可以解决问题。 

    但是现在遇到跨域问题,比如我需要打开页面上存在的广告联盟的地址,进行保存。 

    这就是牵扯到跨域。 一般的错误是:拒绝访问。

    "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"。 

    因为你没有在这个网站去修改另一个网站数据的权利。 

    怎么办?很困恼吧。现在就告诉大家一个好办法。 

    直接上代码了。 

    工具类,大家保存成一个类。需要引用mshtml

      1 using System;
      2 using System.Runtime.InteropServices;
      3 using System.Windows.Forms;
      4 using mshtml;
      5 
      6 namespace WebBrowserTest
      7 {
      8 
      9     // This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface! 
     10 
     11     [ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"),
     12 
     13     InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
     14 
     15     public interface IServiceProvider
     16     {
     17 
     18         [return: MarshalAs(UnmanagedType.I4)]
     19 
     20         [PreserveSig]
     21 
     22         int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
     23 
     24     }
     25 
     26     public enum OLECMDF
     27     {
     28 
     29         OLECMDF_DEFHIDEONCTXTMENU = 0x20,
     30 
     31         OLECMDF_ENABLED = 2,
     32 
     33         OLECMDF_INVISIBLE = 0x10,
     34 
     35         OLECMDF_LATCHED = 4,
     36 
     37         OLECMDF_NINCHED = 8,
     38 
     39         OLECMDF_SUPPORTED = 1
     40 
     41     }
     42 
     43     public enum OLECMDID
     44     {
     45 
     46         OLECMDID_PAGESETUP = 8,
     47 
     48         OLECMDID_PRINT = 6,
     49 
     50         OLECMDID_PRINTPREVIEW = 7,
     51 
     52         OLECMDID_PROPERTIES = 10,
     53 
     54         OLECMDID_SAVEAS = 4
     55 
     56     }
     57 
     58     public enum OLECMDEXECOPT
     59     {
     60 
     61         OLECMDEXECOPT_DODEFAULT,
     62 
     63         OLECMDEXECOPT_PROMPTUSER,
     64 
     65         OLECMDEXECOPT_DONTPROMPTUSER,
     66 
     67         OLECMDEXECOPT_SHOWHELP
     68 
     69     }
     70 
     71     [ComImport, Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E"), TypeLibType(TypeLibTypeFlags.FOleAutomation | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FHidden)]
     72 
     73     public interface IWebBrowser2
     74     {
     75 
     76         [DispId(100)]
     77 
     78         void GoBack();
     79 
     80         [DispId(0x65)]
     81 
     82         void GoForward();
     83 
     84         [DispId(0x66)]
     85 
     86         void GoHome();
     87 
     88         [DispId(0x67)]
     89 
     90         void GoSearch();
     91 
     92         [DispId(0x68)]
     93 
     94         void Navigate([In] string Url, [In] ref object flags, [In] ref object targetFrameName, [In] ref object postData, [In] ref object headers);
     95 
     96         [DispId(-550)]
     97 
     98         void Refresh();
     99 
    100         [DispId(0x69)]
    101 
    102         void Refresh2([In] ref object level);
    103 
    104         [DispId(0x6a)]
    105 
    106         void Stop();
    107 
    108         [DispId(200)]
    109 
    110         object Application { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
    111 
    112         [DispId(0xc9)]
    113 
    114         object Parent { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
    115 
    116         [DispId(0xca)]
    117 
    118         object Container { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
    119 
    120         [DispId(0xcb)]
    121 
    122         object Document { [return: MarshalAs(UnmanagedType.IDispatch)] get; }
    123 
    124         [DispId(0xcc)]
    125 
    126         bool TopLevelContainer { get; }
    127 
    128         [DispId(0xcd)]
    129 
    130         string Type { get; }
    131 
    132         [DispId(0xce)]
    133 
    134         int Left { get; set; }
    135 
    136         [DispId(0xcf)]
    137 
    138         int Top { get; set; }
    139 
    140         [DispId(0xd0)]
    141 
    142         int Width { get; set; }
    143 
    144         [DispId(0xd1)]
    145 
    146         int Height { get; set; }
    147 
    148         [DispId(210)]
    149 
    150         string LocationName { get; }
    151 
    152         [DispId(0xd3)]
    153 
    154         string LocationURL { get; }
    155 
    156         [DispId(0xd4)]
    157 
    158         bool Busy { get; }
    159 
    160         [DispId(300)]
    161 
    162         void Quit();
    163 
    164         [DispId(0x12d)]
    165 
    166         void ClientToWindow(out int pcx, out int pcy);
    167 
    168         [DispId(0x12e)]
    169 
    170         void PutProperty([In] string property, [In] object vtValue);
    171 
    172         [DispId(0x12f)]
    173 
    174         object GetProperty([In] string property);
    175 
    176         [DispId(0)]
    177 
    178         string Name { get; }
    179 
    180         [DispId(-515)]
    181 
    182         int HWND { get; }
    183 
    184         [DispId(400)]
    185 
    186         string FullName { get; }
    187 
    188         [DispId(0x191)]
    189 
    190         string Path { get; }
    191 
    192         [DispId(0x192)]
    193 
    194         bool Visible { get; set; }
    195 
    196         [DispId(0x193)]
    197 
    198         bool StatusBar { get; set; }
    199 
    200         [DispId(0x194)]
    201 
    202         string StatusText { get; set; }
    203 
    204         [DispId(0x195)]
    205 
    206         int ToolBar { get; set; }
    207 
    208         [DispId(0x196)]
    209 
    210         bool MenuBar { get; set; }
    211 
    212         [DispId(0x197)]
    213 
    214         bool FullScreen { get; set; }
    215 
    216         [DispId(500)]
    217 
    218         void Navigate2([In] ref object URL, [In] ref object flags, [In] ref object targetFrameName, [In] ref object postData, [In] ref object headers);
    219 
    220         [DispId(0x1f5)]
    221 
    222         OLECMDF QueryStatusWB([In] OLECMDID cmdID);
    223 
    224         [DispId(0x1f6)]
    225 
    226         void ExecWB([In] OLECMDID cmdID, [In] OLECMDEXECOPT cmdexecopt, ref object pvaIn, IntPtr pvaOut);
    227 
    228         [DispId(0x1f7)]
    229 
    230         void ShowBrowserBar([In] ref object pvaClsid, [In] ref object pvarShow, [In] ref object pvarSize);
    231 
    232         [DispId(-525)]
    233 
    234         WebBrowserReadyState ReadyState { get; }
    235 
    236         [DispId(550)]
    237 
    238         bool Offline { get; set; }
    239 
    240         [DispId(0x227)]
    241 
    242         bool Silent { get; set; }
    243 
    244         [DispId(0x228)]
    245 
    246         bool RegisterAsBrowser { get; set; }
    247 
    248         [DispId(0x229)]
    249 
    250         bool RegisterAsDropTarget { get; set; }
    251 
    252         [DispId(0x22a)]
    253 
    254         bool TheaterMode { get; set; }
    255 
    256         [DispId(0x22b)]
    257 
    258         bool AddressBar { get; set; }
    259 
    260         [DispId(0x22c)]
    261 
    262         bool Resizable { get; set; }
    263 
    264     }
    265 
    266     class CorssDomainHelper
    267     {
    268 
    269         private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
    270 
    271         private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
    272 
    273         // Utility for IE cross domain access 
    274 
    275         // Returns null in case of failure. 
    276 
    277         public static IHTMLDocument3 GetDocumentFromWindow(IHTMLWindow2 htmlWindow)
    278         {
    279 
    280             if (htmlWindow == null)
    281             {
    282                 return null;
    283             }
    284 
    285             // First try the usual way to get the document. 
    286 
    287             try
    288             {
    289 
    290                 IHTMLDocument2 doc = htmlWindow.document;
    291 
    292                 return (IHTMLDocument3)doc;
    293 
    294             }
    295 
    296             catch (COMException comEx)
    297             {
    298 
    299                 // I think COMException won't be ever fired but just to be sure ... 
    300 
    301             }
    302 
    303             catch (UnauthorizedAccessException)
    304             {
    305 
    306             }
    307 
    308             catch (Exception ex)
    309             {
    310                 return null;
    311             }
    312 
    313             // At this point the error was E_ACCESSDENIED because the frame contains a document from another domain. 
    314             // IE tries to prevent a cross frame scripting security issue. 
    315 
    316             try
    317             {
    318 
    319                 // Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider. 
    320                 IServiceProvider sp = (IServiceProvider)htmlWindow;
    321                 // Use IServiceProvider.QueryService to get IWebBrowser2 object. 
    322                 Object brws = null;
    323                 sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws);
    324                 // Get the document from IWebBrowser2. 
    325                 IWebBrowser2 browser = (IWebBrowser2)(brws);
    326                 return (IHTMLDocument3)browser.Document;
    327             }
    328 
    329             catch (Exception ex)
    330             {
    331                 Console.WriteLine(ex);
    332             }
    333             return null;
    334         }
    335     }
    336 }

    调用方法:
     1 public void test()
     2         {
     3             WebBrowser browser = new WebBrowser();
     4 
     5             HTMLDocument doc = (HTMLDocument)browser.Document.DomDocument;
     6 
     7             for (int i = 0; i < browser.Document.Window.Frames.Count; i++)
     8             {
     9 
    10                 IHTMLDocument3 baiduDoc = CorssDomainHelper.GetDocumentFromWindow(browser.Document.Window.Frames[i].DomWindow
    11 
    12                     as IHTMLWindow2);
    13 
    14                 if (baiduDoc != null && baiduDoc.documentElement != null && baiduDoc.documentElement.document != null)
    15                 {
    16 
    17                     IHTMLElementCollection linkss = ((HTMLDocument)(baiduDoc.documentElement.document)).links;
    18 
    19                     foreach (mshtml.IHTMLElement element in linkss)
    20                     {
    21 
    22                         //加入你的代码就可以了。
    23 
    24                     }
    25                 }
    26             }
    27         }

    原文出自:http://www.cnblogs.com/Leo_wl/p/3181353.html

  • 相关阅读:
    人生,时间煮雨,岁月缝花
    Nginx入门到实践---nginx中间件
    CentOS 8 系统安装 Oracle 19c 数据库
    centos8 下安装Oracle jdk8(免安装版)
    Mysql忘记密码
    这个病秋季高发!调理不当最伤孩子体质,记得收好这2个方
    redis client-output-buffer-limit 设置
    redis主从同步收到以下参数影响
    linux:永久打开core文件功能
    linux:core文件的产生和调试
  • 原文地址:https://www.cnblogs.com/changjianblog/p/7456618.html
Copyright © 2020-2023  润新知