嗨,我已经使用以下代码对数据表进行了网络抓取:
import requests
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
df = pd.DataFrame()
for row in links2get:
url = row
response = requests.get(url)
html_page = response.content
soup = BeautifulSoup(html_page, 'html.parser')
text = soup.find_all(text=True)
for a in soup.select('.trackM'):
b = a.get_text()
array = np.array(b)
print(array)
#reshape = ????
#df = df.append(reshape)
我对数组的输出是:
print(array):
Table Title
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
1084
316
No
72
Yes
编辑有时表中缺少值,因此元素的数量可能是奇数(例如5个标题列,但只有4个值)。
我希望将其重塑为一个DataFrame,使其看起来像:
print(df):
Heading 1 Heading 2 Heading 3 Heading 4 Heading 5
1084 316 No 72 Yes
即时通讯在重塑时遇到问题,因此,如果有人提出任何建议,那将是很棒的!谢谢!
答案 0 :(得分:2)
如果您知道表的网址和标题,则只需执行此操作。
import pandas as pd
df = pd.read_html(url, match='Table Title')[0]
如果将表格作为文本,请从美丽的汤中提取。您可以简单地做到这一点。
import pandas as pd
table_string = '''<table>
<tr>
<th>heading 1</th>
<th>heading 2</th>
<th>heading 3</th>
<th>heading 4</th>
</tr>
<tr>
<td>1084</td>
<td>316</td>
<td>No</td>
<td>72</td>
<td>Yes</td>
</tr>
</table>'''
df = pd.read_html(table_string)[0]
输出:
heading 1 heading 2 heading 3 heading 4 Unnamed: 4
0 1084 316 No 72 Yes
答案 1 :(得分:1)
您在正确的轨道上。但是从一系列干净的令牌开始。这将使下游更加简单。
[e for e in b.splitlines()[1:] if len(e)]
# b.splitlines() -> Split the text output into a list at the linebreaks.
# b.splitlines()[1:] -> Drop the first element of the list ("Table Title")
# ... if len(e) -> Only keep the token if it has length greater than zero (i.e. not the empty string.)
至关重要的是,在这一部分中,您始终要创建一个具有偶数个元素的系列:
...
b = a.get_text()
s = pd.Series([e for e in b.splitlines()[1:] if len(e)])
Out[54]:
0 Heading 1
1 Heading 2
2 Heading 3
3 Heading 4
4 Heading 5
5 1084
6 316
7 No
8 72
9 Yes
现在直接重塑为DataFrame。因为我们知道该系列中的元素数是偶数,所以我们可以将其整形为长度为int(len(s) / 2)
的两行:
df = pd.DataFrame(s.values.reshape((2, int(len(s) / 2))))
0 1 2 3 4
0 Heading 1 Heading 2 Heading 3 Heading 4 Heading 5
1 1084 316 No 72 Yes
现在,我们分配第一行中的列:
df.columns = df.iloc[0]
0 Heading 1 Heading 2 Heading 3 Heading 4 Heading 5
0 Heading 1 Heading 2 Heading 3 Heading 4 Heading 5
1 1084 316 No 72 Yes
最后,删除我们用于各列的行:
df.drop(df.index[0])
0 Heading 1 Heading 2 Heading 3 Heading 4 Heading 5
1 1084 316 No 72 Yes