Last modified: Aug 31, 2026

BeautifulSoup br: Handle Line Breaks Easily

Web scraping often involves messy HTML. The <br> tag is a common culprit. It breaks text into lines, which can ruin your data extraction.

This guide focuses on the BeautifulSoup br tag. You will learn how to find, replace, and clean these tags. We will use simple examples to make it clear.

By the end, you will handle line breaks like a pro. Your scraped data will be clean and readable. Let's dive in.

What is the br Tag in HTML?

The <br> tag stands for line break. It is an empty element. It forces content to start on a new line. It has no closing tag.

In HTML, it looks like this: <br>. Sometimes you see it as <br/>. Both are valid in HTML5.

This tag is often used in addresses, poems, or formatted text. But it can be a headache when you are parsing data. It splits strings into fragments, making extraction tricky.

For example, an address might look like this in HTML:

<p>123 Main St.<br>New York, NY 10001</p>

When you get the text, you might get "123 Main St.New York, NY 10001". That is not useful. You need to handle the <br> tag to separate this properly.

How to Find br Tags with BeautifulSoup

Finding these tags is straightforward. Use the find_all() method. It returns a list of all matching tags.

Here is a simple example. We will parse a string with multiple line breaks.

from bs4 import BeautifulSoup

html_doc = """
<p>Line one<br>Line two<br>Line three</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Find all br tags
br_tags = soup.find_all('br')
print(f"Found {len(br_tags)} br tags")
for br in br_tags:
    print(br)

This code finds all <br> tags. The output shows each tag found. This is the first step to managing them.

Found 2 br tags
<br/>
<br/>

You can also use find() to get the first one. This is useful if you only need the first occurrence.

Understanding how to find them is key. Now, let's see how to replace them with newlines.

Replacing br with Newlines

The most common task is converting <br> into newline characters. This makes text readable. Use the replace_with() method.

This method replaces a tag with another string or tag. We can replace the tag with a newline character \n.

Here is how it works:

from bs4 import BeautifulSoup

html_doc = """
<p>First line<br>Second line<br>Third line</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Find all br tags and replace with newline
for br in soup.find_all('br'):
    br.replace_with('\n')

# Get the text
text = soup.get_text()
print(text)

This loop replaces every <br> with a newline. The get_text() method then extracts the text. The output is clean and separated.

First line
Second line
Third line

This is a simple and effective method. It works for most cases. But what if you have multiple <br> tags in a row?

Handling Multiple Consecutive br Tags

Sometimes HTML has multiple <br> tags together. This creates blank lines. You might want to remove these extra lines.

For example, <br><br> creates a blank line. You can replace each with a newline. Then you can clean up the extra newlines.

Here is a robust approach. We replace all <br> tags first. Then we remove duplicate newlines.

from bs4 import BeautifulSoup
import re

html_doc = """
<p>Start<br><br><br>End</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Replace all br tags with newline
for br in soup.find_all('br'):
    br.replace_with('\n')

# Get text and clean up extra newlines
text = soup.get_text()
cleaned_text = re.sub(r'\n+', '\n', text)
print(cleaned_text)

We use the re module to clean up. The regex \n+ matches one or more newlines. We replace them with a single newline. This gives a clean output.

Start
End

This technique is very useful. It ensures your data is not cluttered with blank lines. It makes your extracted text much cleaner.

Removing br Tags Completely

Sometimes you don't want newlines at all. You want to remove the <br> tag entirely. This joins the text together.

You can do this by replacing the tag with an empty string. Use replace_with("").

Here is an example:

from bs4 import BeautifulSoup

html_doc = """
<p>Hello<br>World</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Remove all br tags
for br in soup.find_all('br'):
    br.replace_with('')

text = soup.get_text()
print(text)

This code removes the <br> tags. The result is a single string "HelloWorld". This is useful when you want to join text without spaces.

HelloWorld

This method is perfect for specific use cases. For example, when you are extracting data from a table cell. You might not want any line breaks.

This gives you full control over your data. You decide what happens to line breaks.

Using the get_text() Method with Separators

The get_text() method has a parameter called separator. This is a powerful feature. It lets you define how to join text fragments.

You can use the separator to handle <br> tags indirectly. However, it does not specifically target <br>. It adds a separator between all text nodes.

Here is an example:

from bs4 import BeautifulSoup

html_doc = """
<p>Hello<br>World<br>Again</p>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Get text with a separator
text = soup.get_text(separator=' | ')
print(text)

This adds a pipe separator between text nodes. But notice it also adds it where there are no <br> tags. This can be too broad for some tasks.

Hello | World | Again

This method is not the best for <br> handling. It is better to use replace_with() for precise control. But it is good to know it exists.

For accurate <br> handling, stick with the replace method. It gives you the exact output you need.

Working with Nested br Tags

Sometimes <br> tags are nested inside other elements. Like a <div> or a <span>. The methods we discussed work the same way.

BeautifulSoup traverses the entire tree. It finds all <br> tags, no matter how deep they are. This is a major advantage.

Here is an example with nested tags:

from bs4 import BeautifulSoup

html_doc = """
<div>
    <p>First part<br>Second part</p>
    <span>Third part<br>Fourth part</span>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Replace all br tags
for br in soup.find_all('br'):
    br.replace_with('\n')

text = soup.get_text()
print(text)

This code handles all <br> tags in the document. It does not matter if they are in a <p> or a <span>. The result is clean text.

First part
Second part
Third part
Fourth part

This is powerful. It shows that BeautifulSoup handles complex HTML structures easily. You don't need to write complex logic.

This is a key reason why BeautifulSoup is so popular. It simplifies the process of parsing HTML.

