Categorías
Python

Rethink Frasco – Una lista de tareas simple Desarrollado por Frasco y RethinkDB

 

Tabla de Contenidos

  • Configuración de su Python Web raspador
  • Web Hacer peticiones
  • Wrangling HTML Con BeautifulSoup
  • Usando BeautifulSoup obtener matemático Nombres
  • Conseguir la popularidad Puntuación
  • Poniendo todo junto
  • Conclusión y próximos pasos

¿Qué es la web raspado de todo esto?

Imagine que un día, de repente, te encuentras pensando “Vaya, me pregunto quiénes son los cinco más populares son los matemáticos?”

lo hace un poco de pensamiento, y se obtiene la idea de utilizar Xtools de Wikipedia para medir la popularidad de un matemático igualando popularidad con páginas vistas. Por ejemplo, mira la página sobre Henri Poincaré. Allí, se puede ver que páginas vistas de Poincaré para los últimos 60 días son, a partir de diciembre de 2017, alrededor de 32.000.

A continuación, Google “matemáticos famosos” y encontrar este recurso que enumera 100 nombres. Ahora usted tiene una página donde aparecen los nombres de los matemáticos, así como un sitio web que proporciona información sobre cómo ‘popular’ que es matemático. ¿Ahora que?

Aquí es donde Python y raspado Web vienen en. Raspado web es acerca de la descarga de datos estructurados de la web, la selección de algunos de esos datos, y que pasa a lo largo de lo que haya seleccionado a otro proceso.

En este tutorial, va a escribir un programa Python que descarga la lista de 100 matemáticos y sus Xtools páginas, selecciona los datos acerca de su popularidad, y acabados por decirnos los 5 mejores matemáticos más populares de todos los tiempos! Empecemos.

Importante: Hemos recibido un correo electrónico de un mantenedor Xtools nos informa de que el raspado Xtools es perjudicial y que las API de automatización se debe utilizar en su lugar:

este artículo en su sitio es esencialmente una guía para Xtools raspado […] Este no es necesario, y está causando problemas para nosotros. Tenemos las API que se deben utilizar para la automatización, y además, por páginas vistas en concreto la gente debe estar usando la API oficial de páginas vistas.

El código de ejemplo en el artículo se modificó a ninguna solicitud de maquillaje más largas a la página web Xtools. Las técnicas de raspado web demostradas aquí siguen siendo válidos, pero por favor no los utilizan en las páginas web del proyecto Xtools. Utilizar la API de automatización proporcionada en su lugar.

Configuración de su Python Web raspador

Usted va a utilizar Python y Python 3 ambientes virtuales de todo el tutorial. Siéntase libre de cosas establecido como usted quiera. Así es como yo tiendo a hacerlo:

$ python3 -m venv venv
$ . ./venv/bin/activate

Usted tendrá que instalar sólo estos dos paquetes: solicitudes

  • para realizar su peticiones HTTP
  • BeautifulSoup4 para el manejo de la totalidad de su HTML procesamiento

vamos a instalar estas dependencias con pip :

$ pip install requests BeautifulSoup4

por último, si desea seguir adelante, lanzar su editor de texto favorito y crear un archivo llamado mathematicians.py. Para comenzar, la inclusión de estas declaraciones de importación en la parte superior:

from requests import get
from requests.exceptions import RequestException
from contextlib import closing
from bs4 import BeautifulSoup

Web Hacer Pide

Su primera tarea será la de las páginas web de descarga. El paquete de peticiones viene al rescate. Su objetivo es ser una herramienta fácil de usar para hacer todas las cosas HTTP en Python, y no me decepcionó. En este tutorial, necesitará sólo la función requests.get (), pero que sin duda debe pago y envío de la documentación completa cuando se quiere ir más allá.

En primer lugar, esta es su función: function

def simple_get(url):
"""
Attempts to get the content at `url` by making an HTTP GET request.
If the content-type of response is some kind of HTML/XML, return the
text content, otherwise return None.
"""
try:
with closing(get(url, stream=True)) as resp:
if is_good_response(resp):
return resp.content
else:
return None

except RequestException as e:
log_error('Error during requests to {0} : {1}'.format(url, str(e)))
return None

def is_good_response(resp):
"""
Returns True if the response seems to be HTML, False otherwise.
"""
content_type = resp.headers['Content-Type'].lower()
return (resp.status_code == 200
and content_type is not None
and content_type.find('html') > -1)

def log_error(e):
"""
It is always a good idea to log errors.
This function just prints them, but you can
make it do anything.
"""
print(e)

