New file |
0,0 → 1,432 |
<?php |
// Encodage : UTF-8 |
// +-------------------------------------------------------------------------------------------------------------------+ |
/** |
* Robots |
* |
* Description : classe permettant d'analyser les pages d'un site web. |
* Notes : les noms des pages doivent être dans la bonne casse. http://fr.wikipedia.org/wiki/ambronay ne renvera rien alors que |
* http://fr.wikipedia.org/wiki/Ambronay renvera un résultat (Notez le A ou a). |
* |
//Auteur original : |
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org> |
* @copyright Tela-Botanica 1999-2009 |
* @link http://www.tela-botanica.org/wikini/eflore |
* @licence GPL v3 & CeCILL v2 |
* @version $Id: Robot.class.php 2057 2011-05-13 16:39:06Z Jean-Pascal MILCENT $ |
*/ |
// +-------------------------------------------------------------------------------------------------------------------+ |
class Robot extends ScriptCommande { |
/** |
* Indique le nom du Robot. |
*/ |
private $robot_nom; |
/** |
* Indique le fichier de config de la gestion des cookies du Robot. |
*/ |
private $cookie; |
/** |
* Indique l'url de départ du Robot. |
*/ |
private $page; |
/** |
* Tableau des URLs à analyse |
*/ |
private $pages = array(); |
/** |
* Chemin vers un fichier contenant les noms des pages à analyser (un nom de page par ligne). |
*/ |
private $page_fichier; |
/** |
* Contient soit False soit le chemin vers le dossier où mettre les pages en cache. |
*/ |
private $cache = false; |
/** |
* Contient le squelette de l'url à utiliser pour récupérer les pages web. |
*/ |
private $url_tpl = ''; |
/** |
* Contient false ou l'encodage des pages d'un site web si celui-ci n'est pas en UTF-8. |
*/ |
private $encodage = false; |
/** |
* Contient la chaine de caractères indiquant où commencer une recherche d'informations dans la page web. |
*/ |
private $chaine_debut = ''; |
/** |
* Contient la chaine de caractères indiquant où terminer une recherche d'informations dans la page web. |
*/ |
private $chaine_fin = ''; |
/** |
* Tableau des expressions régulières récupérant des données lors de l'analyse |
*/ |
private $regexps = array(); |
/** |
* Indique le dossier ou fichier où le Robot doit sotcker les informations collectées. |
*/ |
private $sortie; |
|
public $parametres = array( '-pgf' => array(false, '', 'Fichier contenant les pages que le Robot doit analyser'), |
'-s' => array(false, '', 'Fichier où stocker les données récupérées par le Robot'), |
'-pg' => array(false, '', 'Nom de la page que le Robot doit analyser')); |
|
|
public function executer() { |
$this->page = $this->getParam('pg'); |
$this->page_fichier = $this->getParam('pgf'); |
$this->cookie = dirname(__FILE__).DS.'configuration'.DS.'cookieconf.txt'; |
$this->sortie = $this->getParam('s'); |
|
// Construction du tableau contenant les noms des pages à analyser |
if (empty($this->page_fichier)) { |
$this->pages[] = $this->page; |
} else { |
$this->pages = $this->convertirFichierEnTableau($this->page_fichier); |
} |
|
// Création du chemin du cache si le fichier ini du projet l'indique |
if ($this->getIni('cache_chemin')) { |
$this->cache = $this->getIni('cache_chemin'); |
} |
|
// Lancement du Robot demandé |
$cmd = $this->getParam('a'); |
switch ($cmd) { |
case 'wp' : |
$this->lancerRobotWikipedia(); |
break; |
case 'wp-pays' : |
$this->lancerRobotWikipediaPays(); |
break; |
case 'wp-liste-communes' : |
$this->lancerRobotWikipediaListeCommunes(); |
break; |
case 'ipni' : |
$this->lancerRobotIpni(); |
break; |
case 'cassini' : |
$this->lancerRobotCassini(); |
break; |
case 'utm' : |
$this->lancerRobotUtmConverter(); |
break; |
default : |
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd)); |
} |
} |
|
/** |
* Robot analysant les pages de Wikipedia correspondant à des communes. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pgf ~/importation/robots/eFloreBotWp_INSEE_C.txt -s ~/importation/robots/wp_communes.tsv |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pg Montpellier -s ~/importation/robots/wp_communes.tsv |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pg Montpellier |
* |
* @return unknown_type |
*/ |
private function lancerRobotWikipedia() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotWp'; |
$this->url_tpl = 'http://fr.wikipedia.org/wiki/%s'; |
$this->regexp_ligne = '/<!-- bodytext -->(.*)<!-- \/bodytext -->/umsi'; |
$this->regexps = array( 'CodeInsee' => 'Code commune<\/a><\/th>(?:\n|\r\n)<td>(\d+)<\/td>', |
'Nom' => 'class="entete map" style="[^"]+">(.*)<', |
'Latitutde' => '<span class="geo-dec geo" title=".*"><span class="latitude">(.*)<\/span>', |
'Longitude' => '<span class="geo-dec geo" title=".*">.*<\/span>, <span class="longitude">(.*)<\/span>', |
'Superficie' => 'Superficie<\/a>(?:<\/b><\/td>|<\/th>)(?:\n|\r\n)<td>((?:[0-9]| | )+(?:,[0-9]+)?) km<sup>2<\/sup>', |
'AltitudeMin' => 'Altitudes<\/a><\/th>(?:\n|\r\n)<td>mini. (-?[0-9]+) m — maxi. [ 0-9]+ m<\/td>', |
'AltitudeMax' => 'Altitudes<\/a><\/th>(?:\n|\r\n)<td>mini. -?[0-9]+ m — maxi. ([ 0-9]+) m<\/td>', |
'Population' => 'Population<\/a><\/th>(?:\n|\r\n)<td>(.*) hab.', |
'PopulationAnnee' => 'Population<\/a><\/th>(?:\n|\r\n)<td>.* hab. <small>\(<a href="\/wiki\/[0-9]+"(?: title="[0-9]+")?>([0-9]+)<\/a>', |
'CodePostal' => 'Code postal<\/a><\/th>(?:\n|\r\n)<td>([0-9]{5}).*<\/td>', |
'PageWikipedia' => '(?:Ce document provient|Récupérée) de « <a href="http:\/\/fr.wikipedia.org\/wiki\/(.*)">' |
); |
// Préparation des noms des pages |
foreach ($this->pages as $id => $nom) { |
$this->pages[$id] = str_replace(' ', '_', $nom); |
} |
$this->analyserUrls(); |
} |
|
/** |
* Robot analysant les pages de Wikipedia correspondant à des pays. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp-pays -pgf ~/importation/robots/eFloreBotWp_pays.txt -s ~/importation/robots/wp-pays.tsv |
* |
* @return unknown_type |
*/ |
private function lancerRobotWikipediaPays() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotWp'; |
$this->url_tpl = 'http://fr.wikipedia.org/wiki/%s'; |
$this->regexp_ligne = '/<!-- bodytext -->(.*)<!-- \/bodytext -->/umsi'; |
$this->regexps = array( 'Nom' => '<table class="infobox_v2" cellspacing="[^"]+" style="[^"]+">(?:\n|\r\n)<caption style="[^"]+"><b>(.*)<\/b>', |
'Latitutde' => '<span class="geo-dec geo" title=".*"><span class="latitude">(.*)<\/span>', |
'Longitude' => '<span class="geo-dec geo" title=".*">.*<\/span>, <span class="longitude">(.*)<\/span>', |
'Superficie' => 'Superficie<\/a><\/b><\/td>(?:\n|\r\n)<td>((?:[0-9]|\s*| )+(?:,[0-9]+)?)(?: |\s*)km<sup>2<\/sup>', |
'Population' => 'Population<\/a><\/b>(?: |\s)*<small>\([0-9]+\)<\/small><\/td>(?:\n|\r\n)<td>(.*)(?: |\s*)hab.', |
'PopulationAnnee' => 'Population<\/a><\/b>(?: |\s)*<small>\(([0-9]+)\)', |
'Capitale' => 'Capitale<\/a><\/b><\/td>(?:\n|\r\n)<td>(?:<a href="\/wiki\/[^"]+" title="[^"]+">|)(.+)<', |
'PageWikipedia' => '(?:Ce document provient|Récupérée) de « <a href="http:\/\/fr.wikipedia.org\/wiki\/(.*)">' |
); |
// Préparation des noms des pages |
foreach ($this->pages as $id => $nom) { |
$this->pages[$id] = str_replace(' ', '_', $nom); |
} |
$this->analyserUrls(); |
} |
|
/** |
* Robot analysant une page de wikipedia à la recherche de plusieurs données par page. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pgf ~/importation/robots/eFloreBotWp_INSEE_C.txt -s ~/importation/robots/wp_communes.tsv |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pg Montpellier -s ~/importation/robots/wp_communes.tsv |
* /opt/lampp/bin/php script.php robot -p wp_commune -a wp -pg Montpellier |
* |
* @return unknown_type |
*/ |
private function lancerRobotWikipediaListeCommunes() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotWpListe'; |
$this->url_tpl = 'http://fr.wikipedia.org/wiki/%s'; |
$this->regexp_ligne = '/<tr>(.*)?<\/tr>/Uumsi'; |
$this->mode = 'MULTI'; |
$this->regexps = array( 'PageWikipedia' => '^<td align="left"><a href="\/wiki\/([^"]+)"', |
'CodeInsee' => '^<td>.+<\/td>(?:\n|\r\n)<td>(\d+)<\/td>', |
'CodePostal' => '^(?:<td>.+<\/td>(?:\n|\r\n)){2}<td>(\d+)<\/td>', |
'Superficie' => '^(?:<td>.+<\/td>(?:\n|\r\n)){4}<td><span.+span>((?:[0-9]| | )+(?:,[0-9]+)?)<\/td>', |
'Population' => '^(?:<td>.+<\/td>(?:\n|\r\n)){5}<td><span.+span>((?:[0-9]| | )+)<\/td>' |
); |
// Préparation des noms des pages |
foreach ($this->pages as $id => $nom) { |
$this->pages[$id] = str_replace(' ', '_', $nom); |
} |
$this->analyserUrls(); |
} |
|
/** |
* Robot analysant les pages du site de l'IPNI. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p ipni_auteur -a wp -pgf ~/importation/robots/eFloreBotIpni_auteur.txt -s ~/importation/robots/ipni_auteurs.tsv |
* /opt/lampp/bin/php script.php robot -p ipni_auteur -a wp -pg Z -s ~/importation/robots/ipni_auteurs.tsv |
* /opt/lampp/bin/php script.php robot -p ipni_auteur -a wp -pg Z |
* |
* @return unknown_type |
*/ |
private function lancerRobotIpni() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotIpni'; |
$this->url_tpl = 'http://ipni.org/ipni/advAuthorSearch.do?output_format=delimited&find_surname=%s*'; |
$this->regexp_ligne = '/^(.*)$/umi'; |
$this->regexps = array( 'Id' => '^([^%]+)%' , |
'Version' => '^(?:[^%]*%){1,}([^%]*)%' , |
'DefaultAuthorName' => '^(?:[^%]*%){2,}([^%]*)%' , |
'DefaultAuthorForename' => '^(?:[^%]*%){3,}([^%]*)%' , |
'DefaultAuthorSurname' => '^(?:[^%]*%){4,}([^%]*)%' , |
'StandardForm' => '^(?:[^%]*%){5,}([^%]*)%' , |
'NameNotes' => '^(?:[^%]*%){6,}([^%]*)%' , |
'NameSource' => '^(?:[^%]*%){7,}([^%]*)%' , |
'Dates' => '^(?:[^%]*%){8,}([^%]*)%' , |
'DateTypeCode' => '^(?:[^%]*%){9,}([^%]*)%' , |
'DateTypeString' => '^(?:[^%]*%){10,}([^%]*)%' , |
'AlternativeAbbreviations' => '^(?:[^%]*%){11,}([^%]*)%' , |
'AlternativeNames' => '^(?:[^%]*%){12,}([^%]*)%' , |
'TaxonGroups' => '^(?:[^%]*%){13,}([^%]*)%' , |
'ExampleOfNamePublished' => '^(?:[^%]*%){14,}([^%]*)$' ); |
$this->analyserUrls(); |
} |
|
/** |
* Robot analysant les pages du site de Cassini. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pgf ~/importation/robots/eFloreBotCassini.txt -s ~/importation/robots/cassini.tsv |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pg 1 -s ~/importation/robots/cassini.tsv |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pg 1 |
* |
* @return unknown_type |
*/ |
private function lancerRobotCassini() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotCassini'; |
$this->url_tpl = 'http://cassini.ehess.fr/cassini/fr/html/fiche.php?select_resultat=%s'; |
$this->encodage = 'ISO-8859-1'; |
$this->regexp_ligne = '/\s*var\s+chaine1\s+\t=\s+"(.*?)";/umsi'; |
$this->regexps = array( 'NomCommune' => '^([^\\\\]+)\\\\n' , |
'Superficie' => '\\\\nsuperficie;([^\\\\]+)\\\\n', |
'AltitudeMin' => '\\\\naltitude;([^;]+);', |
'AltitudeMax' => '\\\\naltitude;[^;]+;([^\\\\]+)\\\\n', |
'LambertIIEtenduX' => '\\\\ncoordonnées;Lambert II étendu\\\\n;x;([^\\\\]+)\\\\n', |
'LambertIIEtenduY' => '\\\\ncoordonnées;Lambert II étendu\\\\n;x;[^\\\\]+\\\\n;y;([^\\\\]+)\\\\n', |
'Latitude' => '\\\\n;Latitude;(.+)?\\\\ncode', |
'Longitude' => '\\\\n;Longitude;(.+?)\\\\n;Latitude', |
'CodeInsee' => '\\\\ncode insee;([^\\\\]+)\\\\nstatut', |
'Statut' => '\\\\nstatut\(s\);([^\\\\]+)\\\\n\\\\n'); |
$this->analyserUrls(); |
} |
|
/** |
* Robot analysant les pages du site de Cassini. |
* Exemples d'utilisation : |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pgf ~/importation/robots/eFloreBotCassini.txt -s ~/importation/robots/cassini.tsv |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pg 1 -s ~/importation/robots/cassini.tsv |
* /opt/lampp/bin/php script.php robot -p cassini -a cassini -pg 1 |
* |
* @return unknown_type |
*/ |
private function lancerRobotUtmConverter() { |
// Valeur spécifique de ce Robot |
$this->robot_nom = 'eFloreBotUtmConverter'; |
$this->url_tpl = 'http://www.rcn.montana.edu/resources/tools/coordinates.aspx?nav=11&c=DD&md=83&mdt=NAD83/WGS84&lat=%s&lath=N&lon=%s&lonh=E'; |
$this->encodage = 'ISO-8859-1'; |
$this->regexp_ligne = '/Universal Transverse Mercator \(UTM\):<\/td>(.*?)<\/table><\/td>/umsi'; |
$this->regexps = array( 'UTM_Zone' => 'Zone: ([0-9]+)<' , |
'UTM_Est_x' => 'Easting: ([0-9]+)<', |
'UTM_Nord_y' => 'Northing: ([0-9]+)<'); |
$this->analyserUrls(); |
} |
|
private function analyserUrls() { |
// Lancement de l'analyse |
$heure_debut = date('c',time()); |
|
echo "Analyse de l'URL # : "; |
$pagesNum = 0;// Pages |
$lignesNum = 0;// Lignes |
$sortie = ''; |
foreach ($this->pages as $paramsPage) { |
$xhtml_page = $this->getHtml($this->url_tpl, $paramsPage); |
$xhtml_lignes = $this->extraireChaine($this->regexp_ligne, $xhtml_page); |
|
// Pour chaque chaine début/fin trouvées au sein de la page, nous recherchons les regexps des données. |
if (count($xhtml_lignes) > 1 && $this->mode != 'MULTI') { |
$this->traiterAttention("Plusieurs lignes correspondent à votre expression régulière de limitation du contenu :\n %s", array($this->regexp_ligne)); |
} else if ($xhtml_lignes) { |
print_r($xhtml_lignes ); |
foreach ($xhtml_lignes as $xhtml) { |
$champsNum = 1;// Champs |
$ligne = ''; |
foreach ($this->regexps as $chp => $regexp) { |
// Si nous traitons la première ligne nous ajoutons les noms des champs en début de fichier de sortie |
if ($lignesNum == 0) { |
$sortie .= $chp.(($champsNum == count($this->regexps)) ? "\n" : "\t"); |
$champsNum++; |
} |
// Ajout de la valeur trouvée grâce à l'expression régulière à la ligne de sortie |
if (preg_match('/'.$regexp.'/Umsi', $xhtml, $match)) { |
$ligne .= $this->nettoyer($match[1])."\t"; |
} else { |
$ligne .= "\t"; |
} |
} |
$lignesNum++; |
$ligne = trim($ligne); |
$sortie .= $ligne."\n"; |
|
// Affichage en console... |
if (empty($this->sortie)) { |
echo "\t".$ligne."\n"; |
} |
} |
|
} else { |
$this->traiterAttention("Impossible de trouver les chaines début et fin dans la page «%s» avec la regexp :\n%s", array($this->getNomPage($paramsPage), $this->regexp_ligne)); |
} |
// Affichage en console... |
echo str_repeat(chr(8), ( strlen( $pagesNum ) + 1 ))."\t".$pagesNum++; |
} |
echo "\n"; |
$heure_fin = date('c',time()); |
|
// Ajout de métadonnées |
$metadonnees = "Début d'importation : $heure_debut\nFin d'importation : $heure_fin\n"; |
$metadonnees .= "Source des données : ".$this->url_tpl."\n"; |
$sortie = $metadonnees.$sortie; |
|
// Écriture du fichier de sortie ou retour dans la console |
if (!empty($this->sortie)) { |
file_put_contents($this->sortie, $sortie); |
} |
} |
|
private function nettoyer($txt) { |
$txt = trim($txt); |
$txt = preg_replace('/(?: | )/', ' ', $txt); |
return $txt; |
} |
|
private function getHtml($url_tpl, $paramsPage) { |
// Lancement en ligne de commande pour tester : |
//curl -v --url "http://fr.wikipedia.org/wiki/Montpellier" --config /home/jpm/web/eflore_bp/consultation/scripts/modules/robot/configuration/cookieconf.txt |
if ($this->cache && file_exists($fichier_cache = $this->cache.$this->getNomPage($paramsPage))) { |
$html = file_get_contents($fichier_cache); |
} else { |
$url = vsprintf($url_tpl, $paramsPage); |
$this->traiterAttention(" Url : ".$url); |
// Initialisation CURL |
$curl = curl_init(); |
curl_setopt($curl, CURLOPT_COOKIEFILE, $this->cookie); |
curl_setopt($curl, CURLOPT_URL, $url); |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); |
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'); |
|
$html = curl_exec($curl); |
|
// Mise en cache |
if ($this->cache) { |
file_put_contents($fichier_cache, $html); |
} |
} |
|
// Nettoyage des entités html |
$html = $this->encoderUtf8($html, 'HTML-ENTITIES'); |
// Nettoyage de l'encodage des urls |
$html = urldecode($html); |
|
// Convertion en UTF-8 si nécessaire |
if ($this->encodage) { |
$html = $this->encoderUtf8($html, $this->encodage); |
} |
|
return $html; |
} |
|
/** |
* Méthode récupérant seulement une partie du texte passé en paramétre. |
* |
* @param $debut chaine de caractère indiquant le début du texte à prendre en compte. |
* @param $fin chaine de caractère indiquant la fin du texte à prendre en compte. |
* @param $txt le texte duquel extraire une partie bornée par $debut et $fin. |
* @return le texte extrait. |
*/ |
private function extraireChaine($regexp, $txt) { |
if (preg_match_all($regexp, $txt, $match)) { |
return $match[1]; |
} else { |
return false; |
} |
} |
/** |
* Charge les lignes d'un fichier dans un tableau et le retourne. |
* Supprime les caractères blancs et les nouvelles lignes. |
* |
* @param $fichier |
* @return unknown_type |
*/ |
private function convertirFichierEnTableau($fichier) { |
$tableau = array(); |
$handle = fopen($fichier,'r'); |
if ($handle) { |
while ($ligne = fgets($handle)) { |
$tableau[] = explode("\t", trim($ligne)); |
} |
fclose($handle); |
} |
return $tableau; |
} |
|
private function getNomPage($paramsPage) { |
return str_replace(' ', '_', implode('_', $paramsPage)).'.html'; |
} |
|
} |
?> |