【发布时间】:2015-11-13 12:37:53
【问题描述】:
我有一个系统,每 1 秒通过 GET 获取一个 html 来更新这个 html 中的系统数据可以有 1-20 个表单,需要获取所有表单并组装每个表单的查询字符串字段,我有一个函数这样做,问题是它比获取服务器html花费的时间更长,代码有什么问题?或者如何以不同的方式做到这一点?
procedure XThread.GetForms;
var
sTemp, xResF : String;
FormItem, v: Variant;
Field: Variant;
J, q, i, contCampos,
tmForm : Integer;
IDocForm : IHTMLDocument2;
begin
IDocForm := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2;
v := VarArrayCreate([0, 0], VarVariant);
v[0] := strFormMAT; //string html
IDocForm.Write(PSafeArray(System.TVarData(v).VArray));
IDocForm.Close;
tmForm := (IDocForm.all.tags('FORM') as IHTMLElementCollection).Length;
SetLength(matFormsArray, 0); //matFormsArray = Global Array of Array
SetLength(matFormsArray, tmForm);
for q := 0 to tmForm -1 do
begin
SetLength(matFormsArray[q], 2);
FormItem := (IDocForm.all.tags('FORM') as IHTMLElementCollection).item(q, 0);
xResF := '';
sTemp := FormItem.Name;
contCampos := FormItem.Length;
for j := 0 to contCampos - 1 do
begin
Field := FormItem.Item(j);
xResF := xResF + Field.Name + '=' + Field.Value;
if j < FormItem.Length - 1 then
xResF := xResF + '&';
end;
matFormsArray[q, 0] := sTemp;
matFormsArray[q, 1] := xResF;
end;
end;
strFormMAT =
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<form name="fprin" id="fprin">
<input type="hidden" name="field11" value="value11"></input>
<input type="hidden" name="field12" value="value12"></input>
<input type="hidden" name="field13" value="value13"></input>
</form>
<table>
<tr>
<td>Title</td>
<td>Title</td>
<td>Title</td>
<td>Title</td>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx1" id="xxx1">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field11" value="value11"></input>
<input type="hidden" name="field12" value="value12"></input>
<input type="hidden" name="field13" value="value13"></input>
<input type="hidden" name="field14" value="value14"></input>
</form>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx2" id="xxx2">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field21" value="value21"></input>
<input type="hidden" name="field22" value="value22"></input>
<input type="hidden" name="field23" value="value23"></input>
<input type="hidden" name="field24" value="value24"></input>
</form>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx3" id="xxx3">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field31" value="value31"></input>
<input type="hidden" name="field32" value="value32"></input>
<input type="hidden" name="field33" value="value33"></input>
<input type="hidden" name="field34" value="value34"></input>
</form>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx4" id="xxx4">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field41" value="value41"></input>
<input type="hidden" name="field42" value="value42"></input>
<input type="hidden" name="field43" value="value43"></input>
<input type="hidden" name="field44" value="value44"></input>
</form>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx5" id="xxx5">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field51" value="value51"></input>
<input type="hidden" name="field52" value="value52"></input>
<input type="hidden" name="field53" value="value53"></input>
<input type="hidden" name="field54" value="value54"></input>
</form>
</tr>
<tr>
<td>Value</td>
<td>Value</td>
<td>Value</td>
<form name="xxx6" id="xxx6">
<td>Value</td>
<td>Value</td>
<input type="hidden" name="field61" value="value61"></input>
<input type="hidden" name="field62" value="value62"></input>
<input type="hidden" name="field63" value="value63"></input>
<input type="hidden" name="field64" value="value64"></input>
</form>
</tr>
</table>
</body>
</html>
我在线程中使用Synchronize(GetForms); 进行过程调用,但即使如此,也会崩溃且速度很慢。
我的问题是没有获取到html,它已经启动并运行,问题是提取html的形式,这个过程很慢
【问题讨论】:
-
将您的解析器过程带到线程类之外。使其成为 tform 的本地过程,并使用方法“Synchronize”调用它。
-
您正在使用基于 DOM 的解析器,它本身就很慢,因为它必须解析 HTML 并在内存中为每个 HTML 元素创建一个对象树。但更重要的是,您调用
IDocForm.all.tags('FORM')的次数过多 - 一次是为了发现<form>元素的数量,然后在每次循环迭代时再次调用。不要那样做,这是浪费开销。调用一次并将生成的IHTMLElementCollection保存到一个变量中,然后根据需要在该变量上调用item()。 -
在任何情况下,您都在寻找 HTML 中的特定内容,因此您应该考虑完全删除 DOM 解析器并使用简单的子字符串搜索+提取操作。那会快得多。或者至少切换到基于 SAX,或者更好的是基于 Reader 的 HTML 解析器,而不是基于 DOM 的解析器。
-
可能是使用纯pascal HTML解析器。可悲的是我不知道任何免费的 - 只是这个付费的 - DIHtmlParser
-
谢谢各位,我会寻找另一种使用html的方式,它确实是驱动最慢的应用程序,如果有人有任何提示,可以在各个地方使用,谢谢!
标签: html delphi dom ihtmldocument2