【问题标题】:Sub-filtering html using xpath使用 xpath 对 html 进行子过滤
【发布时间】:2014-05-25 14:14:19
【问题描述】:

我怀疑实现这一目标的最佳方法。我正在使用 Symfony Crawler,我有这个过滤器:

$myData = $crawler->filterXPath('//div[@class="container"]');

然后我像这样遍历它们:

      foreach ($myData as $domElementData) {

但是使用 divFirst 我会得到一个带有链接、div 的块......我需要对其进行过滤并为每个块放入一个数组中。我的第一种方法是遍历每个块(divFirst),然后进行子过滤,但我不确定是否应该为此创建第二个子爬虫?

另一种选择是:

$subData1 = $crawler->filterXPath('//*[contains(@id, "date")]');
$subData2 = $crawler->filterXPath('//*[contains(@id, "price")]');
...

然后循环第一个并使用它的索引在第一个数组中包含所有 fest of fields 的信息?

foreach (subData1 as $index=>$subData) {
  $theFinalData [$index]['subdata1'] = subData1;
  $theFinalData [$index]['subdata2'] = subData2;
  ...

但最后一个选择看起来很奇怪,甚至丑陋。有意见吗?

我试图阅读的 html 看起来像这样:

<div class="container1234Y53">
  <div id="date12345">12/02/2014</div>
  <div id="price">80£</div>
  <div id="numberofpeople">4</div>
</div>
  <div class="container1234X123">
  <div id="date3451">2/06/2014</div>
  <div id="price">30£</div>
  <div id="numberofpeople">1</div>
</div>
....

结果应该是这样的数组:

container[0]['date'] = 12/02/2014
container[0]['price'] = 80
container[0]['numberofpeople'] = 4
container[1]['date'] = 2/06/2014
container[1]['price'] = 30
container[1]['numberofpeople'] = 1
....

非常感谢。

【问题讨论】:

  • 可能问题更像是,如何使用 Symfony Crawler 获取节点中的每个元素?
  • 可能还有其他(更简单的)替代方案。显示您的 XML 文件并准确说明您要提取的内容。
  • 是的,你完全正确。它不是 xml 而是 html,只是用示例更新了原始帖子。再次感谢:-)。
  • 你的源代码示例中的divFirst 在哪里?它是否包装了这些节点?你想提取什么?整个container 节点? dateprice 字符串的集合?
  • 理想情况下,一个包含 n 个元素的数组,数组中的每个元素包含日期、数字等...

标签: symfony xpath web-crawler


【解决方案1】:

经过一番研究,我回答自己希望它对其他人有所帮助。

您必须创建一个新的爬虫,如下所述:http://www.ymc.ch/en/webscraping-in-php-with-guzzle-http-and-symfony-domcrawler

基本上,第一个会搜索第一组:

// crate crawler instance from body HTML code
$crawler = new Crawler($response->getBody(true));

// apply css selector filter
$myData = $crawler->filterXPath('//div[@class="container"]');
$result = array();

然后您可以迭代结果,创建一个新的爬虫并使用这个新的爬虫为这个新的搜索提取结果:

// iterate over filter results
foreach ($myData as $i => $content) {

    // create crawler instance for result
    $cralwer = new Crawler($content);
    // extract the values needed
    $result[$i] = array(
        'topic' => $crawler->filterXPath('//*[contains(@id, "date")]')->text();
...

我不确定(我仍然是)这是否是性能方面的最佳解决方案,因为爬虫创建了多次,但在编码样式方面似乎比第一个解决方案更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2013-09-06
    • 2011-04-25
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    相关资源
    最近更新 更多