Real-World Example: Scraping an Address

Let's put this into practice. Imagine you are scraping a website with addresses. The addresses use <br> tags to separate lines.

Here is a typical HTML snippet:

<div class="address">
    123 Main Street<br>
    Suite 400<br>
    New York, NY 10001
</div>

We want to extract this as a clean, multi-line address. Here is the code to do it:

from bs4 import BeautifulSoup

html_doc = """
<div class="address">
    123 Main Street<br>
    Suite 400<br>
    New York, NY 10001
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Find the address div
address_div = soup.find('div', class_='address')

# Replace br tags with newlines
for br in address_div.find_all('br'):
    br.replace_with('\n')

# Get the text and strip extra whitespace
address = address_div.get_text(strip=True)
print(address)

We first find the div with the class "address". Then we replace all <br> tags. The strip=True parameter removes leading and trailing whitespace.

123 Main Street
Suite 400
New York, NY 10001

This is a clean, usable address. You can now store it in a database or use it in your application. This is a very common scraping task.

This example shows the practical use of BeautifulSoup br handling. It makes your data extraction reliable.

Using CSS Selectors to Find br Tags

You can also use CSS selectors with select(). This is another way to find <br> tags. It is useful for more specific queries.

For example, you might want to find all <br> tags inside a specific div. Here is how you do it:

from bs4 import BeautifulSoup

html_doc = """
<div id="content">
    <p>One<br>Two</p>
</div>
<div id="footer">
    <p>Three<br>Four</p>
</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')

# Find br tags only in the content div
br_tags = soup.select('#content br')
print(f"Found {len(br_tags)} br tags in #content")
for br in br_tags:
    print(br)

This uses a CSS selector to target specific <br> tags. It is a precise way to filter your search. This is great for complex documents.

Found 1 br tags in #content
<br/>

This gives you more control. You can target exactly which <br> tags to modify. This is a more advanced technique.

It is a good skill to have. It complements the find_all() method. You can choose the best tool for your task.

Performance Considerations

Handling <br> tags is fast. The replace_with() method is efficient. It does not slow down your scraper.

However, if you have a huge document with thousands of tags, be mindful. The loop might take a bit of time. But it is still very fast.

You can optimize by using list comprehension. But it is not necessary for most tasks. The simple loop is usually enough.

Here is a slightly faster way using a list comprehension:

from bs4 import BeautifulSoup

html_doc = "<p>A<br>B<br>C</p>"
soup = BeautifulSoup(html_doc, 'html.parser')

# Using list comprehension
[br.replace_with('\n') for br in soup.find_all('br')]

print(soup.get_text())

This is a one-liner. It is concise and fast. But for readability, a regular loop is often better.

Performance is rarely an issue here. Focus on writing clear code. Your scraper will be fast enough.

Common Mistakes to Avoid

There are a few common mistakes beginners make. Let's review them to help you avoid them.

Mistake 1: Forgetting to assign the result of replace_with(). This method modifies the tree in place. It does not return a new tag. So you don't need to assign it.

Mistake 2: Using get_text() before replacing. If you extract text first, you lose the tags. You cannot replace them afterward.

Mistake 3: Not handling multiple <br> tags. This can leave extra newlines in your data. Use the re.sub() method to clean them up.

Here is an example of a common error:

from bs4 import BeautifulSoup

html_doc = "<p>A<br>B</p>"
soup = BeautifulSoup(html_doc, 'html.parser')

# Wrong way: getting text before replacing
text = soup.get_text()
print(text)  # Output: AB

# This does not work because br is gone
for br in soup.find_all('br'):
    br.replace_with('\n')

print(text)  # Still prints AB

This shows the wrong order of operations. Always replace first, then extract text. This is a crucial step.

Avoid these mistakes to save time. Your code will be more reliable and easier to debug.

Advanced: Using BeautifulSoup with Other Tools

You can combine <br> handling with other tools. For example, you might use requests to fetch a page. Then you parse it with BeautifulSoup.

Here is a complete example:

import requests
from bs4 import BeautifulSoup

# Fetch a webpage
url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

# Replace all br tags
for br in soup.find_all('br'):
    br.replace_with('\n')

# Extract text
text = soup.get_text()
print(text[:200])  # Print first 200 characters

This is a full workflow. It fetches a page and cleans it. This is a common pattern in web scraping.

You can also use this with other libraries like pandas for data analysis. The clean text is easier to process.

This shows how BeautifulSoup br handling fits into a larger pipeline. It is a small but important part.

Alternatives to Manual br Handling

There are other ways to handle line breaks. Some parsers have built-in options. But BeautifulSoup gives you full control.

For example, you could use html.parser directly. But it is more complex. BeautifulSoup is much easier.

You can also use lxml as a parser. It is faster but has a steeper learning curve. For most users, BeautifulSoup is the best choice.

If you are comparing tools, check out our guide on BeautifulSoup vs Scrapy. It will help you choose the right tool for your project.

For a deeper dive into extracting content, read about extracting the body. It is a related and useful skill.

And if you are setting up your environment, our guide on installing BeautifulSoup with Anaconda can help.

Conclusion

Handling <br> tags is a vital skill for web scraping. It ensures your data is clean and usable. We have covered all the essential methods.

You learned how to find, replace, and remove <br> tags. You also learned how to clean up extra newlines. And you saw real-world examples.

Remember the key steps. First, find all <br> tags with find_all(). Then use replace_with() to change them. Finally, use get_text() to extract the text.

This process is fast and reliable. It will save you a lot of time and frustration. Your scraped data will be much cleaner.

Now you are ready to handle any <br> tag that comes your way. Happy scraping!