Nous écrivons un analyseur de contenu en PHP. Analyser et traiter une page web en PHP : choisir la meilleure bibliothèque Comment analyser une page html

Pages d'analyse de contenu PHP

L'article est consacré à l'analyse, en particulier à l'analyse de sites Web, à l'analyse de pages, à l'analyse de sites Web et à l'analyse de contenu HTML de sites Web.

Dans le processus de développement de divers services Web, nous sommes très souvent confrontés à des tâches dans lesquelles nous devons obtenir rapidement divers types d'informations en gros volumes. Ceci est principalement lié à la saisie, au vol d’informations, peu importe comment vous voulez l’appeler. Le fait est que l’information est accessible et ouverte. La particularité de l'analyse est la collecte rapide et automatisée des données et du contenu des pages du site Web.

De nos jours, il est très courant de gratter dans l'environnement Web, c'est-à-dire de gratter un site qui contient au moins une certaine valeur et pertinence pour les gens. Le catalogue de produits est particulièrement précieux, comprenant des images, des bases de données d'annuaire et bien plus encore qui peuvent être utiles aux concurrents.

Essayons d'analyser les informations nécessaires en HTML, essayons d'obtenir tous les liens de plusieurs pages de notre site.

Tout d’abord, nous devons obtenir le contenu du site au format HTML. Pour ce faire, il suffit de connaître les adresses des pages nécessaires.

Je souhaite montrer 2 manières principales d'obtenir le contenu d'une page de site Web :

Tout d’abord, préparons un tableau avec les adresses de pages nécessaires :

//3 liens vers notre site : $urls = array("http://hello-site..ru/games/");

Option 1 - fonction php file_get_contents. La fonction renvoie une chaîne html que nous analyserons en liens :

//place chaque lien dans la fonction file_get_contents foreach($urls as $urlsItem)( $out .= file_get_contents($urlsItem); //et ajoute le contenu de chaque page à la ligne ) echo $out; //voici le contenu des trois pages

Option 2 - BOUCLE. Une bibliothèque prise en charge par PHP et dotée d'un large éventail de paramètres, des requêtes POST à ​​l'utilisation de FTP. Considérons un appel standard à la bibliothèque curl, qui nous donnera le contenu du site :

