Извлечение текста из HTML-тегов без печати

#python-3.x #beautifulsoup

Вопрос:

Допустим, у меня есть HTML-тег ниже:

 """
<table>
    <tr>
        <td class="alphabet" colspan="3">a</td>
    </tr>
    <tr>
        <td class="sound"><audio controls=""><source src="./sound/5/A2-1-1.mp3" type="audio/mpeg"><audio></audio></source></audio></td>
        <td class="en">apple</td></tr>
    <tr>
        <td class="sound"><audio controls=""><source src="./sound/5/A2-1-2.mp3" type="audio/mpeg"><audio></audio></source></audio></td>
        <td class="en">amend</td>
    </tr>
</table>
"""
 

Мой идеальный результат:

 [apple, amend]
 

Однако в моем выводе всегда есть значение «Нет». Вот мой код:

 from bs4 import BeautifulSoup

soup = BeautifulSoup(html_tags, 'lxml')
tr_lists = soup.find_all("tr") 

def clean_data(src):
    return src.find(class_ = 'en')

list(map(clean_data, tr_lists))
 

Мой вывод:

 [None, <td class="en">apple</td>, <td class="en">amend</td>]
 

(причина, по которой я не использовал src.find(class_ = ‘en’).text, заключается в том, что это вызовет ошибку атрибута)

Есть ли способ получить идеальный результат, не используя приведенный ниже код?

 target = soup.find_all(class_ = 'en')
output = [i.text for i in target]
print(output)
 

Спасибо за любую помощь!!

Комментарии:

1. поскольку второй метод кажется наиболее подходящим, есть ли какая-либо конкретная причина, по которой вы не хотите его использовать ?

2. Вы могли бы использовать soup.find_all("tr > td.en")

Ответ №1:

Вы получаете AttributeError , потому что у первого <tr> нет внутреннего элемента с классом as en , и поэтому функция clean_data() возвращает None . Посмотрите список, который вы опубликовали.

Поэтому, когда вы пытаетесь получить текст из каждого элемента списка, вы получаете эту ошибку!

 AttributeError: 'NoneType' object has no attribute 'text'
 

Проблема с вашим вторым фрагментом кода заключается в том, что он выбирает все элементы, которые имеют en имена классов.

 target = soup.find_all(class_ = 'en')
 

Поскольку нужные вам данные присутствуют только в <td> тегах, выберите только те.

Вот как это сделать:

 from bs4 import BeautifulSoup
s = """
<table>
    <tr>
        <td class="alphabet" colspan="3">a</td>
    </tr>
    <tr>
        <td class="sound"><audio controls=""><source src="./sound/5/A2-1-1.mp3" type="audio/mpeg"><audio></audio></source></audio></td>
        <td class="en">apple</td></tr>
    <tr>
        <td class="sound"><audio controls=""><source src="./sound/5/A2-1-2.mp3" type="audio/mpeg"><audio></audio></source></audio></td>
        <td class="en">amend</td>
    </tr>
</table>
"""

soup = BeautifulSoup(s,'lxml')
td = soup.findAll('td', class_='en')
for i in td:
    print(i.text.strip())
 
 apple
amend