2013-06-12 41 views

回答

4
$crawler = new Crawler($html,$url); 

    $document = new \DOMDocument('1.0', 'UTF-8'); 
    $root = $document->appendChild($document->createElement('_root')); 
    $crawler->rewind(); 
    $root->appendChild($document->importNode($crawler->current(), true)); 
    $domxpath = new \DOMXPath($document); 

    foreach ($selectorsToRemove as $selector) { 
     $crawlerInverse = $domxpath->query(CssSelector::toXPath($selector)); 
     foreach ($crawlerInverse as $elementToRemove) { 
      $parent = $elementToRemove->parentNode; 
      $parent->removeChild($elementToRemove); 
     } 
    } 
    $crawler->clear(); 
    $crawler->add($document); 
+1

我已經將您的代碼作爲功能請求(http://bit.ly/1adIkGk)輸入到DomCrawler組件庫中。如果請求被接受,則稱爲「remove」的新方法將可用。因此,解決方案實現將變成幾乎只有一行代碼'$ crawler-> remove(array('script'));' –

1

Crawler類擴展\SplObjectStorage並且當履帶接收HTML,它使用attach()方法給每個元素添加到存儲。

這就是說,在搜尋器對象上也可以使用detach()方法。我沒有測試以下內容,但我會認爲這可能會完成這項工作。

$crawlerInverse = $crawler->filter('script'); 

foreach ($crawlerInverse as $elementToRemove) { 
    if ($crawler->contains($elementToRemove)) { 
     $crawler->detach($elementToRemove); 
    } 
} 
+0

你的代碼,使得很多道理,但detach方法並沒有從主對象中移除元素。 –

+0

有趣。我認爲這是因爲爬蟲初始化只有與對象匹配的元素,並且沒有存儲任何子節點。順便說一句,你建議編輯是正確的,沒有必要克隆爬蟲,所以我已經應用了你的更改。 –

+0

過濾器方法不會更改對象,但會返回過濾結果,所以它的方式是在$ crawlerInverse上執行任何操作。我想我已經找到了我想做的事情,我會稍微公佈一下。 –

1

由於explained in the docs

的DomCrawler組件簡化DOM導航HTML和XML文檔。

和也:

雖然有可能,在DomCrawler組件未設計用於DOM的操縱或重新傾銷HTML/XML。

DomCrawler旨在從DOM文檔中提取細節而不是修改它們。

但是...

由於PHP經過參考對象,履帶基本上是DOMNode個包裝,這在技術上是可以修改底層DOM文檔:

// will remove all divs with a class .toRemove 
$crawler->filter('div.toRemove')->each(function ($node) { 
    foreach ($crawler as $node) { 
     $node->parentNode->removeChild($node); 
    } 
}); 

下面是一個工作示例:https://gist.github.com/jakzal/8dd52d3df9a49c1e5922

0

使用常用功能,如:

function removeCrawlerNode($crawler_node) { 

    foreach($crawler_node as $node) { 
     $node->parentNode->removeChild($node); 
    } 
} 

然後找到你想要的(說類.sample_section)搜索的爬蟲代碼部分,如果它存在,那麼做一個remove_tag_array與所有標籤要刪除:

if($crawler->filter('.sample_section')->count() > 0) { 

    $remove_tag_array = array("br", "b", "img", "div", "u", "i"); 

    $sub_crawler = $crawler->filter('.sample_section'); 

    foreach ($remove_tag_array as $tag) { 
     $sub_crawler->filter($tag)->each(function ($node) { 
      removeCrawlerNode($node); 
     }); 
    } 
}