Как разобрать весь текстовый контент из HTML с помощью Beautiful Soup

Я хотел извлечь содержимое сообщения электронной почты. Он находится в html-содержимом, используется BeautifulSoup, чтобы получить From, To и тему. При извлечении содержимого тела он извлекает только первую строку. Он оставляет оставшиеся строки и абзац.

Я что-то здесь упускаю, как читать все строки/абзацы.

КОД:

email_message = mail.getEmail(unreadId)
print (email_message['From'])
print (email_message['Subject'])

if email_message.is_multipart():
    for payload in email_message.get_payload():
        bodytext = email_message.get_payload()[0].get_payload()
        if type(bodytext) is list:
            bodytext = ','.join(str(v) for v in bodytext)
else:
    bodytext = email_message.get_payload()[0].get_payload()
    if type(bodytext) is list:
        bodytext = ','.join(str(v) for v in bodytext)
print (bodytext)
parsedContent = BeautifulSoup(bodytext)
body = parsedContent.findAll('p').getText()
print body

Консоль:

body = parsedContent.findAll('p').getText()
AttributeError: 'list' object has no attribute 'getText'

Когда я использую

body = parsedContent.find('p').getText()

Он извлекает первую строку содержимого и не печатает остальные строки.

Добавлено

После получения всех строк из тега html я получаю символ = в конце каждой строки, а также отображается   ; , <. Как их преодолеть.

Извлеченный текст:

Уважаемый во-первых, все мы в GenWatt рады иметь xyz в качестве клиента. Я хотел бы представиться в качестве вашего менеджера по работе с клиентами. Если у вас есть какие-либо вопросы, пожалуйста, позвоните мне или напишите мне по адресу ash= [email protected]. Вы также можете связаться с GenWatt по следующим номерам: Основной: 810-543-1100Продажи: 810-545-1222Обслуживание и поддержка клиентов: 810-542-1233Факс: 810-545-1001Я уверен, что GenWatt будет служить вам хорошо, и надеюсь увидеть нашу отношения =


person Ashok kumar Ganesan    schedule 08.12.2016    source источник
comment
findAll('p') возвращает список со всеми '‹p...›' в вашем HTML. Вы можете получить весь контент 'p с помощью [p.getText() для p в parsedContent.findAll('p')] или весь контент следующим образом: content = '\n'.join([p.getText() для p в parsedContent.findAll('p')])   -  person GustavoIP    schedule 08.12.2016
comment
для абзаца в parsedContent.findAll('p'): value = para.text значение печати, как это правильно Я не понимаю содержание, которое вы упомянули   -  person Ashok kumar Ganesan    schedule 08.12.2016
comment
Как разобрать или как заменить на ‹пробел›   -  person Ashok kumar Ganesan    schedule 08.12.2016


Ответы (1)


Давайте проверим результат soup.findAll('p')

python -i test.py
----------
import requests
from bs4 import BeautifulSoup

bodytext = requests.get("https://en.wikipedia.org/wiki/Earth").text
parsedContent = BeautifulSoup(bodytext, 'html.parser')

paragraphs = soup.findAll('p')
----------

>> type(paragraphs)
<class 'bs4.element.ResultSet'> 
>> issubclass(type(paragraphs), list) 
True # It's a list

Видишь? Это список всех абзацев. Если вы хотите получить доступ к их содержимому, вам нужно будет перебрать список или получить доступ к элементу по индексу, как в обычном списке.

>> # You can print all content with a for-loop
>> for p in paragraphs:
>>     print p.getText()
Earth (otherwise known as the world (...)
According to radiometric dating and other sources of evidence (...)
...    

>> # Or you can join all content
>> content = []
>> for p in paragraphs:
>>     content.append(p.getText())
>> 
>> all_content = "\n".join(content)
>>
>> print(all_content)
Earth (otherwise known as the world (...) According to radiometric dating and other sources of evidence (...)

Используя понимание списков, ваш код будет выглядеть так:

parsedContent = BeautifulSoup(bodytext)
body = '\n'.join([p.getText() for p in parsedContent.findAll('p')]

Когда я использую

body = parsedContent.find('p').getText()

Он извлекает первую строку содержимого и не печатает остальные строки.

Выполните parsedContent.find('p') точно то же самое, что и parsedContent.findAll('p')[0]

>> parsedContent.findAll('p')[0].getText() == parsedContent.find('p').getText()
True
person GustavoIP    schedule 08.12.2016
comment
При извлечении всех абзацев между строками я получаю как этого избежать или как заменить на ‹пробел› - person Ashok kumar Ganesan; 09.12.2016