from bs4 import BeautifulSoup as bs
import re
txt = """<div class="buttons_zoom"><div class="full_prod"><a href="javascript:void(0)" onclick="js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')" title="לחם אחיד פרוס אנג'ל 750 גרם - פרטים נוספים"><img alt="פרטים נוספים" border="0" src="template/images/new_site/icon-view-prod-cartpage.png"/></a></div></div>"""
soup = bs(txt,'html.parser')
a = soup.find("a", attrs={"href":"javascript:void(0)"})
r = re.search(".*'(\d+)'.*", data).groups()[0]
print(r) # will print '379104'
Редактировать
Заменено ".*\}.*,.*'(\d+)'\).*"
на ".*'(\d+)'.*"
.Они дают тот же результат, но последний намного чище.
Объяснение: Суп
find
(первый) элемент с тегом a
, где атрибут "href""имеет" javascript: void (0) "в качестве значения.Подробнее о красивых аргументах ключевого слова супа здесь .
a = soup.find("a", attrs={"href":"javascript:void(0)"})
Это эквивалентно
a = soup.find("a", href="javascript:void(0)")
В более старых версиях Beautiful Soup, у которых нет ярлыка class_, вы можете использовать упомянутый выше трюк attrs.Создайте словарь, значением которого для «class» является строка (или регулярное выражение, или что-то еще), которое вы хотите найти.- см. Прекрасную документацию супа об "attrs"
a
указывает на элемент типа <class 'bs4.element.Tag'>
.Мы можем получить доступ к атрибутам тега так же, как и для словаря, через свойство a.attrs
(подробнее об этом в красивых атрибутах супа ).Это то, что мы делаем в следующем утверждении.
a_tag_attributes = a.attrs # that's the dictionary of attributes in question...
Ключи словаря имеют имена в соответствии с атрибутами тегов.Здесь у нас есть следующие ключи / атрибуты name: 'title', 'href' и 'onclick'.
Мы можем проверить это сами, распечатав их.
print(a_tag_attributes.keys()) # equivalent to print(a.attrs.keys())
Это приведет к выводу
dict_keys(['title', 'href', 'onclick']) # those are the attributes names (the keys to our dictionary)
Отсюда нам нужно получить интересующие нас данные. Ключом к нашим данным является «onclick» (он назван в честь HTMLатрибут, где лежат данные, которые мы ищем).
data = a_tag_attributes["onclick"] # equivalent to data = a.attrs["onclick"]
data
теперь содержит следующую строку.
"js:getProdID('https://www.XXXXXXX.co.il','{31F93B1D-449F-4AD7-BFB0-97A0A8E068F6}','379104')"
Объяснение: Regex
Теперь, когда мы изолировали часть, которая содержит данные, которые мы хотим, мы собираемся извлечь только ту часть, которая нам нужна.
Мы будемсделать это с помощью регулярного выражения ( этот сайт является отличным ресурсом, если вы хотите узнать больше о Regex, полезные вещи ).
Чтобы использовать регулярное выражение в Python, мы должны импортировать Regexмодуль re
.Подробнее о модуле 're' здесь, хорошие хорошие вещи .
import re
Regex позволяет нам искать строку, соответствующую шаблону.
Здесь строка - это наши данные, а шаблон - ".*'(\d+)'.*"
(которая также является строкой, которую можно определить с помощью двойных кавычек).
Вы можетедумайте о регулярных выражениях как о подстановочных знаках на стероидах.Вы, вероятно, знакомы с подстановочными знаками, такими как *.txt
, чтобы найти все текстовые файлы в файловом менеджере.Эквивалент регулярного выражения: ^.*\.txt$
.
Лучше всего читать о регулярных выражениях, чтобы лучше понять, что это такое.Вот быстрый старт, хорошо, хорошо, хорошо .
Здесь мы search
для строки.Мы описываем строку как не имеющую или бесконечное количество символов.За этими символами следуют несколько цифр (хотя бы одна) и заключенные в одинарные кавычки.Тогда у нас есть еще несколько персонажей.
Скобки используются для извлечения группы (это называется захват в регулярном выражении), мы фиксируем только часть, которая является числом.
Поместив часть регулярного выражения в круглые скобки или скобки, вы можете сгруппировать эту часть регулярного выражения вместе.Это позволяет применять квантификатор ко всей группе или ограничивать изменения в части регулярного выражения.
Для группировки можно использовать только круглые скобки.Квадратные скобки определяют класс символов, а фигурные скобки используются квантификатором с конкретными ограничениями.- Использовать скобки для группировки и захвата
r = re.search(".*'(\d+)'.*", data)
Определение символов:
. * Соответствует любому символу (кроме ограничителей строки), * означаетне может быть ни одного, или бесконечного количества
'соответствует символу'
\ d + соответствует хотя бы одной цифре (равно [0-9]);это та часть, которую мы захватили
(\ d +) Capturing Group;это означает захват части строки, где повторяется цифра, по крайней мере один
() используется для захвата, часть, которая соответствует шаблону в круглых скобках, сохраняется.
Захваченная часть (если есть) может быть позже доступна с помощью вызова r.groups()
по результату re.search
.
. Возвращает кортеж, содержащий захваченную информацию, или None
(r
относится к результатам.вызова функции re.search
).
В нашем случае первым (и единственным) элементом кортежа являются цифры ...
captured_group = r.groups()[0] # that's the tuple containing our data (we captured...)
Теперь мы можем получить доступ к нашим данным, которые находятся в первом индексе кортежа (мы захватили только одну группу)
print(captured_group[0]) # this will print out '379104'