Delphi:解析这个 html 表的一些技巧?

2023-12-14

有时我试图从这个 html 表中获取数据,我尝试了付费和免费的组件。我尝试做一些编码,但也没有结果。我有一个类可以直接为 ClientDataSet 抛出 html 表,但是对于这个表它不起作用。有人知道如何获取此 html 表中的数据吗?或者将其转换为 txt / xls / csv 或 xml 的方法?遵循表的代码:

  WebBrowser1.Navigate('http://site2.aesa.pb.gov.br/aesa/monitoramentoPluviometria.do?metodo=listarMesesChuvasMensais');
  WebBrowser1.OleObject.Document.All.Tags('select').Item(0).Value:= '2013';
  WebBrowser1.OleObject.Document.All.Tags('select').Item(1).Value:= '7';
  WebBrowser1.OleObject.Document.All.Tags('input').Item(1).click;
  Memo1.Text:= WebBrowser1.OleObject.Document.All.Tags('table').Item(10).InnerHTML;
  Memo1.Lines.SaveToFile('table.html');

以下将从目标页面上的 HTML 表中提取数据 并将其加载到 ClientDataSet 中。

它相当冗长,也许表明正如大卫所说,德尔福 也许不是完成这项工作的最佳工具。

在我的 Form1 上,我有一个 TEdit,edValue,供我在第一个中键入值 HTML 表格数据中的数据行。我用它来查找表中的表 HTML 文档。我敢说有更好的方法,但至少我的方法应该比关于嵌入表格的文档布局的硬编码假设更强大,这些假设可能无法在页面作者的更改后幸存下来。

概括地说,该代码的工作原理是首先使用以下内容查找 HTML 表格单元格: 我的 edValue.Text,然后找到该单元格所属的表,然后 填充 CDS 的字段和表中的数据。

CDS 字段默认设置为 255 个字符;也许有一个规范 网页上发布的数据,允许您对某些(如果不是全部)字段使用较小的值。它们都被假定为 ftString 类型,以避免代码因意外的单元格内容而阻塞。

顺便说一句,底部是一个用于将 HTML 页面保存到本地的实用函数,以 无需不断点击按钮来选择年份+月份。重新加载 WebBrowser 从保存的文件中加载,只需使用文件名作为 URL 即可加载。

TForm1 = class(TForm)
[ ... ]
public
  { Public declarations }
  Doc : IHtmlDocument2;

procedure TForm1.btnFindValueClick(Sender: TObject);
var
  Table : IHTMLTable;
begin
  Doc := WebBrowser1.Document as IHTMLDocument2;
  Table := FindTableByCellValue(edValue.Text);
  Assert(Table <> Nil);
  LoadCDSFromHTMLTable(CDS, Table);
end;

procedure TForm1.LoadCDSFromHTMLTable(DestCDS : TClientDataSet; Table : IHTMLTable);
var
  I,
  J : Integer;
  vTable : OleVariant;
  iRow : IHTMLTableRow;
  FieldName,
  FieldValue : String;
  Field : TField;
const
  cMaxFieldSize = 255;
  scIDFieldName = 'ID';
begin
  //  Use OleVariant instead of IHTMLTable becuse it's less fiddly for doing what follows
  vTable := Table;
  Assert(not DestCDS.Active and (DestCDS.FieldCount = 0));

  //  First create an AutoInc field
  Field := TAutoIncField.Create(Self);
  Field.FieldName := scIDFieldName;
  Field.DataSet := DestCDS;


  // Next create CDS fields from the names in the cells in the first row of the table
  for I := 0 to (vTable.Rows.Item(0).Cells.Length - 1) do begin
    FieldName := vTable.Rows.Item(0).Cells.Item(I).InnerText;
    Field := TStringField.Create(Self);
    // At this point, we might want to clean up the FieldName by removing embedded spaces, etc
    Field.FieldName := FieldName;
    Field.Size := cMaxFieldSize;
    Field.DataSet := DestCDS;
  end;

  DestCDS.DisableControls;
  try
    DestCDS.IndexFieldNames := scIDFieldName;
    DestCDS.CreateDataSet;

    //  Next load the HTML table data into the CDS
    for I := 1 to (vTable.Rows.Length - 1) do begin
      DestCDS.Insert;
      for J := 0 to vTable.Rows.Item(0).Cells.Length - 1 do begin
        FieldValue := vTable.Rows.Item(I).Cells.Item(J).InnerText;
        // the J + 1 is because Fields[0] is the autoinc one
        DestCDS.Fields[J + 1].AsString := FieldValue;
      end;
      DestCDS.Post;
    end;
    DestCDS.First;
  finally
    DestCDS.EnableControls;
  end;
