From bf3cd02786193b5a5954c42fb2257da1fba48988 Mon Sep 17 00:00:00 2001 From: rebe1603 Date: Sat, 23 Aug 2025 13:34:21 -0500 Subject: [PATCH] Traduccion de Python-Web-Scrapping --- lessons/02_web_scraping.ipynb | 254 +++++++++++++++++----------------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/lessons/02_web_scraping.ipynb b/lessons/02_web_scraping.ipynb index 52b3597..43c4416 100644 --- a/lessons/02_web_scraping.ipynb +++ b/lessons/02_web_scraping.ipynb @@ -4,21 +4,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Web Scraping with Beautiful Soup\n", + "# Web Scraping con Beautiful Soup\n", "\n", "* * * \n", "\n", - "### Icons used in this notebook\n", - "🔔 **Question**: A quick question to help you understand what's going on.
\n", - "🥊 **Challenge**: Interactive exercise. We'll work through these in the workshop!
\n", - "⚠️ **Warning**: Heads-up about tricky stuff or common mistakes.
\n", - "💡 **Tip**: How to do something a bit more efficiently or effectively.
\n", - "🎬 **Demo**: Showing off something more advanced – so you know what Python can be used for!
\n", + "### Iconos utilizados en este notebook\n", + "🔔 **Preguntas**: Una pregunta rápida para ayudarte a entender qué está pasando.
\n", + "🥊 **Desafío**: Ejercicio interactivo. Lo trabajaremos en el taller.!
\n", + "⚠️ **Advertencia**: Aviso sobre cuestiones complicadas o errores comunes.
\n", + "💡 **Tip**:Cómo hacer algo de forma un poco más eficiente o efectiva.
\n", + "🎬 **Demo**: Mostrando algo más avanzado: ¡para que sepas para qué se puede usar Python!
\n", "\n", - "### Learning Objectives\n", - "1. [Reflection: To Scape Or Not To Scrape](#when)\n", - "2. [Extracting and Parsing HTML](#extract)\n", - "3. [Scraping the Illinois General Assembly](#scrape)" + "### Objetivos de aprendizaje\n", + "1. [Objetivos de aprendizaje](#when)\n", + "2. [Extracción y análisis de HTML](#extract)\n", + "3. [Desmantelando la Asamblea General de Illinois](#scrape)" ] }, { @@ -27,22 +27,22 @@ "source": [ "\n", "\n", - "# To Scrape Or Not To Scrape\n", + "# “¿Hacer scraping o no hacerlo?”\n", "\n", - "When we'd like to access data from the web, we first have to make sure if the website we are interested in offers a Web API. Platforms like Twitter, Reddit, and the New York Times offer APIs. **Check out D-Lab's [Python Web APIs](https://github.com/dlab-berkeley/Python-Web-APIs) workshop if you want to learn how to use APIs.**\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", - "However, there are often cases when a Web API does not exist. In these cases, we may have to resort to web scraping, where we extract the underlying HTML from a web page, and directly obtain the information we want. There are several packages in Python we can use to accomplish these tasks. We'll focus two packages: Requests and Beautiful Soup.\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", - "Our case study will be scraping information on the [state senators of Illinois](http://www.ilga.gov/senate), as well as the [list of bills](http://www.ilga.gov/senate/SenatorBills.asp?MemberID=1911&GA=98&Primary=True) each senator has sponsored. Before we get started, peruse these websites to take a look at their structure." + "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Installation\n", + "## Instalación\n", "\n", - "We will use two main packages: [Requests](http://docs.python-requests.org/en/latest/user/quickstart/) and [Beautiful Soup](http://www.crummy.com/software/BeautifulSoup/bs4/doc/). Go ahead and install these packages, if you haven't already:" + "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:" ] }, { @@ -110,7 +110,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We'll also install the `lxml` package, which helps support some of the parsing that Beautiful Soup performs:" + "También instalaremos el paquete `lxml`, que ayuda a soportar parte del análisis que realiza Beautiful Soup:" ] }, { @@ -159,27 +159,27 @@ "source": [ "\n", "\n", - "# Extracting and Parsing HTML \n", + "# Extracción y análisis de HTML\n", "\n", - "In order to succesfully scrape and analyse HTML, we'll be going through the following 4 steps:\n", - "1. Make a GET request\n", - "2. Parse the page with Beautiful Soup\n", - "3. Search for HTML elements\n", - "4. Get attributes and text of these elements" + "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" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 1: Make a GET Request to Obtain a Page's HTML\n", + "## Paso 1: Realizar una solicitud GET para obtener el HTML de una página\n", "\n", - "We can use the Requests library to:\n", + "Podemos usar la biblioteca Requests para:\n", "\n", - "1. Make a GET request to the page, and\n", - "2. Read in the webpage's HTML code.\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", - "The process of making a request and obtaining a result resembles that of the Web API workflow. Now, however, we're making a request directly to the website, and we're going to have to parse the HTML ourselves. This is in contrast to being provided data organized into a more straightforward `JSON` or `XML` output." + "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." ] }, { @@ -202,11 +202,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 2: Parse the Page with Beautiful Soup\n", + "## Paso 2: Analizar la página con Beautiful Soup\n", "\n", - "Now, we use the `BeautifulSoup` function to parse the reponse into an HTML tree. This returns an object (called a **soup object**) which contains all of the HTML in the original document.\n", + "Ahora, usamos la función `BeautifulSoup` para analizar la respuesta en un árbol HTML. Esto devuelve un objeto (llamado **objeto soup**) que contiene todo el HTML del documento original.\n", "\n", - "If you run into an error about a parser library, make sure you've installed the `lxml` package to provide Beautiful Soup with the necessary parsing tools." + "Si se produce un error relacionado con una biblioteca de análisis, asegúrese de haber instalado el paquete `lxml` para proporcionar a Beautiful Soup las herramientas de análisis necesarias." ] }, { @@ -225,26 +225,26 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The output looks pretty similar to the above, but now it's organized in a `soup` object which allows us to more easily traverse the page." + "La salida se ve bastante similar a la anterior, pero ahora está organizada en un objeto 'soup' que nos permite recorrer la página más fácilmente." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 3: Search for HTML Elements\n", + "## Paso 3: Buscar elementos HTML\n", "\n", - "Beautiful Soup has a number of functions to find useful components on a page. Beautiful Soup lets you find elements by their:\n", + "Beautiful Soup cuenta con varias funciones para encontrar componentes útiles en una página. Beautiful Soup permite encontrar elementos por:\n", "\n", - "1. HTML tags\n", - "2. HTML Attributes\n", - "3. CSS Selectors\n", + "1. Etiquetas HTML\n", + "2. Atributos HTML\n", + "3. Selectores CSS\n", "\n", - "Let's search first for **HTML tags**. \n", + "Primero, busquemos **etiquetas HTML**.\n", "\n", - "The function `find_all` searches the `soup` tree to find all the elements with an a particular HTML tag, and returns all of those elements.\n", + "La función `find_all` busca en el árbol `soup` todos los elementos con una etiqueta HTML específica y los devuelve.\n", "\n", - "What does the example below do?" + "¿Qué hace el siguiente ejemplo?" ] }, { @@ -262,9 +262,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Because `find_all()` is the most popular method in the Beautiful Soup search API, you can use a shortcut for it. If you treat the BeautifulSoup object as though it were a function, then it’s the same as calling `find_all()` on that object. \n", + "Dado que `find_all()` es el método más popular en la API de búsqueda de Beautiful Soup, puedes usar un atajo. Si tratas el objeto BeautifulSoup como si fuera una función, es lo mismo que llamar a `find_all()` en ese objeto.\n", "\n", - "These two lines of code are equivalent:" + "Estas dos líneas de código son equivalentes:" ] }, { @@ -285,7 +285,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "How many links did we obtain?" + "¿Cuántos enlaces obtuvimos?" ] }, { @@ -301,11 +301,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "That's a lot! Many elements on a page will have the same HTML tag. For instance, if you search for everything with the `a` tag, you're likely to get more hits, many of which you might not want. Remember, the `a` tag defines a hyperlink, so you'll usually find many on any given page.\n", + "¡Eso es muchísimo! Muchos elementos de una página tendrán la misma etiqueta HTML. Por ejemplo, si buscas todo con la etiqueta `a`, probablemente obtendrás más resultados, muchos de los cuales quizás no quieras. Recuerda que la etiqueta `a` define un hipervínculo, por lo que normalmente encontrarás muchos en cualquier página.\n", "\n", - "What if we wanted to search for HTML tags with certain attributes, such as particular CSS classes? \n", + "¿Qué sucedería si quisiéramos buscar etiquetas HTML con ciertos atributos, como clases CSS específicas?\n", "\n", - "We can do this by adding an additional argument to the `find_all`. In the example below, we are finding all the `a` tags, and then filtering those with `class_=\"sidemenu\"`." + "Podemos hacerlo añadiendo un argumento adicional a `find_all`. En el siguiente ejemplo, buscamos todas las etiquetas `a` y luego las filtramos con `class_=\"sidemenu\"`." ] }, { @@ -325,9 +325,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "A more efficient way to search for elements on a website is via a **CSS selector**. For this we have to use a different method called `select()`. Just pass a string into the `.select()` to get all elements with that string as a valid CSS selector.\n", + "Una forma más eficiente de buscar elementos en un sitio web es mediante un selector CSS. Para ello, debemos usar un método diferente llamado `select()`. Simplemente pase una cadena a `.select()` para obtener todos los elementos con esa cadena como un selector CSS válido.\n", "\n", - "In the example above, we can use `\"a.sidemenu\"` as a CSS selector, which returns all `a` tags with class `sidemenu`." + "En el ejemplo anterior, podemos usar `\"a.sidemenu\"` como selector CSS, que devuelve todas las etiquetas `a` con la clase `sidemenu`." ] }, { @@ -347,9 +347,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 🥊 Challenge: Find All\n", + "## 🥊Desafío: Encontrar todo\n", "\n", - "Use BeautifulSoup to find all the `a` elements with class `mainmenu`." + "Usa BeautifulSoup para encontrar todos los elementos `a` con la clase `mainmenu`." ] }, { @@ -365,14 +365,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Step 4: Get Attributes and Text of Elements\n", + "Paso 4: Obtener los atributos y el texto de los elementos\n", "\n", - "Once we identify elements, we want the access information in that element. Usually, this means two things:\n", + "Una vez identificados los elementos, necesitamos la información de acceso de cada uno. Normalmente, esto implica dos cosas:\n", "\n", - "1. Text\n", - "2. Attributes\n", + "1. Texto\n", + "2. Atributos\n", "\n", - "Getting the text inside an element is easy. All we have to do is use the `text` member of a `tag` object:" + "Obtener el texto dentro de un elemento es sencillo. Solo tenemos que usar el miembro `text` de un objeto `tag`:" ] }, { @@ -398,7 +398,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "It's a Beautiful Soup tag! This means it has a `text` member:" + "¡Es una etiqueta de Beautiful Soup! Esto significa que tiene un miembro \"texto\":" ] }, { @@ -416,9 +416,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Sometimes we want the value of certain attributes. This is particularly relevant for `a` tags, or links, where the `href` attribute tells us where the link goes.\n", + "A veces necesitamos el valor de ciertos atributos. Esto es especialmente relevante para las etiquetas «a» o enlaces, donde el atributo «href» nos indica adónde lleva el enlace.\n", "\n", - "💡 **Tip**: You can access a tag’s attributes by treating the tag like a dictionary:" + "💡 **Consejo**: Puedes acceder a los atributos de una etiqueta tratándola como un diccionario:" ] }, { @@ -436,9 +436,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 🥊 Challenge: Extract specific attributes\n", + "## 🥊 Desafío: Extraer atributos específicos\n", "\n", - "Extract all `href` attributes for each `mainmenu` URL." + "Extraer todos los atributos `href` de cada URL `mainmenu`." ] }, { @@ -456,22 +456,22 @@ "source": [ "\n", "\n", - "# Scraping the Illinois General Assembly\n", + "# Análisis de la Asamblea General de Illinois\n", "\n", - "Believe it or not, those are really the fundamental tools you need to scrape a website. Once you spend more time familiarizing yourself with HTML and CSS, then it's simply a matter of understanding the structure of a particular website and intelligently applying the tools of Beautiful Soup and Python.\n", + "Aunque parezca increíble, estas son las herramientas fundamentales para analizar un sitio web. Una vez que dediques más tiempo a familiarizarte con HTML y CSS, simplemente será cuestión de comprender la estructura de un sitio web específico y aplicar inteligentemente las herramientas de Beautiful Soup y Python.\n", "\n", - "Let's apply these skills to scrape the [Illinois 98th General Assembly](http://www.ilga.gov/senate/default.asp?GA=98).\n", + "Apliquemos estas habilidades para analizar la [98.ª Asamblea General de Illinois](http://www.ilga.gov/senate/default.asp?GA=98).\n", "\n", - "Specifically, our goal is to scrape information on each senator, including their name, district, and party." + "En concreto, nuestro objetivo es analizar la información de cada senador, incluyendo su nombre, distrito y partido." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Scrape and Soup the Webpage\n", + "## Rastrear y analizar la página web\n", "\n", - "Let's scrape and parse the webpage, using the tools we learned in the previous section." + "Rastreemos y analicemos la página web con las herramientas que aprendimos en la sección anterior." ] }, { @@ -494,9 +494,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Search for the Table Elements\n", + "## Buscar los elementos de la tabla\n", "\n", - "Our goal is to obtain the elements in the table on the webpage. Remember: rows are identified by the `tr` tag. Let's use `find_all` to obtain these elements." + "Nuestro objetivo es obtener los elementos de la tabla en la página web. Recuerde: las filas se identifican con la etiqueta `tr`. Usemos `find_all` para obtener estos elementos." ] }, { @@ -514,7 +514,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "⚠️ **Warning**: Keep in mind: `find_all` gets *all* the elements with the `tr` tag. We only want some of them. If we use the 'Inspect' function in Google Chrome and look carefully, then we can use some CSS selectors to get just the rows we're interested in. Specifically, we want the inner rows of the table:" + "⚠️ **Advertencia**: Ten en cuenta que `find_all` obtiene *todos* los elementos con la etiqueta `tr`. Solo necesitamos algunos. Si usamos la función \"Inspeccionar\" de Google Chrome y observamos con atención, podemos usar selectores CSS para obtener solo las filas que nos interesan. En concreto, queremos las filas internas de la tabla:" ] }, { @@ -534,7 +534,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "It looks like we want everything after the first two rows. Let's work with a single row to start, and build our loop from there." + "Parece que queremos todo lo que queda después de las dos primeras filas. Empecemos con una sola fila y construyamos nuestro bucle a partir de ahí." ] }, { @@ -551,11 +551,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let's break this row down into its component cells/columns using the `select` method with CSS selectors. Looking closely at the HTML, there are a couple of ways we could do this.\n", + "Desglosemos esta fila en sus celdas/columnas mediante el método `select` con selectores CSS. Si analizamos el HTML con atención, hay un par de maneras de hacerlo.\n", "\n", - "* We could identify the cells by their tag `td`.\n", - "* We could use the the class name `.detail`.\n", - "* We could combine both and use the selector `td.detail`." + "* Podríamos identificar las celdas por su etiqueta `td`.\n", + "* Podríamos usar el nombre de clase `.detail`.\n", + "* Podríamos combinar ambos y usar el selector `td.detail`." ] }, { @@ -581,7 +581,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We can confirm that these are all the same." + "Podemos confirmar que todos son iguales." ] }, { @@ -599,7 +599,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let's use the selector `td.detail` to be as specific as possible." + "Utilicemos el selector `td.detail` para ser lo más específicos posible." ] }, { @@ -617,7 +617,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Most of the time, we're interested in the actual **text** of a website, not its tags. Recall that to get the text of an HTML element, we use the `text` member:" + "La mayoría de las veces, nos interesa el **texto** real de un sitio web, no sus etiquetas. Recordemos que para obtener el texto de un elemento HTML, usamos el miembro `text`:" ] }, { @@ -636,7 +636,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Looks good! Now we just use our basic Python knowledge to get the elements of this list that we want. Remember, we want the senator's name, their district, and their party." + "¡Se ve bien! Ahora solo necesitamos usar nuestros conocimientos básicos de Python para obtener los elementos de esta lista que necesitamos. Recuerda: queremos el nombre del senador, su distrito y su partido." ] }, { @@ -654,9 +654,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Getting Rid of Junk Rows\n", + "## Eliminando filas basura\n", "\n", - "We saw at the beginning that not all of the rows we got actually correspond to a senator. We'll need to do some cleaning before we can proceed forward. Take a look at some examples:" + "Vimos al principio que no todas las filas que obtuvimos corresponden a un senador. Tendremos que hacer limpieza antes de continuar. Vean algunos ejemplos:" ] }, { @@ -674,9 +674,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "When we write our for loop, we only want it to apply to the relevant rows. So we'll need to filter out the irrelevant rows. The way to do this is to compare some of these to the rows we do want, see how they differ, and then formulate that in a conditional.\n", + "Al escribir nuestro bucle for, queremos que solo se aplique a las filas relevantes. Por lo tanto, debemos filtrar las filas irrelevantes. Para ello, comparamos algunas de estas filas con las que necesitamos, observamos sus diferencias y luego formulamos esto en una condición.\n", "\n", - "As you can imagine, there a lot of possible ways to do this, and it'll depend on the website. We'll show some here to give you an idea of how to do this." + "Como puedes imaginar, hay muchas maneras de hacerlo, y dependerá del sitio web. Aquí te mostraremos algunas para que te hagas una idea de cómo hacerlo." ] }, { @@ -698,7 +698,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Perhaps good rows have a length of 5. Let's check:" + "Quizás las buenas filas tengan una longitud de 5. Comprobémoslo:" ] }, { @@ -719,7 +719,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We found a footer row in our list that we'd like to avoid. Let's try something else:" + "Encontramos una fila de pie de página en nuestra lista que queremos evitar. Probemos algo diferente:" ] }, { @@ -755,16 +755,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Looks like we found something that worked!" + "¡Parece que encontramos algo que funcionó!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Loop it All Together\n", + "## Unir todo en un bucle\n", "\n", - "Now that we've seen how to get the data we want from one row, as well as filter out the rows we don't want, let's put it all together into a loop." + "Ahora que hemos visto cómo obtener los datos que queremos de una fila y filtrar las filas que no necesitamos, vamos a unirlo todo en un bucle." ] }, { @@ -811,7 +811,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let's take a look at what we have in `members`." + "Echemos un vistazo a lo que tenemos en \"miembros\"." ] }, { @@ -827,37 +827,37 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 🥊 Challenge: Get `href` elements pointing to members' bills \n", + "## 🥊 Desafío: Obtener elementos `href` que apunten a los proyectos de ley de los miembros\n", "\n", - "The code above retrieves information on: \n", + "El código anterior recupera información sobre:\n", "\n", - "- the senator's name,\n", - "- their district number,\n", - "- and their party.\n", + "- el nombre del senador,\n", + "- su número de distrito,\n", + "- y su partido.\n", "\n", - "We now want to retrieve the URL for each senator's list of bills. Each URL will follow a specific format. \n", + "Ahora queremos recuperar la URL de la lista de proyectos de ley de cada senador. Cada URL seguirá un formato específico.\n", "\n", - "The format for the list of bills for a given senator is:\n", + "El formato de la lista de proyectos de ley de un senador determinado es:\n", "\n", "`http://www.ilga.gov/senate/SenatorBills.asp?GA=98&MemberID=[MEMBER_ID]&Primary=True`\n", "\n", - "to get something like:\n", + "para obtener algo como:\n", "\n", "`http://www.ilga.gov/senate/SenatorBills.asp?MemberID=1911&GA=98&Primary=True`\n", "\n", - "in which `MEMBER_ID=1911`. \n", + "donde `MEMBER_ID=1911`.\n", "\n", - "You should be able to see that, unfortunately, `MEMBER_ID` is not currently something pulled out in our scraping code.\n", + "Deberías poder ver que, lamentablemente, `MEMBER_ID` no se extrae actualmente en nuestro código de extracción.\n", "\n", - "Your initial task is to modify the code above so that we also **retrieve the full URL which points to the corresponding page of primary-sponsored bills**, for each member, and return it along with their name, district, and party.\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", - "Tips: \n", + "Consejos:\n", "\n", - "* To do this, you will want to get the appropriate anchor element (``) in each legislator's row of the table. You can again use the `.select()` method on the `row` object in the loop to do this — similar to the command that finds all of the `td.detail` cells in the row. Remember that we only want the link to the legislator's bills, not the committees or the legislator's profile page.\n", - "* The anchor elements' HTML will look like `Bills`. The string in the `href` attribute contains the **relative** link we are after. You can access an attribute of a BeatifulSoup `Tag` object the same way you access a Python dictionary: `anchor['attributeName']`. See the documentation for more details.\n", - "* There are a _lot_ of different ways to use BeautifulSoup to get things done. whatever you need to do to pull the `href` out is fine.\n", + "* Para ello, deberá obtener el elemento de anclaje correspondiente (``) 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 `Proyectos de ley`. 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 documentación para obtener más detalles.\n", + "* Hay muchas maneras diferentes de usar BeautifulSoup. Puedes usar cualquier método para extraer el `href`.\n", "\n", - "The code has been partially filled out for you. Fill it in where it says `#YOUR CODE HERE`. Save the path into an object called `full_path`." + "El código se ha completado parcialmente. Complétalo donde dice `#TU CÓDIGO AQUÍ`. Guarda la ruta en un objeto llamado `full_path`." ] }, { @@ -918,9 +918,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 🥊 Challenge: Modularize Your Code\n", + "## 🥊 Desafío: Modulariza tu código\n", "\n", - "Turn the code above into a function that accepts a URL, scrapes the URL for its senators, and returns a list of tuples containing information about each senator. " + "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. " ] }, { @@ -954,21 +954,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 🥊 Take-home Challenge: Writing a Scraper Function\n", + "## 🥊 Desafío práctico: Escribir una función de scraping\n", "\n", - "We want to scrape the webpages corresponding to bills sponsored by each bills.\n", + "Queremos scraping las páginas web correspondientes a los proyectos de ley patrocinados por cada proyecto de ley.\n", "\n", - "Write a function called `get_bills(url)` to parse a given bills URL. This will involve:\n", + "Escribir una función llamada `get_bills(url)` para analizar la URL de un proyecto de ley. Esto implica:\n", "\n", - " - requesting the URL using the `requests` library\n", - " - using the features of the `BeautifulSoup` library to find all of the `` elements with the class `billlist`\n", - " - return a _list_ of tuples, each with:\n", - " - description (2nd column)\n", - " - chamber (S or H) (3rd column)\n", - " - the last action (4th column)\n", - " - the last action date (5th column)\n", - " \n", - "This function has been partially completed. Fill in the rest." + "- Solicitar la URL mediante la biblioteca `requests`\n", + "- Usar las funciones de la biblioteca `BeautifulSoup` para encontrar todos los elementos `` 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", + "Esta función se ha completado parcialmente. Complete el resto." ] }, { @@ -986,11 +986,11 @@ " bills = []\n", " for row in rows:\n", " # YOUR CODE HERE\n", - " bill_id =\n", - " description =\n", - " chamber =\n", - " last_action =\n", - " last_action_date =\n", + " #bill_id =\n", + " #description =\n", + " #chamber =\n", + " #last_action =\n", + " #last_action_date =\n", " bill = (bill_id, description, chamber, last_action, last_action_date)\n", " bills.append(bill)\n", " return bills" @@ -1013,11 +1013,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Scrape All Bills\n", + "### Extraer todos los proyectos de ley\n", "\n", - "Finally, create a dictionary `bills_dict` which maps a district number (the key) onto a list of bills (the value) coming from that district. You can do this by looping over all of the senate members in `members_dict` and calling `get_bills()` for each of their associated bill URLs.\n", + "Finalmente, cree un diccionario `bills_dict` que asigne un número de distrito (la clave) a una lista de proyectos de ley (el valor) provenientes de ese distrito. Puede hacerlo recorriendo en bucle todos los miembros del senado en `members_dict` y llamando a `get_bills()` para cada una de las URL de sus proyectos de ley asociados.\n", "\n", - "**NOTE:** please call the function `time.sleep(1)` for each iteration of the loop, so that we don't destroy the state's web site." + "**NOTA:** Por favor, llame a la función `time.sleep(1)` en cada iteración del bucle para no destruir el sitio web del estado." ] }, {