Python BeautifulSoup извлекает текст сразу после определенного тега - PullRequest
1 голос
/ 10 апреля 2019

Я пытаюсь извлечь информацию из веб-страницы, используя beautifulsoup и python.Я хочу извлечь информацию прямо под конкретным тегом.Чтобы узнать, является ли это правильным тегом, я хотел бы сравнить его текст, а затем извлечь текст в следующем непосредственном теге.
Скажем, например, если следующее является частью источника HTML-страницы,

<div class="row">
    ::before
    <div class="four columns">
        <p class="title">Procurement type</p>
        <p class="data strong">Services</p>
    </div>
  <div class="four columns">
      <p class="title">Reference</p>
      <p class="data strong">ANAJSKJD23423-Commission</p>
  </div>
  <div class="four columns">
      <p class="title">Funding Agency</p>
      <p class="data strong">Health Commission</p>
  </div>
  ::after
</div>
<div class="row">
    ::before
    ::after
</div>
<hr>
<div class="row">
    ::before
    <div class="twelve columns">
        <p class="title">Countries</p>
        <p class="data strong">
            <span class>Belgium</span>
            ", "
            <span class>France</span>
            ", "
            <span class>Luxembourg</span>
        </p>
        <p></p>
    </div>
    ::after
</div>

Я хочу проверить, имеет ли <p class="title"> текстовое значение как Procurement type, тогда я хочу распечатать Services
Аналогично, если <p class="title"> имеет текстовое значение какReference тогда я хочу распечатать ANAJSKJD23423-Commission , а если <p class="title"> имеет значение Countries, то распечатать все страны, т. Е. Бельгия, Франция, Люксембург .

Я знаю, что могу извлечь все тексты с помощью <p class="data strong"> и добавить их в список, а затем извлечь все значения с помощью индексации.Но дело в том, что порядок появления этих <p class="title> не зафиксирован .... в некоторых местах страны могут быть упомянуты до типа закупки.Поэтому я хочу выполнить проверку текстовых значений и затем извлечь текстовое значение следующего немедленного тега.Я все еще новичок в BeautifulSoup, поэтому любая помощь приветствуется.Спасибо

Ответы [ 3 ]

4 голосов
/ 10 апреля 2019

Вы можете сделать это многими способами. Вы идете.

from bs4 import BeautifulSoup
htmldata='''<div class="row">
    ::before
    <div class="four columns">
        <p class="title">Procurement type</p>
        <p class="data strong">Services</p>
    </div>
  <div class="four columns">
      <p class="title">Reference</p>
      <p class="data strong">ANAJSKJD23423-Commission</p>
  </div>
  <div class="four columns">
      <p class="title">Funding Agency</p>
      <p class="data strong">Health Commission</p>
  </div>
  ::after
</div>
<div class="row">
    ::before
    ::after
</div>
<hr>
<div class="row">
    ::before
    <div class="twelve columns">
        <p class="title">Countries</p>
        <p class="data strong">
            <span class>Belgium</span>
            ", "
            <span class>France</span>
            ", "
            <span class>Luxembourg</span>
        </p>
        <p></p>
    </div>
    ::after
</div>'''

soup=BeautifulSoup(htmldata,'html.parser')

items=soup.find_all('p', class_='title')
for item in items:
    if ('Procurement type' in item.text) or ('Reference' in item.text):
        print(item.findNext('p').text)
2 голосов
/ 10 апреля 2019

Вы также можете использовать :contains псевдокласс с bs4 4.7.1.Хотя я прошел список, вы можете выделить каждое условие

from bs4 import BeautifulSoup as bs
import re

html = 'yourHTML'   
soup = bs(html, 'lxml')
items=[re.sub(r'\n\s+','', item.text.strip()) for item in soup.select('p.title:contains("Procurement type") + p, p.title:contains(Reference) + p, p.title:contains(Countries) + p')]
print(items)

Вывод:

enter image description here

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

Вы можете добавить аргумент для проверки конкретного текста при использовании .find() или .find_all(), а затем использовать .next_sibling или findNext(), чтобы получить следующие теги с содержимым

Т.е.:

soup.find('p', {'class':'title'}, text = 'Procurement type')

Дано:

html = '''<div class="row">
    ::before
    <div class="four columns">
        <p class="title">Procurement type</p>
        <p class="data strong">Services</p>
    </div>
  <div class="four columns">
      <p class="title">Reference</p>
      <p class="data strong">ANAJSKJD23423-Commission</p>
  </div>
  <div class="four columns">
      <p class="title">Funding Agency</p>
      <p class="data strong">Health Commission</p>
  </div>
  ::after
</div>
<div class="row">
    ::before
    ::after
</div>
<hr>
<div class="row">
    ::before
    <div class="twelve columns">
        <p class="title">Countries</p>
        <p class="data strong">
            <span class>Belgium</span>
            ", "
            <span class>France</span>
            ", "
            <span class>Luxembourg</span>
        </p>
        <p></p>
    </div>
    ::after
</div>'''

Вы можете сделать что-то вроде:

from bs4 import BeautifulSoup     

soup = BeautifulSoup(html, 'html.parser')

alpha = soup.find('p', {'class':'title'}, text = 'Procurement type')
for sibling in alpha.next_siblings:
    try:
        print (sibling.text)
    except:
        continue

Вывод:

Services

или

ref = soup.find('p', {'class':'title'}, text = 'Reference')
for sibling in ref.next_siblings:
    try:
        print (sibling.text)
    except:
        continue

Выход:

ANAJSKJD23423-Commission    

или

countries = soup.find('p', {'class':'title'}, text = 'Countries')
names = countries.findNext('p', {'class':'data strong'}).text.replace('", "','').strip().split('\n')
names = [name.strip() for name in names if not name.isspace()]

for country in names:
    print (country)

Выход:

Belgium
France
Luxembourg
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...