Script de crawling - PHP - Programmation
Marsh Posté le 23-05-2015 à 21:36:02
La solution pour faire surfer un programme sur le web c'est cURL que tu peux utiliser avec n'importe quel langage (web ou script).
Avec ca tu récupère du html qui s'analyse comme du xml en en gros.
Puis tu enregistre tes résultats en base de données.
A toi de jouer
Marsh Posté le 23-05-2015 à 21:58:21
Ca c'est le genre de truc indispensable pour faciliter le code considérablement:
https://github.com/tburry/pquery
Marsh Posté le 24-05-2015 à 12:25:40
J'allais proposer xpath/xquery. Mais pquery ca à l'air de démonter.
Marsh Posté le 24-05-2015 à 21:19:26
Merci pour vos réponses, qui du coup génèrent des questions
Je me suis baladé sur le site de cURL, j'avoue que j'y comprends pas grand chose. Du coup, mes questions :
- Qu'est-ce qu'il me faut parmi ca : http://curl.haxx.se/dlwiz/ ? Mon ordinateur est sous windows 8.1 64 bits et pour le dev de mon site, j'utilise un hébergement gratuit chez http://www.000webhost.com/
- Je dois installer libcurl (ou cURL ?) sur mon serveur pour m'en servir, j'imagine ? Comment je fais ça ? Je ne trouve que des histoires de ligne de commande (si je comprends bien, je suis paumé)(genre là : http://php.net/manual/fr/curl.installation.php) et je ne comprends pas
Je ne comprends pas du tout ce qu'est pquery, je crois que je comprends ce que ça fait (ça découpe ce que cURL me sortira en plein de morceaux que je pourrai utiliser, c'est ca ?), mais je ne comprends pas comment ça s'installe, comment ça s'utilise... (Je n'ai jamais utilisé github du coup je suis perdu ici aussi)
(Autre question, j'ai hésité à faire faire ça par un développeur qui sait ce qu'il fait, il me dit qu'il pense en avoir pour une semaine à temps plein (40h quoi) pour coder le script (ce qui est carrément hors de mes moyens à 30€ de l'heure). Je sais pas pourquoi, il m'inspire pas confiance, et je m'imaginais beaucoup moins de temps pour quelqu'un qui sait faire, du coup question, il me dit n'importe quoi pour me rouler dans la farine, ou il faut effectivement compter ce temps là pour un pro ? (et donc probablement 3x plus si je le fais seul sachant que je n'y connais pas grand chose)).
Merci d'avance pour vos réponses
Marsh Posté le 24-05-2015 à 21:41:22
Tout dépend de ce que tu souhaites faire, perso je touche ca en 1j de dev environ, jusqu'a 2j si c'est assez complexe (enfin jusqu'a un certain point), pas vraiment plus.
1) Il faut que tu ailles chercher wamp par exemple: http://www.wampserver.com/
2) Pour utiliser pquery, le plus simple est d'apprendre à utiliser composer:
https://getcomposer.org/
Une fois que tu as composer et wamp, tu te fais un dossier dans /www et tu lances la command prompt:
composer install tburry/pquery
(ca t'évitera de te poser la question de comment tu installes/utilise pquery).
Composer n'est qu'un gestionnaire de paquet: tu installes et gère des bouts de code d'autre, venant de github ou ailleurs, tu n'as pas réellement besoin de savoir ce qu'est github ni git.
Le reste est écris dans la doc de composer sur comment l'utiliser.
Pour cUrl, il est installé de base avec wamp, donc rien à faire. cUrl est TRES relou à utiliser, mais tu as des helpers qui vont construire tout pour toi:
https://github.com/php-curl-class/php-curl-class
pour l'avoir:
composer install php-curl-class/php-curl-class
regarde la page github sur comment créer un objet de ce helper, et d'envoyer une requete.
Tu l'as dit, pquery va te servir à utiliser plus facilement la réponse venant de cUrl. une page HTML, est en réalité un fichier texte.
De fait:
Code :
|
N'a rien d'évident sous forme de texte. Ce que tu as besoin, c'est d'un parser, xpath sont les parsers "officiels" de PHP, mais ils sont vites problématiques. pquery émule jQuery, et jQuery fait globalement la même chose que xpath, mais son avantage est la facilité avec laquelle tu vas pouvoir récupérer un élément.
La partie dans laquelle tu vas passer de cUrl à pquery va ressembler à ca:
Code :
|
Et ensuite tu pourras naviguer dans la page sans te soucier des balises (comme dans la doc de pquery):
Code :
|
Morale de l'histoire:
- il te faut des notions de ce qu'est l'HTML et comment tu te ballades dedans. Comment on gère le DOM.
- il te faut des notions sur ce qu'est une requête, à quoi ca ressemble concrètement, et donc qu'est ce que tu peux en tirer avec les éléments que je viens de te donner...
Marsh Posté le 25-05-2015 à 07:36:24
Merci pour ton aide
Alors, comme je marche en terrain complètement inconnu, je préfère demander pour être sur :
Devil'sTiger a écrit : Une fois que tu as composer et wamp, tu te fais un dossier dans /www et tu lances la command prompt: |
Cette commande me donnait "Invalid argument tburry/pquery. Use "composer require tburry/pquery" instead to add packages to your composer.json."
Du coup j'ai fait la commande "composer require tburry/pquery" comme il me dit, et ça m'a sorti :
Code :
|
(Idem pour "composer install php-curl-class/php-curl-class", commande invalide, donc j'ai fait "composer require php-curl-class/php-curl-class" à la place, et ça m'a sorti quasiment la même chose que pour composer require tburry/pquery.)
Et du coup ça m'a créé (sauf erreur) deux fichiers (composer.json, composer.lock) et un dossier (vendor) dans mon dossier CUtilisateurs/[mon_username]
Je les ai déplacés dans un dossier que j'ai nommé composer qui est dans CProgrammes/wamp/www/
J'ai bon ? Ou j'ai fait des trucs pas comme il faut ?
Si j'ai bien compris, ce code là :
Code :
|
...fera la chose suivante : démarrer (ou autre, je sais pas quel est le terme) cURL, récupérer le contenu de www.lapagesurlaquellejeveuxnaviguer.com, parser ce contenu, récupérer tous les éléments <h2> du DOM dont la classe est ".title", remplacer ce qui est entre les balises par "FOO" et remplacer la balise elle même par des balises <h1>, c'est bien ça ?
Plusieurs questions :
- Vu ce que je souhaite faire, j'aurai besoin de récupérer ce qui est dans l'attribut "href" de certaines balises <a>, comment je fais ?
- Et ensuite, comment je fais pour mettre les URL que j'aurais récupérés dans une variable (pour entrer ça dans ma BDD)
- De manière générale, je trouve pas la doc de pquery ? J'ai l'impression qu'il y en a une partie dans IQuery.php sur github, mais bon, c'est lapidaire et il n'y a pas tout, si ?
- Et ça, $curl->close(); je dois le mettre ?
Merci
Marsh Posté le 25-05-2015 à 13:31:25
Tout bon c'est juste moi qui mélange composer et d'autre, va pour require
Presque:
Pour avoir les h2 dont la classe est ".title", il faut faire:
$('h2.title');
L'espace est important, avec l'espace tu sélectionnes les h2, et le sous élement dont la classe est title (quelque soit le nb d'éléments entre h2 et .title).
Alors qu'avec h2.title, tu sélectionnes les h2 qui ont la classe title.
Ensuite, effectivement pour le/les éléments trouvés, tu vas mettre "FOO" dedans.
Je pense par contre que la partie "tagName" à la fin va resélectionner des éléments h1 qui serait a l'intérieur de h2.title plutôt que de les remplacer (donc ca ne fera rien de spécial ici)...
Pour les questions:
- code:
Code :
|
Ca devrait faire le job pour les deux premières questions?
- ya plein de projet sans doc, et pquery a pas trop de doc. Cela dit, il est fait pour émuler jQuery, et la doc de jQuery elle existe, donc tu devrais t'en sortir avec celle de jQuery, modulo quelques changements car tu es en PHP et non en JS + il peut exister quelques différences de comportement entre les deux.
- Habituellement oui, ca libère tout, mais c'est si je ne me trompe pas dans tous les cas appelé automatiquement à la fin du script. Par défaut, met le après le $dom = pQuery::parseStr($html); car tu n'as plus besoin de cUrl à ce moment
Marsh Posté le 26-05-2015 à 07:05:04
Une fois encore, merci pour les réponses
Du coup, j'ai voulu tester ça sur mon serveur, ça me retourne plein d'erreurs :
- Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /home/a8081606/public_html/testcurl.php on line 12
- Parse error: syntax error, unexpected T_STRING, expecting T_CONSTANT_ENCAPSED_STRING or '(' in /home/a8081606/public_html/testcurl.php on line 12
- Parse error: syntax error, unexpected '[' in /home/a8081606/public_html/testcurl.php on line 21
- Parse error: syntax error, unexpected T_STRING in /home/a8081606/public_html/composer/vendor/php-curl-class/php-curl-class/src/Curl/Curl.php on line 3
La ligne 12 en question étant :
use \Curl\Curl;
La ligne 21 :
$links = [];
Et la ligne 3 de Curl.php étant :
namespace Curl;
J'ai des idées de ce qui ne va pas, mais je ne sais pas comment les résoudre
Sauf pour la dernière erreur dans curl.php où là, je n'ai aucune idée de ce qui ne va pas...
Marsh Posté le 26-05-2015 à 13:45:16
Ta version de PHP est probablement bien vielle pour ne pas supporter les namespace et use...
Regarde ta version de PHP...
http://php.net/manual/fr/language. [...] ionale.php
Faut que ton PHP soit 5.3.0 et +...
Marsh Posté le 26-05-2015 à 15:37:33
Question bête : parser les flux RSS des sites en question, ça répondrait pas à son besoin ?
Marsh Posté le 27-05-2015 à 01:20:41
Devil'sTiger a écrit : Ta version de PHP est probablement bien vielle pour ne pas supporter les namespace et use... |
C'était bien ça, merci. Du coup j'ai fait ce qu'il fallait et je suis passé sur un truc où PHP est à jour. Mais comme ça n'arrête jamais ( ), maintenant j'ai :
Fatal error: Class 'pQuery' not found in /home/u735102978/public_html/testcurl.php on line 18
Ma ligne 18 étant : $dom = pQuery::parseStr($html);
Du coup je me suis dit qu'il devait falloir appeler le fichier de pQuery (comme l'était celui de curl), du coup pour tenter j'ai ajouté (juste après la ligne "require 'composer/vendor/php-curl-class/php-curl-class/src/Curl/Curl.php';" ) cette ligne :
require 'composer/vendor/tburry/pquery/pQuery.php';
Du coup j'ai eu l'erreur suivante :
Fatal error: Interface 'pQuery\IQuery' not found in /home/u735102978/public_html/composer/vendor/tburry/pquery/pQuery.php on line 15
La ligne 15 de ce fichier étant : use pQuery\IQuery;
Comme le fichier IQuery.php se trouvait dans le même dossier que mon fichier pQuery.php, j'ai changé cette ligne 15 en :
use IQuery;
Du coup maintenant, j'ai ça :
Code :
|
Les lignes 11 et 16 étant
11 : use IQuery;
16 : class pQuery implements ArrayAccess, Countable, IteratorAggregate, IQuery {
Et là je cale, du coup je veux bien un autre coup de pouce svp .
Edit : après une recherche, je suis tombé sur cette réponse sur stackoverflow, du coup j'ai tenté de modifier la ligne 11 en "use \IQuery;" (nb : il y a un antislash en plus), et maintenant, je n'ai plus que la deuxième erreur, "Fatal error: Interface 'IQuery' not found in /home/u735102978/public_html/composer/vendor/tburry/pquery/pQuery.php on line 16"...
rufo a écrit : Question bête : parser les flux RSS des sites en question, ça répondrait pas à son besoin ? |
En effet, mais pour revenir à ma question d'origine, avec ça, je ne pourrais avoir que l'URL du nouveau billet, et ce qui apparaît dans le flux RSS, mais rien d'autre (enfin, il me semble, mais je me trompe peut-être ?). Du coup ça me permet de poser la question, parmi des données comme le nombre de vues de la page d'un billet, le nombre de lien renvoyant vers ce billet, le nombre de partages sur facebook et sur twitter, est-ce que vous avez une idée desquelles je peux obtenir et desquelles je ne peux pas ? (et éventuellement, comment)
Marsh Posté le 27-05-2015 à 13:35:08
Essai de réinstaller pQuery, visiblement ya un soucis avec l'autoloader...
=> normalement si tu as bien, fait, tu dois avoir cette ligne dans ton script:
Code :
|
Qui va s'assurer le chargement de l'autoloader de composer, car quand tu installes une lib avec composer, celui-ci s'occupe de générer un loader pour l'ensemble des libraries utilisés par ton projet...
Si tu as cette ligne, le problème est ptete dans pquery, faire une réinstall sera ptete nécessaire (ya ptete eu un soucis lors de l'install)
Marsh Posté le 27-05-2015 à 17:59:38
Sans rien réinstaller pour l'instant, j'ai ajouté la ligne dans mon script comme suggéré, et je pense que ça a fonctionné, parce que maintenant, je n'ai plus d'erreur.
Par contre, maintenant, ça m'affiche ça :
Code :
|
(Edit : bon ça fout en l'air la mise en page de HFR, donc je rajoute des retours à la ligne, mais normalement il n'y en a pas, c'est une seule ligne avec 101 fois le mot Array)
True story
Du coup je pense que maintenant c'est dans la boucle qu'il y a un truc qui ne va pas.
Malheureusement j'ai un rdv donc pas le temps de me pencher tout de suite dessus, je regarde ça à mon retour. Si tu as des idées de ce qui ne va pas entre temps je prends. En tout cas encore merci pour l'aide
Marsh Posté le 27-05-2015 à 18:40:25
Array c'est ce qu'on obtient quand on essaye d'afficher un tableau avec echo. Remplace ton echo par print_r pour voir à quoi ressemble ton tableau.
Marsh Posté le 28-05-2015 à 09:04:48
Boooon, ça marche enfin, avec print_r comme avec echo, merci !
Du coup, autre question, là ça me récupère les url dans les href, et j'imagine que pour tous les autres attributs ça suit le même modèle. En revanche, comment je fais pour récupérer le texte entre les balises svp ?
Marsh Posté le 28-05-2015 à 14:53:49
Au pif, mais essaye ca:
Code :
|
Ou :
Code :
|
La différence est que l'un récupère le contenu texte (en supprimant les balises) là ou l'autre prend le texte, mais inclus éventuellement les balises qui pourraient s'y trouver.
Marsh Posté le 29-05-2015 à 06:16:58
Yes, ça fonctionne très bien, merci beaucoup pour ton aide tout au long de mes questions de noobs !
Une question supplémentaire :
Si je veux crawler plusieurs urls différentes, est-ce qu'il vaut mieux faire ça :
Code :
|
Ou ça ? :
Code :
|
Autrement dit, ouvrir et fermer une seule fois (en début et en fin), ou plusieurs fois (à chaque fois pour chaque nouvelle URL) ?
J'ai testé que la première option et ça fonctionne, je pense que la deuxième aussi mais j'ai la flemme de la tester (je vois pas pourquoi ça marcherait pas en tout cas). Ma question, c'est plutôt est-ce qu'il y a des désavantages (en terme de performance ou d'autres choses) à implémenter la première option, et donc laisser cURL "tourner" pendant tout le script ? Ou est-ce que au contraire c'est mieux de la première façon plutôt que de la deuxième, parce que ce serait plus gênant d'ouvrir et fermer plusieurs fois de suite cURL (si je veux crawler beaucoup d'urls par exemple) ?
Edit : bien évidemment, je réalise qu'avec mon option 1, je pourrais plutôt faire une boucle pour crawler et parser toutes mes URL, puis fermer cURL tout de suite, et ensuite faire mes manips sur les DOMs que j'ai obtenus. Mais en fait, je compte aussi crawler les URL crawlées, du coup ça justifie ma question : est-ce qu'il vaut mieux laisser une seule "session" cURL ouverte longtemps, ou en ouvrir puis fermer plein à la suite.
Marsh Posté le 29-05-2015 à 15:47:28
Fait une fonction, et rajoute le close à la fin avant de renvoyer les données faites par cUrl/le parser
Marsh Posté le 29-05-2015 à 23:25:58
L'idéal serait de stocker les url à traiter dans un tableau (qui peut être chargé par la lecture d'un fichier contenant les url ou par une autre source) puis tu fais un boucle foreach sur ce tableau
Marsh Posté le 30-05-2015 à 21:38:49
rufo a écrit : L'idéal serait de stocker les url à traiter dans un tableau puis tu fais un boucle foreach sur ce tableau |
Yes c'est ce que j'ai fait finalement.
Citation : (qui peut être chargé par la lecture d'un fichier contenant les url ou par une autre source) |
Je suis pas une star en php, comment je fais ça ?
Merci
Marsh Posté le 31-05-2015 à 10:41:27
Pour lire un fichier txt et mettre son contenu dans un array, je te dirais bien RTFM ( http://www.phph.et )
Allez, un indice : file() est ton amie
Marsh Posté le 01-06-2015 à 03:16:30
Haha bon ok je l'ai mérité
Pour formuler peut être de manière plus légitime, j'ai du mal à saisir les nuances entre tous les trucs qui appellent des fichiers, file, require, use, include (j'ai que ça en tête là tout de suite mais il y en a peut être d'autres)
Marsh Posté le 01-06-2015 à 09:26:08
Un fichier, tu sais ce que s'est, quand même, non file ben, ça veut dire fichier en anglais Et une lecture de la doc t'indiquera ce que fait cette fonction et d'en indiquera d'autres, ayant ne utilisation proche (genre fopen, fwrite, fread, fclose...).
require et include sont relativement proche. Là encore la doc t'aidera. Tu pourras en profiter pour regarder require_once et include_once
Marsh Posté le 04-06-2015 à 13:13:33
Salut à tous,
Juste pour la gloire et alors que beaucoup de développeurs PHP pensent qu'il faut absolument passer par cURL pour faire des interactions HTTP (GET, POST, récupérer du contenu via HTTP/HTTPS, etc.) je rappelle l'existence des fonctions stream_context_create (défintion d'un contexte de flux) et ... file_get_contents.
Ces deux fonctions permettent depuis PHP 4.3.0 de créer un client HTTP sans cURL.
Dans un projet, je l'utilise pour tester l'API du projet sans avoir à installer de dépendance:
https://github.com/bbalet/jorani/bl [...] st/api.php
+
Marsh Posté le 04-06-2015 à 13:29:06
Et ça marche aussi pour le https ? Parce que j'essaye depuis un moment de fiare un script php pour automatiser des actions sur un site web avec une auth en https et impossible de passer l'étape d'authentification
J'ai utilisé comme Lib SimpleTest puis Snoopy.
Marsh Posté le 03-08-2016 à 23:19:00
Bonjour,
Je cherche un programme/logiciel qui me permettrait de trouver les coordonnais (adresses emails) de centaines de professeurs particuliers/tuteurs en France.
Pouvez vous me dire ou je peux trouver ce type de programme ? Un peu comme Growbots.
Un grand merci d’avance.
Victor DM : der.m.victor@gmail.com
Marsh Posté le 04-08-2016 à 10:40:50
Merci de ne pas squatter ce topic et d'en créer un dédié à votre pb. Pour ce genre de question, le contact en MP n'est pas nécessaire car va limiter le nb de réponses.
Par ailleurs, je déconseille de laisser votre adresse e-mail en claire sur un forum public Ce sont les bots qui vont être contents
Marsh Posté le 23-05-2015 à 20:05:03
Hello hello,
Dans le cadre d'un projet, j'ai besoin d'écrire un script (*) dont la fonction serait la suivante :
- je lui fournis une url (d'un blog, d'un site de news, etc)
- il va vérifier s'il y a un nouvel élément depuis la dernière exécution du script (un nouveau billet, un nouvel article)
- si oui, il me sort quelques données sur ce nouvel élément (ou ces nouveaux éléments s'il y en a plusieurs), comme par exemple (selon ce qu'il est possible d'obtenir, je ne sais pas bien quelles sont les limites) l'URL du nouveau billet, le nombre de vues de la page de ce billet, le nombre de lien renvoyant vers ce billet, le nombre de partages sur facebook et sur twitter, etcaetera et me les enregistre dans une table SQL.
Est-ce que vous auriez des idées d'avec quels outils faire ça ? Merci d'avance
(* en php, je connais pas grand chose d'autre, on m'a dit de tenter en Perl ou en Python mais je ne connais pas les avantages, je ne sais pas si ça s'apprend vite, ni comment j'appelle le script dans ma page web du coup)