pandas - BeautifulSoup 表到数据框

标签 pandas beautifulsoup

似乎无法将表中的值正确复制到数据框中。如果运行 raw_data,它会输出所有值的列表。知道如何使其结构化吗?

pop_source = requests.get("http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm").text

soup = BeautifulSoup(pop_source, 'html5lib')    
source = soup.find_all('td',class_ = 'report_data')


pop = pd.DataFrame(columns=['Zip Code','Population'])


row_data = [data.text for data in source]

temp_df = pd.DataFrame([row_data], columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])   

temp_df = temp_df[['Zip Code','Population']]   
pop = pop.append(temp_df).reset_index(drop=True)    
pop

最佳答案

代码中的一些内容:

  1. 上面的代码实际上不会循环任何内容。事实上,如果您尝试运行它,您应该会遇到大量错误。无法看到仅使用您提供的值循环相同值的输出。

  2. 缩进已关闭,

  3. 您引用了一个变量 source尚未定义。您引用了一个变量cols这也没有定义。

  4. 您初始化一个数据框 pop有 2 列,并尝试附加一个有 7 列的数据框。

这里发生了各种各样的问题。

您是否考虑过直接使用 Pandas 来形成数据框?您仍然可以使用 BeautifulSoup,但 pandas 可以为您完成这项工作,而且您似乎需要更多地练习使用 BeautifulSoup 迭代元素(实际上您甚至从未使用过 .find.find_all 来定位标签与您想要的表关联。)

如果您需要 BeautifulSoup 的方式来做到这一点,请告诉我,我也可以提供这种方式,但说实话,这比仅仅使用 .read_html() 需要做更多的工作。这里有 Pandas 。

import pandas as pd

url = 'http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm'

tables = pd.read_html(url)

df = tables[11][1:]
df.columns = tables[11].iloc[0]

输出:

print (df)
0     # Zip Code      ...      People / Sq. Mile National Rank
1    1.    78705      ...               11008.66          #519
2    2.    78751      ...                5822.28        #1,374
3    3.    78752      ...                5435.92        #1,528
4    4.    78741      ...                5346.47        #1,562
5    5.    78723      ...                5175.95        #1,640
6    6.    78704      ...                5001.96        #1,713
7    7.    78758      ...                4954.80        #1,730
8    8.    78702      ...                4501.98        #2,015
9    9.    78757      ...                4380.92        #2,087
10  10.    78756      ...                4298.80        #2,139
11  11.    78745      ...                4063.22        #2,295
12  12.    78753      ...                3973.96        #2,350
13  13.    78703      ...                3491.54        #2,753
14  14.    78731      ...                3031.63        #3,167
15  15.    78759      ...                2998.68        #3,199
16  16.    78727      ...                2856.67        #3,371
17  17.    78749      ...                2795.02        #3,438
18  18.    78728      ...                2640.31        #3,614
19  19.    78721      ...                2568.43        #3,690
20  20.    78722      ...                2567.53        #3,692
21  21.    78729      ...                2366.94        #3,944
22  22.    78701      ...                2326.65        #3,995
23  23.    78748      ...                1961.73        #4,504
24  24.    78750      ...                1731.01        #4,870
25  25.    78744      ...                1464.78        #5,311
26  26.    78746      ...                1152.39        #5,971
27  27.    78717      ...                1081.05        #6,119
28  28.    78739      ...                 768.80        #7,006
29  29.    78734      ...                 698.96        #7,267
30  30.    78724      ...                 555.85        #7,870
31  31.    78726      ...                 543.24        #7,940
32  32.    78733      ...                 510.92        #8,116
33  33.    78754      ...                 484.73        #8,255
34  34.    78735      ...                 474.14        #8,318
35  35.    78732      ...                 416.13        #8,702
36  36.    78742      ...                 321.40        #9,467
37  37.    78730      ...                 257.86       #10,189
38  38.    78738      ...                 213.29       #10,829
39  39.    78747      ...                 194.02       #11,173
40  40.    78736      ...                 187.88       #11,301
41  41.    78737      ...                 143.90       #12,372
42  42.    78725      ...                 116.87       #13,282
43  43.    78719      ...                  93.88       #14,377

[43 rows x 7 columns]

使用 BeautifulSoup

这不是执行此操作的理想方法。虽然这个网站非常简单,带有 table , tr , td标签。您可能想要的是首先获取所有行,然后迭代每一行以获取 <td>标签。但你捕获了所有<td>一口气标记。这仍然可以,但我们需要将其分成每一行。

然后我所做的就是将其分成 7 组,因为这就是有多少列。请注意,我做了一个巨大的假设,所有数据都在那里。如果不是,则表格将关闭或行、列将移动。

import requests
import pandas as pd
import bs4


# Create a function called "chunks" with two arguments, l and n:
def chunks(l, n):
    # For item i in a range that is a length of l,
    for i in range(0, len(l), n):
        # Create an index range for l of n items:
        yield l[i:i+n]



pop_source = requests.get("http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm").text

soup = bs4.BeautifulSoup(pop_source, 'html5lib')


source = soup.find_all('td',class_ = 'report_data')

pop = pd.DataFrame(columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])

row_data = [data.text for data in source]

rows_data = list(chunks(row_data, 7))

for ele in rows_data:
    temp_df = pd.DataFrame([ele], columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])
    pop = pop.append(temp_df).reset_index(drop=True)

关于pandas - BeautifulSoup 表到数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54335078/

相关文章:

python - Pandas dataframe - 从字典中添加列

python - pandas 中的数据框数学

python - 从 html 文档中获取特定部分

python - 获取 BeautifulSoup 中表的内容

python - 返回特定内容

python - BeautifulSoup FindAll 与 OR 和空类

python - 在复制其他列数据的同时拆分一列中的行中的值

Python:在 Pandas 中进行多列聚合

python - 解析 Pandas 列中的列表

python - 表格抓取中的不完整结果