check if tag contains attribute

21 views
Skip to first unread message

Milan Hauth

unread,
Dec 7, 2021, 11:12:13 AM12/7/21
to beautifulsoup
im surprised that tag.__contains__ is not working
to test if tag contains a certain attribute

```py
import bs4
soup = bs4.BeautifulSoup("""<a href="#">x</a>""")
tag = soup.find("a")

# check if tag contains attribute
"href" in tag
tag.__contains__("href")
# actual: False
# expected: True

# workaround
attribute = tag.get("href")
attribute != None # True
```

facelessuser

unread,
Dec 7, 2021, 11:18:16 AM12/7/21
to beautifulsoup

What you are doing is not supported. The tag object does not implement this behavior.

You can do this though:

import bs4
soup = bs4.BeautifulSoup("""<a href="#">x</a>""")
tag = soup.find("a")

# check if tag contains attribute

print("href" in tag.attrs)

leonardr

unread,
Dec 7, 2021, 11:52:53 AM12/7/21
to beautifulsoup
The reason this behavior isn't implemented is that Tag.__contains__ checks whether the argument is a child of the tag, rather than an attribute.

import bs4 soup = bs4.BeautifulSoup("""<a href="#">x</a>""") 'x' in soup.a # True

Here's the implementation:

    def __contains__(self, x):
        return x in self.contents


The Tag class needs to act both as a dictionary (of attributes) and as a list (of child elements). For any given piece of syntactic sugar, I could only make it work one way or the other. I generally made Tag work as a list, with exceptions like __setitem__ and __delitem__ where you're clearly treating the object as a dictionary.

Tag.attrs is a real dictionary, so as facelessuer says, anything you want to do to a tag's attributes can be done there.

Leonard
Reply all
Reply to author
Forward
0 new messages