This guide shows you how to extract data from websites using Python and Beautiful Soup, a library that parses HTML and makes it easy to navigate and search the page structure. You’ll learn how to fetch a page, locate specific elements, and save the data you need—skills useful for gathering product details, news headlines, or any public information. No prior experience with web scraping is required, but you should have basic Python knowledge and a code editor installed.
What You’ll Need
- Python 3.7 or newer installed on your computer
- pip (Python’s package installer, usually included with Python)
- A code editor or IDE (like VS Code, PyCharm, or even a simple text editor)
- Internet connection to install packages and fetch web pages
Step-by-Step
- Install the required libraries. Open your terminal or command prompt and run:
pip install requests beautifulsoup4
This installsrequests(to download web pages) andbeautifulsoup4(to parse HTML). - Create a new Python script. In your editor, create a file named
scraper.py. This will hold all your code. - Import the libraries. At the top of your script, add:
import requests
from bs4 import BeautifulSoup - Fetch the webpage. Use
requests.get()to download the page content. For example:url = 'https://example.com'
response = requests.get(url)
Always check that the request succeeded by verifyingresponse.status_code == 200. If not, handle the error (see Troubleshooting). - Parse the HTML. Pass the response text to BeautifulSoup:
soup = BeautifulSoup(response.text, 'html.parser')
Thehtml.parseris built into Python, so no extra install is needed. - Find elements. Use methods like
find()(returns the first match) orfind_all()(returns a list of all matches). For example, to get all headings:headings = soup.find_all('h2')
To find by class or id, use theclass_andidparameters:title = soup.find('h1', id='main-title')items = soup.find_all('div', class_='product') - Extract text and attributes. Use
.textor.get_text()to get the visible text inside an element. To get an attribute likehreforsrc, useelement['href']orelement.get('href'). - Loop through multiple elements. If you’re scraping a list, iterate over the results:
for item in items:
name = item.find('h2').text
price = item.find('span', class_='price').text
print(name, price) - Handle missing data gracefully. Not every element may exist. Use
ifchecks or theget_text()method with a default. For example:title = item.find('h2')
if title:
print(title.text)
else:
print('No title') - Save the data. Write the extracted data to a CSV file using Python’s
csvmodule, or to a JSON file withjson.dump(). This makes your scraping useful for later analysis. - Respect the website. Always check the site’s
robots.txt(e.g.,https://example.com/robots.txt) to see if scraping is allowed. Also, add a delay between requests usingtime.sleep(1)to avoid overloading the server.
Common Mistakes
- Using the wrong parser. The default
html.parseris fine for most pages, but if you encounter weird parsing issues, trylxml(install withpip install lxml) orhtml5lib. - Not checking the response status. A page might return a 404 or 403 error, and your script will fail. Always check
response.status_codebefore parsing. - Assuming elements exist. Websites change, and an element you expect might be missing. Use conditional checks to avoid
AttributeError. - Scraping JavaScript-rendered content. Beautiful Soup only sees the initial HTML. If the content is loaded dynamically, you’ll need Selenium or Playwright (see Troubleshooting).
- Ignoring the site’s terms. Some sites explicitly forbid scraping in their terms of service. Always review them and respect rate limits.
Tips
- Use your browser’s developer tools. Right-click on the element you want and select “Inspect” to see its HTML structure. This helps you write precise selectors.
- Start with a small test. Before scraping hundreds of pages, test your script on a single page to ensure it works.
- Use CSS selectors. The
select()method lets you use CSS-like selectors, e.g.,soup.select('div.product > h2'). This can be more concise. - Cache your requests. If you’re developing, save the HTML to a file and parse that instead of hitting the server repeatedly.
- Handle pagination. If the site has multiple pages, look for a “Next” button and loop through it, updating the URL or using the link’s
href.
Troubleshooting
- Request returns 403 Forbidden. The site may be blocking default user agents. Set a custom header:
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
response = requests.get(url, headers=headers) - Content is empty or missing. The data may be loaded via JavaScript. Use a headless browser like Selenium:
pip install selenium
Then usewebdriverto load the page and get the rendered HTML. - Encoding issues. If you see garbled characters, specify the encoding:
response.encoding = 'utf-8'before parsing. - Script crashes due to network errors. Wrap your request in a try-except block and retry after a delay.
- Elements not found. Double-check the class name or id—they are case-sensitive. Use
print(soup.prettify())to see the actual HTML structure.
Frequently Asked Questions
Is web scraping legal?
It depends on the website’s terms of service and local laws. Public data is generally scrapeable, but always check robots.txt and the site’s terms. Avoid scraping personal data or copyrighted content without permission.
Can I scrape sites that require login?
Yes, but it’s more complex. You’ll need to handle sessions and cookies, often using requests.Session() to maintain login state. However, many sites prohibit automated login scraping, so proceed with caution.
How do I scrape data from tables?
Use soup.find('table') to get the table, then iterate over tr (rows) and td or th (cells). Extract text from each cell and store in a list of lists.
What’s the difference between find() and find_all()?
find() returns the first matching element or None if no match. find_all() returns a list of all matches (empty list if none). Use find_all() when you expect multiple elements.
How do I avoid being blocked?
Respect the site’s rate limits by adding delays between requests, rotate user agents, and avoid aggressive scraping patterns. Consider using a proxy if you’re scraping at scale, but always follow ethical practices.
Can I scrape dynamic content with Beautiful Soup alone?
No. Beautiful Soup parses static HTML only. For JavaScript-rendered content, use Selenium, Playwright, or Puppeteer to render the page first, then feed the resulting HTML to Beautiful Soup.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- Fix Unfortunately App Has Stopped: Step-by-Step
- Restart a Frozen Samsung Galaxy A12
- HomePod Stereo Pair with AirPlay 2 from iPhone
- Fix 0x8e5e0247 Error on Windows
- Pixel & Pixel XL No Sound: Solved?
- How to Edit Playlists on iPhone