Delphi通过MSHTML实现一个HTML解析类

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

最近经常会模拟网页提交返回网页源码,然后获得网页中相应的元素,于是需要常常解析Html中相应的各种元素,网络是个好东西,搜索一番,就找到了好几个Delphi版本的HtmlParser的类库,试着使用了几个,发现解析起来都不完整,或多或少的回出现一些问题!于是想到了如果界面上有一个浏览器,我们可以通过WebBrowser的Document接口对网页元素进行操作,很是方便!但是模拟网页提交,界面上是不一定要出现WebBrowser的,肯定有办法,不通过WebBrowser就直接解析HTML的,那便是我不要WebBrowser这个外壳,只要他里面的Document文档接口对象就能实现对Html的解析了,查找了一番MSDN,然后Google一下,果然可行,构建方法如下:

//创建IHTMLDocument2接口
  CoCreateInstance(CLASS_HTMLDocument, nil, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, FHtmlDoc);

接口创建好了之后就能够对文档元素进行解析了,很是爽快!

结合了我自己的特有操作,我对Combobox,Table,Frame等一些网页元素做了相应的封装,实现了一个HTMLParser,大致代码如下:

这里只给出声明,代码请在最后下载 

复制代码
代码
(* **************************************************** *)
(*                 得闲工作室                           *)
(*               网页元素操作类库                       *)
(*                                                      *)
(*               DxHtmlElement Unit                     *)
(*     Copyright(c) 2008-2010  不得闲                   *)
(*     email:appleak46@yahoo.com.cn     QQ:75492895     *)
(* **************************************************** *)
unit  DxHtmlElement;

interface
uses  Windows,sysUtils,Clipbrd,MSHTML,ActiveX,OleCtrls,Graphics,TypInfo;

{ Get EleMent Type }
function  IsSelectElement(eleElement: IHTMLElement): Boolean;
function  IsPwdElement(eleElement: IHTMLElement): Boolean;
function  IsTextElement(element: IHTMLElement): boolean;
function  IsTableElement(element: IHTMLElement): Boolean;
function  IsElementCollection(element: IHTMLElement): Boolean;
function  IsChkElement(element: IHTMLElement): boolean;
function  IsRadioBtnElement(element: IHTMLElement): boolean;
function  IsMemoElement(element: IHTMLElement): boolean;
function  IsFormElement(element: IHTMLElement): boolean;
function  IsIMGElement(element: IHTMLElement): boolean;
function  IsInIMGElement(element: IHTMLElement): boolean;
function  IsLabelElement(element: IHTMLElement): boolean;
function  IsLinkElement(element: IHTMLElement): boolean;
function  IsListElement(element: IHTMLElement): boolean;
function  IsControlElement(element: IHTMLElement): boolean;
function  IsObjectElement(element: IHTMLElement): boolean;
function  IsFrameElement(element: IHTMLElement): boolean;
function  IsInPutBtnElement(element: IHTMLElement): boolean;
function  IsInHiddenElement(element: IHTMLElement): boolean;
function  IsSubmitElement(element: IHTMLElement): boolean;
{ Get ImgElement Data }
function  GetPicIndex(doc: IHTMLDocument2; Src:  string ; Alt:  string ): Integer;
function  GetPicElement(doc: IHTMLDocument2;imgName:  string ;src:  string ;Alt:  string ): IHTMLImgElement;
function  GetRegCodePic(doc: IHTMLDocument2;ImgName:  string ; Src:  string ; Alt:  string ): TPicture;  overload ;
function  GetRegCodePic(doc: IHTMLDocument2;Index: integer): TPicture;  overload ;
function  GetRegCodePic(doc: IHTMLDocument2;element: IHTMLIMGElement): TPicture; overload ;

type
  TObjectFromLResult 
=   function (LRESULT: lResult; const  IID: TIID; WPARAM: wParam; out  pObject): HRESULT;  stdcall ;
  TEleMentType 
=  (ELE_UNKNOW,ELE_TEXT,ELE_PWD,ELE_SELECT,ELE_CHECKBOX,ELE_RADIOBTN,ELE_MEMO,ELE_FORM,ELE_IMAGE,
  ELE_LABEL,ELE_LINK,ELE_LIST,ELE_CONTROL,ELE_OBJECT,ELE_FRAME,ELE_INPUTBTN,ELE_INIMAGE,ELE_INHIDDEN);


function  GetElementType(element: IHTMLELEMENT): TEleMentType;
function  GetElementTypeName(element: IHTMLELEMENT):  string ;
function  GetHtmlTableCell(aTable: IHTMLTable;aRow,aCol: Integer): IHTMLElement;
function  GetHtmlTable(aDoc: IHTMLDocument2; aIndex: Integer): IHTMLTable;
function  GetWebBrowserHtmlTableCellText(Doc: IHTMLDocument2;
         
const  TableIndex, RowIndex, ColIndex: Integer; var  ResValue:  string ):   Boolean;
function  GetHtmlTableRowHtml(aTable: IHTMLTable; aRow: Integer): IHTMLElement;