foreach($urls as $urlsItem)( //passer chaque lien dans une boucle $output = curl_init(); //connecter curl curl_setopt($output, CURLOPT_URL, $urlsItem); //envoyer l'adresse de la page curl_setopt($output, CURLOPT_RETURNTRANSFER, 1); curl_setopt($output, CURLOPT_HEADER, 0); $out .= curl_exec($output); //mettre le contenu html dans la ligne curl_close($output); //fermer la connexion) echo $out; //voici le contenu des trois pages

Désormais, notre ligne $out contient le contenu des trois pages. Passons donc directement à l’analyse de notre chaîne.

Encore une fois, je souhaite montrer 3 options pour résoudre notre problème : la méthode « native » en PHP, utilisant la bibliothèque DOMDocument intégrée et la bibliothèque SimpleHTMLDOM.

1. La fonction php explose. La fonction trouve le caractère recherché ou une partie d'une chaîne et divise la chaîne entière en éléments du tableau.

Je le répète, nous devons obtenir les valeurs de tous les attributs href des balises a ; pour cela, nous diviserons la chaîne générale en quelques parties\segments :

// explose $hrefs = explose("

Si nous imprimons notre tableau, il ressemblera à ceci :

Array ( => / => /hello => /timer/ => /leftmenu/ => /faq/ => /blog/ => /web-notes/ => /ordersite/ => /games)

2. bibliothèque DOMDocument intégrée. Nous travaillons avec la classe approximativement comme suit :

//domelement $dom = nouveau DOMDocument; //crée un objet $dom->loadHTML($out); //charger le contenu $node = $dom->getElementsByTagName("a"); //prend toutes les balises a pour ($i = 0; $i< $node->longueur; $i++) ( $hrefText = $node->item($i)->getAttribute("href"); //récupère l'attribut href de la balise) foreach($hrefText as $hrefTextItem)( //se débarrasser des liens avec un attribut vide href if($hrefTextItem!="")( $clearHrefs=$hrefTextItem; ) ) $clearHrefs = array_unique($clearHrefs); //se débarrasser des liens identiques print_r($clearHrefs); // au final on a un tableau avec tous les liens de 3 pages

Le résultat de ce code est exactement le même que celui de l'utilisation de la fonction d'explosion.

3. Bibliothèque SimpleHTMLDOM. Il doit être inclus à partir d'un fichier. Le travail est à peu près similaire à DOMDocument. Travailler avec la classe :

//simplehtml include("simple_html_dom.php"); //inclut un fichier avec la classe SimpleHTMLDOM $html = new simple_html_dom(); //crée un objet $html->load($out); //place notre contenu $collection = $html->find("a"); //collecte toutes les balises a foreach($collection as $collectionItem) ( $articles = $collectionItem->attr; //tableau de tous les attributs, href incluant ) foreach($articles as $articlesItem)( $hrefText = $articlesItem[ " href"]; //collecter dans un tableau les valeurs du sous-tableau avec la clé href ) foreach($hrefText as $hrefTextItem)( //se débarrasser des liens avec un attribut href vide if($hrefTextItem!="" )( $clearHrefs=$hrefTextItem; ) ) $clearHrefs = array_unique($clearHrefs); //se débarrasser des liens identiques print_r($clearHrefs); // au final on a un tableau avec tous les liens de 3 pages

Je le répète, le résultat dans le tableau est exactement le même que dans les deux ci-dessus.

Désormais, disposant d'un tableau avec tous les liens collectés sur trois pages du site, vous pouvez envoyer les liens dans la bonne direction, tout dépend de la tâche et de l'imagination. Grâce à de telles capacités, vous pouvez analyser une grande quantité de données contenant divers types d'informations, d'images, de textes, de journaux, etc. Les informations de quelqu'un d'autre sont entre vos mains, disposez-en à votre guise, mais défendez-vous, même si cela est impossible)

La tâche d'analyser et de traiter les informations nécessaires provenant d'un site tiers est confrontée assez souvent à un développeur Web et pour diverses raisons : vous pouvez ainsi remplir votre projet de contenu, charger dynamiquement certaines informations, etc.

Dans de tels cas, le programmeur est confronté à la question : laquelle parmi des dizaines de bibliothèques choisir ? Dans cet article, nous avons essayé de considérer les options les plus populaires et de choisir la meilleure.

Expressions régulières

Même si les « classiques » sont la première chose qui vous vient à l’esprit, vous ne devriez pas les utiliser pour de vrais projets.

Oui, les expressions régulières font le meilleur travail avec des tâches simples, mais leur utilisation devient beaucoup plus difficile lorsque vous devez analyser un morceau de code HTML volumineux et complexe, qui, de plus, ne correspond pas toujours à un modèle spécifique et peut généralement contenir des erreurs de syntaxe. .

Au lieu de « terminer » votre expression régulière avec le moindre changement dans le code, nous vous recommandons d’utiliser les outils ci-dessous : c’est plus simple, plus pratique et plus fiable.

XPath et DOM

htmlSQL

Si vous n'utilisez pas PHP, vous pouvez consulter cette courte liste d'outils similaires pour d'autres langages de programmation.

Récemment, j'ai travaillé dans une entreprise SARL "Radio City Sakhaline" dans l'équipe de développeurs et de journalistes du portail d'information et de divertissement « Sitisakh ». Surtout pour les fans de football, le portail propose une section « Sports » avec des nouvelles du monde du football, des classements et une liste des joueurs de l'équipe du FC Sakhalin.

Le portail étant actuellement en pleine refonte, j'ai été chargé de gérer la rubrique « Sports ». Ma fonction principale au sein de l'équipe est la mise en page de nouvelles mises en page de conception. Parfois, nous devons résoudre des problèmes secondaires afin de faciliter le travail déjà difficile de notre programmeur principal. Aujourd'hui, je vais parler de Microparser.

