如何从TWebBrowser获取HTML源代码

13

我该如何从WebBrowser组件获取源代码?

我想要获取WebBrowser组件上激活页面的源代码并将其写入备忘录组件。

谢谢。

4个回答

21

您可以使用 IPersistStreamInit 接口和 save 方法将Web浏览器的内容存储在数据流中。

Uses 
  ActiveX;

function GetWebBrowserHTML(const WebBrowser: TWebBrowser): String;
var
  LStream: TStringStream;
  Stream : IStream;
  LPersistStreamInit : IPersistStreamInit;
begin
  if not Assigned(WebBrowser.Document) then exit;
  LStream := TStringStream.Create('');
  try
    LPersistStreamInit := WebBrowser.Document as IPersistStreamInit;
    Stream := TStreamAdapter.Create(LStream,soReference);
    LPersistStreamInit.Save(Stream,true);
    result := LStream.DataString;
  finally
    LStream.Free();
  end;
end;

我们如何使其反向工作:SetWebBrowserHTML,从而重新将先前提取的代码注入到WebBrowser(或TEmbeddedWebBrowser)中。我想象以下情况:备忘录组件使用GetWebBrowserHTML获取HTML源代码,然后用户对源代码进行一些更改,然后将更改后的源代码重新注入到WebBrowser中。这将成为一个不错的HTML编辑器,并且可以在浏览器中实时预览! - user1580348
2
更好的写法:LStream := TStringStream.Create('', TEncoding.UTF8); - user1580348
如果你想要“反转”它,你只需要将LPersistStreamInit.Save更改为LPersistStreamInit.Load,并使用某些内容初始化TStringStream(或传入不同的流)。 - tmjac2

6
那也可以运行良好:
    uses MSHTML;

    function GetHTML(w: TWebBrowser): String;
    Var
      e: IHTMLElement;
    begin
      Result := '';
      if Assigned(w.Document) then
      begin
         e := (w.Document as IHTMLDocument2).body;
    
         while e.parentElement <> nil do
         begin
           e := e.parentElement;
         end;
    
         Result := e.outerHTML;
      end;
    end;

错误。这将获取document元素的DOM表示,而不是HTML源代码。 - kobik
是的,你说得对,我只是用它来解析一些HTML源代码中可用的数据,并且使用DOM表示法就足够了。 - Mehmet Fide
1
我会为你的答案点赞,它在任何情况下都非常有用。我在我们的爬虫中也使用类似的方法来操作/解析外国网站的HTML。 - kobik
1
我不得不点赞,因为我尝试获取源代码的页面被JavaScript更改了内容,所以 @rruz 的建议无法奏效,它返回的是原始HTML,而不是更改后的。谢谢。 - Fernando M. Pinheiro

3
这个问题在 Embarcadero 论坛上已经被问答多次,并发布了大量代码示例。请搜索档案。
总体来说,你需要使用 Navigate() 方法导航到所需的 URL 并等待 OnDocumentComplete 事件触发,然后对 Document 属性调用 QueryInterface() 方法以获取 IPersistStreamInit 接口,并调用其 save() 方法。创建一个 TStream 对象实例,例如 TMemoryStream,将其包装在 TStreamAdapter 对象中,然后将适配器传递给 save() 方法。然后,您可以根据需要将 TStream 加载到 TMemo 中。

2
为什么不要选择快速而肮脏的方法:
OnNavigateComplete2()

Form1.RichEdit1.Text:=(WebBrowser1.OleObject.Document.documentElement.outerhtml);

这个简单版本在UTF-8编码的页面上,对于非ASCII文本的处理效果要好得多。 - Kevin Davidson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接