El simple_get () acepta un solo argumento url. Luego hace una petición GET a la URL. Si nada sale mal, se termina con el contenido HTML prima para la página solicitada. Si hubiera algún problema con su solicitud (como la URL es malo, o el servidor remoto está abajo), entonces su función devuelve Ninguno.

Usted puede haber notado el uso de la función de cierre () en su definición de simple_get (). Las asegura la función de cierre () que todos los recursos de red se liberan cuando salen del ámbito en el que con el bloque. El uso de cierre () de esa manera es una buena práctica y ayuda a prevenir errores fatales y los tiempos de espera de la red.

Puede probar simple_get () así:

>>> from mathematicians import simple_get
>>> raw_html = simple_get('https://realpython.com/blog/')
>>> len(raw_html)
33878

>>> no_html = simple_get('https://realpython.com/blog
ope-not-gonna-find-it')
>>> no_html is None
True

Wrangling HTML Con BeautifulSoup

Una vez que tenga el HTML puro delante de usted, usted puede comenzar a seleccionar y extracto. Para este propósito, que va a utilizar BeautifulSoup. El constructor BeautifulSoup analiza cadenas HTML primas y produce un objeto que los espejos estructura del documento HTML. El objeto incluye una serie de métodos para seleccionar, ver y manipular nodos DOM y contenido de texto.

Consideremos el siguiente ejemplo rápido y artificial de un documento HTML:




Contrived Example<itle><br /> </head><br /> <body></p> <p id="eggman"> I am the egg man </p> <p id="walrus"> I am the walrus </p> <p></body><br /> </html><br /> </code> </p> <p> Si lo anterior HTML se guarda en el archivo de contrived.html, entonces se puede utilizar BeautifulSoup así: </p> <p> <code>>>> from bs4 import BeautifulSoup<br /> >>> raw_html = open('contrived.html').read()<br /> >>> html = BeautifulSoup(raw_html, 'html.parser')<br /> >>> for p in html.select('p'):<br /> ... if p['id'] == 'walrus':<br /> ... print(p.text)</p> <p>'I am the walrus'<br /> </code> </p> <p> descomponer el ejemplo, primero analizar el HTML puro pasándolo al constructor BeautifulSoup. BeautifulSoup acepta múltiples programas de análisis de back-end, pero el back-end estándar es ‘html.parser’, que usted proporciona aquí como el segundo argumento. (Si usted se olvida de que el suministro ‘html.parser’, entonces el código seguirá funcionando, pero usted verá una impresión advertencia a la pantalla.) </p> <p> El seleccione () en el objeto HTML le permite utilizar los selectores CSS para localizar los elementos del documento. En el caso anterior, html.select ( ‘p’) devuelve una lista de elementos de párrafo. Cada p tiene atributos HTML que se puede acceder como un dict. En la línea si p [ ‘id == ‘morsa’, por ejemplo, se comprueba si el atributo id es igual a la cadena ‘morsa’, que corresponde a </p> <p id = "morsa"> en el código HTML. </p> <h2> Usando BeautifulSoup obtener matemático Nombres </h2> <p> Ahora que ha dado el método de selección () en BeautifulSoup un corto recorrido de prueba, ¿cómo determinar lo que puede suministrar para seleccionar ()? La forma más rápida es a salir de Python y en las herramientas de desarrollo de su navegador web. Puede utilizar el navegador para examinar el documento en detalle. Suelo buscar atributos id o elemento de clase o cualquier otra información que identifica de manera única la información que desea extraer. </p> <p> Para hacer las cosas concretas, a su vez, a la lista de los matemáticos que vimos antes. Si pasas un minuto o dos mirando en la fuente de esta página, se puede ver que el nombre de cada uno matemático aparece dentro del contenido de texto de una etiqueta </p> <li>. Para hacer las cosas aún más simple, etiquetas <li> en esta página parecen contener nada más que los nombres de los matemáticos. </p> <p> He aquí un vistazo rápido con Python: </p> <p> <code>>>> raw_html = simple_get('http://www.fabpedigree.com/james/mathmen.htm')<br /> >>> html = BeautifulSoup(raw_html, 'html.parser')<br /> >>> for i, li in enumerate(html.select('li')):<br /> print(i, li.text)</p> <p>0 Isaac Newton<br /> Archimedes<br /> Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p>1 Archimedes<br /> Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p>2 Carl F. Gauss<br /> Leonhard Euler<br /> Bernhard Riemann</p> <p> 3 Leonhard Euler<br /> Bernhard Riemann</p> <p>4 Bernhard Riemann</p> <p># 5 ... and many more...<br /> </code> </p> <p> El anterior experimento muestra que algunos de los elementos </p> <li> contienen varios nombres separados por caracteres de nueva línea, mientras que otras contienen solo un nombre. Con esta información en mente, usted puede escribir su función para extraer una única lista de nombres: </p> <p> <code>def get_names():<br /> """<br /> Downloads the page where the list of mathematicians is found<br /> and returns a list of strings, one per mathematician<br /> """<br /> url = 'http://www.fabpedigree.com/james/mathmen.htm'<br /> response = simple_get(url)</p> <p> if response is not None:<br /> html = BeautifulSoup(response, 'html.parser')<br /> names = set()<br /> for li in html.select('li'):<br /> for name in li.text.split('\n'):<br /> if len(name) > 0:<br /> names.add(name.strip())<br /> return list(names)</p> <p> # Raise an exception if we failed to get any data from the url<br /> raise Exception('Error retrieving contents at {}'.format(url))<br /> </code> </p> <p> Los get_names () descarga de la página de función y itera sobre los elementos </p> <li>, escogiendo cada nombre que se da. A continuación, añadir cada nombre para un conjunto de Python, lo que asegura que no termina con nombres duplicados. Por último, a convertir el conjunto a una lista y lo devuelve. </p> <h2> Conseguir la popularidad Puntuación </h2> <p> Niza, usted está a punto de terminar! Ahora que tiene una lista de nombres, es necesario seleccionar las páginas vistas para cada uno. La función se escribe es similar a la función que realizan para obtener la lista de nombres, sólo que ahora proporciona un nombre y seleccionar un valor entero de la página. </p> <p> vez más, usted debe consultar primero a cabo una página de ejemplo, en las herramientas de desarrollo de su navegador. Parece como si el texto aparece dentro de un elemento <a>, y el atributo href del elemento que siempre contiene la cadena ‘última-60’ como una subcadena. Esa es toda la información que necesita para escribir su función: </p> <p> <code>def get_hits_on_name(name):<br /> """<br /> Accepts a `name` of a mathematician and returns the number<br /> of hits that mathematician's Wikipedia page received in the<br /> last 60 days, as an `int`<br /> """<br /> # url_root is a template string that is used to build a URL.<br /> url_root = 'URL_REMOVED_SEE_NOTICE_AT_START_OF_ARTICLE'<br /> response = simple_get(url_root.format(name))</p> <p> if response is not None:<br /> html = BeautifulSoup(response, 'html.parser')</p> <p> hit_link = [a for a in html.select('a')<br /> if a['href'].find('latest-60') > -1]</p> <p> if len(hit_link) > 0:<br /> # Strip commas<br /> link_text = hit_link[0].text.replace(',', '')<br /> try:<br /> # Convert to integer<br /> return int(link_text)<br /> except:<br /> log_error("couldn't parse {} as an `int`".format(link_text))</p> <p> log_error('No pageviews found for {}'.format(name))<br /> return None<br /> </code> </p> <h2> Poniendo todo junto </h2> <p> Usted ha llegado a un punto en el que finalmente puede averiguar qué matemático es más querido por el público! El plan es simple: </p> <ul> <li> Obtener una lista de nombres </li> <li> iterar sobre la lista para obtener una “puntuación de popularidad” para cada nombre </li> <li> acabado clasificando los nombres de popularidad </li> </ul> <p> simple, ¿verdad? Bueno, hay una cosa que no se ha mencionado todavía: errores. </p> <p> Trabajo con datos del mundo real es desordenado, y tratando de forzar datos desordenados en una forma uniforme, invariablemente como resultado el salto error ocasional en meterse con su buena visión limpia de cómo deberían ser las cosas. Lo ideal sería que le gustaría hacer un seguimiento de errores cuando se producen con el fin de obtener un mejor sentido de la calidad de sus datos. </p> <p> para sus propósitos presentes, se hará un seguimiento de los casos en los que no se podía encontrar una puntuación de popularidad para el nombre de un matemático dado. Al final de la secuencia de comandos, se va a imprimir un mensaje que indica el número de matemáticos que se quedaron fuera de la clasificación. </p> <p> Aquí está el código: </p> <p> <code>if __name__ == '__main__':<br /> print('Getting the list of names....')<br /> names = get_names()<br /> print('... done.\n')</p> <p> results = []</p> <p> print('Getting stats for each name....')</p> <p> for name in names:<br /> try:<br /> hits = get_hits_on_name(name)<br /> if hits is None:<br /> hits = -1<br /> results.append((hits, name))<br /> except:<br /> results.append((-1, name))<br /> log_error('error encountered while processing '<br /> '{}, skipping'.format(name))</p> <p> print('... done.\n')</p> <p> results.sort()<br /> results.reverse()</p> <p> if len(results) > 5:<br /> top_marks = results[:5]<br /> else:<br /> top_marks = results</p> <p> print('\nThe most popular mathematicians are:\n')<br /> for (mark, mathematician) in top_marks:<br /> print('{} with {} pageviews'.format(mathematician, mark))</p> <p> no_results = len([res for res in results if res[0] == -1])<br /> print('\nBut we did not find results for '<br /> '{} mathematicians on the list'.format(no_results))<br /> </code> </p> <p> Eso es todo! </p> <p> Cuando se ejecuta la secuencia de comandos, debería ver en el siguiente informe: </p> <p> <code>The most popular mathematicians are:</p> <p>Albert Einstein with 1089615 pageviews<br /> Isaac Newton with 581612 pageviews<br /> Srinivasa Ramanujan with 407141 pageviews<br /> Aristotle with 399480 pageviews<br /> Galileo Galilei with 375321 pageviews</p> <p>But we did not find results for 19 mathematicians on our list<br /> </code> </p> <h2> Conclusión y próximos pasos raspado </h2> <p> web es un campo grande, y que acaba de terminar un breve recorrido de ese campo, el uso de Python en la conducción. Se puede llegar muy lejos usando sólo las solicitudes y BeautifulSoup, pero a medida que ha seguido a lo largo, es posible que tenga llegado con algunas preguntas: </p> <ul> <li> ¿Qué pasa si las cargas de contenido de página como resultado de las peticiones de JavaScript asíncrono? (Salida API Python de selenio.) </li> <li> ¿Cómo se escribe una tela de araña o robot de búsqueda del motor que atraviesa gran parte de la web? </li> <li> ¿Qué es esta cosa Scrapy que tanto se habla? </li> </ul> <p> Estos son temas para otro post … Mantenga los ojos bien abiertos! Habrá un seguimiento que utiliza selenio y un navegador sin cabeza que lidiar con contenido dinámico: </p> <p> <strong> Informarte: </strong> no se pierda la continuación de este tutorial-Haga clic aquí para unirse a la Newsletter pitón real y sabrá cuando la próxima entrega sale. </p> <p> Hasta entonces, raspado feliz! </p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> <nav class="pagination-single section-inner" aria-label="Entrada" role="navigation"> <hr class="styled-separator is-style-wide" aria-hidden="true" /> <div class="pagination-single-inner"> <a class="previous-post" href="https://eltecnofilo.es/introduccion-a-la-programacion-orientada-a-objetos-poo-en-python/"> <span class="arrow" aria-hidden="true">←</span> <span class="title"><span class="title-inner">Introducción a la programación orientada a objetos (POO) en Python</span></span> </a> <a class="next-post" href="https://eltecnofilo.es/inicio-de-sesion-en-python/"> <span class="arrow" aria-hidden="true">→</span> <span class="title"><span class="title-inner">Inicio de sesión en Python</span></span> </a> </div><!-- .pagination-single-inner --> <hr class="styled-separator is-style-wide" aria-hidden="true" /> </nav><!-- .pagination-single --> <div class="comments-wrapper section-inner"> <div id="respond" class="comment-respond"> <h2 id="reply-title" class="comment-reply-title">Deja un comentario <small><a rel="nofollow" id="cancel-comment-reply-link" href="/rethink-frasco-una-lista-de-tareas-simple-desarrollado-por-frasco-y-rethinkdb/#respond" style="display:none;">Cancelar la respuesta</a></small></h2><form action="https://eltecnofilo.es/wp-comments-post.php" method="post" id="commentform" class="section-inner thin max-percentage" novalidate><p class="comment-notes"><span id="email-notes">Tu dirección de correo electrónico no será publicada.</span> Los campos obligatorios están marcados con <span class="required">*</span></p><p class="comment-form-comment"><label for="comment">Comentario</label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea></p><p class="comment-form-author"><label for="author">Nombre <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required='required' /></p> <p class="comment-form-email"><label for="email">Correo electrónico <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required='required' /></p> <p class="comment-form-url"><label for="url">Web</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" /></p> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Guardar mi nombre, correo electrónico y sitio web en este navegador para la próxima vez que haga un comentario.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Publicar el comentario" /> <input type='hidden' name='comment_post_ID' value='7031' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div><!-- .comments-wrapper --> </article><!-- .post --> </main><!-- #site-content --> <div class="footer-nav-widgets-wrapper header-footer-group"> <div class="footer-inner section-inner"> <aside class="footer-widgets-outer-wrapper" role="complementary"> <div class="footer-widgets-wrapper"> <div class="footer-widgets column-one grid-item"> <div class="widget widget_search"><div class="widget-content"><form role="search" method="get" class="search-form" action="https://eltecnofilo.es/"> <label for="search-form-2"> <span class="screen-reader-text">Buscar:</span> <input type="search" id="search-form-2" class="search-field" placeholder="Buscar …" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Buscar" /> </form> </div></div> <div class="widget widget_recent_entries"><div class="widget-content"> <h2 class="widget-title subheading heading-size-3">Entradas recientes</h2> <ul> <li> <a href="https://eltecnofilo.es/vps-cloud-hosting/">VPS cloud hosting</a> </li> <li> <a href="https://eltecnofilo.es/versiones-de-ejecucion-de-python-en-acoplable-como-probar-la-ultima-release-python/">Versiones de ejecución de Python en acoplable: Cómo probar la última Release Python</a> </li> <li> <a href="https://eltecnofilo.es/leer-y-escribir-archivos-csv/">Leer y escribir archivos CSV</a> </li> <li> <a href="https://eltecnofilo.es/python-puro-vs-vs-numpy-tensorflow-comparacion-de-rendimiento/">Python puro vs vs NumPy TensorFlow Comparación de Rendimiento</a> </li> <li> <a href="https://eltecnofilo.es/estructura-python-programa-lexico/">Estructura Python Programa léxico</a> </li> </ul> </div></div><div class="widget widget_recent_comments"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Comentarios recientes</h2><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href="https://wordpress.org/" rel="external nofollow ugc" class="url">A WordPress Commenter</a></span> en <a href="https://eltecnofilo.es/hello-world/#comment-1">Hello world!</a></li></ul></div></div> </div> <div class="footer-widgets column-two grid-item"> <div class="widget widget_archive"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Archivos</h2> <ul> <li><a href='https://eltecnofilo.es/2020/04/'>abril 2020</a></li> <li><a href='https://eltecnofilo.es/2020/03/'>marzo 2020</a></li> <li><a href='https://eltecnofilo.es/2019/12/'>diciembre 2019</a></li> </ul> </div></div><div class="widget widget_categories"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Categorías</h2> <ul> <li class="cat-item cat-item-22"><a href="https://eltecnofilo.es/category/python/">Python</a> </li> <li class="cat-item cat-item-1"><a href="https://eltecnofilo.es/category/uncategorized/">Uncategorized</a> </li> </ul> </div></div><div class="widget widget_meta"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Meta</h2> <ul> <li><a rel="nofollow" href="https://eltecnofilo.es/wp-login.php">Acceder</a></li> <li><a href="https://eltecnofilo.es/feed/">Feed de entradas</a></li> <li><a href="https://eltecnofilo.es/comments/feed/">Feed de comentarios</a></li> <li><a href="https://es.wordpress.org/">WordPress.org</a></li> </ul> </div></div> </div> </div><!-- .footer-widgets-wrapper --> </aside><!-- .footer-widgets-outer-wrapper --> </div><!-- .footer-inner --> </div><!-- .footer-nav-widgets-wrapper --> <footer id="site-footer" role="contentinfo" class="header-footer-group"> <div class="section-inner"> <div class="footer-credits"> <p class="footer-copyright">© 2020 <a href="https://eltecnofilo.es/">My Blog</a> </p><!-- .footer-copyright --> <p class="powered-by-wordpress"> <a href="https://es.wordpress.org/"> Funciona gracias a WordPress </a> </p><!-- .powered-by-wordpress --> </div><!-- .footer-credits --> <a class="to-the-top" href="#site-header"> <span class="to-the-top-long"> Ir arriba <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long --> <span class="to-the-top-short"> Subir <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short --> </a><!-- .to-the-top --> </div><!-- .section-inner --> </footer><!-- #site-footer --> <script src='https://eltecnofilo.es/wp-includes/js/comment-reply.min.js?ver=5.3.4'></script> <script src='https://eltecnofilo.es/wp-includes/js/wp-embed.min.js?ver=5.3.4'></script> <script> /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1); </script> </body> </html>