[SOURCE] HideMyAss Proxy Scrapper

Iniciado por xiruko, 6 Febrero 2013, 16:00 PM

0 Miembros y 1 Visitante están viendo este tema.

xiruko

buenas foro,

hace unos dias pedi consejo acerca de hacer web scraping a una web y para ello necesitaba de varios proxies. pues bien, me gustaria compartir este codigo que supongo que a algunos les ayudara.

es un script en php que recopila la lista de proxies de la web de hidemyass. esta probado y funciona perfectamente (al menos hace 2 semanas, si no han cambiado el formato de hidemyass deberia funcionar). la lista la carga en una base de datos de mysql, en la que crea una tabla de nombre el dia y mes actual, con los siguientes campos: id, address (ip:port), type (http, https, socks4/5) y used (la cantidad de veces que se ha usado). ademas, actualiza un fichero de texto con el nombre de la tabla actualizada. tan solo habria que rellenar los datos del apartado 'DATA' y correrlo. el codigo es el siguiente:

Código (php) [Seleccionar]
<?php

//// includes
include('./simple_html_dom.php');

/************ DATA ************/

$num_pages=10// 50 proxies/page
$speed_limit=50// min speed to take proxy
$conn_limit=50// min connection time to take proxy
$sleep_time=3// seconds to wait between different pages

// data for mysql
$server='localhost';
$user='foo';
$pass='bar';
$db_name='example';

/************ MAIN ************/

$proxy_address=array();
$proxy_type=array();
for (
$i=1$i<=$num_pages$i++) {
$html=file_get_html('http://www.hidemyass.com/proxy-list/'.$i);
foreach ($html->find('tr') as $tr) {
if (isset($tr->id)) continue;
$speed=get_proxy_specs($tr->find('td'4));
$connection_time=get_proxy_specs($tr->find('td'5));
if ($speed $speed_limit && $connection_time $conn_limit) {
$proxy_address[]=get_proxy_address($tr);
$proxy_type[]=$tr->find('td'6)->plaintext;
}
}
sleep($sleep_time);
}
$proxy_address=array_filter($proxy_address);
$proxy_type=array_filter($proxy_type);

//// save data in the database
$database=mysql_connect($server$user$pass);
mysql_select_db($db_name$database);
$name='proxies_'.date('d_m'); // name of the new daily table is 'proxies_$d_$m', where $d=day and $m=month
$table='CREATE TABLE '.$name.' (id smallint NOT NULL AUTO_INCREMENT, address VARCHAR(25) NOT NULL, type VARCHAR(10) NOT NULL, used smallint default \'0\', PRIMARY KEY (id))';
mysql_query($table$database);

for (
$i=0$i<count($proxy_address); $i++) {
$query='INSERT INTO '.$name.' (address, type) VALUES (\''.$proxy_address[$i].'\', \''.$proxy_type[$i].'\')';
mysql_query($query$database);
}

//// update file 'daily_table.txt' with the new name of daily table
$file=fopen('./daily_table.txt''w');
fwrite($file$name);
fclose($file);

//// close mysql connection
mysql_close($database);

/************ FUNCTIONS ************/

function get_proxy_specs($td) {

$html=$td->find('div'0)->find('div'0)->style;
preg_match('/width:(\d+)%/'$html$result);
return $result[1];
}

function 
get_proxy_address($tr) {

// retrieve classes with the 'display:inline' css attribute
$classes=get_classes($tr->find('td'1)->find('span'0)->find('style'0)->xmltext);

// get the piece of html with the proxy ip and make some formating to it
$html=$tr->find('td'1)->xmltext;
$html=preg_replace(array('%<style>(\s+\.[_\w\-]+\{display:(none|inline)\})*\s+</style>%''%\s%''%"%''%/%'), ''$html);
$html=str_replace(array('<''>''div'), array('#''#''span'), $html);
$html=explode('span'$html);

// get the proxy ip applying some filters
$ip=filter($html$classes);

// get the proxy port
$port=$tr->find('td'2)->plaintext;
$port=preg_replace('%\s%'''$port);

// return with the format 'ip:port'
return $ip.':'.$port;
}

function 
get_classes($html) {

$html=preg_replace('%\s%'''$html);
$html=explode('.'$html);
$classes=array();
foreach ($html as $element) {
if (preg_match('%([\w\-_]+?)\{display:inline\}%'$element$result)) {
$classes[]=$result[1];
}
}
return $classes;
}

