{ "cells": [ { "cell_type": "markdown", "id": "0deef6c7", "metadata": {}, "source": [ "# scraping with `bs4`\n", "Now we have a sense of the `bs4` syntax, and a list of the html elements that we want to scrape from the `https://translegislation.com/` website, we can write some code that extracts those elements and saves them in a structured format, like a spreadsheet.\n", "\n", "Before doing all that, we will import the libraries we need and create our `soup` object (that holds our website content). " ] }, { "cell_type": "code", "execution_count": 1, "id": "2419132e", "metadata": {}, "outputs": [], "source": [ "import requests\n", "from bs4 import BeautifulSoup\n", "import lxml" ] }, { "cell_type": "code", "execution_count": 2, "id": "ea364855", "metadata": {}, "outputs": [], "source": [ "site = requests.get('https://translegislation.com/bills/2023/passed')\n", "html_code = site.content\n", "soup = BeautifulSoup(html_code, 'lxml')" ] }, { "cell_type": "markdown", "id": "6dcf736e", "metadata": {}, "source": [ "Now that we have loaded up the necessary libraries and soup object, we can extract the data we want. Like all good programmers, we will break our task up into a number of steps:\n", "1. isolate the bill_cards data from the rest of the webpage\n", "2. pick out the information we want from the bill cards\n", "3. process the information from the bill cards into the format we want\n", "4. save that information to a csv file\n", "\n", "Each of these steps itself contains smaller steps, which we will figure out as we go along. Let's begin with the first step" ] }, { "cell_type": "markdown", "id": "94726fbd", "metadata": {}, "source": [ "## step 1: isolate the bill cards data from the rest of the page\n", "First, create a new object called `bill_cards`, which enables us to narrow down the parts of the website that we want to scrape." ] }, { "cell_type": "code", "execution_count": null, "id": "87f41013", "metadata": {}, "outputs": [], "source": [ "# to get the element and class for the cards, use the inspector\n", "\n", "bill_cards = soup.find_all('div', class_ ='css-4rck61')" ] }, { "cell_type": "code", "execution_count": 36, "id": "126f6ccc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[

AL HB261

SPORTS
PASSED

Relating to two-year and four-year public institutions of higher education; to amend Section 16-1-52, Code of Alabama 1975, to prohibit a biological male from participating on an athletic team or sport designated for females; to prohibit a biological female from participating on an athletic team or sport designated for males; to prohibit adverse action against a public K-12 school or public two-year or four-year institution of higher education for complying with this act; to prohibit adverse action or retaliation against a student who reports a violation of this act; and to provide a remedy for any student who suffers harm or is directy deprived of an athletic opportunity as a result of a violation of this act.

,\n", "

AL SB261

OTHER
PASSED

Relating to public contracts; to prohibit governmental entities from entering into certain contracts with companies that boycott businesses because the business engages in certain sectors or does not meet certain environmental or corporate governance standards or does not facilitate certain activities; to provide that no company in the state shall be required by a governmental entity, nor penalized by a governmental entity for declining to engage in economic boycotts or other actions that further social, political, or ideological interests; to require the Attorney General to take actions to prevent federal laws or actions from penalizing, inflicting harm on, limiting commercial relations with, or changing or limiting the activities of companies or residents of the state based on the furtherance of economic boycott criteria; and to authorize the Attorney General to investigate and enforce this act; and to provide definitions.

,\n", "

AR HB1156

BATHROOM
PASSED

Concerning A Public School District Or Open-enrollment Public Charter School Policy Relating To A Public School Student's Sex.

]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# checking our list by printing just the first three items\n", "\n", "bill_cards[:3]" ] }, { "cell_type": "markdown", "id": "726926e3", "metadata": {}, "source": [ "# step 2: pick out information from each bill card\n", "Everything that we need is contained within the object, `bill_cards`. Now, we use the inspector to get the elements and attributes for the items within `bill_cards`, like:\n", "- bill title\n", "- bill category\n", "- bill description\n", "- link to bill" ] }, { "cell_type": "code", "execution_count": 4, "id": "db345235", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'AL HB261'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get bill title\n", "\n", "soup.h3.text" ] }, { "cell_type": "code", "execution_count": 5, "id": "98436908", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Relating to two-year and four-year public institutions of higher education; to amend Section 16-1-52, Code of Alabama 1975, to prohibit a biological male from participating on an athletic team or sport designated for females; to prohibit a biological female from participating on an athletic team or sport designated for males; to prohibit adverse action against a public K-12 school or public two-year or four-year institution of higher education for complying with this act; to prohibit adverse action or retaliation against a student who reports a violation of this act; and to provide a remedy for any student who suffers harm or is directy deprived of an athletic opportunity as a result of a violation of this act.'" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get bill caption\n", "\n", "soup.find('div', class_ ='css-4rck61').h2.text" ] }, { "cell_type": "code", "execution_count": 6, "id": "6cd4bbdc", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SPORTS'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get bill category\n", "\n", "soup.find('div', class_='css-4rck61').span.text" ] }, { "cell_type": "code", "execution_count": 7, "id": "72446853", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get bill description (if any)\n", "\n", "soup.find('div', class_ ='css-4rck61').p.text" ] }, { "cell_type": "code", "execution_count": 8, "id": "ab9104da", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'/bills/2023/AL/HB261'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get link extension\n", "\n", "soup.find('div', class_ ='css-4rck61').a['href']" ] }, { "cell_type": "markdown", "id": "519807f5", "metadata": {}, "source": [ "Because we now have the code for the relevant HTML elements, we will now extract them and save them. To do that, we will write a loop that goes through each item in our `bill_cards`, gets the relevant HTML element, and saves it to a variable. Our loop will goes through each bill card, one by one, and pull out the title, description, category, and link. \n", "\n", "*Note: loops are ways of programmatically going through a dataset and doing something to each item in the dataset, like extracting it. Read more about [loops in the intro workshop](../intro/loops.ipynb)*\n", "\n", "Below, I will be explaining the code logic in by writing it out in \"pseudo-code\" in the comments. Pseudo-code is a cross between normal language and programming language, that is useful for explaining and working out how to write the actual programming code in Python." ] }, { "cell_type": "code", "execution_count": 46, "id": "46bbc6ee", "metadata": {}, "outputs": [], "source": [ "# for each card in bill_cards:\n", "# get the title in h3.text\n", "# get the caption in h2.text\n", "# get the category in span.text\n", "# get the descriptoin in p.text (if any)\n", "# get the link in a tag, class \"chakra-link\"" ] }, { "cell_type": "code", "execution_count": 60, "id": "95a1c269", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AL HB261\n", "Relating to two-year and four-year public institutions of higher education; to amend Section 16-1-52, Code of Alabama 1975, to prohibit a biological male from participating on an athletic team or sport designated for females; to prohibit a biological female from participating on an athletic team or sport designated for males; to prohibit adverse action against a public K-12 school or public two-year or four-year institution of higher education for complying with this act; to prohibit adverse action or retaliation against a student who reports a violation of this act; and to provide a remedy for any student who suffers harm or is directy deprived of an athletic opportunity as a result of a violation of this act.\n", "SPORTS\n", "\n", "/bills/2023/AL/HB261\n", "AL SB261\n", "Relating to public contracts; to prohibit governmental entities from entering into certain contracts with companies that boycott businesses because the business engages in certain sectors or does not meet certain environmental or corporate governance standards or does not facilitate certain activities; to provide that no company in the state shall be required by a governmental entity, nor penalized by a governmental entity for declining to engage in economic boycotts or other actions that further social, political, or ideological interests; to require the Attorney General to take actions to prevent federal laws or actions from penalizing, inflicting harm on, limiting commercial relations with, or changing or limiting the activities of companies or residents of the state based on the furtherance of economic boycott criteria; and to authorize the Attorney General to investigate and enforce this act; and to provide definitions.\n", "OTHER\n", "\n", "/bills/2023/AL/SB261\n", "AR HB1156\n", "Concerning A Public School District Or Open-enrollment Public Charter School Policy Relating To A Public School Student's Sex.\n", "BATHROOM\n", "\n", "/bills/2023/AR/HB1156\n", "AR HB1468\n", "To Create The Given Name Act; And To Prohibit Requiring Employees Of Public Schools And State-supported Institutions Of Higher Education To Use A Person's Preferred Pronoun, Name, Or Title Without Parental Consent.\n", "EDUCATION\n", "\n", "/bills/2023/AR/HB1468\n", "AR HB1615\n", "To Create The Conscience Protection Act; And To Amend The Religious Freedom Restoration Act.\n", "OTHER\n", "\n", "/bills/2023/AR/HB1615\n", "AR SB125\n", "Concerning Free Speech Rights At State-supported Institutions Of Higher Education.\n", "EDUCATION\n", "\n", "/bills/2023/AR/SB125\n", "AR SB199\n", "Concerning Medical Malpractice And Gender Transition In Minors; And To Create The Protecting Minors From Medical Malpractice Act Of 2023.\n", "HEALTHCARE\n", "\n", "/bills/2023/AR/SB199\n", "AR SB270\n", "To Amend The Criminal Offense Of Sexual Indecency With A Child.\n", "BATHROOM\n", "\n", "/bills/2023/AR/SB270\n", "AR SB294\n", "To Create The Learns Act; To Amend Various Provisions Of The Arkansas Code As They Relate To Early Childhood Through Grade Twelve Education In The State Of Arkansas; And To Declare An Emergency.\n", "BATHROOM\n", "\n", "/bills/2023/AR/SB294\n", "AR SB43\n", "To Add Certain Restrictions To An Adult-oriented Performance; And To Define An Adult-oriented Performance.\n", "OTHER\n", "\n", "/bills/2023/AR/SB43\n" ] } ], "source": [ "# runs the loop on the bill cards\n", "\n", "for item in bill_cards[:10]: # only the first ten cards, just to check if it is working\n", " print(item.h3.text) # title\n", " print(item.h2.text) # caption\n", " print(item.span.text) # category\n", " print(item.p.text) # description (if any)\n", " print(item.a['href']) # add https://translegislation.com/bills/2023/US" ] }, { "cell_type": "markdown", "id": "5b38a118", "metadata": {}, "source": [ "It worked! Now, the next step is to assign a variable for each item. This allows us to save the data to the variable name, and later, to add it to a list." ] }, { "cell_type": "code", "execution_count": 61, "id": "912fe161", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AL HB261 Relating to two-year and four-year public institutions of higher education; to amend Section 16-1-52, Code of Alabama 1975, to prohibit a biological male from participating on an athletic team or sport designated for females; to prohibit a biological female from participating on an athletic team or sport designated for males; to prohibit adverse action against a public K-12 school or public two-year or four-year institution of higher education for complying with this act; to prohibit adverse action or retaliation against a student who reports a violation of this act; and to provide a remedy for any student who suffers harm or is directy deprived of an athletic opportunity as a result of a violation of this act. SPORTS https://translegislation.com/bills/2023/passed/bills/2023/AL/HB261\n", "AL SB261 Relating to public contracts; to prohibit governmental entities from entering into certain contracts with companies that boycott businesses because the business engages in certain sectors or does not meet certain environmental or corporate governance standards or does not facilitate certain activities; to provide that no company in the state shall be required by a governmental entity, nor penalized by a governmental entity for declining to engage in economic boycotts or other actions that further social, political, or ideological interests; to require the Attorney General to take actions to prevent federal laws or actions from penalizing, inflicting harm on, limiting commercial relations with, or changing or limiting the activities of companies or residents of the state based on the furtherance of economic boycott criteria; and to authorize the Attorney General to investigate and enforce this act; and to provide definitions. OTHER https://translegislation.com/bills/2023/passed/bills/2023/AL/SB261\n", "AR HB1156 Concerning A Public School District Or Open-enrollment Public Charter School Policy Relating To A Public School Student's Sex. BATHROOM https://translegislation.com/bills/2023/passed/bills/2023/AR/HB1156\n", "AR HB1468 To Create The Given Name Act; And To Prohibit Requiring Employees Of Public Schools And State-supported Institutions Of Higher Education To Use A Person's Preferred Pronoun, Name, Or Title Without Parental Consent. EDUCATION https://translegislation.com/bills/2023/passed/bills/2023/AR/HB1468\n", "AR HB1615 To Create The Conscience Protection Act; And To Amend The Religious Freedom Restoration Act. OTHER https://translegislation.com/bills/2023/passed/bills/2023/AR/HB1615\n", "AR SB125 Concerning Free Speech Rights At State-supported Institutions Of Higher Education. EDUCATION https://translegislation.com/bills/2023/passed/bills/2023/AR/SB125\n", "AR SB199 Concerning Medical Malpractice And Gender Transition In Minors; And To Create The Protecting Minors From Medical Malpractice Act Of 2023. HEALTHCARE https://translegislation.com/bills/2023/passed/bills/2023/AR/SB199\n", "AR SB270 To Amend The Criminal Offense Of Sexual Indecency With A Child. BATHROOM https://translegislation.com/bills/2023/passed/bills/2023/AR/SB270\n", "AR SB294 To Create The Learns Act; To Amend Various Provisions Of The Arkansas Code As They Relate To Early Childhood Through Grade Twelve Education In The State Of Arkansas; And To Declare An Emergency. BATHROOM https://translegislation.com/bills/2023/passed/bills/2023/AR/SB294\n", "AR SB43 To Add Certain Restrictions To An Adult-oriented Performance; And To Define An Adult-oriented Performance. OTHER https://translegislation.com/bills/2023/passed/bills/2023/AR/SB43\n" ] } ], "source": [ "for item in bill_cards[:10]:\n", " title = item.h3.text\n", " caption = item.h2.text\n", " category = item.find('span').text\n", " description = item.p.text\n", " link = 'https://translegislation.com/bills/2023/passed' + item.a['href']\n", " print(title, caption, category, description, link)" ] }, { "cell_type": "markdown", "id": "8e480df5", "metadata": {}, "source": [ "It works! Now let's save it to lists. " ] }, { "cell_type": "code", "execution_count": null, "id": "10e11cb9", "metadata": {}, "outputs": [], "source": [ "# a bunch of empty lists where we will dump our data\n", "titles = []\n", "captions = []\n", "categories = []\n", "descriptions = []\n", "\n", "# our for loop that saves each item we want from the bill_cards\n", "for item in bill_cards:\n", " title = item.h3.text\n", " caption = item.h2.text\n", " category = item.find('span').text\n", " description = item.p.text\n", " \n", " # adding the items to the empty lists\n", " titles.append(title)\n", " captions.append(caption)\n", " categories.append(category)\n", " descriptions.append(description)" ] }, { "cell_type": "markdown", "id": "933f4fc8", "metadata": {}, "source": [ "## step 3: processing information about the bills\n", "Before adding saving our dataset to a spreadsheet, we are going to do a bit more data processing and gathering. This will enable us to make a more robust dataset at the end. Here, we are going to do two things:\n", "\n", "1. split the title column into state and title\n", "2. get the link directly to the bill page on LegiScan\n", "\n", "Like the previous sections, I'm going to use comments to write some pseudo-code that separates out the steps of the larger task. This is good practice for all programmers. " ] }, { "cell_type": "code", "execution_count": 59, "id": "385087f5", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AL HB261\n", "AL SB261\n", "AR HB1156\n", "AR HB1468\n", "AR HB1615\n", "AR SB125\n", "AR SB199\n", "AR SB270\n", "AR SB294\n", "AR SB43\n" ] } ], "source": [ "# first, we will split the bill name into two variables, state and title \n", "# this will make things more clean when we add it to our spreadsheet\n", "\n", "for item in bill_cards[:10]:\n", " state, title = item.h3.text.split(' ')\n", " print(state, title)" ] }, { "cell_type": "code", "execution_count": null, "id": "a9c2b7eb", "metadata": {}, "outputs": [], "source": [ "## now, we will get the link to state bill, in the following steps:\n", "\n", "## first, make a list of URLs:\n", "## then, for each URL, make a soup.\n", "## then, for each soup, get the link to the state bill, called \"extension\"\n", "## then, add the link extension to the root, saving it as \"urls\"\n", "## finally, add the urls to a new list, called \"legiscan links\"" ] }, { "cell_type": "code", "execution_count": 58, "id": "9051983f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "https://translegislation.com//bills/2023/AL/HB261\n", "https://translegislation.com//bills/2023/AL/SB261\n", "https://translegislation.com//bills/2023/AR/HB1156\n", "https://translegislation.com//bills/2023/AR/HB1468\n", "https://translegislation.com//bills/2023/AR/HB1615\n", "https://translegislation.com//bills/2023/AR/SB125\n", "https://translegislation.com//bills/2023/AR/SB199\n", "https://translegislation.com//bills/2023/AR/SB270\n", "https://translegislation.com//bills/2023/AR/SB294\n", "https://translegislation.com//bills/2023/AR/SB43\n" ] } ], "source": [ "for item in bill_cards[:10]:\n", " extension = 'https://translegislation.com/' + item.a['href']\n", " print(extension)" ] }, { "cell_type": "code", "execution_count": 53, "id": "92bd2f85", "metadata": {}, "outputs": [], "source": [ "urls = []\n", "for item in bill_cards:\n", " extension = 'https://translegislation.com/' + item.a['href']\n", " urls.append(extension)" ] }, { "cell_type": "code", "execution_count": 54, "id": "b6d9222e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['https://translegislation.com//bills/2023/AL/HB261',\n", " 'https://translegislation.com//bills/2023/AL/SB261',\n", " 'https://translegislation.com//bills/2023/AR/HB1156',\n", " 'https://translegislation.com//bills/2023/AR/HB1468',\n", " 'https://translegislation.com//bills/2023/AR/HB1615',\n", " 'https://translegislation.com//bills/2023/AR/SB125',\n", " 'https://translegislation.com//bills/2023/AR/SB199',\n", " 'https://translegislation.com//bills/2023/AR/SB270',\n", " 'https://translegislation.com//bills/2023/AR/SB294',\n", " 'https://translegislation.com//bills/2023/AR/SB43']" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "urls[:10]" ] }, { "cell_type": "code", "execution_count": 55, "id": "edd8695f", "metadata": {}, "outputs": [], "source": [ "# making a soup object of *every* page that is linked\n", "# this may take several seconds\n", "\n", "soups = []\n", "for item in urls:\n", " site = requests.get(item)\n", " html_code = site.content\n", " soup = BeautifulSoup(html_code, 'lxml')\n", " soups.append(soup)" ] }, { "cell_type": "code", "execution_count": 27, "id": "e68204d9", "metadata": {}, "outputs": [], "source": [ "legiscan_links = []\n", "for item in soups:\n", " # get the url for state url\n", " anchor_tag = item.find('a', class_='chakra-link css-oga2ct')\n", " link = anchor_tag['href']\n", " legiscan_links.append(link)" ] }, { "cell_type": "markdown", "id": "d12cc727", "metadata": {}, "source": [ "## 3. saving our data to a CSV\n", "This is the final step. First, we will import two libraries for working with tabular data `pandas` and `csv`. \n", "\n", "Then, we will add each of our lists into the \"DataFrame\" (the `pandas` term for a tabular type of object), where they will appear as separate columns. Finally, we will save our DataFrame as a .csv file. " ] }, { "cell_type": "code", "execution_count": 28, "id": "6f35aa77", "metadata": {}, "outputs": [], "source": [ "# importing the necessary libraries\n", "\n", "import pandas as pd\n", "import csv" ] }, { "cell_type": "code", "execution_count": 29, "id": "ad4614dc", "metadata": {}, "outputs": [], "source": [ "# creating empty lists to hold all of our data\n", "\n", "states = []\n", "titles = []\n", "captions = []\n", "categories = []\n", "descriptions = []\n", "\n", "# extracting the data from the bill cards\n", "for item in bill_cards:\n", " state, title = item.h3.text.split(' ') # adding the extra step to split the bill name into state and title items\n", " caption = item.h2.text\n", " category = item.find('span').text\n", " description = item.p.text\n", " \n", " # adding the items to the empty lists\n", " states.append(state)\n", " titles.append(title)\n", " captions.append(caption)\n", " categories.append(category)\n", " descriptions.append(description)\n", " # remember that \"legiscan_links\" is already saved as a list, so we don't have to create it here" ] }, { "cell_type": "code", "execution_count": 30, "id": "65381e18", "metadata": {}, "outputs": [], "source": [ "# creating a dataframe, with separate columns to hold each of our lists\n", "df = pd.DataFrame(\n", " {'state': states,\n", " 'title': titles,\n", " 'caption': captions,\n", " 'category': categories,\n", " 'description': descriptions,\n", " 'legiscan link': legiscan_links\n", " })" ] }, { "cell_type": "code", "execution_count": 31, "id": "6003a39d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
statetitlecaptioncategorydescriptionlegiscan link
0ALHB261Relating to two-year and four-year public inst...SPORTShttps://legiscan.com/AL/text/HB261/id/2817698
1ALSB261Relating to public contracts; to prohibit gove...OTHERhttps://legiscan.com/AL/text/SB261/id/2821857
2ARHB1156Concerning A Public School District Or Open-en...BATHROOMhttps://legiscan.com/AR/text/HB1156/id/2756961
3ARHB1468To Create The Given Name Act; And To Prohibit ...EDUCATIONhttps://legiscan.com/AR/text/HB1468/id/2781770
4ARHB1615To Create The Conscience Protection Act; And T...OTHERhttps://legiscan.com/AR/text/HB1615/id/2781807
\n", "
" ], "text/plain": [ " state title caption category \\\n", "0 AL HB261 Relating to two-year and four-year public inst... SPORTS \n", "1 AL SB261 Relating to public contracts; to prohibit gove... OTHER \n", "2 AR HB1156 Concerning A Public School District Or Open-en... BATHROOM \n", "3 AR HB1468 To Create The Given Name Act; And To Prohibit ... EDUCATION \n", "4 AR HB1615 To Create The Conscience Protection Act; And T... OTHER \n", "\n", " description legiscan link \n", "0 https://legiscan.com/AL/text/HB261/id/2817698 \n", "1 https://legiscan.com/AL/text/SB261/id/2821857 \n", "2 https://legiscan.com/AR/text/HB1156/id/2756961 \n", "3 https://legiscan.com/AR/text/HB1468/id/2781770 \n", "4 https://legiscan.com/AR/text/HB1615/id/2781807 " ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# checking the first 5 lines of the dataframe\n", "\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 32, "id": "6f63d6e8", "metadata": {}, "outputs": [], "source": [ "# saving the dataframe as a csv file\n", "\n", "df.to_csv('bill_data.csv')" ] }, { "cell_type": "markdown", "id": "e367833f", "metadata": {}, "source": [ "And that's all! If you are on google colab, check your sidebar under the \"files\" tab. You should see a .csv file containing the data we've scraped from the `translegislation.com` website. Well done!\n", "\n", "In the next section, we will look at an API method for getting legislative data, and save that data to a CSV file. In that activity, you'll see the differences in handling data acrossn web scraping and API methods." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.0" } }, "nbformat": 4, "nbformat_minor": 5 }