Как я могу проанализировать div и получить содержимое каждого тега <strong>в разных строках? - PullRequest
1 голос
/ 29 апреля 2019

Я пытаюсь разобрать сайт рецептов, в котором его ингредиенты сгруппированы в отдельные категории, описанные тегом <strong> в HTML, как показано ниже:

<div class="opskriften">
<p class="h3">Ingrediensliste</p>
<p></p>
<p><strong>Påskeæg med nougat (6 stk)</strong><br>150 g. marcipan <br>ca. 40 g. nougat<br>150 g. mørk chokolade <br>50 g. lys chokolade &nbsp;</p>

Мне удалось разделить ингредиенты на разные столбцы для количества, единицы и ингредиента, но я обнаружил, что пытаюсь создать еще один столбец для содержимого внутри тегов <strong>.

Это код, который я использовал.

ingredients = soup.find('div', class_='opskriften')      

#if len(ingredients.find_all('strong'))>0:
s = f"{ingredients}"
r = re.compile(r"(?P<amount>\d+)\s+(?P<unit>\w+.)\s+(?P<ingredient>.+?(?=<))")
df = pd.DataFrame([m.groupdict() for m in r.finditer(s)])

with open("somefile.csv", 'w') as fh:
    df.to_csv(fh)

Я пытался поиграться с RegEx, но не смог найти никакого решения, чтобы заставить его работать.

изображение того, как выглядит мой сайт,

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Здесь у меня есть несколько предложений для вас. Может быть проблема с синтаксическим анализом из-за языка, поэтому открытие тегов br исключается

from  bs4 import BeautifulSoup
soup_chunk = '''<div class="opskriften">
<p class="h3">Ingrediensliste</p>
<p></p>
<p><strong>Påskeæg med nougat (6 stk)</strong><br>150 g. marcipan <br>ca. 40 g. nougat<br>150 g. mørk chokolade <br>50 g. lys chokolade &nbsp;</p>'''

soup = BeautifulSoup(soup_chunk,'lxml')
requiredData = []
for tags in soup.find_all('p'):
    if tags.select('br'):
        contents = {}
        contents['MainItem'] = tags.select('strong')[0].text
        [i.decompose() for i in tags.select('strong')]
        contents['SubItems'] = [i.strip().replace("</p>",'') for i in str(tags).split("<br/>") if "<p>" not in i]
        requiredData.append(contents)
print(requiredData)

Я поместил вывод в список dict, чтобы он мог использоваться где угодно.

[{'MainItem': 'Påskeæg med nougat (6 stk)', 'SubItems': ['150 g. marcipan', 'ca. 40 g. nougat', '150 g. mørk chokolade', '50 g. lys chokolade']}]
1 голос
/ 29 апреля 2019

Если все div выглядят одинаково, вы можете анализировать ингредиенты с BeautifulSoup.Это зависит от тега <strong>, являющегося дочерним элементом тега <p>, который содержит все ингредиенты:

from bs4 import BeautifulSoup as BS

s = '''<div class="opskriften">
<p class="h3">Ingrediensliste</p>
<p></p>
<p><strong>Påskeæg med nougat (6 stk)</strong><br>150 g. marcipan <br>ca. 40 g. nougat<br>150 g. mørk chokolade <br>50 g. lys chokolade &nbsp;</p>
'''

soup = BS(s,'html.parser')
q = soup.find('div', class_='opskriften')
r = q.find('strong')
ingredients = r.parent


In [13]: for tag in ingredients.childGenerator():
    ...:     if tag.name == 'strong':
    ...:         print(tag.text)
    ...:     elif tag.name == 'br':
    ...:         continue
    ...:     else:
    ...:         print(tag)
    ...:         
Påskeæg med nougat (6 stk)
150 g. marcipan 
ca. 40 g. nougat
150 g. mørk chokolade 
50 g. lys chokolade  

Если тег <p>, содержащий все ингредиенты, всегда является последним <p>в теге div, тогда вы можете найти его следующим образом.

q = soup.find('div', class_='opskriften')
ingredients = q.find_all('p')[-1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...