python beautifulsoup new_tag: assign class as an attribute

Question:

I’m new to both python and beautifulsoup, so maybe there is a simple answer I can’t find.

When I call .new_tag('name') I also can assign attributes like .new_tag('a', href='#', id='link1')

But I can’t assign class this way, because it is reserved word. Also I can’t add name this way, because it’s used as keyword for the tag name attribute. I know I can add them later, using tag['class'] for example, but I would like to know, is this the only way to add class to new tag? Or there is a way to do that with a single step?

Asked By: Anton Vernigor

||

Answers:

You are right – class is a python reserved word and cannot be used as a keyword argument because the language parser complains.

There’s a way around this – you can give the function keyword arguments through a dictionary preceded by **.
That way “class” is just another string and wont collide with the reserved word when the python syntax is parsed, but the keyword argument gets passed correctly at runtime.

In your case the workaround should be –

soup.new_tag('a', href='#', id='link1', **{'class':'classname'})

Kind of ugly I know but it works.. 😉

Answered By: itai

You can use the attrs dictionnary:

soup.new_tag("a",attrs={"class": "classname", "href" : "#", "id" : "link1"})

The result will be:

<a class="classname" href="#" id="link1"></a>    
Answered By: Yom

This simple function allows one to bypass the limitation by using klass argument:

from bs4 import BeautifulSoup

def create_tag(name, namespace=None, nsprefix=None, attrs={},
               sourceline=None, sourcepos=None, **kwattrs):
    """It does the same as soup.new_tag(),
    but turns 'klass' attribute into 'class'"""
    newkwattrs = {}
    for key, value in kwattrs.items():
        if key == 'klass':
            key = 'class'
        newkwattrs[key] = value
    soup = BeautifulSoup('', 'html.parser')
    tag = soup.new_tag(name, namespace, nsprefix, attrs, sourceline,
                       sourcepos, **newkwattrs)
    return tag.extract()

Now one is able code like this, for example:

p_tag = create_tag('p', klass='foo')

The result will be:

<p class="foo"></p>
Answered By: Eduardo Bandeira
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.