วิธีแยกเนื้อหาข้อความทั้งหมดจาก HTML โดยใช้ Beautiful Soup

ฉันต้องการแยกเนื้อหาข้อความอีเมล มันอยู่ในเนื้อหา HTML ใช้ BeautifulSoup เพื่อดึงข้อมูลจาก จาก ถึง และหัวเรื่อง เมื่อดึงเนื้อหาเนื้อหา จะดึงข้อมูลบรรทัดแรกเพียงอย่างเดียว โดยจะเหลือบรรทัดและย่อหน้าที่เหลือ

ขาดอะไรไปตรงนี้ ต้องอ่านทุกบรรทัด/ย่อหน้ายังไง

รหัส:

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() for p in parsedContent.findAll('p')] หรือเนื้อหาทั้งหมดด้วยวิธีนี้: content = '\n'.join([p.getText() for p in parsedContent.findAll('p')])   -  person GustavoIP    schedule 08.12.2016
comment
สำหรับย่อหน้าใน parsedContent.findAll('p'): value = comparison.text print value like this right ฉันไม่เข้าใจเนื้อหาที่คุณพูดถึง   -  person Ashok kumar Ganesan    schedule 08.12.2016
comment
วิธีแยกวิเคราะห์หรือเปลี่ยนด้วย ‹space›   -  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 (...)

การใช้ List Comprehension โค้ดของคุณจะมีลักษณะดังนี้:

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

เมื่อฉันใช้

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

ดึงข้อมูลบรรทัดแรกของเนื้อหา และไม่ได้พิมพ์บรรทัดที่เหลือ

Do parsedContent.find('p') สิ่งเดียวกันที่ทำ parsedContent.findAll('p')[0] ทุกประการ

>> parsedContent.findAll('p')[0].getText() == parsedContent.find('p').getText()
True
person GustavoIP    schedule 08.12.2016
comment
เมื่อแยกย่อหน้าทั้งหมด ในระหว่างบรรทัด ฉันจะได้ วิธีหลีกเลี่ยงสิ่งนี้ หรือวิธีแทนที่ด้วย ‹space› - person Ashok kumar Ganesan; 09.12.2016