Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: xiruko en 6 Febrero 2013, 16:00 pm



Título: [SOURCE] HideMyAss Proxy Scrapper
Publicado por: xiruko en 6 Febrero 2013, 16:00 pm
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
  1. <?php
  2.  
  3. //// includes
  4. include('./simple_html_dom.php');
  5.  
  6. /************ DATA ************/
  7.  
  8. $num_pages=10; // 50 proxies/page
  9. $speed_limit=50; // min speed to take proxy
  10. $conn_limit=50; // min connection time to take proxy
  11. $sleep_time=3; // seconds to wait between different pages
  12.  
  13. // data for mysql
  14. $server='localhost';
  15. $user='foo';
  16. $pass='bar';
  17. $db_name='example';
  18.  
  19. /************ MAIN ************/
  20.  
  21. $proxy_address=array();
  22. $proxy_type=array();
  23. for ($i=1; $i<=$num_pages; $i++) {
  24. $html=file_get_html('http://www.hidemyass.com/proxy-list/'.$i);
  25. foreach ($html->find('tr') as $tr) {
  26. if (isset($tr->id)) continue;
  27. $speed=get_proxy_specs($tr->find('td', 4));
  28. $connection_time=get_proxy_specs($tr->find('td', 5));
  29. if ($speed > $speed_limit && $connection_time > $conn_limit) {
  30. $proxy_address[]=get_proxy_address($tr);
  31. $proxy_type[]=$tr->find('td', 6)->plaintext;
  32. }
  33. }
  34. sleep($sleep_time);
  35. }
  36. $proxy_address=array_filter($proxy_address);
  37. $proxy_type=array_filter($proxy_type);
  38.  
  39. //// save data in the database
  40. $database=mysql_connect($server, $user, $pass);
  41. mysql_select_db($db_name, $database);
  42. $name='proxies_'.date('d_m'); // name of the new daily table is 'proxies_$d_$m', where $d=day and $m=month
  43. $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))';
  44. mysql_query($table, $database);
  45.  
  46. for ($i=0; $i<count($proxy_address); $i++) {
  47. $query='INSERT INTO '.$name.' (address, type) VALUES (\''.$proxy_address[$i].'\', \''.$proxy_type[$i].'\')';
  48. mysql_query($query, $database);
  49. }
  50.  
  51. //// update file 'daily_table.txt' with the new name of daily table
  52. $file=fopen('./daily_table.txt', 'w');
  53. fwrite($file, $name);
  54. fclose($file);
  55.  
  56. //// close mysql connection
  57. mysql_close($database);
  58.  
  59. /************ FUNCTIONS ************/
  60.  
  61. function get_proxy_specs($td) {
  62.  
  63. $html=$td->find('div', 0)->find('div', 0)->style;
  64. preg_match('/width:(\d+)%/', $html, $result);
  65. return $result[1];
  66. }
  67.  
  68. function get_proxy_address($tr) {
  69.  
  70. // retrieve classes with the 'display:inline' css attribute
  71. $classes=get_classes($tr->find('td', 1)->find('span', 0)->find('style', 0)->xmltext);
  72.  
  73. // get the piece of html with the proxy ip and make some formating to it
  74. $html=$tr->find('td', 1)->xmltext;
  75. $html=preg_replace(array('%<style>(\s+\.[_\w\-]+\{display:(none|inline)\})*\s+</style>%', '%\s%', '%"%', '%/%'), '', $html);
  76. $html=str_replace(array('<', '>', 'div'), array('#', '#', 'span'), $html);
  77. $html=explode('span', $html);
  78.  
  79. // get the proxy ip applying some filters
  80. $ip=filter($html, $classes);
  81.  
  82. // get the proxy port
  83. $port=$tr->find('td', 2)->plaintext;
  84. $port=preg_replace('%\s%', '', $port);
  85.  
  86. // return with the format 'ip:port'
  87. return $ip.':'.$port;
  88. }
  89.  
  90. function get_classes($html) {
  91.  
  92. $html=preg_replace('%\s%', '', $html);
  93. $html=explode('.', $html);
  94. $classes=array();
  95. foreach ($html as $element) {
  96. if (preg_match('%([\w\-_]+?)\{display:inline\}%', $element, $result)) {
  97. $classes[]=$result[1];
  98. }
  99. }
  100. return $classes;
  101. }
  102.  
  103. function filter($html, $classes) {
  104.  
  105. // filter 1: class with the 'display:inline' value css attribute
  106. foreach ($html as $key=>$element) {
  107. foreach ($classes as $cl) {
  108. if (strpos($element, $cl)) {
  109. $pattern='class='.$cl;
  110. $html[$key]=str_replace($pattern, '', $element);
  111. }
  112. }
  113. }
  114. // filter 2: class name is made only by numbers and is not in the $classes array
  115. foreach ($html as $key=>$element) {
  116. if (preg_match('%class=\d+#%', $element)) {
  117. $html[$key]=preg_replace('%class=\d+%', '', $element);
  118. }
  119. }
  120. // filter 3: elements with the 'display:inline' css-style value attribute
  121. foreach ($html as $key=>$element) {
  122. if (strpos($element, 'display:inline')) {
  123. $html[$key]=str_replace('style=display:inline', '', $element);
  124. }
  125. }
  126.  
  127. // retrieve de ip address
  128. $ip='';
  129. foreach ($html as $key=>$element) {
  130. if (preg_match('%^#([\d.]+)#$%', $element, $result)) {
  131. $ip.=$result[1];
  132. }
  133. }
  134. return $ip;
  135. }
  136.  
  137. ?>

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

