解析具有大量节点的 XML 个文件
Parse XML files that has large number of nodes
我有一个 XML 供稿,其中 URL 包含要检索的行程 ID。
http://www.expeditiontrips.com/xml/triplist.xml
基于每个行程的信息可以从下面URL中检索,其中ID变成XML名字
http://www.expeditiontrips.com/xml/trips/3481.xml
现在,如果您查看 http://www.expeditiontrips.com/xml/trips/3481.xml link,您会看到添加节点下有一个添加项,其标签名为 "JRO Teaser"。我需要做的是解析这两个文件并显示具有此 "JRO Teaser" 标签的旅行列表。包含此附加项的行程为折扣行程。我写了一个代码,它可以检索列表,但问题是因为第一个 XML 文件中有 518 个节点,加载页面需要 5 分钟。换句话说,由于编号很大,它花费太多时间来显示结果。的旅行。有人可以为我提供一种无需太多加载时间即可正确显示的方法吗?以下是我到目前为止的代码。
<?php
$ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$trips = simplexml_load_string($xml_raw);
$total = count($trips);
for($a=0; $a<=$total; ++$a) {
$ch = curl_init('http://www.expeditiontrips.com/xml/trips/' . $trips->trip[$a] . '.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$info = simplexml_load_string($xml_raw);
//print_r($info);
$name = 'JRO Teaser';
$tripss = $info->xpath("/trip/additions/addition/label");
if($tripss[1] == 'JRO Teaser') {
echo $info->code;
}
}
?>
您正在尝试处理 500 多个 xml 个平均大小为 18-25KB 的文档。
对我来说,每个文档需要 0.5-1 秒。
如果您的业务逻辑允许,我建议您在页面加载之外执行此操作,例如在 cron 作业中,每 30 分钟或 1 小时一次,并将结果保存在数据库中,甚至保存在服务器上的文本文件中.
你可以用更高的频率来做,这取决于你追求的是什么,例如。跳过已处理的 ID 或类似注释的内容。
在实际页面加载时,只需查询您的存储、平面文件或数据库。
稍微更改了您的代码:
$trips = simplexml_load_file('http://www.expeditiontrips.com/xml/triplist.xml');
foreach ($trips as $tripId) {
$info = simplexml_load_file('http://www.expeditiontrips.com/xml/trips/' . $tripId .'.xml');
$name = 'JRO Teaser';
foreach ($info->additions->addition as $add)
if ($add->label==$name) $codes[] = (string)$info->code;
}
// process the $codes array, save to text file or database
// saveCodes($codes);
print_r($codes);
你当然可以通过将机器的力量投入其中来解决这个问题——或者只是要求正确的文档来解析。
JRO 很可能代表刚刚发布的优惠。您可以通过将 HTML 文档加载到 DOMDocument 并使用一些 xpath:
来获得这些列表
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($buffer);
libxml_use_internal_errors($saved);
$doc->formatOutput = true;
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$ids = $xpath->query('//section/article[@class="sr search_result"]//input[@class="tc"]/@value');
foreach ($ids as $id) {
echo $id->nodeValue, "\n";
}
因此,与其查询您自己的所有文档,不如查询一个已经为您查询的网站。
这里仍然适用缓存规则。这已经有助于像您一样开发此类抓取工具。
$url = 'http://www.expeditiontrips.com/jro-list/?region=all&pricerange=special';
$key = 'scratch_3_' . md5($url);
if (file_exists($key)) {
$buffer = file_get_contents($key);
} else {
$buffer = file_get_contents($url);
file_put_contents($key, $buffer);
}
输出:
3770
3025
3667
3781
3571
3078
3431
3433
3382
3173
3944
3887
3890
3731
2779
3313
3901
3900
3896
3430
3882
3884
2991
3777
3181
3921
3869
3935
3873
3923
3788
3789
3785
3786
3864
3927
3926
3054
3792
3793
3528
3928
3929
3930
3780
3790
3922
3810
3291
3796
3231
3835
2901
2883
3918
3815
3807
3808
3809
3919
3269
3734
3735
3718
3736
3904
3916
3917
3806
2548
3530
3760
2093
2704
3444
3489
3773
3772
2841
2842
3797
3932
2889
3891
3894
3895
3481
3938
3521
2547
3547
3589
3872
3939
3940
3620
3879
3545
3259
3933
2487
1831
3616
3188
3546
3838
3881
3749
3751
3131
3549
2806
3795
3062
3061
3931
3837
3142
1234
3799
2758
2490
3653
3068
3155
1929
2293
2975
2193
2923
3418
3122
2395
2846
2831
3119
3120
3802
2821
2820
3803
3801
3725
1555
3365
3228
3229
3204
3742
2410
3722
3412
3413
3174
3707
3434
3175
3383
3758
3631
3634
3679
3937
3870
3581
3897
3934
3778
3779
3924
3447
3583
3782
3768
3866
3548
3544
3821
3822
3925
我有一个 XML 供稿,其中 URL 包含要检索的行程 ID。
http://www.expeditiontrips.com/xml/triplist.xml
基于每个行程的信息可以从下面URL中检索,其中ID变成XML名字
http://www.expeditiontrips.com/xml/trips/3481.xml
现在,如果您查看 http://www.expeditiontrips.com/xml/trips/3481.xml link,您会看到添加节点下有一个添加项,其标签名为 "JRO Teaser"。我需要做的是解析这两个文件并显示具有此 "JRO Teaser" 标签的旅行列表。包含此附加项的行程为折扣行程。我写了一个代码,它可以检索列表,但问题是因为第一个 XML 文件中有 518 个节点,加载页面需要 5 分钟。换句话说,由于编号很大,它花费太多时间来显示结果。的旅行。有人可以为我提供一种无需太多加载时间即可正确显示的方法吗?以下是我到目前为止的代码。
<?php
$ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$trips = simplexml_load_string($xml_raw);
$total = count($trips);
for($a=0; $a<=$total; ++$a) {
$ch = curl_init('http://www.expeditiontrips.com/xml/trips/' . $trips->trip[$a] . '.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$info = simplexml_load_string($xml_raw);
//print_r($info);
$name = 'JRO Teaser';
$tripss = $info->xpath("/trip/additions/addition/label");
if($tripss[1] == 'JRO Teaser') {
echo $info->code;
}
}
?>
您正在尝试处理 500 多个 xml 个平均大小为 18-25KB 的文档。
对我来说,每个文档需要 0.5-1 秒。
如果您的业务逻辑允许,我建议您在页面加载之外执行此操作,例如在 cron 作业中,每 30 分钟或 1 小时一次,并将结果保存在数据库中,甚至保存在服务器上的文本文件中.
你可以用更高的频率来做,这取决于你追求的是什么,例如。跳过已处理的 ID 或类似注释的内容。
在实际页面加载时,只需查询您的存储、平面文件或数据库。
稍微更改了您的代码:
$trips = simplexml_load_file('http://www.expeditiontrips.com/xml/triplist.xml');
foreach ($trips as $tripId) {
$info = simplexml_load_file('http://www.expeditiontrips.com/xml/trips/' . $tripId .'.xml');
$name = 'JRO Teaser';
foreach ($info->additions->addition as $add)
if ($add->label==$name) $codes[] = (string)$info->code;
}
// process the $codes array, save to text file or database
// saveCodes($codes);
print_r($codes);
你当然可以通过将机器的力量投入其中来解决这个问题——或者只是要求正确的文档来解析。
JRO 很可能代表刚刚发布的优惠。您可以通过将 HTML 文档加载到 DOMDocument 并使用一些 xpath:
来获得这些列表$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($buffer);
libxml_use_internal_errors($saved);
$doc->formatOutput = true;
$doc->preserveWhiteSpace = false;
$xpath = new DOMXPath($doc);
$ids = $xpath->query('//section/article[@class="sr search_result"]//input[@class="tc"]/@value');
foreach ($ids as $id) {
echo $id->nodeValue, "\n";
}
因此,与其查询您自己的所有文档,不如查询一个已经为您查询的网站。
这里仍然适用缓存规则。这已经有助于像您一样开发此类抓取工具。
$url = 'http://www.expeditiontrips.com/jro-list/?region=all&pricerange=special';
$key = 'scratch_3_' . md5($url);
if (file_exists($key)) {
$buffer = file_get_contents($key);
} else {
$buffer = file_get_contents($url);
file_put_contents($key, $buffer);
}
输出:
3770
3025
3667
3781
3571
3078
3431
3433
3382
3173
3944
3887
3890
3731
2779
3313
3901
3900
3896
3430
3882
3884
2991
3777
3181
3921
3869
3935
3873
3923
3788
3789
3785
3786
3864
3927
3926
3054
3792
3793
3528
3928
3929
3930
3780
3790
3922
3810
3291
3796
3231
3835
2901
2883
3918
3815
3807
3808
3809
3919
3269
3734
3735
3718
3736
3904
3916
3917
3806
2548
3530
3760
2093
2704
3444
3489
3773
3772
2841
2842
3797
3932
2889
3891
3894
3895
3481
3938
3521
2547
3547
3589
3872
3939
3940
3620
3879
3545
3259
3933
2487
1831
3616
3188
3546
3838
3881
3749
3751
3131
3549
2806
3795
3062
3061
3931
3837
3142
1234
3799
2758
2490
3653
3068
3155
1929
2293
2975
2193
2923
3418
3122
2395
2846
2831
3119
3120
3802
2821
2820
3803
3801
3725
1555
3365
3228
3229
3204
3742
2410
3722
3412
3413
3174
3707
3434
3175
3383
3758
3631
3634
3679
3937
3870
3581
3897
3934
3778
3779
3924
3447
3583
3782
3768
3866
3548
3544
3821
3822
3925