【问题标题】:BeautifulSoup table to dataframeBeautifulSoup 表到数据框
【发布时间】:2019-06-17 12:08:26
【问题描述】:

似乎无法将表中的值正确复制到数据框中。如果您运行 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

【问题讨论】:

  • 8 列是什么意思?我在网站上只看到 7 个。
  • 你还有两次'Population' temp_df = pd.DataFrame([row_data], columns=['Zip Code','Location','City', 'Population', 'People/Sq.Mile','Population','National Rank'])

标签: pandas beautifulsoup


【解决方案1】:

代码中的一些东西:

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

  2. 缩进关闭,

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

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

这里发生的各种问题。

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

如果您需要 BeautifulSoup 方法,请告诉我,我也可以提供这种方法,但老实说,这比在此处使用带有 pandas 的 .read_html() 要多得多。

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

这不是执行此操作的理想方式。虽然这个网站使用tabletrtd 标签非常简单。您可能想要的是首先获取所有行,然后遍历每一行以获取 <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)

【讨论】:

  • 查看更新后的帖子。我以前使用过您推荐的相同方法。这肯定更容易。但我只是想掌握使用 BS 的窍门。现在我几乎有一个表中所有值的列表,并试图弄清楚如何将它构造成一个数据框。另外,对不起,我在这里编辑时不断删除部分代码。现在应该一切都好。
  • 酷。您可以完全复制该代码以获取该列表吗?顺便说一句,我不是要批评,只是帮忙。这很棘手,所以绝对是示例/练习越多,就越容易
  • 我试图使用相同的功能。我在获取数据列表然后将其转换为数据框后尝试使用它,但是您这样做的方式要容易一些。感谢您的帮助
  • 我也补充一下,也没有义务。非常欢迎您继续努力并在 SO 上发帖。只是你还没有完全理解或感觉完全卡住了
  • 太棒了,如果你找到一个很好的例子,请随时通过 cubsrocker94@gmail.com 给我发电子邮件
猜你喜欢
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 2023-03-20
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多