function  GetWebBrowserHtmlTableCellHtml(Doc: IHTMLDocument2;
         
const  TableIndex,RowIndex,ColIndex: Integer; var  ResValue:  string ):   Boolean;
function  GeHtmlTableHtml(aTable: IHTMLTable; aRow: Integer): IHTMLElement;
function  GetWebBrowserHtmlTableHtml(Doc: IHTMLDocument2;
         
const  TableIndex,RowIndex: Integer; var  ResValue:  string ):   Boolean;

type
  TDxWebFrameCollection 
=   class ;
  TDxWebElementCollection 
=   class ;

 
  TLoadState 
=  (Doc_Loading,Doc_Completed,Doc_Invalidate);

  TDxWebFrame 
=   class
  
private
    FFrame: IHTMLWINDOW2;
    FElementCollections: TDxWebElementCollection;
    FWebFrameCollections: TDxWebFrameCollection;
    
function  GetSrc:  string ;
    
function  GetElementCount: integer;
    
function  GetWebFrameCollections: TDxWebFrameCollection;
    
function  GetElementCollections: TDxWebElementCollection;
    
function  GetDocument: IHTMLDOCUMENT2;
    
function  GetReadState: TLoadState;
    
function  GetIsLoaded: boolean;
    
procedure  SetFrame( const  Value: IHTMLWINDOW2);
    
function  GetName:  string ;
  
public
    Constructor Create(IFrame: IHTMLWINDOW2);
    Destructor Destroy;
override ;
    
property  Frame: IHTMLWINDOW2  read  FFrame  write  SetFrame;
    
property  Src:  string   read  GetSrc;
    
property  Document: IHTMLDOCUMENT2  read  GetDocument;
    
property  Name:  string   read  GetName;
    
property  Frames: TDxWebFrameCollection  read  GetWebFrameCollections;
    
property  ElementCount: integer  read  GetElementCount;
    
property  ElementCollections: TDxWebElementCollection  read  GetElementCollections;
    
property  ReadyState: TLoadState  read  GetReadState;
    
property  IsLoaded: boolean  read  GetIsLoaded;  
  
end ;


  TDxWebFrameCollection 
=  Class
  
private
    FFrameCollection: IHTMLFramesCollection2;
    Frame: TDxWebFrame;
    
function  GetCount: integer;
    
function  GetFrameInterfaceByIndex(index: integer): IHTMLWINDOW2;
    
function  GetFrameInterfaceByName(Name:  string ): IHTMLWINDOW2;
    
function  GetFrameByIndex(index: integer): TDxWebFrame;
    
function  GetFrameByName(Name:  string ): TDxWebFrame;
    
procedure  SetFrameCollection( const  Value: IHTMLFramesCollection2);
  
public
    Constructor Create(ACollection: IHTMLFramesCollection2);
    Destructor Destroy;
override ;
    
property  FrameCollection: IHTMLFramesCollection2  read  FFrameCollection  write  SetFrameCollection;
    
property  Count: integer  read  GetCount;
    
property  FrameInterfaceByIndex[index: integer]: IHTMLWINDOW2  read  GetFrameInterfaceByIndex;
    
property  FrameInterfaceByName[Name:  string ]: IHTMLWINDOW2  read  GetFrameInterfaceByName;

    
property  FrameByIndex[index: integer]: TDxWebFrame  read  GetFrameByIndex;
    
property  FrameByName[Name:  string ]: TDxWebFrame  read  GetFrameByName;
  
end ;
  
  TDxWebElementCollection 
=   class
  
private
    FCollection: IHTMLElementCollection;
    FChildCollection:  TDxWebElementCollection;
    
function  GetCollection(index: String): TDxWebElementCollection;
    
function  GetCount: integer;
    
function  GetElement(itemName:  string ; index: integer): IHTMLElement;
    
function  GetElementByName(itemName:  string ): IHTMLELEMENT;
    
function  GetElementByIndex(index: integer): IHTMLELEMENT;
    
procedure  SetCollection( const  Value: IHTMLElementCollection);
  
public
    Constructor Create(ACollection: IHTMLElementCollection);
    Destructor Destroy;
override ;
    
property  Collection: IHTMLElementCollection  read  FCollection  write  SetCollection;
    
property  ChildElementCollection[index: String]: TDxWebElementCollection  read  GetCollection;
    
property  ElementCount: integer  read  GetCount;
    
property  Element[itemName:  string ;index: integer]: IHTMLElement  read  GetElement;
    
property  ElementByName[itemName:  string ]: IHTMLELEMENT  read  GetElementByName;
    
