[{"data":1,"prerenderedAt":17},["ShallowReactive",2],{"article":3},{"id":4,"category":5,"slug":6,"title":7,"image":8,"page_image":9,"published_at":10,"updated_at":11,"meta_title":12,"meta_description":13,"meta_keywords":14,"content":15,"tags":16},129,"blog","es-php-for-data-harvesting-in-collaboration-with-a-trusted-proxy-website","PHP para la recolección de datos en colaboración con un sitio web proxy de confianza","https://blog.dexodata.com/storage/uploads/previews/15-3-s-trusted-proxy-website-php-and-data-collection-cover-1032x491-058e15f3-9c89-4100-a80c-ca121dc343ea.webp","https://blog.dexodata.com/storage/uploads/covers/15-3-b-trusted-proxy-website-php-and-data-collection-cover-1032x491-accb4767-8ff9-4506-aa0e-4cf5aac6a61e.webp","2024/08/13","2024/07/31","Cómo recolectar datos en PHP con un sitio web proxy de confianza","Explorando el potencial de PHP para el scraping en internet con Dexodata, un sitio web proxy de confianza con un grupo de proxies geográficamente dirigidos en lista blanca.","trusted proxy website, geo targeted proxies, paid proxy free trial, proxies for social media","\u003Cp>\u003Cem>\u003Cstrong>Contenido del artículo:\u003C/strong>\u003C/em>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"#anchor1\">Scraping web con PHP: conceptos básicos y requisitos previos\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor2\">Recolección de datos web con PHP: escenario de ejemplo\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor3\">Evolución. Bibliotecas y herramientas\u003C/a>\n\u003Cul>\n\u003Cli>\u003Ca href=\"#anchor4\">Goutte\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor5\">Simple HTML DOM\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor6\">PHP Scraper\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor7\">PHP cURL para operaciones de scraping\u003C/a>\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor8\">Creando un scraper: un escenario de ejemplo\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"#anchor9\">Comentarios finales\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Cp>La pieza que estás leyendo finaliza nuestro largo viaje a través del desafiante dominio del scraping web. El \u003Ca href=\"https://dexodata.com/en/blog/10-credible-reasons-to-use-dexodata\" target=\"_blank\" rel=\"noopener\">sitio web proxy de confianza Dexodata con configuraciones avanzadas y flexibles\u003C/a> ya ha explorado el potencial de Python, JavaScript y Java. Ahora estamos invitando a los lectores a centrarse en otra dirección bien conocida para recolectar información. Nos referimos al buen viejo asistente PHP.\u003C/p>\n\u003Cp>¿Por qué deberían los usuarios intentarlo si tienen la intención de obtener contenido de una presencia web y van a recurrir a nuestros proxies geográficamente dirigidos para este propósito? Aquí está la respuesta. Básicamente, PHP puede describirse como un lenguaje de scripting del lado del servidor de propósito general nacido tan temprano como en 1995. Como tal, está, por naturaleza, destinado al desarrollo web (la \u003Ca href=\"https://php.watch/versions/8.4\" target=\"_blank\" rel=\"noopener\">última versión de PHP es 8.4\u003C/a>). La cuota que PHP ha ganado y mantenido sigue siendo enorme.&nbsp;&nbsp;\u003C/p>\n\u003Col>\n\u003Cli>Cualquier persona que sepa al menos algo sobre los aspectos técnicos de internet sabe qué es WordPress. Basado en PHP, ese CMS alimenta y mantiene alrededor del 40% de todos los sitios web existentes. No todos son tan populares, el 40% de los sitios no necesariamente equivale al 40% del tráfico o al 40% de los datos. Pero este hecho habla por sí mismo.\u003C/li>\n\u003Cli>Además de todo lo relacionado con la gestión de contenido, \u003Ca href=\"https://w3techs.com/technologies/details/pl-php\" target=\"_blank\" rel=\"noopener\">aproximadamente el 80% de los sitios web dependen de PHP\u003C/a> (cuando su propiedad del lado del servidor puede ser identificada).\u003C/li>\n\u003Cli>Finalmente, productos verdaderamente avanzados y en gran demanda pueden ser diseñados con PHP. Por ejemplo, aquellos que solicitan nuestra prueba gratuita de proxy de pago como nuevos usuarios para aplicar direcciones como proxies para redes sociales deberían saber que Slack se basa en código PHP. Sí, no es una red social en su forma más pura, pero aún así.\u003C/li>\n\u003C/ol>\n\u003Cp>Como un lenguaje \"predispuesto\" para la Web, PHP es una opción decente para escenarios de baja a media complejidad. A través de él, los programadores pueden:\u003C/p>\n\u003Cul>\n\u003Cli>Iniciar solicitudes que se transfieran a una página dada;&nbsp;&nbsp;\u003C/li>\n\u003Cli>Obtener información;\u003C/li>\n\u003Cli>Guardar información en una forma organizada, por ejemplo, en formatos como CSV, JSON o XML.\u003C/li>\n\u003C/ul>\n\u003Cp>En resumen: PHP es sin duda un recurso para aplicar a tareas de scraping, ya que es capaz de interactuar con sitios y entender y manejar HTML, así como obtener información de presencias a través de una variedad de funciones y bibliotecas adecuadas. En esta capacidad, PHP no es tan avanzado y flexible y no debería ser elegido para contenido dinámico, aun así, es una opción viable y funcional (hasta cierto punto). Lo decimos como un sitio web proxy de confianza con \u003Ca href=\"https://dexodata.com/en/data-gathering\" target=\"_blank\" rel=\"noopener\">direcciones para scraping web\u003C/a> que conoce muy bien este oficio de recolección de datos.\u003C/p>\n\u003Ch2>\u003Ca name=\"anchor1\">\u003C/a>Scraping web con PHP: conceptos básicos y requisitos previos\u003C/h2>\n\u003Cp>Antes de avanzar, valida si estás bien informado sobre lo que se presenta a continuación.\u003C/p>\n\u003Col>\n\u003Cli>\u003Cspan style=\"color: #236fa1;\">\u003Cstrong>Solicitudes HTTP\u003C/strong>\u003C/span>. Aquí nos referimos al protocolo aplicado por los servidores para enviar y obtener información. Para obtener algunos datos de una presencia, un usuario debe dirigir una consulta HTTP al servidor encargado de alojar la página. PHP cuenta con funciones integradas como \u003Ccode>cURL\u003C/code>, \u003Ccode>file_get_contents()\u003C/code>, así como \u003Ccode>fopen()\u003C/code> que permiten dirigir consultas HTTP y obtener información de las páginas.\u003C/li>\n\u003Cli>\u003Cspan style=\"color: #236fa1;\">\u003Cstrong>Análisis de HTML\u003C/strong>\u003C/span>. Como un lenguaje concebido para \"construir\" páginas web, PHP ofrece elementos integrados como \u003Ccode>DOMDocument\u003C/code> junto con \u003Ccode>SimpleXMLElement\u003C/code> que permiten a los usuarios analizar HTML para obtener información.\u003C/li>\n\u003Cli>\u003Cspan style=\"color: #236fa1;\">\u003Cstrong>Expresiones Regulares\u003C/strong>\u003C/span> sirven como una herramienta útil y potente para hacer coincidir patrones y manipular textos. Nuevamente, PHP ofrece funciones integradas, por ejemplo, \u003Ccode>preg_match()\u003C/code> junto con \u003Ccode>preg_replace()\u003C/code> que permiten aplicar expresiones regulares para obtener información proveniente de sitios.\u003C/li>\n\u003C/ol>\n\u003Cp>Aún estas nociones básicas serían suficientes en caso de que los usuarios deseen crear un programa PHP simple capaz de transferir consultas HTTP a una presencia, \"salvaguardar\" el HTML, y finalmente analizar el código así como obtener la información buscada con el ecosistema de proxies éticos dirigidos geográficamente de Dexodata (con prueba gratuita de proxy de pago, incluidos proxies para redes sociales).\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor2\">\u003C/a>Recolección de datos web con PHP: escenario de ejemplo\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Supongamos que es necesario raspar información contenida en una presencia como una lista de artículos en venta (lo que mostraremos es un caso muy básico, habrá escenarios más avanzados en secciones posteriores). Es imprescindible obtener el nombre, costo e imagen de cada artículo y guardar esa información como un archivo CSV. Aquí está la forma más simple de hacerlo, es decir, cuando no hay escenarios complejos e impedimentos. Simplemente sigue los pasos del ecosistema de proxies dirigidos geográficamente en lista blanca de Dexodata.\u003C/p>\n\u003Cp>\u003Ccode>&lt;?php\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$url = 'https://sample.com/items';\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$html = file_get_contents($url);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$dom = new DOMDocument();\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$dom-&gt;loadHTML($html);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$products = $dom-&gt;getElementsByTagName('article');\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$data = [];\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>foreach ($items as $items) {\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>&nbsp; &nbsp; $name = $item-&gt;getElementsByTagName('h2')[0]-&gt;textContent;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>&nbsp; &nbsp; $price = $item-&gt;getElementsByTagName('span')[0]-&gt;textContent;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>&nbsp; &nbsp; $image = $item-&gt;getElementsByTagName('img')[0]-&gt;getAttribute('src');\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>&nbsp; &nbsp; $data[] = [$name, $price, $image];\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>}\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$fp = fopen('items.csv', 'w');\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>foreach ($data as $fields) {\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>&nbsp; &nbsp; fputcsv($fp, $fields);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>}\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>fclose($fp);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>?&gt;\u003C/code>\u003C/p>\n\u003Cp>¡Nada ha sido más fácil!\u003C/p>\n\u003Cp>Lo que los lectores ven aquí es que primero transferimos una consulta HTTP a la presencia mediante \u003Ccode>file_get_contents()\u003C/code>. Posteriormente, pasamos al análisis del HTML a través de la clase \u003Ccode>DOMDocument\u003C/code> y obtenemos información relevante mediante la técnica \u003Ccode>getElementsByTagName()\u003C/code>. Luego somos libres de guardar la información obtenida en un array multidimensional, que posteriormente se escribe en un archivo CSV mediante \u003Ccode>fputcsv()\u003C/code>.\u003C/p>\n\u003Cp>Si sientes que todo está claro, avancemos. El sitio web proxy de confianza Dexodata con opciones de prueba gratuita de proxy de pago te mostrará el camino hacia los datos.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor3\">\u003C/a>Evolución. Bibliotecas y herramientas\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Desde su inicio, PHP ha evolucionado significativamente. Probablemente, sus bibliotecas no se ven tan \"de moda\" y \"elegantes\" (no es Python), sin embargo, este lenguaje cuenta con una gran comunidad de participantes que apoyan bibliotecas funcionales. Examinemos estas en el contexto del scraping web. Nosotros, como un sitio web proxy de confianza que ejecuta un ecosistema de proxies dirigidos geográficamente (incluyendo \u003Ca href=\"https://dexodata.com/en/blog/dexodata-proxies-for-instagram-tools\" target=\"_blank\" rel=\"noopener\">proxies para redes sociales, como Instagram\u003C/a>) proponemos la siguiente escalera, en nuestra opinión, desde opciones más simples hasta más avanzadas.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor4\">\u003C/a>1. Goutte\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>\u003Ca href=\"https://github.com/FriendsOfPHP/Goutte\" target=\"_blank\" rel=\"noopener\">Goutte sirve como una biblioteca completamente funcional\u003C/a> que se puede aplicar con el marco PHP. Puede ser dominada incluso por principiantes para obtener datos provenientes de HTML. La curva de aprendizaje en este caso tampoco es desafiante, gracias a su comprensible diseño orientado a objetos. En cuanto a otras ventajas, incluyen una comunidad visible, un impresionante volumen de documentación útil y, finalmente, velocidad. Debido a que se basa en conexiones persistentes HTTP 1.1, implica que un navegador necesita solo una conexión al servidor. Después de eso, la misma conexión se utilizará para todas las solicitudes posteriores a la primera.\u003C/p>\n\u003Cp>También hay algunas desventajas. En ciertos proyectos, se pueden enfrentar limitaciones insuperables relacionadas con contenido dinámico. Probemos Goutte y PHP en acción y hagamos clic en la página de interés (como siempre, al raspar cualquier cosa en la web, no olvides sobre los proxies residenciales, de centro de datos y de red móvil de Dexodata \u003Ca href=\"https://dexodata.com/en/pricing\" target=\"_blank\" rel=\"noopener\">dirigidos geográficamente disponibles a tarifas favorables\u003C/a>).\u003C/p>\n\u003Cp>Para comenzar, uno debe \u003Ca href=\"https://getcomposer.org/\" target=\"_blank\" rel=\"noopener\">instalar Composer\u003C/a>. Este último se utiliza para gestionar dependencias cuando se trata de PHP. Permite declarar las bibliotecas de importancia para un proyecto.\u003C/p>\n\u003Cp>Todo lo que se necesita es ejecutar este tipo de comando en la terminal:\u003C/p>\n\u003Cp>\u003Ccode>composer require fabpot/goutte\u003C/code>\u003C/p>\n\u003Cp>Luego genera un script PHP para la iniciativa. Dale cualquier nombre que desees. Luego abre tu nuevo script y complementa estas líneas de código para hacer que Goutte funcione:\u003C/p>\n\u003Cp>\u003Ccode>require 'vendor/autoload.php';\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>use Goutte\\Client;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$client = new Client();\u003C/code>\u003C/p>\n\u003Cp>¡Genial, Goutte está en pleno funcionamiento e inicializado! Después de eso, proporciona estas líneas de código al final del archivo para obtener una URL mediante la función \u003Ccode>client-&gt;request()\u003C/code>.\u003C/p>\n\u003Cp>\u003Ccode>$url = \"http://instance.com/\";\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$crawler = $client-&gt;request('GET', $url);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// Haz clic en el enlace \"Más información...\"\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$link = $crawler-&gt;selectLink('Más información&hellip;')-&gt;link();\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$crawler = $client-&gt;click($link);\u003C/code>\u003C/p>\n\u003Cp>Nos ha llevado solo un par de líneas de código para llegar a la posición correcta para navegar a una presencia y hacer clic en las cosas. Ahora es el momento de la segunda ronda con el sitio web proxy de confianza Dexodata.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor5\">\u003C/a>2. Simple HTML DOM\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Siendo un analizador, este programa está diseñado para trabajar con cualquier documento HTML, incluidos aquellos que son definidos como inválidos por las especificaciones HTML correspondientes. Su gran ventaja es que es fácil de dominar, y no contiene ningún elemento relacionado con JS externo que deba cargarse por separado antes de comenzar a trabajar. Otras ventajas incluyen velocidad (los usuarios no necesitan cargar toda la página en memoria, por lo que pueden procesar un montón de páginas HTML concurrentemente sin que su rendimiento se vea afectado) y el hecho de que es ligero (es decir, no es necesario instalar ningún software o biblioteca adicional, solo PHP será suficiente).\u003C/p>\n\u003Cp>Sin duda, hay limitaciones. Tu acceso a los componentes de la página estará limitado: se pueden realizar manipulaciones con la estructura de una página, pero su contenido estará fuera de alcance. Es notable que Simple HTML DOM es bastante rígido, así que a menos que seas un dios del HTML, el potencial estará restringido.\u003C/p>\n\u003Cp>Eso ha sido suficiente teoría, pasemos a la práctica.\u003C/p>\n\u003Cp>Para comenzar, obtén la última versión visitando este \u003Ca href=\"https://simplehtmldom.sourceforge.io/docs/1.9/index.html\" target=\"_blank\" rel=\"noopener\">espacio de documentación de Simple HTML DOM\u003C/a>. Eso te dará todo lo que necesitas.\u003C/p>\n\u003Cp>Primero, copia el archivo \u003Ccode>simple_html_dom.php\u003C/code>. Después, simplemente pega este último en tu proyecto activo.\u003C/p>\n\u003Cp>Genera tu archivo PHP (los nombres no importan). Por ejemplo, webscrapingstuff.php.\u003C/p>\n\u003Cp>Ahora, abre el archivo y \"arma\" tu proyecto con la biblioteca Simple HTML DOM añadiéndola. Usa el código propuesto por el sitio web proxy de confianza Dexodata a continuación:\u003C/p>\n\u003Cp>\u003Ccode>include('simple_html_dom_php');\u003C/code>\u003C/p>\n\u003Cp>Ingresa esta línea de código. Es importante, ya que te llevará a la página misma:\u003C/p>\n\u003Cp>\u003Ccode>$html = file_get_html('http://instance.com/')\u003C/code>\u003C/p>\n\u003Cp>El elemento \u003Ccode>file_get_html\u003C/code>, siendo parte de Simple HTML DOM, es capaz de recuperar HTML asociado con la URL que se especifica. Luego entrega un objeto DOM que almacena nuestra variable \u003Ccode>$html\u003C/code>.\u003C/p>\n\u003Cp>Digamos que necesitas el encabezado principal. Para obtener ese primer encabezado H1, aplica este código:\u003C/p>\n\u003Cp>\u003Ccode>echo $html-&gt;find('h1', 0)-&gt;plaintext;\u003C/code>\u003C/p>\n\u003Cp>Si abres este archivo resultante en tu servidor web, encontrarás lo que necesitas allí.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor6\">\u003C/a>3. PHP Scraper\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Como un ecosistema de direcciones IP en lista blanca y éticamente obtenidas centradas en la recolección de datos, no podemos ignorar \u003Ca href=\"https://phpscraper.de\" target=\"_blank\" rel=\"noopener\">PHP Scraper\u003C/a>. Este último sirve como una herramienta que permite a los recolectores raspar información a través de scripts PHP. Este enfoque implica que no es necesario codificar mucho por tu cuenta. Todo lo que se necesita es aplicar comandos tan simples como \u003Ccode>find_element_by_class\u003C/code> o \u003Ccode>find_element_by_id\u003C/code>. Serán suficientes para componentes específicos en cualquier presencia particular al escribir su número de clase o id.\u003C/p>\n\u003Cp>¿Algún problema? Por supuesto, existen algunos. PHP Scraper puede no coincidir con cada caso de uso posible, ya que, naturalmente, se basa en PHP. Por lo tanto, es compatible con servidores asociados con Apache o Nginx y configurados a través de \u003Ccode>mod_rewrite\u003C/code> activado por defecto. PHP Scraper no es tu dirección si pretendes obtener información de una API o analizar presencias HTML sofisticadas.\u003C/p>\n\u003Cp>De todos modos, ejecutemos un escenario básico.\u003C/p>\n\u003Cp>Nuestros lectores deben instalar Composer, como hicimos en la sección de Goutte. Después de eso, complementa tu proyecto con la biblioteca que se está discutiendo, con este código a través de Composer:\u003C/p>\n\u003Cp>\u003Ccode>composer require spekulatius/phpscraper\u003C/code>\u003C/p>\n\u003Cp>Una vez que la etapa de instalación haya quedado atrás, el autoloader de Composer se encargará del paquete. En caso de que uno trabaje con una biblioteca VanillaPHP, debe incorporar el autoloader en su script, como se muestra a continuación:\u003C/p>\n\u003Cp>\u003Ccode>require 'vendor/autoload.php'\u003C/code>\u003C/p>\n\u003Cp>Como ejercicio, genera un script que acceda a una presencia y enumere la cantidad de enlaces publicados allí. Inicia el programa y dale una variable, como se muestra aquí:\u003C/p>\n\u003Cp>\u003Ccode>$web = new \\spekulatius\\phpscraper();\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>Da la orden al programa para visitar la URL:&nbsp;&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$web-&gt;go(' [http://instance.com/](http://instance.com/) ');\u003C/code>\u003C/p>\n\u003Cp>Complementa esta sección de código encargada de tomar cada enlace contenido en la presencia e imprimir la cantidad de ellos.\u003C/p>\n\u003Cp>\u003Ccode>// Imprimir el número de enlaces.\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>echo \"Esta página contiene \" . count($web-&gt;links) . \" enlaces.\n\n\";\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// Recorrer los enlaces\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>foreach ($web-&gt;links as $link) {\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>echo \" - \" . $link . \"\n\";\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>}\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>/**\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>* Este código imprimirá:\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>*\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>* Esta página contiene 1 enlace.\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>*\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>* - https://www.iana.org/domains/instance\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>*/\u003C/code>\u003C/p>\n\u003Cp>Recuerda: usamos una dirección irreal.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor7\">\u003C/a>4. PHP cURL para operaciones de scraping\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Habiendo revisado una variedad de opciones disponibles para actividades de recolección por PHP, nuestro sitio web proxy de confianza Dexodata te ofrece una opción adicional conveniente y ampliamente utilizada. Por supuesto, nos referimos a \u003Ca href=\"https://www.php.net/manual/en/book.curl.php\" target=\"_blank\" rel=\"noopener\">\u003Ccode>cURL\u003C/code>, una biblioteca y herramienta de línea de comandos\u003C/a> (normalmente disponible con el lenguaje por defecto) que permite a los usuarios enviar y recibir archivos a través de HTTP y FTP. Al trabajar con él, se pueden aplicar proxies geográficamente dirigidos (incluidos aquellos proporcionados con nuestra prueba gratuita de proxy de pago), transmitir datos a través de conexiones SSL, definir cookies, y más. Probemos en la práctica.\u003C/p>\n\u003Cp>Genera un nuevo script PHP y complementa este código:\u003C/p>\n\u003Cp>\u003Ccode>// Inicializar curl\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$ch = curl_init();\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// URL para Scraping\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($ch, CURLOPT_URL,\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>'https://dexodata.com/en/blog');\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// Devolver Transferencia Verdadera\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$output = curl_exec($ch);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// Cerrar cURL\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_close($ch);\u003C/code>\u003C/p>\n\u003Cp>Definir \u003Ccode>CURLOPT_RETURNTRANSFER\u003C/code> como \u003Ccode>TRUE \u003C/code>envía la página en la capacidad de una cadena en lugar de mostrarla directamente. Por lo tanto, nuestro código toma la información que necesitamos recolectar del sitio.\u003C/p>\n\u003Cp>Se puede echar un vistazo a estos datos mediante un echo con la variable para el almacenamiento de datos:\u003C/p>\n\u003Cp>\u003Ccode>echo $output\u003C/code>\u003C/p>\n\u003Cp>Nuestro siguiente paso es colocar esta información en un documento DOM, lo que nos permitirá acceder a ella con fines de scraping.\u003C/p>\n\u003Cp>\u003Ccode>$dom = new DOMDocument;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$dom-&gt;loadHTML($output);\u003C/code>\u003C/p>\n\u003Cp>Actualmente, tenemos nuestra información como una estructura HTML dentro de una variable. Genera algún código adicional para imprimir cada enlace disponible en la página HTML:\u003C/p>\n\u003Cp>\u003Ccode>$tags = $dom-&gt;getElementsByTagName('a');\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>for($I=0; $I &lt; $tags-&gt;length; $I++){\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$link = $tags-&gt;item($i);\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>echo \" - \" . $link . \"\n\";\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>}\u003C/code>\u003C/p>\n\u003Cp>Por cierto, como fuente de proxies geográficamente dirigidos con oportunidades de prueba gratuita de proxy de pago, instamos a los usuarios a no olvidar proteger sus iniciativas de scraping con las direcciones que proporcionamos (por ejemplo, nuestros \u003Ca href=\"https://dexodata.com/en/residential-proxies\" target=\"_blank\" rel=\"noopener\">IPs residenciales de primera calidad de ISP\u003C/a> o, alternativamente, nuestros proxies móviles de alta calidad). El ecosistema de Dexodata mostrará a los lectores el camino para hacerlo a través de \u003Ccode>cURL\u003C/code>. Todo lo que necesitan hacer es seguir la sintaxis.\u003C/p>\n\u003Cp>\u003Ccode>curl --proxy &lt;proxy-ip&gt;:&lt;proxy-port&gt; &lt;url&gt;\u003C/code>\u003C/p>\n\u003Cp>Primero, la sección &lt;proxy-ip&gt; es para insertar la IP, mientras que la segunda sección &lt;proxy-port&gt; está destinada, predeciblemente, al número de puerto. Finalmente, se verá así:\u003C/p>\n\u003Cp>\u003Ccode>curl --proxy 193.191.56.12:7070 -k https://dexodata.com/en/blog\u003C/code>\u003C/p>\n\u003Cp>Siempre que la dirección sea funcional y la consulta sea exitosa, nuestro script mostrará el contenido de la presencia para salir después.&nbsp;\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor8\">\u003C/a>Creando un scraper: un escenario de ejemplo\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Imaginemos una presencia de comercio electrónico con una lista de artículos en venta que queremos recolectar a través de PHP. ¿Qué deberíamos hacer? ¿Qué alternativas deberíamos usar? Sigue nuestro sitio web proxy de confianza y examina este escenario de ejemplo.\u003C/p>\n\u003Cp>Comienza descargando todo el HTML de la presencia de comercio electrónico a través del potencial de PHP y el buen viejo \u003Cspan style=\"font-family: monospace; background-color: #b4d7ff;\">cURL\u003C/span>, así:\u003C/p>\n\u003Cp>\u003Ccode>// inicializar la solicitud cURL&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$curl = curl_init();&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// establecer la URL a alcanzar con una solicitud HTTP GET&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_URL, \"https://scrapeme.live/shop/\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// obtener los datos devueltos por la solicitud cURL como una cadena&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// hacer que la solicitud cURL siga eventuales redirecciones,&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// y alcanzar la página final de interés&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// ejecutar la solicitud cURL y&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// obtener el HTML de la página como una cadena&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$html = curl_exec($curl);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// liberar los recursos de cURL&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_close($curl);\u003C/code>\u003C/p>\n\u003Cp>Las cosas relacionadas con HTML están a nuestra plena disposición, en la capacidad de la variable \u003Ccode>$html\u003C/code>, como destaca Dexodata. Tu siguiente medida es cargar \u003Ccode>$html\u003C/code> en una instancia de \u003Ccode>HtmlDomParser\u003C/code> que cuenta con la función \u003Ccode>str_get_html()\u003C/code>. Veamos cómo se puede hacer a continuación:\u003C/p>\n\u003Cp>\u003Ccode>require_once __DIR__ . \"../../vendor/autoload.php\";\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>use voku\\helper\\HtmlDomParser;&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$curl = curl_init();&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_URL, \"https://scrapeme.live/shop/\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$html = curl_exec($curl);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_close($curl);&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// inicializar HtmlDomParser&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$htmlDomParser = HtmlDomParser::str_get_html($html);\u003C/code>\u003C/p>\n\u003Cp>Tú y nuestro sitio web proxy de confianza ahora están en la posición correcta para aplicar \u003Ccode>HtmlDomParser\u003C/code> con el propósito final de navegar por el DOM de la presencia HTML e iniciar efectivamente el proceso de recolección de datos.\u003C/p>\n\u003Cp>Eso es lo que Dexodata está a punto de lograr. Para hacerlo, \"salvaguarda\" la lista completa de todos los enlaces relacionados con la paginación en nuestro escenario. En nuestro caso, esto nos dará la oportunidad de rastrear toda la sección de la presencia web. Haz clic derecho en el componente HTML relacionado con la figura de paginación y elige \"Inspeccionar\". Después de eso, nuestras DevTools nos mostrarán el elemento DOM.\u003C/p>\n\u003Cp style=\"text-align: center;\">\u003Cimg src=\"/storage/uploads/images/129/15-3-geo-targeted-proxies-php-and-data-collection-1032x491-d5d805e4-e80c-4dfc-a6e5-401c7a54a0fc.png\" alt=\"Cómo recolectar datos en PHP con un sitio web proxy de confianza\" width=\"1032\" height=\"491\" />\u003C/p>\n\u003Cp>Avancemos con el ecosistema de proxies dirigidos geográficamente de Dexodata. Se puede esperar que el \u003Ccode>.page-numbers\u003C/code>, en la capacidad de una clase CSS, identifique los componentes HTML relacionados con la paginación. Sin embargo, el equipo de nuestro sitio web proxy de confianza nos recordaría a todos que una clase CSS puede no identificar necesariamente un componente HTML de manera única. Múltiples nodos pueden estar relacionados con la misma clase única.\u003C/p>\n\u003Cp>Por lo tanto, si tu intención es aplicar un selector CSS para obtener los componentes en el DOM, inevitablemente debes aplicar la clase CSS junto con otros selectores. Específicamente, los usuarios podrían aplicar el asistente HtmlDomParser, con el selector CSS \u003Ccode>.page-numbers\u003C/code>, para seleccionar todos los componentes HTML relacionados con la paginación. Luego, nuestro ecosistema de proxies dirigidos geográficamente te sugeriría iterar a través de ellos para obtener todas las URLs necesarias directamente del atributo href.\u003C/p>\n\u003Cp>Revisa esto:\u003C/p>\n\u003Cp>\u003Ccode>// recuperar los elementos HTML de paginación con&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// el selector CSS \".page-numbers a\"&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$paginationElements = $htmlDomParser-&gt;find(\".page-numbers a\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$paginationLinks = [];&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>foreach ($paginationElements as $paginationElement) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// poblar el conjunto paginationLinks con la URL&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// extraída del atributo href del elemento HTML de paginación&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$paginationLink = $paginationElement-&gt;getAttribute(\"href\");&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// evitar duplicados en la lista de URLs&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>if (!in_array($paginationLink, $paginationLinks)) {&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$paginationLinks[] = $paginationLink;&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>} &nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>}\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// imprimir el array paginationLinks&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>print_r($paginationLinks);\u003C/code>\u003C/p>\n\u003Cp>Presta atención al hecho de que \u003Ccode>find()\u003C/code> permite a los usuarios \u003Ca href=\"https://github.com/voku/simple_html_dom/blob/master/README_API.md#findstring-selector-intnull-idx-simplehtmldominterfacesimplehtmldominterfacesimplehtmldomnodeinterfacesimplehtmldominterface\" target=\"_blank\" rel=\"noopener\">obtener componentes DOM\u003C/a> en función de un selector CSS. Además, en el escenario hipotético de Dexodata, los componentes relacionados con la paginación aparecen dos veces en cada página de la presencia de comercio electrónico. Se necesita proporcionar un truco único y ajustado para manejar el problema de los componentes duplicados cuando se trata del array \u003Ccode>$paginationLinks\u003C/code>.\u003C/p>\n\u003Cp>Aquí está lo que veremos si intentamos ejecutar nuestro script para el escenario:\u003C/p>\n\u003Cp>\u003Ccode>Array (&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[0] =&gt; https://scrapeme.live/shop/page/2/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[1] =&gt; https://scrapeme.live/shop/page/3/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[2] =&gt; https://scrapeme.live/shop/page/4/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[3] =&gt; https://scrapeme.live/shop/page/46/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[4] =&gt; https://scrapeme.live/shop/page/47/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>[5] =&gt; https://scrapeme.live/shop/page/50/&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>)\u003C/code>\u003C/p>\n\u003Cp>Ten en cuenta que todas las direcciones poseen una estructura idéntica. Es decir, todas están marcadas por la figura final responsable de la paginación. Si los lectores tienen la intención de iterar sobre cada una de ellas, lo único que necesitan es la figura identificativa asociada con la última página.\u003C/p>\n\u003Cp>Está sujeta a ser recuperada como se muestra a continuación:\u003C/p>\n\u003Cp>\u003Ccode>// eliminar todos los caracteres no numéricos en el último elemento del&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// array $paginationLinks para recuperar el número más alto de paginación&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$highestPaginationNumber = preg_replace(\"/\\D/\", \"\", end($paginationLinks));\u003C/code>\u003C/p>\n\u003Cp>Digamos que nuestro \u003Ccode>$highestPaginationNumber\u003C/code> será \"50\".\u003C/p>\n\u003Cp>Entonces, ha llegado el momento de obtener la información que describe un producto individual con el equipo de Dexodata. Necesitamos hacer clic derecho en un artículo y activar la ventana de DevTools, seguida de \"Inspeccionar\". Se puede esperar que un artículo esté \"compuesto de\" un elemento HTML \u003Ccode>li.product\u003C/code> que abarca una URL, una imagen, un título y una etiqueta de precio. Tal información proviene de los componentes HTML \u003Ccode>a\u003C/code>, luego \u003Ccode>mg\u003C/code>, luego \u003Ccode>h2\u003C/code>, y luego \u003Ccode>span\u003C/code>, respectivamente.\u003C/p>\n\u003Cp>El sitio web proxy de confianza Dexodata propone esta forma de obtener esta información a través de HtmlDomParser:\u003C/p>\n\u003Cp>\u003Ccode>$productDataLit = array();&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// recuperar la lista de productos en la página&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$productElements = $htmlDomParser-&gt;find(\"li.product\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>foreach ($productElements as $productElement) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// extraer los datos del producto&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$url = $productElement-&gt;findOne(\"a\")-&gt;getAttribute(\"href\");&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$image = $productElement-&gt;findOne(\"img\")-&gt;getAttribute(\"src\");&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$name = $productElement-&gt;findOne(\"h2\")-&gt;text;&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$price = $productElement-&gt;findOne(\".price span\")-&gt;text;&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// transformar los datos del producto en un array asociativo&nbsp;\u003C/span>\u003C/p>\n\u003Cp>\u003Ccode>$productData = array(&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>\"url\" =&gt; $url,&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>\"image\" =&gt; $image,&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>\"name\" =&gt; $name,&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>\"price\" =&gt; $price&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>);&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$productDataList[] = $productData;&nbsp;\u003C/code>\u003C/p>\n\u003Cp>}\u003C/p>\n\u003Cp>Una vez que nuestra lógica captura todos los fragmentos de información del artículo de una sola página y posteriormente los guarda como el array \u003Ccode>$productDataList\u003C/code>. Aplica esta lógica a cada página.\u003C/p>\n\u003Cp>\u003Ccode>// iterar sobre todas las páginas \"/shop/page/X\" y recuperar todos los datos del producto&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>for ($paginationNumber = 1; $paginationNumber &lt;= $highestPaginationNumber; $paginationNumber++) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$curl = curl_init();&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>curl_setopt($curl, CURLOPT_URL, \"https://scrapeme.live/shop/page/$paginationNumber/\");&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$pageHtml = curl_exec($curl);&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>curl_close($curl);&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$paginationHtmlDomParser = HtmlDomParser::str_get_html($pageHtml);&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// lógica de scraping...&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>}\u003C/p>\n\u003Cp>¡Genial! Hemos llegado a la situación en la que podemos extraer datos según lo planeado.\u003C/p>\n\u003Cp style=\"line-height: 0.5;\">&nbsp;\u003C/p>\n\u003Ch3>\u003Ca name=\"anchor9\">\u003C/a>Comentarios finales&nbsp;\u003C/h3>\n\u003Cp style=\"line-height: 0.1;\">&nbsp;\u003C/p>\n\u003Cp>Ejecutando un ecosistema de proxies dirigidos geográficamente, nos gustaría finalizar esta guía con un par de comentarios. Intenta evitar ser detectado y restringido como un scraper. Para eso, te recordamos los proxies que ya hemos mencionado.\u003C/p>\n\u003Cp>Aquí hay otro recordatorio de cómo uno puede agregar sus identificadores de proxy:\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_PROXY, \"&lt;PROXY_URL&gt;\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_PROXYPORT, \"&lt;PROXY_PORT&gt;\");&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_PROXYTYPE, \"&lt;PROXY_TYPE&gt;\");\u003C/code>\u003C/p>\n\u003Cp>1. Una capa extra de protección puede constituirse mediante un encabezado HTTP de agente de usuario. Por definición,&nbsp;\u003Cspan style=\"font-family: monospace; background-color: #b4d7ff;\">cURL\u003C/span>&nbsp;siempre establecería algo como \u003Ccode>curl/XX.YY.ZZ\u003C/code>. No será un gran problema atrapar a un usuario con tal encabezado. En su lugar, intenta \"jugar\" con el encabezado aquí.\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_USERAGENT, \"&lt;USER_AGENT_STRING&gt;\");\u003C/code>\u003C/p>\n\u003Cp>Como resultado, colocarás algo como esto, un ejemplo encontrado en internet:\u003C/p>\n\u003Cp>\u003Ccode>curl_setopt($curl, CURLOPT_USERAGENT, \"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6\")\u003C/code>\u003C/p>\n\u003Cp>2. Otro comentario de Dexodata se centra en contenido dinámico. Hemos enfatizado que la consulta \u003Ccode>GET cURL\u003C/code> habitual no te ayudará con eso, se requerirán técnicas más avanzadas. Regresa a nuestra \u003Ca href=\"https://dexodata.com/en/blog/using-java-for-data-scraping-and-harvesting-on-the-web\" target=\"_blank\" rel=\"noopener\">guía dedicada a JS\u003C/a> y aprende más sobre navegadores sin cabeza, es decir, paquetes de software de navegación sin UI. Esto te ayudará a construir un scraper que interactúe con una presencia como un usuario real y extraiga contenido dinámico simultáneamente.\u003C/p>\n\u003Cp>3. Nuestro tercer comentario está dedicado al scraping paralelo. La multi-threading en PHP es desafiante pero a veces inevitable. Aquí está cómo puedes abordar este desafío con el sitio web proxy de confianza Dexodata. Nuestro concepto es permitir que tu script de scraping se ejecute en varias instancias aplicando \u003Ccode>HTTP GET\u003C/code> parámetros.\u003C/p>\n\u003Cp>Modifica el script para que no itere sobre todas las páginas y se concentre en piezas paralelas más pequeñas en su lugar. Aquí está cómo uno puede modificar el script y establecer los límites de una \"pieza\". Simplemente establece un par de parámetros GET, tal como se destaca a continuación:\u003C/p>\n\u003Cp>\u003Ccode>$from = null;&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>$to = null;&nbsp;\u003C/code>\u003C/p>\n\u003Cp>&nbsp;\u003C/p>\n\u003Cp>\u003Ccode>if (isset($_GET[\"from\"]) &amp;&amp; is_numeric($_GET[\"from\"])) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$from = $_GET[\"from\"];&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>}&nbsp;\u003C/p>\n\u003Cp>\u003Ccode>if (isset($_GET[\"to\"]) &amp;&amp; is_numeric($_GET[\"to\"])) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>$to = $_GET[\"to\"];&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>}&nbsp;\u003C/p>\n\u003Cp>\u003Ccode>if (is_null($from) || is_null($to) || $from &gt; $to) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>die(\"¡Parámetros from y to inválidos!\");&nbsp;\u003C/span>\u003C/code>\u003C/p>\n\u003Cp>}&nbsp;\u003C/p>\n\u003Cp>\u003Ccode>// raspar solo las páginas de paginación cuyo número va&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>// de \"$from\" a \"$to\"&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Ccode>for ($paginationNumber = $from; $paginationNumber &lt;= $to; $paginationNumber++) {&nbsp;\u003C/code>\u003C/p>\n\u003Cp>\u003Cspan style=\"white-space: normal;\">\u003Cspan style=\"white-space: pre;\"> \u003C/span>// lógica de scraping...&nbsp;\u003C/span>\u003C/p>\n\u003Cp>}\u003C/p>\n\u003Cp>\u003Ccode>// escribir los datos raspados en una base de datos/archivo\u003C/code>\u003C/p>\n\u003Cp>Esto te preparará para iniciar múltiples instancias activando varios enlaces en el navegador:\u003C/p>\n\u003Cp>\u003Ccode>https://instance.com/scripts/scrapeme.live/scrape-products.php?from=1&amp;to=5&nbsp;\u003C/code>\u003C/p>\n\u003Cp>y similares.\u003C/p>\n\u003Cp>Se ejecutarán simultáneamente y rasparán la presencia en paralelo. Eso es todo. Gracias por quedarte con Dexodata, tu ecosistema ético de proxies móviles, de centro de datos y residenciales \u003Ca href=\"https://dexodata.com/en/blog/why-dexodata-implements-aml-and-kyc-policies\" target=\"_blank\" rel=\"noopener\">con todas las normas KYC y AML aplicadas\u003C/a>.\u003C/p>",[],1774967986211]