end;

function TForm1.FindTableCellByTagValue(Doc : IHtmlDocument2; const AValue : String) : IHTMLTableCell;
var
  All: IHTMLElementCollection;
  Value: String;
  I,
  Len: Integer;
  E: OleVariant;
  iE : IHTMLElement;
  iT : IHTMLTextElement;
  iC : IHTMLTableCell;
begin
  Result := Nil;
  All := Doc.All;
  if All = Nil then Exit;
  Len := All.Length;

  for I := 0 to Len - 1 do begin
    E := All.Item(I, varEmpty);
    iE := IDispatch(E) as IHTMLElement;
    if Supports(iE, IHTMLTableCell, iC) then begin
      Value := Trim(iE.Get_InnerText);
      if Pos(Trim(AValue), Value) = 1 then begin
        Result := iC;
        Break;
      end
    end
    else
      Continue;
  end;
end;

function TForm1.FindTableByCellValue(Value : String): IHTMLTable;
var
  Node : IHtmlElement;
  iTable : IHTMLTable;
  iCell : IHTMLTableCell;
begin
  Result := Nil;
  iCell := FindTableCellByTagValue(Doc, edValue.Text);
  if iCell = Nil then
    Exit;
  Node := IDispatch(iCell) as IHtmlElement;

  //  if we found a Node with the cell text we were looking for,
  //  we can now find the HTML table to which it belongs

  while Node <> Nil do begin
    Node := Node.parentElement;
    if Supports(Node, IHTMLTable, iTable) then begin
      Result := iTable;
      Break;
    end;
  end;
end;

procedure TForm1.SaveFileLocally(const FileName : String);
var
  PFile: IPersistFile;  // declared in ActiveX unit
