Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions lessons/02_web_scraping.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
"\n",
"* * *\n",
"\n",
"### Iconos utilizados en este notebook\n",
"🔔 **Preguntas**: Una pregunta rápida para ayudarte a entender qué está pasando.<br>\n",
"🥊 **Desafío**: Ejercicio interactivo. Lo trabajaremos en el taller.!<br>\n",
"⚠️ **Advertencia**: Aviso sobre cuestiones complicadas o errores comunes.<br>\n",
"💡 **Tip**:Cómo hacer algo de forma un poco más eficiente o efectiva.<br>\n",
"🎬 **Demo**: Mostrando algo más avanzado: ¡para que sepas para qué se puede usar Python!<br>\n",
"\n",
"### Objetivos de aprendizaje\n",
"1. [Objetivos de aprendizaje](#when)\n",
"### Íconos usados ​​en este cuaderno\n",
"🔔 **Pregunta**: Una pregunta rápida para ayudarte a entender qué está pasando.<br>\n",
"🥊 **Desafío**: Ejercicio interactivo. ¡Lo resolveremos en el taller!<br>\n",
Expand All @@ -27,13 +36,21 @@
"source": [
"<a id='when'></a>\n",
"\n",
"# “¿Hacer scraping o no hacerlo?”\n",
"\n",
"Cuando queremos acceder a datos de la web, primero debemos asegurarnos de que el sitio web que nos interesa ofrezca una API web. Plataformas como Twitter, Reddit y The New York Times ofrecen API. **Echa un vistazo a D-Lab [Python Web APIs](https://github.com/dlab-berkeley/Python-Web-APIs) Taller si quieres aprender a utilizar las API.**\n",
"\n",
"Sin embargo, a menudo no existe una API web. En estos casos, podemos recurrir al web scraping, donde extraemos el HTML subyacente de una página web y obtenemos directamente la información deseada. Existen varios paquetes en Python que podemos usar para realizar estas tareas. Nos centraremos en dos paquetes: Requests y Beautiful Soup.\n",
"\n",
"Nuestro estudio de caso consistirá en extraer información sobre el [Senadores estatales de Illinois](http://www.ilga.gov/senate), así como el [lista de facturas](http://www.ilga.gov/senate/SenatorBills.asp?MemberID=1911&GA=98&Primary=True) Cada senador ha patrocinado. Antes de empezar, revise estos sitios web para conocer su estructura."
"# Scraping o no scraping\n",
"\n",
"Para acceder a datos de la web, primero debemos asegurarnos de que el sitio web que nos interesa ofrezca una API web. Plataformas como Twitter, Reddit y el New York Times ofrecen API. **Consulta el taller de D-Lab sobre [API web de Python](https://github.com/dlab-berkeley/Python-Web-APIs) si quieres aprender a usar las API.**\n",
"\n",
"Sin embargo, a menudo no existe una API web. En estos casos, podemos recurrir al web scraping, donde extraemos el HTML subyacente de una página web y obtenemos directamente la información que buscamos. Existen varios paquetes en Python que podemos usar para realizar estas tareas. Nos centraremos en dos paquetes: Requests y Beautiful Soup.\n",
"\n",
"Nuestro estudio de caso recopilará información sobre los senadores estatales de Illinois (http://www.ilga.gov/senate), así como la lista de proyectos de ley patrocinados por cada senador. Antes de comenzar, revise estos sitios web para conocer su estructura."

]
},
{
Expand All @@ -42,7 +59,11 @@
"source": [
"## Instalación\n",
"\n",

"Utilizaremos dos paquetes principales: [Solicitudes](http://docs.python-requests.org/en/latest/user/quickstart/) y [Beautiful Soup](http://www.crummy.com/software/BeautifulSoup/bs4/doc/). Continúe e instale estos paquetes, si aún no lo ha hecho:"

"Usaremos dos paquetes principales: [Requests](http://docs.python-requests.org/en/latest/user/quickstart/) y [Beautiful Soup](http://www.crummy.com/software/BeautifulSoup/bs4/doc/). Continúe instalando estos paquetes, si aún no lo ha hecho:"

]
},
{
Expand Down Expand Up @@ -156,6 +177,11 @@
"\n",
"# Extracción y análisis de HTML\n",
"\n",
"Para extraer y analizar HTML correctamente, seguiremos los siguientes 4 pasos:\n",
"1. Realizar una solicitud GET\n",
"2. Analizar la página con Beautiful Soup\n",
"3. Buscar elementos HTML\n",
"4. Obtener los atributos y el texto de estos elementos"
"Para extraer y analizar correctamente HTML, seguiremos los siguientes 4 pasos:\n",
"1. Realizar una solicitud GET\n",
"2. Analizar la página con Beautiful Soup\n",
Expand All @@ -167,6 +193,15 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Paso 1: Realizar una solicitud GET para obtener el HTML de una página\n",
"\n",
"Podemos usar la biblioteca Requests para:\n",
"\n",
"1. Realizar una solicitud GET a la página y\n",
"2. Leer el código HTML de la página web.\n",
"\n",
"El proceso de realizar una solicitud y obtener un resultado es similar al del flujo de trabajo de la API web. Sin embargo, ahora realizamos una solicitud directamente al sitio web y tendremos que analizar el HTML nosotros mismos. Esto contrasta con recibir datos organizados en una salida JSON o XML más sencilla."
=======
"## Paso 1: Realiza una solicitud GET para obtener el HTML de una página\n",
"\n",
"Podemos usar la librería Requests para:\n",
Expand Down Expand Up @@ -374,7 +409,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [

"¿Cuántos enlaces obtuvimos?"

"¿Cuantos enlaces obtuvimos?"

]
},
{
Expand Down Expand Up @@ -466,7 +505,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [

"## 🥊Desafío: Encontrar todo\n",

"## 🥊 Desafío: Encontrar todo\n",

"\n",
"Usa BeautifulSoup para encontrar todos los elementos `a` con la clase `mainmenu`."
]
Expand All @@ -484,7 +527,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [

"Paso 4: Obtener los atributos y el texto de los elementos\n",

"## Paso 4: Obtener los atributos y el texto de los elementos\n",

"\n",
"Una vez identificados los elementos, necesitamos la información de acceso de cada uno. Normalmente, esto implica dos cosas:\n",
"\n",
Expand Down Expand Up @@ -976,6 +1023,19 @@
"\n",
"`http://www.ilga.gov/senate/SenatorBills.asp?MemberID=1911&GA=98&Primary=True`\n",
"\n",

"donde `MEMBER_ID=1911`.\n",
"\n",
"Deberías poder ver que, lamentablemente, `MEMBER_ID` no se extrae actualmente en nuestro código de extracción.\n",
"\n",
"Tu tarea inicial es modificar el código anterior para que también **recuperemos la URL completa que apunta a la página correspondiente de los proyectos de ley patrocinados por las primarias** de cada miembro, y la devolvamos junto con su nombre, distrito y partido.\n",
"\n",
"Consejos:\n",
"\n",
"* Para ello, deberá obtener el elemento de anclaje correspondiente (`<a>`) en la fila de cada legislador de la tabla. Puede usar el método `.select()` en el objeto `row` del bucle para hacerlo, de forma similar al comando que busca todas las celdas `td.detail` de la fila. Recuerde que solo necesitamos el enlace a los proyectos de ley del legislador, no a los comités ni a su página de perfil.\n",
"* El HTML de los elementos de anclaje se verá como `<a href=\"/senate/Senator.asp/...\">Proyectos de ley</a>`. La cadena del atributo `href` contiene el enlace **relativo** que buscamos. Puede acceder a un atributo de un objeto `Tag` de BeatifulSoup de la misma manera que accede a un diccionario de Python: `anchor['attributeName']`. Consulta la <a href=\"http://www.crummy.com/software/BeautifulSoup/bs4/doc/#tag\">documentación</a> para obtener más detalles.\n",
"* Hay muchas maneras diferentes de usar BeautifulSoup. Puedes usar cualquier método para extraer el `href`.\n",

"en el cual `MEMBER_ID=1911`. \n",
"\n",
"Deberías poder ver que, lamentablemente, `MEMBER_ID` no se extrae actualmente en nuestro código de extracción.\n",
Expand All @@ -987,6 +1047,7 @@
"* Para ello, deberás obtener el elemento de anclaje apropiado (`<a>`) en la fila de la tabla de cada legislador. Puedes usar el método `.select()` en el objeto `row` del bucle para hacerlo, similar al comando que encuentra todas las celdas `td.detail` de la fila. Recuerda que solo queremos el enlace a los proyectos de ley del legislador, no a los comités ni a su página de perfil.\n",
"* El HTML de los elementos de anclaje se verá como `<a href=\"/senate/Senator.asp/...\">Proyectos de ley</a>`. La cadena del atributo `href` contiene el enlace **relativo** que buscamos. Puedes acceder a un atributo de un objeto `Tag` de BeatifulSoup de la misma manera que accedes a un diccionario de Python: `anchor['attributeName']`. Consulta la <a href=\"http://www.crummy.com/software/BeautifulSoup/bs4/doc/#tag\">documentación</a> para más detalles.\n",
"* Hay muchas maneras diferentes de usar BeautifulSoup. Puedes hacer lo que necesites para extraer el `href`.\n",

"\n",
"El código se ha completado parcialmente. Complétalo donde dice `#TU CÓDIGO AQUÍ`. Guarda la ruta en un objeto llamado `full_path`."
]
Expand Down Expand Up @@ -1051,7 +1112,11 @@
"source": [
"## 🥊 Desafío: Modulariza tu código\n",
"\n",

"Convierte el código anterior en una función que acepte una URL, rastree la URL para encontrar sus senadores y devuelva una lista de tuplas con información sobre cada senador. "

"Convierte el código anterior en una función que acepte una URL, rastree la URL para encontrar sus senadores y devuelva una lista de tuplas con información sobre cada senador."

]
},
{
Expand Down Expand Up @@ -1085,6 +1150,22 @@
"cell_type": "markdown",
"metadata": {},
"source": [

"## 🥊 Desafío práctico: Escribir una función de scraping\n",
"\n",
"Queremos scraping las páginas web correspondientes a los proyectos de ley patrocinados por cada proyecto de ley.\n",
"\n",
"Escribir una función llamada `get_bills(url)` para analizar la URL de un proyecto de ley. Esto implica:\n",
"\n",
"- Solicitar la URL mediante la biblioteca <a href=\"http://docs.python-requests.org/en/latest/\">`requests`</a>\n",
"- Usar las funciones de la biblioteca `BeautifulSoup` para encontrar todos los elementos `<td>` con la clase `billlist`\n",
"- Devolver una _lista_ de tuplas, cada una con:\n",
"- Descripción (2.ª columna)\n",
"- Cámara (S o H) (3.ª columna)\n",
"- La última acción (4.ª columna)\n",
"- La fecha de la última acción (5.ª columna)\n",
"\n",

"## 🥊Desafío práctico: Escribir una función de scraping\n",
"\n",
"Queremos scraping las páginas web correspondientes a los proyectos de ley patrocinados por cada proyecto de ley.\n",
Expand All @@ -1099,6 +1180,7 @@
"- La última acción (4.ª columna)\n",
"- La fecha de la última acción (5.ª columna)\n",
"\n",

"Esta función se ha completado parcialmente. Complete el resto."
]
},
Expand All @@ -1117,7 +1199,11 @@
" bills = []\n",
" for row in rows:\n",
" # YOUR CODE HERE\n",

" #bill_id =\n",

" # bill_id =\n",

" #description =\n",
" #chamber =\n",
" #last_action =\n",
Expand Down