Как спарсить текст из тега, вложенного в другой тег с помощью BS4
Задача состоит в том, чтобы спарсить карточку товара с сайта https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start=0. При работе у меня возникло несколько проблем:
- Не получается взять из карточки описание из двух тегов p и a. Так как тег а вложен в тег р, у меня не выходит вытащить текст.
- Не получается спарсить карточки с других страниц, т.е. при попытки парсинга товаров со второй страницы в консоль все равно выводятся названия товаров с первой, и т.д. На мой взгляд, я правильно прописал цикл так, чтобы он подставлял в ссылку число, соответствующее ссылке страницы.
В течение дня я пробовал разные способы и конструкции, но в последнем варианте я все таки смог вытащить описание, хотя я понимаю, что можно сделать намного легче и правильнее.
Вот код, который я накидал:
import requests
from bs4 import BeautifulSoup
from time import sleep
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac), Apple Inc (US)
AppleWebKit/537.36 (KHTML, like Ge)'}
for count in range(0, 180, 20):
url = f'https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start={count}'
response = requests.get(url, headers=headers, params=None)
soup = BeautifulSoup(response.text, 'lxml')
data = soup.find('ul', class_='item_ul')
for i, el in enumerate(data):
for j in data.find_all('p'):
name = data.find_all('h3')
print('-' * 20 + '\n',
name[i].text.strip() + '\n',
f'{j.text.strip()}' + '\n' +
'-' * 20)
sleep(5)
Ответы (1 шт):
Если я правильно понял, то вы пытаетесь получить название масел. Как вариант это можно сделать так:
soup = BeautifulSoup(html_text, 'lxml') # в html_text код страницы
# ищем все ul с классом item_ul и перебираем
for el_ul in soup.findAll('ul', attrs = {'class':'item_ul'}):
# перебираем найденные ul и ищем в них тег а с классом brandInfoLink
for el_a in el_ul.findAll ('a', attrs = {'class':'brandInfoLink'}):
# перебираем все найденный а и выводим содержимое и параметры (тут ссылка) при необходимости
name = el_a.text.strip()
print (f'Название: {name} Ссылка: {el_a["href"]}')
Выводом будет:
Название: Hyundai-KIA Ссылка: https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start=0#
Название: LUKOIL Ссылка: https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start=0#
Название: GENERAL MOTORS Ссылка: https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start=0#
Название: NISSAN Ссылка: https://vedro.pro/oils_catalog?viewMode=tile&goods_group=oils&start=0#
Стоит отметить, что не обязательно перемещаться по всему дереву элемент за элементом, просто укажите в каком элементе вы собираетесь что-то искать.
Если нужно бонусом вытащить еще и дополнительные атрибуты товара, то возможно сделать так:
soup = BeautifulSoup(html_text, 'lxml')
for el_li in soup.findAll('li', attrs = {'class':'item'}):
print (f"Название: {el_li.find ('a', attrs = {'class':'brandInfoLink'}).text.strip()}")
# перебираем все td в li
for el_td in el_li.findAll ('td'):
print (el_td.text.strip())
Выводом для такого кода будет:
Название: Hyundai-KIA
PP481
2 - 4 дня
> 100
3 370 руб.
Стоит обратить внимание, что в этом случае поиск осуществляется по тегу li, а не ul. Так же, если есть доступно несколько складов, то они будут выведены под названием друг за другом.