MSDN.WhiteKnight - Stack Overflow answers
Ответ на "c#. System.Windows.Forms.WebBrowser и код текста для IFrame"
Answer 773093
Свойство
DocumentText
возвращает то, что вы просите - код документа. Код содержимого iframe'ов в него не входит, поскольку iframe - это больше, чем просто механизм подстановки одного HTML внутрь другого (*). Чтобы получить документ вместе с содержимым iframe'ов, единственный способ - пройти по всем iframe'ам, взять их содержимое (например, через интерфейсMSHTML.IHTMLIFrameElement3
) и подставить в исходный документ. Понятно, нельзя получить содержимое, если iframe смотрит в другой домен.Как-то так:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace WebBrowserTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public String DomDocumentText { get { var document = webBrowser1.Document; string returnstr = ""; MSHTML.IHTMLDocument3 doc3 = null; MSHTML.HTMLDocument new_doc = null; MSHTML.IHTMLDocument2 doc2 = null; MSHTML.IHTMLElementCollection elems = null; MSHTML.IHTMLDocument3 new_doc3 = null; MSHTML.IHTMLElementCollection elems_new = null; MSHTML.IHTMLDocument3 child_doc = null; MSHTML.IHTMLElement content = null; MSHTML.IHTMLElement content_new = null; MSHTML.IHTMLElementCollection elem_col = null; try { doc3 = (MSHTML.IHTMLDocument3)document.DomDocument;//исходный документ new_doc = new MSHTML.HTMLDocument();//копия документа doc2 = new_doc as MSHTML.IHTMLDocument2; doc2.write(webBrowser1.DocumentText);//создаем копию документа //получаем все iframe в документе и его копии... elems = doc3.getElementsByTagName("iframe"); new_doc3 = new_doc as MSHTML.IHTMLDocument3; elems_new = (new_doc3).getElementsByTagName("iframe"); int i = 0; foreach (MSHTML.IHTMLIFrameElement3 elem in elems) //для каждого iframe... { try { child_doc = elem.contentDocument as MSHTML.IHTMLDocument3; elem_col = child_doc.getElementsByTagName("body"); if (elem_col == null || elem_col.length == 0) { i++; continue; } content = (MSHTML.IHTMLElement)elem_col.item(0); string str = (content).innerHTML;//получаем содержимое iframe content_new = elems_new.item(i) as MSHTML.IHTMLElement; (content_new).outerHTML = str;//заменяем iframe на его содержимое i++; } catch (Exception ex) { //для iframe, URL которых в другом домене, будет исключение //HRESULT: 0x80070005 (E_ACCESSDENIED) System.Diagnostics.Debug.WriteLine("Can't process iframe " + i.ToString()); System.Diagnostics.Debug.WriteLine(ex.Message); } finally { //Очистка ресурсов, задействованных в цикле... if (child_doc != null) { Marshal.ReleaseComObject(child_doc); child_doc = null; } if (elem_col != null) { Marshal.ReleaseComObject(elem_col); elem_col = null; } if (content != null) { Marshal.ReleaseComObject(content); content = null; } if (content_new != null) { Marshal.ReleaseComObject(content_new); content_new = null; } } }//end foreach returnstr = new_doc.documentElement.innerHTML; return returnstr; } finally { //Окончательная очистка ресурсов... if (doc3 != null) Marshal.ReleaseComObject(doc3); if (new_doc != null) Marshal.ReleaseComObject(new_doc); if (doc2 != null) Marshal.ReleaseComObject(doc2); if (elems != null) Marshal.ReleaseComObject(elems); if (new_doc3 != null) Marshal.ReleaseComObject(new_doc3); if (elems_new != null) Marshal.ReleaseComObject(elems_new); if (child_doc != null) Marshal.ReleaseComObject(child_doc); if (content != null) Marshal.ReleaseComObject(content); if (content_new != null) Marshal.ReleaseComObject(content_new); if (elem_col != null) Marshal.ReleaseComObject(elem_col); } } } private void button1_Click(object sender, EventArgs e) { MessageBox.Show(DomDocumentText); } } }
Для использования нужно подключить библиотеку COM-объектов IE (в Visual Studio Добавить ссылку -> СОМ -> Microsoft HTML Object Library, либо вручную указать файл mshtml.tlb).
Примечания
(*) - Для iframe браузер создает отдельное окно внутри основного окна, которое может, в общем случае, отображать не HTML, а документ другого типа. Поэтому в модели DOM свойство
InnerHTML
у iframe соответствует не его содержимому, а замещающему тексту для браузеров без поддержки iframe, который можно поместить внутрь тега iframe (что редко используется в наше время).
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.