Зачем использовать soup.find
, если вы можете использовать soup.select
, получить помощь от всех CSS wiz kids и , чтобы сначала проверить ваши критерии в браузере?
Есть тест производительности на SO и select
быстрее или, по крайней мере, не значительно медленнее, так что это не так. Наверное, привычка.
(работает так же хорошо без квалификатора тега <p>
, т.е. просто "[itemprop=name]"
)
found = soup.select("p[itemprop=name]")
results = dict()
for node in found:
itemtype = node.parent.attrs.get("itemtype", "?")
itemtype = itemtype.split("/")[-1]
results[itemtype] = node.text
print(results)
output:
Это то, что вы просили, но если бы с FoodEstablishment существовало много узлов, последний выиграл бы, потому что вы используете словарь. Судья по умолчанию со списком может работать лучше.
{'PostalAddress': '33 San Francisco', 'FoodEstablishment': "The Dormouse's story"}
шаг 1, до Python: качайте CSS!
и если вам нужно проверить высших предков на itemtype
:
, было бы полезно, если бы у вас было html с этим случаем:
<div class="address" itemtype="http://schema.org/PostalAddress">
<div>
<p itemprop="name">33 San Francisco</p>
</div>
</div>
found = soup.select("[itemprop=name]")
results = dict()
for node in found:
itemtype = None
parent = node.parent
while itemtype is None and parent is not None:
itemtype = parent.attrs.get("itemtype")
if itemtype is None:
parent = parent.parent
itemtype = itemtype or "?"
itemtype = itemtype.split("/")[-1]
results[itemtype] = node.text
print(results)
тот же вывод.
с использованием defautdict
все остается прежним, за исключением объявления результатов и помещения в них данных.
from collections import defaultdict
...
results = defaultdict(list)
...
results[itemtype].append(node.text)
вывод (после того, как я добавил брата в 33 Сан-Франциско):
defaultdict(<class 'list'>, {'PostalAddress': ['33 San Francisco', '34 LA'], 'FoodEstablishment': ["The Dormouse's story"]})