function 
filter($html$classes) {

// filter 1: class with the 'display:inline' value css attribute
foreach ($html as $key=>$element) {
foreach ($classes as $cl) {
if (strpos($element$cl)) {
$pattern='class='.$cl;
$html[$key]=str_replace($pattern''$element);
}
}
}
// filter 2: class name is made only by numbers and is not in the $classes array
foreach ($html as $key=>$element) {
if (preg_match('%class=\d+#%'$element)) {
$html[$key]=preg_replace('%class=\d+%'''$element);
}
}
// filter 3: elements with the 'display:inline' css-style value attribute
foreach ($html as $key=>$element) {
if (strpos($element'display:inline')) {
$html[$key]=str_replace('style=display:inline'''$element);
}
}

// retrieve de ip address
$ip='';
foreach ($html as $key=>$element) {
if (preg_match('%^#([\d.]+)#$%'$element$result)) {
$ip.=$result[1];
}
}
return $ip;
}

?>


luego haria falta otro archivo que yo le he llamado 'proxy_functions.php', que contendria lo siguiente:

Código (php) [Seleccionar]
<?php

//// data
$server='localhost';
$user='foo';
$pass='bar';
$db_name='example';

$used_limit=9;

function 
get_proxy() {

// read the name of the updated proxy list
$file=fopen('./daily_table.txt''r');
$name=fread($file15);
fclose($file);

// connect to database
$database=mysql_connect($server$user$pass);
if (!$database) die('Could not connect: '.mysql_error());
mysql_select_db($db_name$database);

// select a pseudo-random proxy that have been used $used_limit or less times
$query='SELECT id, address, type FROM '.$name.' WHERE used<'.$used_limit.' ORDER BY rand() LIMIT 1';
$result=mysql_query($query$database);
$row=mysql_fetch_array($resultMYSQL_ASSOC);

// update the number of times the proxy has been used
$query='UPDATE '.$name.' SET used=used+1 WHERE id='.$row['id'];
mysql_query($query$database);

// return the array=(address, type)
return array('address'=>$row['address'], 'type'=>$row['type']);
}

?>


con lo que simplemente, para usar un proxy al azar en un script php, bastaria con correr en una cron job el primer script 1 vez al dia por ejemplo (o 2, o las que sean), y luego en el script en el que quieras usar el proxy hacer:

Código (php) [Seleccionar]
<?php

include('proxy_functions.php');
$proxy=get_proxy();
// $proxy['address']=a.b.c.d:p
// $proxy['type']=http | https | socks4/5

?>


y bueno, el codigo no tiene casi nada de verificacion de errores, por no decir que tiene solo 1 xD, y tampoco creo que sea el codigo mas optimo y eficiente pero funcionar funciona. por ultimo decir que quien quiera usar el codigo que lo use, asi como copiarlo, modificarlo, imprimirlo y pegarlo en la nevera, o lo que sea, pero se agradeceria que si se comparte en alguna otra web o blog, se ponga un enlace a la fuente que en este caso seria esta pagina.

un saludo!

#!drvy

Así a primera vista, muy bueno. Lo unico que te recomiendo es no usar mysql.. usa mysqli. mysql en futuras versiones ser ira a la *****. xD

Citarimprimirlo y pegarlo en la nevera,

:silbar:

Saludos

EFEX

Cita de: xiruko en  6 Febrero 2013, 16:00 PM
por ultimo decir que quien quiera usar el codigo que lo use, asi como copiarlo, modificarlo, imprimirlo y pegarlo en la nevera, o lo que sea, pero se agradeceria que si se comparte en alguna otra web o blog, se ponga un enlace a la fuente que en este caso seria esta pagina.

Podrias agregarle tu comentario, autor(vos), version, contacto., tambien subirlo a github  ;)
GITHUB 

xiruko

@ drvy | BSM

gracias por la recomendacion, aunque de momento mientras funcione se quedara asi ya que ahora estoy liado con otras cosas xD ademas igual en 3 o 4 meses vuelven a cambiar el formato de hidemyass y entonces ya aprovecharia para cambiarlo todo.

@ EFEX

no estaria mal, pero bueno tampoco creo que sea necesario. si fuera mas codigo aun, pero apenas son 150 lineas o por ahi. me conformo con esperar que si alguien lo comparte ponga un enlace a esta web jeje

gracias a los 2 por los comentarios! un saludo!