property  ElementByIndex[index: integer]: IHTMLELEMENT  read  GetElementByIndex;
  
end ;

  TLinkCollection 
=   class (TDxWebElementCollection)
  
  
end ;
  TDxWebTable 
=   class ;

  TDxTableCollection 
=   class
  
private
    FTableCollection: IHTMLElementCollection;
    FDocument: IHTMLDOCUMENT2;
    FWebTable: TDxWebTable;
    
function  GetTableInterfaceByName(AName:  string ): IHTMLTABLE;
    
procedure  SetDocument(Value: IHTMLDOCUMENT2);
    
function  GetTableInterfaceByIndex(index: integer): IHTMLTABLE;
    
function  GetCount: integer;
    
function  GetTableByIndex(index: integer): TDxWebTable;
    
function  GetTableByName(AName:  string ): TDxWebTable;
  
public
    Constructor Create(Doc: IHTMLDOCUMENT2);
    
destructor  Destroy; override ;
    
property  TableInterfaceByName[AName:  string ]: IHTMLTABLE  read  GetTableInterfaceByName;
    
property  TableInterfaceByIndex[index: integer]: IHTMLTABLE  read  GetTableInterfaceByIndex;

    
property  TableByName[AName:  string ]: TDxWebTable  read  GetTableByName;
    
property  TableByIndex[index: integer]: TDxWebTable  read  GetTableByIndex;
    
    
property  Document: IHTMLDOCUMENT2  read  FDocument  write  SetDocument;
    
property  Count: integer  read  GetCount;
  
end ;

  TDxWebTable 
=   class
  
private
    FTableInterface: IHTMLTABLE;
    
function  GetRowCount: integer;
    
procedure  SetTableInterface( const  Value: IHTMLTABLE);
    
function  GetCell(ACol, ARow: integer):  string ;
    
function  GetRowColCount(RowIndex: integer): integer;
    
function  GetInnerHtml:  string ;
    
function  GetInnerText:  string ;
    
function  GetCellElement(ACol, ARow: Integer): IHTMLTableCell;
  
public
    Constructor Create(ATable: IHTMLTABLE);
    
property  TableInterface: IHTMLTABLE  read  FTableInterface  write  SetTableInterface;
    
property  RowCount: integer  read  GetRowCount;
    
property  Cell[ACol: integer;ARow: integer]:  string   read  GetCell;
    
property  CellElement[ACol: Integer;ARow: Integer]: IHTMLTableCell  read  GetCellElement;
    
property  RowColCount[RowIndex: integer]: integer  read  GetRowColCount;
    
property  InnerHtml:  string   read  GetInnerHtml;
    
property  InnerText:  string   read  GetInnerText;
  
end ;

  TDxWebCombobox 
=   class
  
private
    FHtmlSelect: IHTMLSelectElement;
    
function  GetCount: Integer;
    
procedure  SetItemIndex( const  Value: Integer);
    
function  GetItemIndex: Integer;
    
function  GetName:  string ;
    
procedure  SetName( const  Value:  string );
    
function  GetValue:  string ;
    
procedure  SetValue( const  Value:  string );
    
procedure  SetCombInterface( const  Value: IHTMLSelectElement);
    
function  GetItemByName(EleName:  string ):  string ;
    
function  GetItemByIndex(index: integer):  string ;
    
function  GetItemAttribute(index: Integer; AttribName:  string ): OleVariant;
  
public
    
constructor  Create(AWebCombo: IHTMLSelectElement);
    
procedure  Add(Ele: IHTMLElement);
    
procedure  Insert(Ele: IHTMLElement;Index: Integer);
    
procedure  Remove(index: Integer);

    
property  CombInterface: IHTMLSelectElement  read  FHtmlSelect  write  SetCombInterface;
    
property  Count: Integer  read  GetCount;
    
property  ItemIndex: Integer  read  GetItemIndex  write  SetItemIndex;
    
property  ItemByIndex[index: integer]:  string   read  GetItemByIndex;
    
property  ItemByName[EleName:  string ]:  string   read  GetItemByName;
    
property  ItemAttribute[index: Integer;AttribName:  string ]: OleVariant  read  GetItemAttribute;
    
property  Name:  string   read  GetName  write  SetName;
    
property  value:  string   read  GetValue  write  SetValue;
  
end ;

implementation
end .
复制代码


 HTMLParser解析类的代码实现单元

复制代码
代码
(* **************************************************** *)
(*                 得闲工作室                           *)
(*               HTML解析单元库                         *)
(*                                                      *)
(*               DxHtmlParser Unit                      *)
(*     Copyright(c) 2008-2010  不得闲                   *)
(*     email:appleak46@yahoo.com.cn     QQ:75492895     *)
(* **************************************************** *)
unit  DxHtmlParser;

