Delphi中从剪贴板读取HTML内容

3
我有一个网页,里面有各种表格。这些表格是JavaScript组件,不仅仅是纯HTML表格。我需要用Delphi程序(Delphi 10.3)处理此网页的文本(有点类似于屏幕抓取)。
我使用Ctrl-A/Ctrl-C选择整个网页并将所有内容复制到剪贴板中。如果我将其粘贴到程序中的TMemo组件中,我只能得到表格外的文本。如果我将其粘贴到MS Word中,则可以查看所有内容,包括表格内的文本。
我可以将其正确地粘贴到TAdvRichEditor(第三方软件)中,但这需要很长时间,并且我经常会遇到内存不足的情况。这使我相信我需要直接读取带有HTML格式的剪贴板。
我设置了一个剪贴板HTML格式。当我检查剪贴板内容时,我看到的是所有汉字字符。
当剪贴板内容为HTML时,如何读取剪贴板内容?
在完美的情况下,我只想要文本本身,而不是HTML本身,但我以后可以将其去除。这是我现在正在做的...
在初始化时...(其中CF_HTML是全局变量)
CF_HTML := RegisterClipboardFormat('HTML Format');

那么我的例行工作就是...
function TMain.ClipboardAsHTML: String;
var
  Data: THandle;
  Ptr: PChar;
begin
  Result := '';
  with Clipboard do
  begin
    Open;
    try
      Data := GetAsHandle(CF_HTML);
      if Data <> 0 then
      begin
        Ptr := PChar(GlobalLock(Data));
        if Ptr <> nil then
        try
          Result := Ptr;
        finally
          GlobalUnlock(Data);
        end;
      end;
    finally
      Close;
    end;
  end;
end;

**附加信息-当我从网页复制时...,我可以使用一个名为InsideClipboard的免费工具检查剪贴板缓冲区的内容。它显示剪贴板包含1个条目,有5种格式:CT_TEXT, CF_OEMTEXT, CF_UNICODETEXT, CF_LOCALE'HTML Format' (格式ID为49409)。只有'HTML Format'包含我正在寻找的内容....这就是我尝试使用所示代码访问的内容。


问题在于,当您使用CTRL+A和CTRL+C复制网页内容时,内容不会以HTML格式保存在剪贴板中。至少根据WindowsXP中可用的剪贴板查看器Clipbrd.exe是这样的。是的,您可以将此文件复制到Windows 7并且它仍然有效。但是根据我所读到的信息,它在Windows 10上无法使用。无论如何,根据Clibrd.exe的信息,网页的内容以文本、Unicode文本、区域设置和OEM文本格式保存到剪贴板中... - SilverWarior
本地格式是以二进制形式存储的,可能导致所有那些看起来像汉字的字符。不过,为什么不尝试使用纯HTML格式从浏览器保存网页呢?这可能会强制浏览器将JavaScript生成的表格替换为易于处理的纯HTML表格。 - SilverWarior
从调试开始。深入挖掘。检查剪贴板。它实际包含了什么。 - David Heffernan
@@David - 我在我的问题中添加了一些额外的信息。数据以“HTML格式”存储在剪贴板中,但我无法弄清如何访问它。 - user1009073
1个回答

10

HTML 格式的文档可以在这里找到。它以 UTF-8 编码的文本形式放置在剪贴板上,您可以像这样提取它。

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows,
  Vcl.Clipbrd;

procedure Main;
var
  CF_HTML: Word;
  Data: THandle;
  Ptr: Pointer;
  Error: DWORD;
  Size: NativeUInt;
  utf8: UTF8String;
  Html: string;
begin
  CF_HTML := RegisterClipboardFormat('HTML Format');

  Clipboard.Open;
  try
    Data := Clipboard.GetAsHandle(CF_HTML);
    if Data=0 then begin
      Writeln('HTML data not found on clipboard');
      Exit;
    end;

    Ptr := GlobalLock(Data);
    if not Assigned(Ptr) then begin
      Error := GetLastError;
      Writeln('GlobalLock failed: ' + SysErrorMessage(Error));
      Exit;
    end;
    try
      Size := GlobalSize(Data);
      if Size=0 then begin
        Error := GetLastError;
        Writeln('GlobalSize failed: ' + SysErrorMessage(Error));
        Exit;
      end;

      SetString(utf8, PAnsiChar(Ptr), Size - 1);
      Html := string(utf8);
      Writeln(Html);
    finally
      GlobalUnlock(Data);
    end;
  finally
    Clipboard.Close;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

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