Zeynel
Zeynel

Reputation: 13525

BeautifulSoup: AttributeError: 'NavigableString' object has no attribute 'name'

Do you know why the first example in BeautifulSoup tutorial http://www.crummy.com/software/BeautifulSoup/documentation.html#QuickStart gives AttributeError: 'NavigableString' object has no attribute 'name'? According to this answer the space characters in the HTML causes the problem. I tried with sources of a few pages and 1 worked the others gave the same error (I removed spaces). Can you explain what does "name" refer to and why this error happens? Thanks.

Upvotes: 41

Views: 91318

Answers (4)

Praveen Kumar
Praveen Kumar

Reputation: 959

This is the latest working code to obtain the name of the tags in soup.

from bs4 import BeautifulSoup, Tag

res = requests.get(url).content
soup = BeautifulSoup(res, 'lxml')

for child in soup.body.children:
    if isinstance(body_child, Tag):
        print(child.name)

Upvotes: 3

Max Malysh
Max Malysh

Reputation: 31615

Just ignore NavigableString objects while iterating through the tree:

from bs4 import BeautifulSoup, NavigableString, Tag

response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

for body_child in soup.body.children:
    if isinstance(body_child, NavigableString):
        continue
    if isinstance(body_child, Tag):
        print(body_child.name)

Upvotes: 41

Tomarinator
Tomarinator

Reputation: 782

You can use try catch to eliminate the cases when Navigable String is being parsed in the loop, like this:

    for j in soup.find_all(...)
        try:
            print j.find(...)
        except NavigableString: 
            pass

Upvotes: 9

MattoTodd
MattoTodd

Reputation: 15209

name will refer to the name of the tag if the object is a Tag object (ie: <html> name = "html")

if you have spaces in your markup in between nodes BeautifulSoup will turn those into NavigableString's. So if you use the index of the contents to grab nodes, you might grab a NavigableString instead of the next Tag.

To avoid this, query for the node you are looking for: Searching the Parse Tree

or if you know the name of the next tag you would like, you can use that name as the property and it will return the first Tag with that name or None if no children with that name exist: Using Tag Names as Members

If you wanna use the contents you have to check the objects you are working with. The error you are getting just means you are trying to access the name property because the code assumes it's a Tag

Upvotes: 34

Related Questions