begin
  PFile := Doc as IPersistFile;
  PFile.Save(StringToOleStr(FileName), False);
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi:解析这个 html 表的一些技巧? 的相关文章

  • 两列表:一列尽可能小,另一列占据其余部分

    我在 div 中有一个 to columns 表 div table tbody tr td class action a a td td class content p Bigger text variable size p td tr
  • 如何在模态打开时防止主体滚动

    我在用着W3schools 模态脚本 https www w3schools com howto tryit asp filename tryhow css modal我想添加一个功能 防止模型打开时整个主体滚动 我根据我的需要对原始脚本做
  • 为什么我的交互式图像仅在 Internet Explorer 上出现故障?

    我的问题 我为自己制作了一个图像地图 交互式图像 它在 Chrome safari 和 Firefox 上完美运行 然而 当我在可怕的互联网浏览器上尝试它时 它真的很糟糕 这些小点应该扩展到更大的盒子中 在互联网浏览器上它要么不起作用 要么
  • 使用 CSS 折叠和展开元素

    我正在尝试构建一个页面 加载时仅可见标题 并且 当用户单击标题时 每个标题下方的表格会在隐藏和显示状态之间切换 我的限制是只能在 CSS 中执行此操作 这是我到目前为止想到的 https jsfiddle net Argoron c1ypx
  • 禁用允许文本选择的

    残疾人可以吗
  • 在所有浏览器的 HTML 页面中嵌入 .wav 文件(无控件)

    我需要在单击按钮时播放一些 wav 文件 我找到了在 IE 中工作的解决方案 但它需要 Firefox 的 QuickTime 插件 还有其他办法吗 h1 test h1 span span
  • 仅 IE9_有时_会忽略

    我们正在开发一个大量使用 这是典型的 TYPO3 网站 该网站是在子目录中开发的 稍后将被重新定位到顶级目录 因此我们无法轻易删除 我们的客户告诉我们 有时当她浏览新页面时 她得到的页面内容没有应用布局 我们对此进行了调试 仅在 IE9 中
  • 我可以在元标记中使用 HTML 字符实体吗?

    我有一个有两种语言的网站 英语和中文 在使用 UTF 8 字符集的英文主页中 我有 例如 这出现在搜索结果中 我想将其更改为 在哪里 20013 25991 是 中文 的 ISO 实体 搜索结果中会显示为 中文 吗 我无法将 中文 直接粘贴
  • 为什么开发者讨厌 iframe? [复制]

    这个问题在这里已经有答案了 可能的重复 iframe 被认为是 不好的做法 吗 https stackoverflow com questions 362730 are iframes considered bad practice 在与
  • 如何为 HTML 元素创建鼠标拖动滑块?

    我发现的许多滑块插件要么仅单击以查看下一个图像 要么如果它们确实具有鼠标拖动或触摸拖动功能 则仅允许图像 有谁知道为任何 html 元素编写鼠标拖动滑块的插件或可能的方法 我专门使用 SVG 但将来如果能在 div 元素之间滑动就更好了 H
  • 如何在 select2 下拉列表中换行?

    我正在使用 select 2 下拉菜单 然后在其内容中显示一些长句子 我想在句子的正确位置添加换行符 但下拉菜单是自动调整的 For example the content of the dropdown right now looks l
  • 如何在有序列表中组合数字和字母?

    如何在 CSS 中用数字和字母递增有序列表 ol nested margin bottom 0 counter reset item ol nested li display block position relative ol neste
  • Twitter 卡元标签问题

    有问题的网址 https www halleonard com viewpressreleasedetail action releaseid 10261 https www halleonard com viewpressreleased
  • 网站的主体和元素固定在 980px 宽度上,不会缩小

    我试图在 Rails 应用程序顶部启动前端 仅 HTML CSS 页面 但在使用 320px 视口时遇到问题 有些元素不会按比例缩小 我不明白为什么 我已经完成了检查元素 为各种元素提供了max width 100 and or width
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • 不可勾选的单选按钮与专有的复选框

    从 UI 角度来看 是拥有一组具有取消选中功能的单选按钮更好 还是拥有一组独占的复选框 意味着一次只能选中一个 更好 Update 我没想到对此会有如此负面的反应 如果我给出一个更接近其使用方式的示例 也许会有所帮助 我有一个充满数据绑定内
  • 如何更改 TPageControl 上标签的方向?

    我是 Delphi 的新手 再次强调 我在 1994 年就使用过 Delphi 我现在有 Delphi 2009 Pro 来自Java 我发现对象继承非常晦涩 我的用户想要选项卡位于左侧的选项卡式页面 但是 TPageControl 不允许
  • 可以设置标题样式吗? (并且使用CSS或js?)[重复]

    这个问题在这里已经有答案了 我想知道是否可以设计一个title a href title This is a title Hello a 样式问题有两个方面 文本格式 编码 我猜这是可能的 所以在问题中这样做 工具提示样式 你能把它弄大一点
  • 在 Delphi 中编程延迟的最佳方法是什么?

    我正在开发的 Delphi 应用程序必须延迟一秒 有时甚至两秒 我想使用最佳实践来对此延迟进行编程 在阅读 stackoverflow 上有关 Delphi Sleep 方法的条目时 我发现了以下两条评论 我遵循这样的格言 如果你觉得需要使
  • 使用css bootstrap时如何仅向一列添加右边框?

    我正在尝试使用CSS引导框架 http getbootstrap com css tables在我的项目中 我正在使用带有以下类的表table table bordered table striped 我想删除除第一列之外的所有列的边框 这

