我正在尝试使用具有以下结构的HashMap
来解析HTML:
beautifulSoup
我遇到的问题是我想将标题添加到数据框的同一行作为数据。但是使用for循环(基于查找表)我不知道如何将标题与数据点放在同一个列表中 - 这样进入数据框的数据就是[ <table>
<tr><td class="title">Title 2</td></tr>
</table>
<table>
<tr><td>Label 1</td><td>Label 2</td><td>Label 3</td></tr>
<tr><td class="data">Data 1</td><td class="data">Data 2</td><td class="data">Data33</td></tr> </table>
<table>
<tr><td class="title">Title 2</td></tr>
</table>
<table>
<tr><td>Label 1</td><td>Label 2</td><td>Label 3</td></tr>
<tr><td class="data">Data 1</td><td class="data">Data 2</td><td class="data">Data33</td></tr>
</table>
] < / p>
python代码是:
title, Data 1, Data 2, Data 3
我已经尝试将其包装在另一个for循环中,但由于需要遍历表格,因此无效。
我可以创建两个数据框(一个用于标题,一个用于数据),然后在最后合并它们,但如果这是最好的方法,我会感到惊讶。
有谁知道如何合并两个for循环的集合结果(即tables = soup.find_all('table')
i = 0
for t in tables:
if(i % 2) == 1:
datapoints = t.find_all('td', class_='data')
data = []
for d in datapoints:
data.append(d.text)
i += 1
else:
title = t.find('td', class_='title').text
i += 1
)?
答案 0 :(得分:0)
如何使用try..except
:
for table in soup.find_all('table'):
try:
title = table.find('td', class_='title').text
except AttributeError: # Triggers if no title present
data = [td.text for td in table.find_all('td', class_='data')]
获取所需的列表:
data = []
for table in soup.find_all('table'):
try:
data.append([table.find('td', class_='title').text])
except AttributeError: # Triggers if no title present
data[-1].extend(td.text for td in table.find_all('td', class_='data'))
print(data)
# [['Title 1', 'Data 1', 'Data 2', 'Data33'],
# ['Title 2', 'Data 1', 'Data 2', 'Data33']]
只要标题后面紧跟着包含相应数据的表格,就可以正常工作。
但是,如果您想在之后将其添加到pandas.DataFrame
,这可能更容易:
import pandas as pd
titles, data = [], []
for table in soup.find_all('table'):
try:
titles.append(table.find('td', class_='title').text)
except AttributeError: # Triggers if no title present
data.append([td.text for td in table.find_all('td', class_='data')])
df = pd.DataFrame(zip(*data), columns=titles)
# df = pd.DataFrame.from_items(zip(titles, data)) # also works
print(df)
# Title 1 Title 2
# 0 Data 1 Data 1
# 1 Data 2 Data 2
# 2 Data33 Data33
答案 1 :(得分:0)
一些意见:
enumerate
循环for
您可以使用zip()
进行合并
titles = [t.find('td', class_='title').text for idx,t in enumerate(tables) if idx % 2 == 0]
datas = [[td.text for td in table.find_all('td', class_='data')] for idx,t in enumerate(tables) if idx % 2 != 0 ]
structured = zip(titles,datas)