Auparavant, les tableaux des tournois de football sur le portail étaient remplis manuellement par les gestionnaires de contenu. Il arrive parfois que les résultats des matchs apparaissent sur Championship.com plus rapidement que sur notre portail. Nous avons enfin décidé de rendre automatique la mise à jour des tables. Étant donné que Championship.com ne fournit pas d'API (au moins une ouverte) pour obtenir les tables de tournoi qu'il affiche, la seule option est d'analyser.

Comment utiliser Microparser

Le « microparseur » se compose d'une seule fonction - parse_site(array $sites, array $defaults = array()) . Le premier argument est un tableau de sites (ou de pages sur un site) qui doivent être analysés, et le second est un tableau de paramètres par défaut.

Le tableau $sites a le format suivant :

Array("zona_vostok" => array("url" => "http://www.championat.com/football/_russia2d/589/table/all.html", "xpath" => "some/x/path" , //facultatif "xsl" => "absolute/path/to/xsl", //facultatif), "stackoverflow" => array("url" => "http://stackoverflow.com", "xpath" = > "some/x/path", "transform" => false //facultatif));

Toutes les clés, à l'exception de l'URL, sont facultatives. Si l'expression XPath est manquante, la page spécifiée dans la valeur de la clé url sera traitée dans son intégralité. Une feuille de style XSL peut également être incluse uniquement si le traitement du code brut est nécessaire.

Faites attention à la "transformation" => fausse clé. Il est utilisé lorsque le tableau $defaults contient la feuille de style XSL par défaut, mais que la transformation n'est pas nécessaire pour la page donnée.

Le tableau $defaults évite de copier les paramètres dans le tableau $sites. Il ne peut contenir que deux clés : xpath et xsl. Les autres clés sont simplement ignorées.

Résumé

L'analyseur que j'ai écrit se compose d'une fonction avec deux paramètres (pour les paramètres privés et généraux), vous permet de charger la page entière ou un fragment séparé de celle-ci et, si vous le souhaitez, de traiter le résultat avec une feuille de style XSL.

Au début, je voulais utiliser une bibliothèque comme phpQuery ou Ganon pour parcourir les nœuds, mais j'ai ensuite réfléchi attentivement et j'ai réalisé qu'il ne servait à rien de faire glisser des dépendances supplémentaires - vous pouviez utiliser l'outil intégré déjà existant.

Exemple de travail

Regardons le classement du championnat russe de football en deuxième division, zone « Est ».

Puisque nous devons « extraire » la table du tournoi directement depuis la page, l'expression XPath sera la suivante : //div[@id="section-statistics"]/table

La table source contient beaucoup de déchets : attributs, classes, styles en ligne. Nous allons donc lui donner un aspect plus joli en utilisant une feuille de style XSL avec le contenu suivant :

Équipe Jeux La victoire Tirages Pertes Des balles Lunettes
même impair

Écrivons maintenant le code pour afficher la table du tournoi terminée.

$results = parse_site(array("zona_vostok" => array("url" => "http://www.championat.com/football/_russia2d/589/table/all.html", "xpath" => "xpath " => "//div[@id="section-statistics"]/table", "xsl" => __DIR__."/football.xsl")); print $results["zona_vostok"];

Et le résultat est le code HTML suivant :

...
Équipe Jeux La victoire Tirages Pertes Des balles Lunettes
1 Luch-Énergie 20 12 6 2 30-17 42
2 Tchita 20 12 5 3 28-14 41

Télécharger "Microanalyseur"

Voici quelques façons de mettre la main sur Microparser :

  1. Fork sur Github : git clone https://github.com/franzose/microparser.git
  2. Téléchargez les archives :

Vous êtes nombreux à vous poser des questions sur créer un analyseur en PHP. Par exemple, il existe un site Web et vous devez en extraire du contenu. Je n’ai pas voulu écrire cet article depuis longtemps, car il n’a pas de sens précis. À faire un analyseur en PHP, vous devez connaître cette langue. Et ceux qui le connaissent ne poseront tout simplement pas une telle question. Mais dans cet article, je vais vous expliquer comment les analyseurs sont créés en général, ainsi que ce qui doit spécifiquement être étudié.

Voici donc une liste de points que vous devez parcourir afin de créer un analyseur de contenu en PHP:

  1. Récupérez le contenu de la page et écrivez-le dans une variable chaîne. L'option la plus simple est la fonction fichier_get_contents(). Si le contenu n'est disponible que pour les utilisateurs autorisés, tout est alors un peu plus compliqué. Ici, nous devons examiner quel est le mécanisme d’autorisation. Ensuite, en utilisant boucle, envoyez la demande correcte au formulaire d'autorisation, recevez une réponse puis envoyez les en-têtes corrects (par exemple, l'identifiant de session reçu), et également dans la même demande accédez à la page nécessaire. Ensuite, dans cette réponse, vous recevrez la dernière page.
  2. Étudiez la structure de la page. Vous devez trouver le contenu dont vous avez besoin et voir dans quel bloc il se trouve. Si le bloc dans lequel il se trouve n'est pas unique, recherchez d'autres caractéristiques communes grâce auxquelles vous pouvez certainement dire que si la ligne les satisfait, alors c'est ce dont vous avez besoin.
  3. À l'aide des fonctions de chaîne, extrayez le contenu dont vous avez besoin de la chaîne source en fonction des caractéristiques trouvées dans 2ème indiquer.

Je noterai aussi que seuls ceux qui savent comprendront tout cela et pourront le mettre en pratique PHP. Par conséquent, pour ceux qui commencent tout juste à l’étudier, vous aurez besoin des connaissances suivantes :

  1. Fonctions de chaîne.
  2. Bibliothèque boucle, ou son analogue.
  3. Excellente connaissance HTML.

Ceux qui ne savent toujours pas du tout PHP, alors les analyseurs dans ce cas sont encore loin et vous devez étudier l'intégralité de la base de données. Cela vous aidera avec ça

Vous apprendrez comment obtenir une liste de tous les articles publiés sur un site.

Étape 1. Préparation

Tout d'abord, vous devez copier la bibliothèque simpleHTMLdom, disponible sur le site

L'archive de téléchargement contient plusieurs fichiers, mais vous n'en avez besoin que d'un seul simple_html_dom.php. Tous les autres fichiers sont des exemples et de la documentation.

Étape 2 : bases de l'analyse

Cette bibliothèque est très simple à utiliser, mais il y a quelques éléments de base à apprendre avant de la mettre en œuvre.

$html = nouveau simple_html_dom();
// Charger depuis une chaîne
$html->charger("

Bonjour le monde!

");
// Téléverser un fichier
$html->load_file("http://net.tutsplus.com/");

Vous pouvez créer un objet source en chargeant HTML soit à partir d'une chaîne, soit à partir d'un fichier. Le chargement à partir d'un fichier peut être effectué soit en spécifiant URL, ou depuis votre système de fichiers local.

Remarques : Méthode fichier de chargement() les délégués travaillent sur une fonction PHP fichier_get_contents. Si Allow_url_fopen pas défini sur la valeur vrai dans ton dossier php.ini, vous ne pourrez peut-être pas ouvrir les fichiers distants de cette façon. Dans ce cas, vous pouvez revenir à l'utilisation de la bibliothèque CURL pour charger des pages distantes, puis lire à l'aide de la méthode charger().

Accès aux informations

Une fois que vous disposez d'un objet DOM, vous pouvez commencer à travailler avec lui en utilisant la méthode trouver() et créer des collections. Une collection est un groupe d'objets trouvés par un sélecteur. La syntaxe est très similaire à celle de jQuery.



Bonjour le monde!


Nous sommes là.






Dans cet exemple HTML, nous allons comprendre comment accéder aux informations du deuxième paragraphe, les modifier, puis imprimer le résultat des actions.

1. # créer et charger du HTML
2. include("simple_html_dom.php");
3. $html = new simple_html_dom();
4. $html->load("

Bonjour le monde!



“);
5. # récupère l'élément représentant le deuxième paragraphe
6. $element = $html->find("p");
7. # modifiez-le
8. $element->innertext .= « et nous sommes là pour rester. » ;
9. # Sortie !
10. echo $html->save();

Lignes 2 à 4: Chargez le HTML à partir d'une chaîne comme expliqué ci-dessus.

Ligne 6 : Trouver tous les tags

En HTML, et renvoyez-les dans un tableau. Le premier paragraphe aura l'index 0 et les paragraphes suivants seront indexés en conséquence.

Ligne 8: Nous accédons au deuxième élément de notre collection de paragraphes (index 1), en ajoutant du texte à son attribut innertext. L'attribut innertext représente le contenu entre les balises et l'attribut externaltext représente le contenu incluant les balises. Nous pouvons remplacer complètement la balise en utilisant l'attribut externaltext.

Ajoutons maintenant une ligne et modifions la classe de balises de notre deuxième paragraphe.

$element->class = "nom_classe";
echo $html->save();

Le code HTML final après la commande save ressemblera à ceci :



Bonjour le monde!


Nous sommes là et nous sommes là pour rester.





Autres sélecteurs

Quelques autres exemples de sélecteurs. Si vous avez utilisé jQuery, tout vous semblera familier.

# récupère le premier élément trouvé avec id="foo"
$single = $html->find("#foo", 0);
# récupère tous les éléments avec la classe "foo"
$collection = $html->find(".foo");
# récupère toutes les balises de lien sur la page
$collection = $html->find("a");
# récupère toutes les balises de lien situées à l'intérieur de la balise H1
$collection = $html->find("h1 a");
# récupère toutes les balises img avec title="himom"!}
$collection = $html->find("img");

Le premier exemple nécessite quelques explications. Toutes les requêtes renvoient des collections par défaut, même la requête ID, qui ne doit renvoyer qu'un seul élément. Cependant, en spécifiant le deuxième paramètre, nous disons « renvoyer uniquement le premier élément de la collection ».

Cela signifie que $single- un seul élément, et non un tableau d'éléments avec un seul membre.

Les autres exemples sont assez évidents.

Documentation

La documentation complète de la bibliothèque est disponible sur .

Étape 3 : Exemple du monde réel

Pour démontrer la bibliothèque en action, nous allons écrire un script pour récupérer le contenu du site net.tutsplus.com et générer une liste de titres et de descriptions d'articles présentés sur le site... juste à titre d'exemple. Le scraping est une astuce Web et ne doit pas être utilisé sans l'autorisation du propriétaire de la ressource.

Inclure("simple_html_dom.php");
$articles = tableau();
getArticles("http://net.tutsplus.com/page/76/");

Commençons par connecter la bibliothèque et appeler la fonction obtenirArticles indiquant la page à partir de laquelle nous voulons commencer l'analyse.

Nous déclarerons également un tableau global pour faciliter la collecte de toutes les informations sur les articles en un seul endroit. Avant de commencer l’analyse, examinons comment l’article du site Web Nettuts+ est décrit.



...


Titre




Description



Il s'agit du format de base d'une publication sur le site, incluant des commentaires sur le code source. Pourquoi les commentaires sont-ils importants ? Ils sont comptés par l'analyseur comme des nœuds.

Étape 4 : Démarrez la fonction d'analyse

fonction getArticles($page) (
articles $ globaux ;
$html = nouveau simple_html_dom();
$html->load_file($page);
// ... Plus loin...
}

Nous commençons par déclarer un tableau global, créant un nouvel objet simple_html_dom, puis chargez la page pour l'analyse. Cette fonction sera appelée de manière récursive, nous définissons donc l'URL de la page comme paramètre.

Étape 5. Trouvez les informations dont nous avons besoin

1. $items = $html->find("div");
2. foreach($éléments comme $post) (
3. # n'oubliez pas de compter les commentaires comme des nœuds
4. $articles = array($post->children(3)->outertext,
5. $post->children(6)->first_child()->outertext);
6. }

C'est l'essence de la fonction obtenirArticles. Nous devons y réfléchir plus en détail pour comprendre ce qui se passe.

Ligne 1: Créer un tableau d'éléments - tag div avec la classe d'aperçu. Nous avons maintenant une collection d'articles enregistrés dans $articles.

Ligne 4: $poster fait désormais référence à un seul div de la classe d'aperçu. Si nous regardons le HTML original, nous pouvons voir que le troisième élément descendant est une balise H1, qui contient le titre de l'article. On le prend et on se l'approprie $articles.

N'oubliez pas de commencer à 0 et de prendre en compte les commentaires du code source lors de la détermination de l'index de nœud correct.

Ligne 5: Sixième descendant $poster- Ce

. Nous avons besoin du texte de description, nous utilisons donc texte extérieur- la balise de paragraphe sera incluse dans la description. Une seule entrée dans le tableau articles ressemblera à ceci :

$articles = « Titre de l'article » ;
$articles = « Voici la description de mon article »

Étape 6, Travailler avec des pages

La première étape consiste à déterminer comment trouver la page suivante. Sur le site Nettuts+, il est très facile de deviner le numéro de page à partir de l'URL, mais nous devons obtenir le lien lors de l'analyse.

Si vous regardez le HTML, vous trouverez ce qui suit :

»

Ceci est un lien vers la page suivante et on peut facilement le trouver par classe' articles suivantslien'. Désormais, ces informations peuvent être utilisées.

Si($next = $html->find("a", 0)) (
$URL = $suivant->href;
$html->clear();
non défini($html);
getArticles($URL);
}

Dans la première ligne, nous vérifions si une référence à la classe peut être trouvée articles suivantslien. Notez l'utilisation du deuxième paramètre dans la fonction trouver(). De cette façon, nous indiquons que nous voulons obtenir le premier élément (index 0) de la collection renvoyée. $suivant contient un seul élément, pas une collection.

Nous attribuons ensuite le lien HREF à la variable $URL. Ceci est important car nous supprimons ensuite l’objet HTML. Pour éviter les fuites de mémoire dans php5, l'objet actuel simple_html_dom doit être effacé et désactivé avant de pouvoir créer un autre objet. Si cela n'est pas fait, toute la mémoire disponible risque d'être consommée.

Enfin, nous appelons la fonction getArticles avec l'URL de la page suivante. La récursion s'interrompt lorsqu'il n'y a plus de pages à analyser.

Étape 7. Afficher les résultats

Tout d’abord, nous allons installer quelques styles de base. Tout est complètement arbitraire - vous pouvez installer ce que vous voulez.

#principal (
marge : 80px automatique ;
largeur : 500 px ;
}
h1 (
police : gras 40px/38px helvetica, verdana, sans-serif ;
marge : 0 ;
}
h1 une (
couleur : #600 ;
décoration de texte : aucune ;
}
p(
contexte : #ECECEC ;
police : 10px/14px verdana, sans empattement ;
marge : 8px 0 15px ;
bordure : 1px #CCC solide ;
remplissage : 15 px ;
}
.article(
remplissage : 10 px ;
}

On écrit ensuite une petite fonction PHP sur la page pour afficher les informations précédemment enregistrées.

foreach($articles comme $item) (
écho "

";
echo $élément ;
echo $élément ;
écho "
";
}
?>

Le résultat final est une seule page HTML listant tous les articles des pages Nettuts+, en commençant par celui spécifié lors du premier appel. obtenirArticles().

Étape 8. Conclusion

Si vous commencez à parcourir un grand nombre de pages (par exemple, l'ensemble du site), cela peut prendre beaucoup de temps. Sur un site comme Nettuts+, qui compte plus de 86 pages, le processus d'analyse peut prendre plus d'une minute.

Cette leçon vous présente le sujet de l'analyse HTML. Il existe d'autres techniques de manipulation DOM qui vous permettent de travailler avec le sélecteur XPath pour rechercher des éléments. La bibliothèque décrite dans ce didacticiel est facile à utiliser et idéale pour démarrer rapidement. N'oubliez pas de demander la permission avant de supprimer un site.





Avoir des questions?

Signaler une faute de frappe

Texte qui sera envoyé à nos rédacteurs :