Python 美化组在主表中对多个表进行分组
我正在使用BeautifulSoup解析具有以下结构的HTML文档:Python 美化组在主表中对多个表进行分组,python,beautifulsoup,Python,Beautifulsoup,我正在使用BeautifulSoup解析具有以下结构的HTML文档: <table> <tr> <th>Thread</th> <td> (555EEE555)<br/> <table> <tr> <th>Participants</th> <td>Joh
<table>
<tr>
<th>Thread</th>
<td> (555EEE555)<br/>
<table>
<tr>
<th>Participants</th>
<td>John Doe<br/>Jane Doe<br/>
</td>
</tr>
</table><br/><br/>
<table>
<tr>
<th>Author</th>
<td>John Doe<br/></td>
</tr>
</table>
<table>
<tr>
<th>Sent</th>
<td>2017-10-16 19:03:23 UTC<br/>
</td>
</tr>
</table>
<table>
<tr>
<th>Body</th>
<td>Test message with some body text<br/>
</td>
</tr>
</table><br/>
<table>
<tr>
<th>Author</th>
<td>Jane Doe<br/></td>
</tr>
</table>
<table>
<tr>
<th>Sent</th>
<td>2017-10-17 08:03:23 UTC<br/>
</td>
</tr>
</table>
<table>
<tr>
<th>Body</th>
<td>Second test message with some body text<br/>
</td>
</tr>
</table><br/>
</td>
</tr>
</table>
其中打印以下内容:
key: Current Participants | data: John DoeJane Doe
key: Author | data: John Doe
key: Sent | data: 2017-10-16 19:03:23 UTC
key: Body | data: Test message with some body text
我如何编写代码,使其在整个文档中循环,并对每个
作者
、发送的
和正文
进行适当分组,以解析出每个单独的消息?以下是我的解决方案,我继续使用您的代码:
table_parent = soup.find('td')
tables = table_parent.find_all('table', recursive=False)
tables_str = " ".join([str(t) for t in tables[1:]])
soup_tables = BeautifulSoup(tables_str)
trs = soup_tables.find_all("tr")
for i in xrange(0, len(trs), 3):
print(trs[i].contents[1].text, trs[i].contents[3].text)
print(trs[i+1].contents[1].text, trs[i+1].contents[3].text)
print(trs[i+2].contents[1].text, trs[i+2].contents[3].text)
print("-"*8)
这将打印:
(u'Author', u'John Doe')
(u'Sent', u'2017-10-16 19:03:23 UTC\n')
(u'Body', u'Test message with some body text\n')
--------
(u'Author', u'Jane Doe')
(u'Sent', u'2017-10-17 08:03:23 UTC\n')
(u'Body', u'Second test message with some body text\n')
--------
如果您需要一些解释,请询问我。我假设您总是有一个主表作为父表 您应该能够做到这一点:
from bs4 import BeautifulSoup as soup
import requests
html = """<table>
<tr>
<th>Thread</th>
<td> (555EEE555)<br/>
<table>
<tr>
<th>Participants</th>
<td>John Doe<br/>Jane Doe<br/>
</td>
</tr>
</table><br/><br/>
<table>
<tr>
<th>Author</th>
<td>John Doe<br/></td>
</tr>
</table>
<table>
<tr>
<th>Sent</th>
<td>2017-10-16 19:03:23 UTC<br/>
</td>
</tr>
</table>
<table>
<tr>
<th>Body</th>
<td>Test message with some body text<br/>
</td>
</tr>
</table><br/>
<table>
<tr>
<th>Author</th>
<td>Jane Doe<br/></td>
</tr>
</table>
<table>
<tr>
<th>Sent</th>
<td>2017-10-17 08:03:23 UTC<br/>
</td>
</tr>
</table>
<table>
<tr>
<th>Body</th>
<td>Second test message with some body text<br/>
</td>
</tr>
</table><br/>
</td>
</tr>
</table>"""
def _get_obj():
r = {
'Author': '',
'Sent': '',
'Body': ''
}
return r
page = soup(html, 'html.parser')
main_table = page.find('table')
result = []
r = _get_obj()
for t in main_table.find_all('table'):
if t.find('th', text='Author'):
r['Author'] = t.find('td').get_text()
if t.find('th', text='Sent'):
r['Sent'] = t.find('td').get_text()
if t.find('th', text='Body'):
r['Body'] = t.find('td').get_text()
result.append(r)
r = _get_obj()
print(result)
我宁愿避免获取表格,而将重点放在带有
作者
、已发送
和正文
文本的标记上。然后可以使用获取下一个td
,并获取其中的文本。然后可以使用该函数来聚合数据。如果标记位于变量html\u doc
中,则以下代码应该可以工作
from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'html.parser')
authors=[x.find_next('td').text for x in soup.find_all('th',text='Author')]
sent=[x.find_next('td').text.strip() for x in soup.find_all('th',text='Sent')]
body=[x.find_next('td').text.strip() for x in soup.find_all('th',text='Body')]
for item in zip(authors,sent,body):
print(item)
产出:
请张贴完整的HTML或url@Wonka我更新了问题的HTML部分。我不能发布整个文档,但是我的示例中的结构应该足够了。内部结构只是在整个过程中重复。好的,您知道每条消息都以Author
键开头。您可以在列表中输入每条消息的dict,在每个作者
键上添加一个新的dict,并将相关数据存储到该dict中。我无法用代码发布真实的答案,因为您显示的代码与您给出的html示例不兼容…很抱歉,回复太晚,但这似乎有效。但我并不完全理解它在做什么。我发现它会查看所有内部表的表头并提取指定头的文本,我只是对在for循环末尾使用函数的结构感到困惑。
[
{'Author': 'John Doe', 'Sent': '2017-10-16 19:03:23 UTC\n', 'Body': 'Test message with some body text\n'},
{'Author': 'Jane Doe', 'Sent': '2017-10-17 08:03:23 UTC\n', 'Body': 'Second test message with some body text\n'}
]
from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'html.parser')
authors=[x.find_next('td').text for x in soup.find_all('th',text='Author')]
sent=[x.find_next('td').text.strip() for x in soup.find_all('th',text='Sent')]
body=[x.find_next('td').text.strip() for x in soup.find_all('th',text='Body')]
for item in zip(authors,sent,body):
print(item)
('John Doe', '2017-10-16 19:03:23 UTC', 'Test message with some body text')
('Jane Doe', '2017-10-17 08:03:23 UTC', 'Second test message with some body text')