Delphi 解析HTTP目录列表

Delphi 解析HTTP目录列表,delphi,delphi-xe,Delphi,Delphi Xe,你好!我正在使用Delphi XE和Indy TIdHTTP。使用Get方法,我得到远程目录列表,我需要解析它=获取文件列表及其大小和时间戳,并区分文件和子目录。请问,有没有一个很好的例行程序?提前谢谢你!沃伊特 以下是示例: <head> <title>127.0.0.1 - /</title> </head> <body> <H1>127.0.0.1 - /</H1><hr> <pr

你好!我正在使用Delphi XE和Indy TIdHTTP。使用Get方法,我得到远程目录列表,我需要解析它=获取文件列表及其大小和时间戳,并区分文件和子目录。请问,有没有一个很好的例行程序?提前谢谢你!沃伊特

以下是示例:

<head>
  <title>127.0.0.1 - /</title>
</head>
<body>
  <H1>127.0.0.1 - /</H1><hr>
<pre>      
  Mittwoch, 30. März 2011    12:01        &lt;dir&gt; <A HREF="/SubDir/">SubDir</A><br />
  Mittwoch, 9. Februar 2005    17:14          113 <A HREF="/file.txt">file.txt</A><br />
</pre>
<hr>
</body>

127.0.0.1 - /
127.0.0.1-/
米特沃赫,30岁。玛尔兹2011 12:01目录
米特沃赫,9岁。2005年2月17:14113


给定代码示例,我想最快的解析方法如下:

  • 识别包含所有列表行的
    块。应该很容易
  • A HREF=/SubDir/
    A innerText=SubDir
    Mittwoch, 30. März 2011 12:01 <dir>
    -------------
    A HREF=/file.txt
    A innerText=file.txt
    Mittwoch, 9. Februar 2005 17:14 113
    -------------
    
  • 之间的所有内容放入
    TStringList
    中。每行都是一个文件或文件夹,格式非常简单
  • 从每行提取链接,如果需要,提取日期、时间和大小。最好使用正则表达式(你有Delphi XE,所以你有内置正则表达式)

这将为您提供一个使用DOM的良好开端和想法:

使用
MSHTML,
ActiveX,
科莫布;
过程文档FromString(文档:IHTMLDocument2;常量S:WideString);
变量
v:油变异体;
开始
v:=VarArrayCreate([0,0],varvarvariant);
v[0]:=S;
写作(诗篇(TVarData(v.VArray));
文件。关闭;
结束;
函数StripMultipleChar(常数S:string;常数C:Char):string;
开始
结果:=S;
而位置(C+C,结果)0
结果:=StringReplace(结果,C+C,C[rfReplaceAll]);
结束;
程序TForm1.按钮1单击(发送方:TObject);
变量
文件:IHTML文件2;
要素:IHTMlementCollection;
要素:IHTMlement;
I:整数;
行:字符串;
开始
文档:=CreateComObject(类\u HTMLDocument)作为IHTMLDDocument2;
DocumentFromString(文档“…”);//你的HTML在这里
元素:=Document.all.tags('A'),作为IHTMlementCollection;
对于I:=0到Elements.length-1 do
开始
元素:=元素。项(I,“”)作为IHTMLElement;
Memo1.Lines.Add('A HREF='+Element.getAttribute('HREF',2));
Memo1.Lines.Add('A innerText='+Element.innerText);
//返回的文本紧跟在元素之前
行:=(元素作为IHTMlement2.getAdjacentText('beforeBegin');
//行=>“Mittwoch,30.März 2011 12:01”或:
//行=>“Mittwoch,9.Februar 2005 17:14 113”。。。
//我不知道实际的分隔符是什么:
//它可以是[space]或[tab],因此我们需要规范化该行
//如果是制表符,则更容易,因为时间戳也包含空格
线条:=修剪(线条);
行:=StripMultipleChar(行,#32);//带多空间序列
行:=StripMultipleChar(行,#9);//带多个标签序列
//TODO:ParseLine(从右到左)
备注1.行。添加(行);
备注1.行。添加('--------------');
结束;
结束;

输出:

A HREF=/SubDir/
innerText=SubDir
米特沃赫,30岁。玛尔兹2011 12:01
-------------
A HREF=/file.txt
A innerText=file.txt
米特沃赫,9岁。2005年2月17:14113
-------------

编辑:

我已将
StripMultipleChar
实现更改为更加简化。但我相信前一个版本在速度方面更优化。考虑到线路长度很短,性能不会有太大差异。

有样品吗?实际上,没有一个标准的“目录列表”(实际上,有几个目录列表,具体取决于服务器和它运行的操作系统),如果不知道您使用的是哪个,很难判断您可能需要做什么。您需要的是一个创建树的HTML解析器,因此很容易找到所有的“目录列表”标记并根据您的需要进行操作。如果服务器支持WebDAV,则使用WebDAV客户端库可以轻松实现更强健的解决方案。每次服务器版本更新或软件更改都会破坏特定于此HTML输出的解析器。@DorinDuminica,我还想到了DOM“解析器”。看一看。但我认为在这种情况下,这是一种过度的杀伤力。所以我使用@Cosmin Prund(+1 BTW),特别是如果
pre
标记中的每一行都是
TAB
分隔的(
TStringList
就可以了)。@kobik是不是有点过分了?我不这么认为,主要是因为如果解析器稍微优化一下,它会非常快,如果使用Pos()或类似的搜索,它很容易在以后中断,通常在没有时间修复时中断…+1。有样品就容易了。我问你,你不高兴吗?:)+1因为它会起作用。
StripMultipleChar
可以简化一点。它可以简化和优化。你们有这么多while循环,这让我头晕目眩:你们只需要一个简单的、直接的for循环。@Cosmin Prund,请看我的编辑。前一个函数实际上是基于一个JCL单元。。。
A HREF=/SubDir/
A innerText=SubDir
Mittwoch, 30. März 2011 12:01 <dir>
-------------
A HREF=/file.txt
A innerText=file.txt
Mittwoch, 9. Februar 2005 17:14 113
-------------