Извлечение текстовых данных из тега Div, но не из дочернего тега H3 - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть HTML-фрагмент, который мне нужен для получения данных с помощью BeautifuSoup:

<!doctype html>
<html lang="en">
    <body>
        <div class="sidebar-box">
            <h3><i class="fa fa-users"></i> Management Team</h3>
                        Chairman, Director
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-male"></i> Teacher</h3>
                        John Doe
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-mortar-board"></i> Awards </h3>
                        National Top Quality Educational Development
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-building"></i> School Type</h3>
                        Secondary
        </div>
    </body>
</html>

Мне нужно получить значение .text второго div сверху "John Doe",но не значение .text внутри тега h3 в этом div.Моя проблема заключается в том, что в настоящее время я получаю оба текстовых значения, как в следующем фрагменте кода:

# Python 3.7, BeautifulSoup 4.7
# html variable is equal to the above HTML snippet
from bs4 import BeautifulSoup
soup4 = BeautifulSoup(html, "html.parser")
# Get School Head Teacher
school_head_teacher = soup4.find_all('div', {'class':'sidebar-box'})
school_head_teacher = school_head_teacher[1].text.strip()
print(school_head_teacher)

Это выводит:

Teacher
                        John Doe

Однако мне нужно только значение Джона Доу.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Другой вариант:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")

teacher_name = soup.find_all('div', class_='sidebar-box')
print(teacher_name[1].contents[2].strip())

Вывод:

John Doe
0 голосов
/ 16 февраля 2019

Так как <div class="sidebar-box"> <h3><i class="fa fa-male"></i> Teacher</h3> John Doe </div>

Поскольку Джон Доу является следующим братом <h3><i class="fa fa-male"></i> Teacher</h3>

Мы можем использовать комбинацию find_next () и next_sibling для <div class="sidebar-box">

!doctype html>
<html lang="en">
    <body>
        <div class="sidebar-box">
            <h3><i class="fa fa-users"></i> Management Team</h3>
                        Chairman, Director
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-male"></i> Teacher</h3>
                        John Doe
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-mortar-board"></i> Awards </h3>
                        National Top Quality Educational Development
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-building"></i> School Type</h3>
                        Secondary
        </div>
    </body>
</html>'''

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Get School Head Teacher
school_head_teacher = soup.find_all('div', {'class':'sidebar-box'})
head_teacher = school_head_teacher[1].find_next().next_sibling
print(head_teacher)

Таким образом, вы можете зацикливаться и на других div, которые следуют той же схеме.

for school_info in school_head_teacher:
    print (school_info.find_next().next_sibling)

0 голосов
/ 15 февраля 2019

Я предложил 2 решения.Первое не самое элегантное решение.Но быстро, прямо у меня в голове, вы можете разделить это снова и объединить все после «Учителя»

Вариант 1:

html = '''
!doctype html>
<html lang="en">
    <body>
        <div class="sidebar-box">
            <h3><i class="fa fa-users"></i> Management Team</h3>
                        Chairman, Director
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-male"></i> Teacher</h3>
                        John Doe
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-mortar-board"></i> Awards </h3>
                        National Top Quality Educational Development
        </div>
        <div class="sidebar-box">
            <h3><i class="fa fa-building"></i> School Type</h3>
                        Secondary
        </div>
    </body>
</html>'''



from bs4 import BeautifulSoup
soup4 = BeautifulSoup(html, "html.parser")
# Get School Head Teacher
school_head_teacher = soup4.find_all('div', {'class':'sidebar-box'})
school_head_teacher = school_head_teacher[1].text.strip()

school_head_teacher = school_head_teacher.split()[1:]
school_head_teacher = ' '.join(school_head_teacher)

print(school_head_teacher)

Вывод:

print(school_head_teacher)
John Doe

Вариант 2:

Я думаю, что этот вариант немного лучше.Вы найдете тег с Teacher.Тогда вы получите родительский тег.Затем, так как вы хотите вторую часть, вы используете .next_sibling и лишаете ее.

soup4(text=re.compile('Teacher'))[0].parent.next_sibling.strip()

У меня это было в цикле for, там есть несколько учителей.Но вы можете заменить верхний код вместо for loop

from bs4 import BeautifulSoup
import re

soup4 = BeautifulSoup(html, "html.parser")
# Get School Head Teacher
for elem in soup4(text=re.compile('Teacher')):
    print (elem.parent.next_sibling.strip())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...