{"id":574,"date":"2019-03-07T17:08:07","date_gmt":"2019-03-07T16:08:07","guid":{"rendered":"https:\/\/tiraquelibras.com\/blog\/?p=574"},"modified":"2019-12-26T17:00:42","modified_gmt":"2019-12-26T16:00:42","slug":"web-scraping-con-beautifulsoup-en-python","status":"publish","type":"post","link":"https:\/\/blog.tiraquelibras.com\/?p=574","title":{"rendered":"Web Scraping con BeautifulSoup en Python"},"content":{"rendered":"<p><strong>Web Scraping<\/strong> es una t\u00e9cnica utilizada para la extracci\u00f3n de informaci\u00f3n dentro de una web, simulando la navegaci\u00f3n humana. Con esta informaci\u00f3n podemos obtener el contenido de las etiquetas de un documento <strong>HTML<\/strong> o <strong>XML<\/strong> con el fin de recopilar informaci\u00f3n sobre el contenido de una p\u00e1gina web, como los valores y contenidos de sus etiquetas, <em>metadatos<\/em>, enlaces dentro de etiquetas de tipo <em><strong>&lt;a&gt;<\/strong><\/em>, etc. En resumen, y haciendo una traducci\u00f3n literal, se trata de \u00ab<em><strong>escarbar una web<\/strong><\/em>\u00ab.<\/p>\n<p>Estas t\u00e9cnicas se conocen con varios nombres, como <strong>web crawling<\/strong>,\u00a0<strong>screen scraping<\/strong>,\u00a0<strong>web extraction<\/strong>,\u00a0<strong>crawl spider<\/strong>,\u00a0<strong>web-bot<\/strong>,\u00a0<strong>spider robot<\/strong>,\u00a0<strong>data mining<\/strong>,\u00a0<strong>harvests<\/strong>, \u2026<\/p>\n<p>Se puede aprovechar esta t\u00e9cnica para obtener grandes cantidades de informaci\u00f3n haciendo uso de b\u00fasquedas en p\u00e1ginas web, que junto al uso de expresiones regulares podemos obtener la informaci\u00f3n deseada.<\/p>\n<p>Como ejemplos de uso, sin entrar en detalle ya que no es el objetivo de esta entrada:<\/p>\n<ul>\n<li><strong>Marketing de contenidos<\/strong>: recopilar informaci\u00f3n de una web para generar nuestro propio contenido con datos estad\u00edsticos.<\/li>\n<li><strong>Visibilidad en redes sociales<\/strong>: interactuar con usuarios en redes sociales.<\/li>\n<li>I<strong>magen y visibilidad de marca en Internet<\/strong>: tener bajo control la posici\u00f3n de nuestra web en Google obteniendo la posici\u00f3n de las entradas en sus b\u00fasquedas, o la presencia de nuestra marca en las entradas de un foro.<\/li>\n<\/ul>\n<p>Tambi\u00e9n podremos usar esta t\u00e9cnica para obtener informaci\u00f3n valiosa para realizar auditor\u00edas de seguridad, obteniendo los formularios para pruebas de <strong>XSS<\/strong> (<em><strong>Cross-site Scripting<\/strong><\/em>), llamadas a funciones de <strong>JavaScript<\/strong>, informaci\u00f3n relevante de etiquetas\u00a0<em><strong>&lt;meta&gt;<\/strong><\/em> con informaci\u00f3n de la Web, &#8230;<\/p>\n<p>Existen varios problemas a la hora de realizar esta t\u00e9cnica:<\/p>\n<ul>\n<li>Sesiones de navegaci\u00f3n necesarias para acceder al contenido web.<\/li>\n<li>Uso de <strong>JavaScript<\/strong> para mostrar el contenido, lo que nos obligar\u00e1 a utilizar un motor para obtener este contenido.<\/li>\n<li>Bloqueos en la aplicaci\u00f3n web, por superar el n\u00famero m\u00e1ximo de peticiones, no solicitar todos los elementos de la p\u00e1gina, problemas con el <strong><em>user-agent<\/em><\/strong>, bloqueo de la IP o uso de <strong>reCaptcha<\/strong>.<\/li>\n<li>Tambi\u00e9n las implicaciones legales que tienen este tipo de t\u00e9cnicas, ya que en ocasiones podr\u00edan llegar a ser denunciables.<\/li>\n<\/ul>\n<p>Para ello vamos a utilizar la librer\u00eda <strong>BeautifulSoup<\/strong> de <strong>Python<\/strong>, que junto a <strong>urllib<\/strong> nos permitir\u00e1 recopilar cualquier informaci\u00f3n contenida en una p\u00e1gina web.<\/p>\n<p>A continuaci\u00f3n se muestran los comandos m\u00e1s habituales para empezar a trabajar con esta t\u00e9cnica. Al final de la entrada podr\u00e1s consultar el enlace oficial con muchos m\u00e1s comandos y ejemplos para ampliar conocimientos.<\/p>\n<p>Vamos al l\u00edo!!!<\/p>\n<hr \/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_76 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Tabla de contenidos<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a0d350085e81\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a0d350085e81\"  aria-label=\"Alternar\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Objetivo\"  rel=\"nofollow\" target=\"_blank\">Objetivo<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-2 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Escenario\"  rel=\"nofollow\" target=\"_blank\">Escenario<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-3 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Librerias_necesarias\"  rel=\"nofollow\" target=\"_blank\">Librer\u00edas necesarias<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-4 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Extraccion_HTML\"  rel=\"nofollow\" target=\"_blank\">Extracci\u00f3n HTML<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Instancia_BeautifulSoup\"  rel=\"nofollow\" target=\"_blank\">Instancia BeautifulSoup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Acceso_al_contenido\"  rel=\"nofollow\" target=\"_blank\">Acceso al contenido<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Etiquetas\"  rel=\"nofollow\" target=\"_blank\">Etiquetas<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Contenido_de_etiquetas\"  rel=\"nofollow\" target=\"_blank\">Contenido de etiquetas<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Atributos_y_valores\"  rel=\"nofollow\" target=\"_blank\">Atributos y valores<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Etiqueta_anterior_siguiente\"  rel=\"nofollow\" target=\"_blank\">Etiqueta anterior \/ siguiente<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Etiqueta_padre\"  rel=\"nofollow\" target=\"_blank\">Etiqueta padre<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Mostrar_todos_los_resultados\"  rel=\"nofollow\" target=\"_blank\">Mostrar todos los resultados<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Buscar_por_id_y_class\"  rel=\"nofollow\" target=\"_blank\">Buscar por id y class<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Auditoria_Web_%E2%80%93_Formularios\"  rel=\"nofollow\" target=\"_blank\">Auditor\u00eda Web &#8211; Formularios<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-15 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Extraccion_XML\"  rel=\"nofollow\" target=\"_blank\">Extracci\u00f3n XML<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Archivo_XML\"  rel=\"nofollow\" target=\"_blank\">Archivo XML<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Instancia_BeautifulSoup-2\"  rel=\"nofollow\" target=\"_blank\">Instancia BeautifulSoup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Acceso_al_contenido-2\"  rel=\"nofollow\" target=\"_blank\">Acceso al contenido<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-19 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Conclusion\"  rel=\"nofollow\" target=\"_blank\">Conclusi\u00f3n<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-20 external external_icon\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\/#Enlaces_relacionados\"  rel=\"nofollow\" target=\"_blank\">Enlaces relacionados<\/a><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"Objetivo\"><\/span>Objetivo<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Vamos a realizar el <em>parseo<\/em> de informaci\u00f3n contenida en documentos <strong>HTML<\/strong> y <strong>XML<\/strong>.<\/p>\n<p>Haremos uso de la librer\u00eda <strong>BeautifulSoup<\/strong>:<\/p>\n<ul>\n<li>Librer\u00eda utilizada para realizar operaciones de <em><strong>W<\/strong><\/em><em><strong>eb Scraping<\/strong><\/em> desde <strong>Python<\/strong>.<\/li>\n<li><em>Parsea<\/em> y permite extraer informaci\u00f3n de documentos <strong>HTML<\/strong>.<\/li>\n<li>Soporta m\u00faltiples <em>parsers<\/em> para tratar documentos <strong>XML\/XHTML<\/strong> y <strong>HTML<\/strong>.<\/li>\n<li>Genera una estructura de \u00e1rbol con todos los elementos del documento <em>parseado<\/em>.<\/li>\n<li>Permite de manera muy sencilla buscar elementos <strong>HTML<\/strong>, tales como enlaces, formularios o cualquier otra etiqueta <strong>HTML<\/strong>.<\/li>\n<\/ul>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Escenario\"><\/span>Escenario<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Vamos a contemplar dos escenarios para la extracci\u00f3n del contenido:<\/p>\n<ul>\n<li>Documento <strong>HTML<\/strong> a trav\u00e9s de una <strong>URL<\/strong>.<\/li>\n<li>Documento <strong>XML<\/strong> a trav\u00e9s de un archivo <strong>.xml<\/strong><\/li>\n<\/ul>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Librerias_necesarias\"><\/span>Librer\u00edas necesarias<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Instalaremos las librer\u00edas bs4 y lxml para el <em>parseo<\/em>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">pip install bs4\r\npip install lxml<\/pre>\n<p>Tambi\u00e9n podemos instalar el\u00a0<em>parser<\/em> para <strong>HTML5<\/strong>, pero en mi caso no fue necesario:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">pip install html5lib<\/pre>\n<p><span style=\"color: #ff0000;\"><strong>OJO!!!<\/strong> <\/span>Si no funcionara la instalaci\u00f3n con <strong>pip<\/strong> probar a instalar el paquete desde los repositorios oficiales. Por ejemplo, la librer\u00eda <em><strong>lxml<\/strong><\/em> solo la pude instalar en mi Debian con el comando <em><strong>apt-get install python-lxml<\/strong><\/em>, ya que con <strong>pip<\/strong> me daba error.<\/p>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Extraccion_HTML\"><\/span>Extracci\u00f3n HTML<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Vamos a extraer el contenido de este blog utilizando la <strong>URL<\/strong> como fuente de datos.<\/p>\n<h2><\/h2>\n<h2 style=\"text-align: center;\"><span class=\"ez-toc-section\" id=\"Instancia_BeautifulSoup\"><\/span>Instancia BeautifulSoup<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Primero importamos las librer\u00edas reci\u00e9n instaladas:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">from bs4 import BeautifulSoup\r\nimport urllib<\/pre>\n<p>Leemos el contenido de la URL y la guardamos en una variable:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">contents = urllib.urlopen(\"https:\/\/tiraquelibras.com\/blog\").read()<\/pre>\n<p>Creamos una instancia <strong>BeautifulSoup<\/strong> indicando como primer argumento el contenido <strong>HTML<\/strong> y como segundo el <em>parser,<\/em> con el fin de acceder y navegar por el documento y acceder a su contenido.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">bs = BeautifulSoup(contents, \"lxml\")<\/pre>\n<p>Ahora ya podemos acceder al contenido de todas sus etiquetas.<\/p>\n<h2><\/h2>\n<h2 style=\"text-align: center;\"><span class=\"ez-toc-section\" id=\"Acceso_al_contenido\"><\/span>Acceso al contenido<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A continuaci\u00f3n vamos a ver los comandos necesarios para acceder al contenido del documento extra\u00eddo.<\/p>\n<h3 style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"Etiquetas\"><\/span>Etiquetas<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Obtenemos el contenido de las etiquetas indicando el nombre de esta. Por ejemplo, mostramos el contenido de las etiquetas <em><strong>&lt;title&gt;<\/strong><\/em> y <em><strong>&lt;meta&gt;<\/strong><\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.title\r\n&lt;title&gt;Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI&lt;\/title&gt;\r\n&gt;&gt;&gt; bs.meta\r\n&lt;meta charset=\"unicode-escape\"\/&gt;\r\n<\/pre>\n<p>Por defecto solo se muestra el contenido de la primera coincidencia. M\u00e1s adelante veremos como obtener todos los resultados.<\/p>\n<h3 style=\"text-align: left;\"><span class=\"ez-toc-section\" id=\"Contenido_de_etiquetas\"><\/span>Contenido de etiquetas<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Para obtener el contenido de las etiquetas, si lo tuviera, indicamos la funci\u00f3n <em><strong>string<\/strong><\/em><em>\u00a0<\/em>a continuaci\u00f3n del nombre de la etiqueta. Tambi\u00e9n podemos usar la funci\u00f3n <em><strong>text<\/strong><\/em>. Por ejemplo, la etiqueta <em><strong>&lt;meta&gt;<\/strong><\/em><em>\u00a0<\/em>no tiene contenido alguno, pero <em><strong>&lt;title&gt;<\/strong><\/em> s\u00ed:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.meta.string\r\n&gt;&gt;&gt; bs.title.string\r\nu'Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI'\r\n\r\n&gt;&gt;&gt; bs.title.text\r\nu'Tira\u00a0que\u00a0libras\u00a0\\u2026\u00a0\\u2013\u00a0Blog\u00a0de\u00a0ciberseguridad\u00a0y\u00a0TI'\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Atributos_y_valores\"><\/span>Atributos y valores<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Cada etiqueta se trata como un <strong>diccionario<\/strong>, ya que contiene <strong>atributos<\/strong> y <strong>valores<\/strong>. Por ejemplo, la etiqueta\u00a0<em><strong>&lt;meta&gt;<\/strong><\/em> no tiene contenido, pero si atributos y valores, por lo que si hacemos una consulta al diccionario por su atributo como <em>key<\/em> nos muestra el contenido como <em>value<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.meta\r\n&lt;meta charset=\"unicode-escape\"\/&gt;\r\n&gt;&gt;&gt; bs.meta.content\r\n&gt;&gt;&gt; bs.meta['charset']\r\nu'UTF-8'\r\n<\/pre>\n<p>Por ejemplo, podemos obtener los enlaces del documento, indicados en etiquetas de tipo\u00a0<em><strong>&lt;a&gt;,<\/strong><\/em> usando la funci\u00f3n <em><strong>get()<\/strong><\/em> para obtener el valor de un atributo\u00a0<em><strong>href<\/strong><\/em> en concreto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.a\r\n&lt;a class=\"skip-link screen-reader-text\" href=\"#main\"&gt;Skip to content&lt;\/a&gt;\r\n&gt;&gt;&gt; bs.a.get('href')\r\n'#main'\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Etiqueta_anterior_siguiente\"><\/span>Etiqueta anterior \/ siguiente<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Para acceder a la siguiente o anterior etiqueta en el documento usamos las funciones <em><strong>next<\/strong><\/em> y\u00a0<em><strong>previous<\/strong><\/em>, respectivamente.<\/p>\n<p>Importante tener en cuenta que para mostrar la siguiente o anterior etiqueta es necesario concatenar varias veces estas funciones, de tal forma que una solo me muestra el siguiente valor del \u00e1rbol, osea el contenido de la etiqueta con la funci\u00f3n siguiente y el retorno de carro para la anterior. Lo veremos mejor en el siguiente ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.title\r\n&lt;title&gt;Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI&lt;\/title&gt;\r\n&gt;&gt;&gt; bs.title.next\r\nu'Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI'\r\n\r\n&gt;&gt;&gt; bs.title.next.next\r\nu'\\n'\r\n\r\n&gt;&gt;&gt; bs.title.next.next.next\r\n&lt;link href=\"\/\/tiraquelibras.com\" rel=\"dns-prefetch\"\/&gt;\r\n<\/pre>\n<p>Y a la inversa:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.title.previous\r\nu'\\n'\r\n\r\n&gt;&gt;&gt; bs.title.previous.previous\r\n&lt;link href=\"http:\/\/gmpg.org\/xfn\/11\" rel=\"profile\"\/&gt;\r\n\r\n# SI BUSCAMOS EL PRIMER LINK OBTENEMOS EL RESULTADO ANTERIOR:\r\n&gt;&gt;&gt; bs.link\r\n&lt;link href=\"http:\/\/gmpg.org\/xfn\/11\" rel=\"profile\"\/&gt;\r\n<\/pre>\n<p>Podemos concatener estos comandos con otras funciones, por ejemplo si usamos la funci\u00f3n <em><strong>string<\/strong><\/em> mostramos \u00fanicamente el contenido.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">&gt;&gt;&gt; bs.link.next.next\r\n&lt;title&gt;Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI&lt;\/title&gt;\r\n\r\n&gt;&gt;&gt; bs.link.next.next.string\r\nu'Tira que libras \\u2026 \\u2013 Blog de ciberseguridad y TI'\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Etiqueta_padre\"><\/span>Etiqueta padre<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Con la funci\u00f3n\u00a0<em><strong>parent<\/strong><\/em> obtenemos la etiqueta del nivel inmediatamente superior a la que pertenece la que estamos consultando.<\/p>\n<p>Por ejemplo, para mostrar la etiqueta a la que pertenece el primer p\u00e1rrafo o etiqueta\u00a0<em><strong>&lt;p&gt;<\/strong><\/em>, observamos como se muestra la etiqueta padre y a continuaci\u00f3n sus etiquetas hijas:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">&gt;&gt;&gt; bs.p\r\n&lt;p class=\"site-description\"&gt;Blog de ciberseguridad y TI&lt;\/p&gt;\r\n\r\n&gt;&gt;&gt; bs.p.parent\r\n&lt;div class=\"center-brand\"&gt;\\n&lt;h1 class=\"site-title\"&gt;&lt;a href=\"https:\/\/blog.tiraquelibras.com\/\" rel=\"home\"&gt;Tira que libras \\u2026&lt;\/a&gt;&lt;\/h1&gt;\\n&lt;p class=\"site-description\"&gt;Blog de ciberseguridad y TI&lt;\/p&gt;\\n&lt;\/div&gt;\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Mostrar_todos_los_resultados\"><\/span>Mostrar todos los resultados<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Los comandos vistos hasta ahora solo muestran el primer resultado de la consulta, pero si queremos ver todos los resultados debemos de usar la funci\u00f3n\u00a0<em><strong>find_all()<\/strong> <\/em>indicando la etiqueta a buscar.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.find_all('meta')\r\n[&lt;meta charset=\"unicode-escape\"\/&gt;, &lt;meta content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" name=\"viewport\"\/&gt;, &lt;meta content=\"WordPress 5.1\" name=\"generator\"\/&gt;, &lt;meta content=\"website\" name=\"og:type\" property=\"og:type\"\/&gt;, &lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/04\/cropped-favicon.png\" name=\"og:image\" property=\"og:image\"\/&gt;, &lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/03\/cropped-office-2539844_1280-2.jpg\" name=\"og:image\" property=\"og:image\"\/&gt;, &lt;meta content=\"Blog de ciberseguridad y TI\" name=\"og:description\" property=\"og:description\"\/&gt;, &lt;meta content=\"es_ES\" name=\"og:locale\" property=\"og:locale\"\/&gt;, &lt;meta content=\"Tira que libras ...\" name=\"og:site_name\" property=\"og:site_name\"\/&gt;, &lt;meta content=\"summary\" name=\"twitter:card\" property=\"twitter:card\"\/&gt;, &lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/04\/cropped-favicon-270x270.png\" name=\"msapplication-TileImage\"\/&gt;, &lt;meta content=\"width=device-width, user-scalable=yes, initial-scale=1.0, minimum-scale=0.1, maximum-scale=10.0\" name=\"viewport\"\/&gt;]\r\n<\/pre>\n<p>Para verlo mejor formateado usamos un diccionario y le hacemos un bucle <em><strong>for<\/strong><\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; metas = bs.find_all('meta')\r\n&gt;&gt;&gt; for meta in metas:\r\n...  print meta\r\n...\r\n&lt;meta charset=\"utf-8\"\/&gt;\r\n&lt;meta content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" name=\"viewport\"\/&gt;\r\n&lt;meta content=\"WordPress 5.1\" name=\"generator\"\/&gt;\r\n&lt;meta content=\"website\" name=\"og:type\" property=\"og:type\"\/&gt;\r\n&lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/04\/cropped-favicon.png\" name=\"og:image\" property=\"og:image\"\/&gt;\r\n&lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/03\/cropped-office-2539844_1280-2.jpg\" name=\"og:image\" property=\"og:image\"\/&gt;\r\n&lt;meta content=\"Blog de ciberseguridad y TI\" name=\"og:description\" property=\"og:description\"\/&gt;\r\n&lt;meta content=\"es_ES\" name=\"og:locale\" property=\"og:locale\"\/&gt;\r\n&lt;meta content=\"Tira que libras ...\" name=\"og:site_name\" property=\"og:site_name\"\/&gt;\r\n&lt;meta content=\"summary\" name=\"twitter:card\" property=\"twitter:card\"\/&gt;\r\n&lt;meta content=\"https:\/\/blog.tiraquelibras.com\/wp-content\/uploads\/2018\/04\/cropped-favicon-270x270.png\" name=\"msapplication-TileImage\"\/&gt;\r\n&lt;meta content=\"width=device-width, user-scalable=yes, initial-scale=1.0, minimum-scale=0.1, maximum-scale=10.0\" name=\"viewport\"\/&gt;\r\n<\/pre>\n<p>Con esta funci\u00f3n podemos buscar todos los enlaces contenidos en el documento consultado:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; enlaces = bs.find_all('a')\r\n&gt;&gt;&gt; for enlace in enlaces:\r\n...  print enlace\r\n...\r\n&lt;a class=\"skip-link screen-reader-text\" href=\"#main\"&gt;Skip to content&lt;\/a&gt;\r\n&lt;a href=\"https:\/\/blog.tiraquelibras.com\/\" rel=\"home\"&gt;Tira que libras \u2026&lt;\/a&gt;\r\n&lt;a aria-current=\"page\" href=\"https:\/\/blog.tiraquelibras.com\/\"&gt;Inicio&lt;\/a&gt;\r\n&lt;a href=\"https:\/\/blog.tiraquelibras.com\/?page_id=49\"&gt;Info&lt;\/a&gt;\r\n&lt;a href=\"https:\/\/blog.tiraquelibras.com\/?page_id=151\"&gt;Pol\u00edtica&lt;\/a&gt;\r\n&lt;a href=\"https:\/\/blog.tiraquelibras.com\/?page_id=66\"&gt;Contacto&lt;\/a&gt;\r\n...<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Buscar_por_id_y_class\"><\/span>Buscar por id y class<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Podemos buscar capas o etiquetas concretas buscando por su identificador o clase. Para el primero indicamos el nombre del identificador, pero para el segundo debemos de indicar un diccionario de atributos para aplicar el filtro.<\/p>\n<ul>\n<li>La sintaxis para\u00a0<em><strong>id<\/strong><\/em> ser\u00eda -&gt;\u00a0<em><strong>find_all(&#8216;&lt;tag_name&gt;&#8217;, id='&lt;id_name&gt;&#8217;)<\/strong><\/em><\/li>\n<li>La sintaxis para\u00a0<em><strong>class<\/strong><\/em> ser\u00eda -&gt;\u00a0<em><strong>find_all(&#8216;&lt;tag_name&gt;&#8217;, {&#8216;class&#8217;:'&lt;class_name&gt;&#8217;})<\/strong><\/em><\/li>\n<\/ul>\n<p>Buscar por <em><strong>id<\/strong><\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.find_all('footer', id=\"colophon\")\r\n[&lt;footer class=\"site-footer\" id=\"colophon\" role=\"contentinfo\"&gt;\\n&lt;div class=\"footer-copy\"&gt;\\n&lt;div class=\"container\"&gt;\\n&lt;div class=\"row\"&gt;\\n&lt;div class=\"col-12 col-sm-12\"&gt;\\n&lt;div class=\"site-credits\"&gt;\\xa9 2019 Tira que libras ...&lt;\/div&gt;\\n&lt;div class=\"site-info\"&gt;\\n&lt;a href=\"https:\/\/wordpress.org\/\"&gt;Powered by WordPress&lt;\/a&gt;\\n&lt;span class=\"sep\"&gt; - &lt;\/span&gt;\\n&lt;a href=\"http:\/\/themeegg.com\"&gt;Miteri by ThemeEgg&lt;\/a&gt;\\n&lt;\/div&gt;&lt;!-- .site-info --&gt;\\n&lt;\/div&gt;\\n&lt;\/div&gt;\\n&lt;\/div&gt;&lt;!-- .container --&gt;\\n&lt;\/div&gt;&lt;!-- .footer-copy --&gt;\\n&lt;\/footer&gt;]\r\n<\/pre>\n<p>Buscar por <em><strong>class<\/strong><\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.find_all('h1', {'class':'site-title'})\r\n[&lt;h1 class=\"site-title\"&gt;&lt;a href=\"https:\/\/blog.tiraquelibras.com\/\" rel=\"home\"&gt;Tira que libras \\u2026&lt;\/a&gt;&lt;\/h1&gt;]\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Auditoria_Web_%E2%80%93_Formularios\"><\/span>Auditor\u00eda Web &#8211; Formularios<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Para buscar los formularios indicamos el nombre de esta etiqueta directamente. Esto nos es muy \u00fatil para auditor\u00edas Web, con el fin de identificar d\u00f3nde hacer pruebas de <strong>XSS<\/strong>, por ejemplo.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; forms = bs.find_all('form')\r\n\r\n\r\n&gt;&gt;&gt; for form in forms:\r\n...  print form\r\n...\r\n&lt;form action=\"https:\/\/blog.tiraquelibras.com\/\" class=\"search-form clear\" method=\"get\" role=\"search\"&gt;\r\n&lt;label&gt;\r\n&lt;span class=\"screen-reader-text\"&gt;Search for:&lt;\/span&gt;\r\n&lt;input class=\"search-field\" id=\"s\" miteri=\"search\" name=\"s\" placeholder=\"Search \u2026\" value=\"\"\/&gt;\r\n&lt;\/label&gt;\r\n&lt;button class=\"search-submit\" miteri=\"submit\"&gt;\r\n&lt;i class=\"fa fa-search\"&gt;&lt;\/i&gt; &lt;span class=\"screen-reader-text\"&gt;\r\n                Search&lt;\/span&gt;\r\n&lt;\/button&gt;\r\n&lt;\/form&gt;\r\n...<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Extraccion_XML\"><\/span>Extracci\u00f3n XML<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Vamos a extraer el contenido utilizando un archivo <strong>.xml<\/strong>\u00a0como fuente de datos.<\/p>\n<h2><\/h2>\n<h2 style=\"text-align: center;\"><span class=\"ez-toc-section\" id=\"Archivo_XML\"><\/span>Archivo XML<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Vamos a tomar como ejemplo el archivo <em><strong>bs.xml<\/strong> <\/em>con el siguiente contenido:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\">&lt;note&gt;\r\n  &lt;to&gt;Manolo&lt;\/to&gt;\r\n  &lt;frm&gt;Lorena&lt;\/frm&gt;\r\n  &lt;heading&gt;Recordatorio&lt;\/heading&gt;\r\n  &lt;body&gt;\u00a1Hacer la compra al salir del trabajo!&lt;\/body&gt;\r\n&lt;\/note&gt;<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Instancia_BeautifulSoup-2\"><\/span>Instancia BeautifulSoup<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Primero accedemos al documento:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">xml = open(\"bs.xml\", \"r\").read()<\/pre>\n<p>Y luego creamos la instancia de <strong>BeautifulSoup<\/strong> indicando el parser a utilizar, en este caso <em><strong>xml<\/strong><\/em> aunque valdr\u00eda <em><strong>lxml<\/strong><\/em> tambi\u00e9n:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">bs = BeautifulSoup(xml, \"xml\")<\/pre>\n<h2><\/h2>\n<h2 style=\"text-align: center;\"><span class=\"ez-toc-section\" id=\"Acceso_al_contenido-2\"><\/span>Acceso al contenido<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>El acceso al contenido es exactamente igual que lo indicado para los archivos\u00a0<strong>HTML<\/strong>, por lo que no vamos a repetir los pasos anteriores de nuevo.<\/p>\n<p>A continuaci\u00f3n indicamos unos sencillos ejemplos de extracci\u00f3n sobre la instancia generada:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">&gt;&gt;&gt; bs.note\r\n&lt;note&gt;\\n&lt;to&gt;Manolo&lt;\/to&gt;\\n&lt;frm&gt;Lorena&lt;\/frm&gt;\\n&lt;heading&gt;Recordatorio&lt;\/heading&gt;\\n&lt;body&gt;\\u0e22\\u0e01Hacer la compra al salir del trabajo!&lt;\/body&gt;\\n&lt;\/note&gt;\r\n\r\n&gt;&gt;&gt; bs.note.string\r\n&gt;&gt;&gt;\r\n\r\n&gt;&gt;&gt; bs.note.to\r\n&lt;to&gt;Manolo&lt;\/to&gt;\r\n\r\n&gt;&gt;&gt; bs.note.to.string\r\nu'Manolo'<\/pre>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusi\u00f3n<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Con esta t\u00e9cnica no solo podemos obtener informaci\u00f3n valiosa de un archivo HTML o XML, en resumen de una web, foro, chat o de un enlace en concreto, sino que podemos obtener informaci\u00f3n importante para la realizaci\u00f3n de una auditor\u00eda Web o de un an\u00e1lisis de contenido en busca de enlaces maliciosos, por ejemplo.<\/p>\n<hr \/>\n<h1><span class=\"ez-toc-section\" id=\"Enlaces_relacionados\"><\/span>Enlaces relacionados<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Enlace oficial de <strong>BeautifulSoup<\/strong>, pincha <a href=\"https:\/\/www.crummy.com\/software\/BeautifulSoup\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n<p>Videotutorial de <em>DragonJar<\/em> muy interesante sobre este asunto, pincha <a href=\"https:\/\/www.youtube.com\/watch?reload=9&amp;v=y80UPf8mIdE&amp;list=PLbMc9DOHlK9xm2DQmDc3qS7yc2x1kZ_Qu&amp;index=8\" target=\"_blank\" rel=\"noopener noreferrer nofollow\" class=\"external external_icon\">aqu\u00ed<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Web Scraping es una t\u00e9cnica utilizada para la extracci\u00f3n de informaci\u00f3n dentro de una web, simulando la navegaci\u00f3n humana. Con esta informaci\u00f3n podemos obtener el<span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/blog.tiraquelibras.com\/?p=574\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":582,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,6,22],"tags":[50,27,44],"class_list":["post-574","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ciberseguridad","category-programacion","category-ti","tag-auditoria","tag-python","tag-web"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/574","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=574"}],"version-history":[{"count":0,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/posts\/574\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=\/wp\/v2\/media\/582"}],"wp:attachment":[{"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=574"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=574"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiraquelibras.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=574"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}