Yep, I'm a geek !
Extraction automatique de .torrents
Deux programmes (PHP et Bash) pour parcourir tout ThePirateBay et choper tous ses torrents sans s'embèter. Le principe étant que le script Shell/Bash commande un script PHP qui lui, se charge de tout le travail de reconnaissance de chaînes et d'extraction d'URLs. Ces deux scripts sont censés s'exécuter depuis la ligne de commande, un navigateur ne nous sert à rien ici.
#!/bin/bash
#"The Pirate Bay"-specific
BaseURL="http://thepiratebay.org"
ListPagePattern='/<a[ \n\r\t]*href="(.*tor\/[^">]*)[^>]*>(.*)<\/a>/'
TorrentPagePattern='/<a href="(.*\.torrent)">.*<\/a>/'
OtherPagePattern='/<a href="(\/brwsearch[^>"]*page=[0-9]+)"/'
FirstPage=brwsearch.php\?b\=1\&c\=501
./extract.php $BaseURL $FirstPage --get-pages "$OtherPagePattern" | sort | uniq > pages.list
pageIndex=0
for page in `cat pages.list`; do
PageURL=page$pageIndex.html
wget $BaseURL$page -O $PageURL #Download de la page du site en question
./extract.php $BaseURL $PageURL --extract-torrents "$ListPagePattern" "$TorrentPagePattern" > page$pageIndex.list
#
for url in `cat page$pageIndex.list`; do
grep $url torrents.list.done > /dev/null
[[ $? == 0 ]] && echo "$url est déjà mis à télécharger" && continue;
echo "On doit télécharger $url"
dcop ktorrent KTorrent openTorrentSilently "$url";
echo $url >> torrents.list.done
done
exit 12
#
((pageIndex++))
done
#!/usr/local/bin/php -q
<?
//Extrait d'une page toutes les sous-pages contenant un torrent et pour chaque sous-page, stocke l'URL du torrent dans un fichier local.
//
//Syntaxe :
//
//./extract.php <BaseURL> <FirstListPage> <ListPagePattern> <TorrentPagePattern> <OtherPagePattern>
//
//1 : BaseURL, l'URL de base du site visé, préfixe de toutes les adresses internes.
//2 : adresse d'une des pages contenant les liste d'éléments à extraire.
//3 : pattern repérant l'URL d'une page descriptive d'un torrent sur une page-liste.
//4 : pattern repérant l'URL d'un fichier torrent sur une page descriptive.
//5 : pattern repérant les URL des autres pages-listes à partir de celle passée en paramètre 2.
//
//Exemples d'utilisation :
//
//The Pirate Bay :
//./extract.php http://www.thepiratebay.org brwsearch.php\?b\=1\&c\=501 '/<a[ \n\r\t]*href="(.*tor\/[^">]*)[^>]*>(.*)<\/a>/' '/<a href="(.*\.torrent)">.*<\/a>/' '/<a href="(\/brwsearch[^>"]*page=[0-9]+)"/'
//TODO : penser à l'option --debug pour afficher des choses...
//DONE : faire deux options, --get-pages et --extract-torrents pour différencier les deux types d'appels de ce script
function displayArray(&$arr)
{
$Output = "<ul>\n";
foreach($arr as $key=>$val)
$Output .= "<li>$key : ".(is_array($val) ? displayArray($val) : $val)."</li>\n";
return $Output."</ul>\n";
}
$Args =& $_SERVER["argv"];
if (count($Args) == 1) die("Rien...");
$BaseURL = isset($Args[1]) ? $Args[1] : "";
$SrcFile = isset($Args[2]) ? $Args[2] : "";
if (!strlen($SrcFile)) die("Pas d'URL de fichier source à analyser.\n");
if (!file_exists($SrcFile)) die("Pas de fichier source à analyser.\n");
$Contents = file_get_contents($SrcFile);
if ($Debug) echo "Taille du fichier : ".strlen($Contents)."\n";
//
$Action = isset($Args[3]) ? $Args[3] : "";
if (!strlen($Action)) die("Aucune action passée en paramètre.\n");
switch ($Action) {
case "--get-pages":
$PatternPages = isset($Args[4]) ? $Args[4] : "";
break;
case "--extract-torrents":
$Pattern = isset($Args[4]) ? $Args[4] : "";
$Pattern2 = isset($Args[5]) ? $Args[5] : "";
if (!strlen($Pattern) || !strlen($Pattern2)) die("Extraction de torrents : il manque des patterns...\n");
break;
default: die("Action inconnue : $Action.\n");
}
//Sous-pages
if (strlen($PatternPages)) {
$SubPages = array();
$NbSubPages = preg_match_all($PatternPages, $Contents, $SubPages);
//echo "Nb de matches : $NbSubPages\n";
foreach($SubPages[1] as $PageURL) echo $PageURL."\n";
//echo displayArray($SubPages);
die();
}
//Extraction de torrents
$Matches = array();
if ($Debug) echo "Pattern = $Pattern\n";
$NbMatches = preg_match_all($Pattern, $Contents, $Matches);
if ($Debug) echo "NbMatches = $NbMatches\n";
//echo displayArray($Matches);
$SubMatches = array();
for($i=0; $i<$NbMatches; $i++) {
// echo $Matches[1][$i]."\n";
if ($Debug) echo $Matches[2][$i]."\n";
$DownloadPage = file_get_contents($BaseURL.$Matches[1][$i]);
if (!$DownloadPage) echo "Problème !\n";
//Tentative de détection de pages erronées...
if (strlen($DownloadPage) < 100) {
continue;
echo "$DownloadPage\n";
}
// echo "Taille de la page téléchargée : ".strlen($DownloadPage)." octets\n";
$Ret = preg_match($Pattern2, $DownloadPage, $SubMatches);
$TorrentURL = $SubMatches[1];
if ($Debug) echo "Torrent : ";
echo (strlen($TorrentURL) ? $TorrentURL : "FALSE")."\n";
// echo displayArray($SubMatches);
}
?>
Aspirateur de site utilisant Fusker
Au départ était Fusker, qui agrégeait des sites épars et permettait leur consultation depuis un lieu unique. A partir d'un site de ce type on peut très facilement, en couplant Bash et PHP, rapatrier ces images localement. Voici :
#!/bin/bash
BaseURL="http://kladblog.funwithbabes.com/"
IndexURL=$BaseURL"index.php?offset=0"
for page in `wget -q -O- $IndexURL | grep "special=preview" | awk 'BEGIN{FS="<a href=\"[^\"]*\">.*</a>"} {URL=substr($0, index($0, $1)+length($1)+9); print substr(URL, 1, index(URL, "\"")-1)}'`; do
page=$BaseURL$page
pixList=$(wget -q -O- $page | php -r '$Contents=file_get_contents("php://stdin"); preg_match_all("@You are looking at <b>(http://[^<]*)</b>@", $Contents, $Matches); $Nb=count($Matches[1]); if ($Nb != 1) die("Oups"); $ToFusk=$Matches[1][0]; if (!preg_match("@(http://[^\[]*)\[[^\]]*\](.*)@", $ToFusk, $Matches)) die("Oups2\n"); $FP=$Matches[1]; $SP=$Matches[2]; $NbPix=preg_match_all("@(".$FP."[^<:]*).*<img src=\"\\1\"@", $Contents, $Matches); if (!$NbPix) die("Oups3"); $DirName=str_replace("/","",str_replace("http://","",$FP)); mkdir($DirName); echo $DirName."\n"; foreach($Matches[1] as $Item) echo $Item."\n";' 2>/dev/null)
DirName=""
for pix in $pixList; do
if [[ ${#DirName} -eq 0 ]]; then
DirName=$pix
echo "Dossier : $DirName"
else
echo "Image : "$pix
wget -P $DirName -nd -q $pix
fi
done
done
En changeant la déclaration de la variable IndexURL on peut rapatrier toutes les pages restantes. Ceci peut se faire automatiquement, mais je me suis arrêté là :).
C'est sûr que ça n'est pas ni du grand code ni du code propre mais ça fait le boulot. Il ne faut pas avoir envie de revenir dessus au bout de 6 mois c'est tout...