随机推荐

  • ConnectivityManager.CONNECTIVITY_ACTION,注册接收器时总是广播?

    我正在注册一个接收器来捕获 ConnectivityManager CONNECTIVITY ACTIONin code即我没有在应用程序清单中注册它 一切工作正常 但我注意到 尽管网络已经打开 但只要我注册接收器 我就会自动收到广播 我的
  • 合并两个文本文件的最简单的脚本方法 - Ruby、Python、JavaScript、Java?

    我有两个文本文件 一个包含 HTML 另一个包含 URL slugs 文件 1 HTML li a href article a li
  • 在 Common Lisp 中创建函数定义时,首选 defun 还是 setf?为什么?

    使用定义的函数的根本区别是什么defun and setf如下所示 除了风格考虑之外 是否一种方法优于另一种方法 Using defun defun myfirst l car l MYFIRST myfirst A B C A Using
  • 在Python中创建HTTPS代理服务器

    我正在尝试在 python 中创建 HTTPS 代理服务器 我创建了以下适用于 HTTP 的脚本 usr bin env python3 coding utf 8 import socket from threading import Th
  • C# - for 循环以奇怪的间隔冻结

    我正在研究问题14在 Project Euler 上 我的代码似乎会以随机的间隔冻结 没有明显的原因 static void Main int maxNum 0 int maxLength 0 for int x 2 x lt 100000
  • 如何强制 jqGrid 4.10.1-pre 始终对 ' 字符进行编码[重复]

    这个问题在这里已经有答案了 免费jqgrid使用设置 autoencode true 网格定义包含 grid jqGrid url admin API Entity datatype json editurl admin Detail Ed
  • C# 纸牌游戏中的最佳纸牌选择

    问题在于在游戏的每个时刻遵循以下规则选择最佳选项 您只能选择最左边或最右边的卡 你的对手总是先选 并且总是从最左边或最右边的牌中选择最大的牌 如果是平局 它将选择最右边的 考虑到这并不总是最好的选择 有时不可能获胜 但无论如何 你必须通过与
  • 编译一个Rcpp包,调试符号中包含行信息

    我不知道如何为我的 R 包提供共享库调试符号源行信息 我缺少什么 我创建以下内容src Makevars file PKG CXXFLAGS O0 ggdb PKG LIBS O0 ggdb 我使用编译包R CMD INSTALL no m
  • 为什么 Spring Batch 为每个线程使用 1 个数据库连接?

    为什么 Spring Batch 为每个线程使用 1 个数据库连接 Stack Java 8 春季启动 1 5 春季批次 3 0 7 光CP 2 7 6 数据源配置 batcdb postgres 读数据库 Oracle writedb p
  • 以编程方式从 iPhone 应用程序访问设备音乐文件

    我想访问 iPhone 上可用的音乐文件并将其列出 或 将文件放入我的 iPhone 应用程序中并开始播放 有可能做到吗 类似于我们使用 UIImagePickerController 委托方法从设备相册访问图像的方式 谢谢你 您可以参考M
  • 是否可以使用 try/catch 捕获段错误?

    我做了这个测试来看看发生了什么 try int x 0 x 1234 catch cout lt lt OK 但它抛出了段错误 为什么它没有捕获段错误 不 你不能 A SEGFAULT不是一个常规的例外 您显示的代码只是未定义的行为 任何事
  • 没有标签的结构

    如果我声明一个这样的结构 struct int a char b ident 该结构有类型吗 即未指定的类型 默认类型等 相反 如果我声明一个结构 例如 struct J int a char b ident 我们可以说ident是一个类型
  • JsHint 警告:正则表达式文字可能会与“/=”混淆

    我的 Javascript 代码中有这一行 var regex Hello n JsHint 在这一行给了我一个警告 A regular expression literal can be confused with 但我不知道这个正则表达
  • 如何解析GDB中的段:偏移地址

    gdb info registers ds ds 0x7b 123 gdb disassemble Dump of assembler code for function printf plt 0x0804831c lt 0 gt jmp
  • 播放错误时关闭 MPMoviePlayerViewController

    我的 MPMovies PlayerViewController 遇到问题 如果控制器在指定的 URL 处找不到电影 它会显示白屏 并且我无法使其关闭 这就是我启动电影播放器 的方式 void playVideo NSString path
  • 多线程不起作用

    我正在制作一个简单的多线程程序来解释线程的工作原理 我想要两个计数器同时计数 但它不起作用 它仅在我使用时才有效 CheckForIllegalCrossThreadCalls False 但是 我想以正确的方式编程 Code Dim Th
  • nginx:未知指令“位置”

    这是我的代码 从第 35 行开始 location index index php root home body if request filename js css images robots txt index php rewrite
  • 将 Unicode 代码点数字转换为 Unicode 字符

    我正在使用 Python 3 中的 argparse 库从命令行参数读取 Unicode 字符串 这些字符串通常包含 普通 Unicode 字符 扩展拉丁语等 但有时 特别是当字符属于从右到左的脚本时 将字符串编码为 Unicode 代码点
  • PyQt类继承

    我很难理解 Python PyQt 的类继承 我有一个MainWindow和一个弹出窗口QWidget 我想与互动self label1 of the MainWindow之后QWidget在弹出窗口中打开 但我不知道该怎么做 我只知道相反
  • Delphi:解析这个 html 表的一些技巧?

    有时我试图从这个 html 表中获取数据 我尝试了付费和免费的组件 我尝试做一些编码 但也没有结果 我有一个类可以直接为 ClientDataSet 抛出 html 表 但是对于这个表它不起作用 有人知道如何获取此 html 表中的数据吗