← Back to Python Course | Chapter 13: Data Science & Web | Lesson 11 of 14

Python Web Scraping Basics

Web scraping is having a program read a web page and pick out the pieces you want, like using a highlighter on a newspaper. It saves copying by hand.

What is Web Scraping?

Web scraping means programmatically fetching a page's raw HTML and then parsing that markup to extract the specific data you need, rather than reading it visually in a browser.

This tutorial uses BeautifulSoup for parsing -- install it first with pip install beautifulsoup4.

Example: What is Web Scraping?

python
# pip install beautifulsoup4
from bs4 import BeautifulSoup

html = "<html><body><h1>Title</h1></body></html>"
soup = BeautifulSoup(html, "html.parser")
print(soup.h1.text)

Finding Tags and Titles

BeautifulSoup's .find(tag_name) locates the first matching HTML element anywhere in the parsed document and gives you access to its text and attributes, which is the basic building block for pulling out things like a page's main heading or title.

Example: Finding Tags and Titles

python
from bs4 import BeautifulSoup

html = "<html><head><title>My Page</title></head></html>"
soup = BeautifulSoup(html, "html.parser")
print(soup.find("title").text)  # locates the first <title> element and reads its text

Filtering with Classes

Since real-world pages rely heavily on CSS classes to distinguish elements that share the same tag, .find(tag, class_=name) lets you narrow a search to only elements carrying a specific class -- essential for scraping structured content like article titles or price tags that share a tag name with unrelated elements.

Example: Filtering with Classes

python
from bs4 import BeautifulSoup

html = '<div class="price">$10</div><div>Other</div>'
soup = BeautifulSoup(html, "html.parser")
print(soup.find("div", class_="price").text)  # narrows the search to a specific CSS class

Finding Multiple Elements

.find_all(tag) returns every matching element on the page as a list, rather than stopping at the first match like .find() does.

Use it whenever you need all instances of something -- every link, every list item, every row in a table -- not just one.

Example: Finding Multiple Elements

python
from bs4 import BeautifulSoup

html = "<ul><li>One</li><li>Two</li></ul>"
soup = BeautifulSoup(html, "html.parser")
items = soup.find_all("li")  # returns every matching element, not just the first
print([item.text for item in items])

Extracting Link Attributes

Links live in <a> tags, and the actual destination URL is stored in the tag's href attribute, accessed like a dictionary key: link[href].

Forgetting this and trying to read the link's visible text as if it were the URL is a common scraping mistake.

Example: Extracting Link Attributes

python
from bs4 import BeautifulSoup

html = '<a href="https://example.com">Visit</a>'
soup = BeautifulSoup(html, "html.parser")
link = soup.find("a")
print(link["href"])  # the destination URL lives in the href attribute
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Scraping without checking a site's terms or robots.txt, or sending many requests too quickly.
  2. Calling soup.find(...) and using the result without checking for None, which raises AttributeError.
  3. Using class= in find() instead of class_=, since class is a reserved word and gives SyntaxError.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.