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?
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.. 😉
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>
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>
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?
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.. 😉
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>
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>