interface
uses  Windows,MSHTML,ActiveX,DxHtmlElement,Forms;

type
  TDxHtmlParser 
=   class
  
private
    FHtmlDoc: IHTMLDocument2;
    FHTML: 
string ;
    FWebTables: TDxTableCollection;
    FWebElements: TDxWebElementCollection;
    FWebComb: TDxWebCombobox;
    
procedure  SetHTML( const  Value:  string );
    
function  GetWebCombobox(AName:  string ): TDxWebCombobox;
  
public
    
constructor  Create;
    
destructor  Destroy; override ;
    
property  HTML:  string   read  FHTML  write  SetHTML;
    
property  WebTables: TDxTableCollection  read  FWebTables;
    
property  WebElements: TDxWebElementCollection  read  FWebElements;
    
property  WebCombobox[Name:  string ]: TDxWebCombobox  read  GetWebCombobox;
  
end ;
implementation

{  TDxHtmlParser  }

constructor  TDxHtmlParser.Create;
begin
  CoInitialize(
nil );
  
// 创建IHTMLDocument2接口
  CoCreateInstance(CLASS_HTMLDocument, 
nil , CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, FHtmlDoc);
  Assert(FHtmlDoc
<> nil , ' 构建HTMLDocument接口失败 ' );
  FHtmlDoc.Set_designMode(
' On ' );  // 设置为设计模式,不执行脚本
  
while   not  (FHtmlDoc.readyState  =   ' complete ' do
  
begin
    sleep(
1 );
    Application.ProcessMessages;
  
end ;                   
  FWebTables :
=  TDxTableCollection.Create(FHtmlDoc);
  FWebElements :
=  TDxWebElementCollection.Create( nil );
  FWebComb :
=  TDxWebCombobox.Create( nil );
end ;

destructor  TDxHtmlParser.Destroy;
begin
  FWebTables.Free;
  FWebElements.Free;
  FWebComb.Free;
  CoUninitialize;
  
inherited ;
end ;

function  TDxHtmlParser.GetWebCombobox(AName:  string ): TDxWebCombobox;
begin
   
if  FWebElements.Collection  <>   nil   then
   
begin
     FWebComb.CombInterface :
=  FWebElements.ElementByName[AName]  as  IHTMLSelectElement;
     Result :
=  FWebComb;
   
end
   
else  Result : =   nil ;
end ;

procedure  TDxHtmlParser.SetHTML( const  Value:  string );
begin
  
if  FHTML  <>  Value  then
  
begin
    FHTML :
=  Value;
    FHtmlDoc.body.innerHTML :
=  FHTML;
    FWebElements.Collection :
=  FHtmlDoc.all;
  
end ;
end ;

end .
复制代码
相关文章
|
5天前
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
26 2
|
20天前
|
XML 数据采集 数据格式
Python 爬虫必备杀器,xpath 解析 HTML
【11月更文挑战第17天】XPath 是一种用于在 XML 和 HTML 文档中定位节点的语言,通过路径表达式选取节点或节点集。它不仅适用于 XML,也广泛应用于 HTML 解析。基本语法包括标签名、属性、层级关系等的选择,如 `//p` 选择所有段落标签,`//a[@href=&#39;example.com&#39;]` 选择特定链接。在 Python 中,常用 lxml 库结合 XPath 进行网页数据抓取,支持高效解析与复杂信息提取。高级技巧涵盖轴的使用和函数应用,如 `contains()` 用于模糊匹配。
|
1月前
|
XML JavaScript 前端开发
如何解析一个 HTML 文本
【10月更文挑战第23天】在实际应用中,根据具体的需求和场景,我们可以灵活选择解析方法,并结合其他相关技术来实现高效、准确的 HTML 解析。随着网页技术的不断发展,解析 HTML 文本的方法也在不断更新和完善,
|
1月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
113 1
|
2月前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
68 3
|
2月前
|
XML 数据格式
HTML 实例解析
本文介绍了HTML中常见元素的使用方法,包括`&lt;p&gt;`、`&lt;body&gt;`和`&lt;html&gt;`等。详细解析了这些元素的结构和作用,并强调了正确使用结束标签的重要性。此外,还提到了空元素的使用及大小写标签的规范。
|
2月前
|
XML 前端开发 数据格式
Beautiful Soup 解析html | python小知识
在数据驱动的时代,网页数据是非常宝贵的资源。很多时候我们需要从网页上提取数据,进行分析和处理。Beautiful Soup 是一个非常流行的 Python 库,可以帮助我们轻松地解析和提取网页中的数据。本文将详细介绍 Beautiful Soup 的基础知识和常用操作,帮助初学者快速入门和精通这一强大的工具。【10月更文挑战第11天】
68 2
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
76 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
62 0

推荐镜像

更多
下一篇
DataWorks