Ответ 1
first_h1
и second_h1
являются Tag
class экземплярами. Когда вы выполняете my_dict[first_h1]
или my_dict[second_h1]
, для хеширования используются строковые представления тегов. Проблема в том, что оба этих экземпляра Tag
имеют одинаковые представления строк:
<h1>some_header</h1>
Это связано с тем, что класс Tag
имеет магический метод __hash__()
, который определяется следующим образом:
def __hash__(self):
return str(self).__hash__()
Одним из обходных решений может быть использование значений id()
как хэширования, но существует проблема переопределения Tag
классы внутри BeautifulSoup
. Вы можете обойти эту проблему, создав свою собственную "обертку тегов":
class TagWrapper:
def __init__(self, tag):
self.tag = tag
def __hash__(self):
return id(self.tag)
def __str__(self):
return str(self.tag)
def __repr__(self):
return str(self.tag)
Затем вы сможете:
In [1]: from bs4 import BeautifulSoup
...:
In [2]: class TagWrapper:
...: def __init__(self, tag):
...: self.tag = tag
...:
...: def __hash__(self):
...: return id(self.tag)
...:
...: def __str__(self):
...: return str(self.tag)
...:
...: def __repr__(self):
...: return str(self.tag)
...:
In [3]: HTML_string = "<html><h1>some_header</h1><h1>some_header</h1></html>"
...:
...: HTML_soup = BeautifulSoup(HTML_string, 'lxml')
...:
In [4]: first_h1 = HTML_soup.find_all('h1')[0] #first_h1 = <h1>some_header</h1>
...: second_h1 = HTML_soup.find_all('h1')[1] #second_h1 = <h1>some_header</h1>
...:
In [5]: my_dict = {}
...: my_dict[TagWrapper(first_h1)] = 1
...: my_dict[TagWrapper(second_h1)] = 1
...:
...: print(my_dict)
...:
{<h1>some_header</h1>: 1, <h1>some_header</h1>: 1}
Это, однако, не очень и не очень удобно использовать. Я хотел бы повторить вашу первоначальную проблему и проверить, действительно ли вам нужно помещать теги в словарь.
Вы также можете использовать monkey-patch bs4
с помощью возможностей самоанализа Python, например но это будет входить на довольно опасную территорию.