2016-07-16 1 views
0

Si j'ai une page web comme ceci:Comment obtenir <a> balises dans <body> mais excluent les sections d'en-tête et pied de page

<body> 
    <header> 
    <a href='http://domain1.com'>link 1 text</a> 
    </header> 

    <a href='http://domain2.com'>link 2 text</a> 

    <footer> 
    <a href='http://domain3.com'>link 3 text</a> 
    </footer> 
</body> 

Comment puis-je tirer les <a> balises de la <body> mais excluent les liens de <header> et <footer> ?

Dans la vraie page Web, il y aura beaucoup de <a> tags dans le <header> donc je préfère ne pas avoir à parcourir tous.

Je veux tirer les URL et le texte d'ancrage de chacun des <a> balises qui ne sont pas dans les <header> ou <footer> tags.

EDIT: voilà comment je trouve des liens dans l'en-tête:

$header = $html->find('header',0); 
foreach ($header->find('a') as $a){ 
    do something 
} 

Je voudrais le faire (« ! » Notez l'utilisation)

$foo = $html->find('!header,!footer'); 
foreach ($foo->find('a') as $a){ 
    do something 
} 
+0

Est-ce que vous faites ceci avec Javascript ou PHP? Javascript serait nettement plus facile. –

+1

@JamesPaterson - La question est étiquetée à la fois PHP et avec une bibliothèque PHP DOM spécifique, et pas du tout JavaScript. Il est sûr de supposer qu'ils utilisent PHP. – Quentin

Répondre

1

Supprimez l'en-tête et le pied de page du DOM avec lequel vous travaillez avant de rechercher les liens.

<?php 
    include("simple_html_dom.php"); 
    $source = <<<EOD 
    <body> 
     <header> 
      <a href='http://domain1.com'>link 1 text</a> 
     </header> 

     <a href='http://domain2.com'>link 2 text</a> 

     <a href='http://domain4.com'>link 4 text</a> 

     <footer> 
      <a href='http://domain3.com'>link 3 text</a> 
     </footer> 
    </body> 
EOD; 

    $html = str_get_html($source); 
    foreach ($html->find('header, footer') as $unwanted) { 
     $unwanted->outertext = ""; 
    } 
    $html->load($html->save()); 
    $links = $html->find("a"); 
    foreach ($links as $link) { 
     print $link; 
}; 

?> 
+0

Parfait. Dans mon cas j'utilise 'file_get_html' Avec la fonction' save' que vous montrez, je suis maintenant capable de traiter le "nouveau" '$ html' plus bas dans le code sans avoir à analyser à nouveau les balises d'en-tête et de pied de page. Bravo pour la réponse rapide. – limeygent

-1

Il est impossible avec de simples -html-dom, tout simplement bien sûr. Vous ne pouvez pas faire cela avec simple-html-dom.

$html->find('body > a'); 

Ce sélecteur CSS Sélectionne tous les éléments <a> où le parent est un élément <body>.
Vous devez faire une boucle par les enfants de corps de nœuds, puis obtenir <a>

Je suggère de regarder How do you parse and process HTML/XML in PHP?

Pour ma part, j'utilise Symfony/DomCrawler et Symfony/cssSelector pour le faire.

+0

Cela fonctionne pour cet exemple spécifique, où les liens souhaités sont * enfants * de l'élément body. Vraisemblablement, cependant, c'est un exemple simplifié et les liens vont être à l'intérieur d'autres éléments (tels que des paragraphes). – Quentin

+0

Oui, et comme je l'ai dit, simplehtmldom est une ** vieille ** bibliothèque, elle ne supporte pas les récents sélecteurs Css définis par ** W3C **. Si le simple exemple est compliqué, qu'en est-il si c'est plus compliqué? ^^ – Rebangm

0

Sans endommager le corps? Vous pourriez faire quelque chose comme:

$bad_as = $html->find('header a, footer a'); 
foreach($html->find('a') as $a){ 
    if(in_array($a, $bad_as)) continue; 
    // do something 
}