Código
  1. <?php
  2.  
  3. //// data
  4. $server='localhost';
  5. $user='foo';
  6. $pass='bar';
  7. $db_name='example';
  8.  
  9. $used_limit=9;
  10.  
  11. function get_proxy() {
  12.  
  13. // read the name of the updated proxy list
  14. $file=fopen('./daily_table.txt', 'r');
  15. $name=fread($file, 15);
  16. fclose($file);
  17.  
  18. // connect to database
  19. $database=mysql_connect($server, $user, $pass);
  20. if (!$database) die('Could not connect: '.mysql_error());
  21. mysql_select_db($db_name, $database);
  22.  
  23. // select a pseudo-random proxy that have been used $used_limit or less times
  24. $query='SELECT id, address, type FROM '.$name.' WHERE used<'.$used_limit.' ORDER BY rand() LIMIT 1';
  25. $result=mysql_query($query, $database);
  26. $row=mysql_fetch_array($result, MYSQL_ASSOC);
  27.  
  28. // update the number of times the proxy has been used
  29. $query='UPDATE '.$name.' SET used=used+1 WHERE id='.$row['id'];
  30. mysql_query($query, $database);
  31.  
  32. // return the array=(address, type)
  33. return array('address'=>$row['address'], 'type'=>$row['type']);
  34. }
  35.  
  36. ?>

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
  1. <?php
  2.  
  3. include('proxy_functions.php');
  4. $proxy=get_proxy();
  5. // $proxy['address']=a.b.c.d:p
  6. // $proxy['type']=http | https | socks4/5
  7.  
  8. ?>

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!


Título: Re: [SOURCE] HideMyAss Proxy Scrapper
Publicado por: #!drvy en 6 Febrero 2013, 17:26 pm
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

Citar
imprimirlo y pegarlo en la nevera,

 :silbar:

Saludos


Título: Re: [SOURCE] HideMyAss Proxy Scrapper
Publicado por: EFEX en 6 Febrero 2013, 17:54 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  ;)


Título: Re: [SOURCE] HideMyAss Proxy Scrapper
Publicado por: xiruko en 7 Febrero 2013, 14:50 pm
@ 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!