如何解决,列表索引超出范围,从抓取网站?

How to resolve, list index out of range, from scraping website?

from bs4 import BeautifulSoup
import pandas as pd
with open("COVID-19 pandemic in the United States - Wikipedia.htm", "r", encoding="utf-8") as fd:
    soup=BeautifulSoup(fd)

print(soup.prettify())

all_tables = soup.find_all("table")
print("The total number of tables are {} ".format(len(all_tables)))

data_table = soup.find("div", {"class": 'mw-stack stack-container stack-clear-right mobile-float-reset'})
print(type(data_table))

sources = data_table.tbody.findAll('tr', recursive=False)[0]

sources_list = [td for td in sources.findAll('td')]

print(len(sources_list))


data = data_table.tbody.findAll('tr', recursive=False)[1].findAll('td', recursive=False)

data_tables = []

for td in data:

    data_tables.append(td.findAll('table'))

header1 = [th.getText().strip() for th in data_tables[0][0].findAll('thead')[0].findAll('th')]

header1

出于某种原因,最后一行 header 给我一个错误,“列表索引超出范围”。我不太确定是什么导致了这个错误的发生,但我知道我需要这一行。这是我用于数据的网站 link,https://en.wikipedia.org/wiki/COVID-19_pandemic_in_the_United_States。具体table我要的是水平条形图下方的那个


回溯

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-47-67ef2aac7bf3> in <module>
     28     data_tables.append(td.findAll('table'))
     29 
---> 30 header1 = [th.getText().strip() for th in data_tables[0][0].findAll('thead')[0].findAll('th')]
     31 
     32 header1

IndexError: list index out of range

使用pandas.read_html

  • 将 HTML table 读入 list of DataFrame objects.
  • 这个答案 side-steps 这个问题提供了一种更有效的方法来从维基百科中提取 tables 并且 为 OP 提供了所需的最终结果
  • 以下代码将更容易地从维基百科页面获取所需的 table。
  • .read_html 将 return 数据帧列表。
    • 您感兴趣的 table 位于索引 4
  • 清洁 table
    • Select 具有有效数据的行和列。
    • 此方法执行 return table headers,但列名称为 multi-level,因此我们将重命名它们。
      • 在重命名列之前,如果您需要列名中的原始数据,请使用us_covid_data.columns,这将return一个包含所有内容的元组列表列名值。
import pandas as pd

# get list of dataframes and select index 4
us_covid_data = pd.read_html('https://en.wikipedia.org/wiki/COVID-19_pandemic_in_the_United_States')[4]

# select rows and columns
us_covid_data = us_covid_data.iloc[0:56, 1:6]

# rename columns
us_covid_data.columns = ['state_territory', 'cases', 'deaths', 'recovered', 'hospitalized']

# display(us_covid_data)
             state_territory   cases deaths recovered hospitalized
0                    Alabama   45785   1033     22082         2961
1                     Alaska    1184     17       560           78
2             American Samoa       0      0         –            –
3                    Arizona  116892   2082         –         5272
4                   Arkansas   24253    292     17834         1604
5                 California  296499   6711         –            –
6                   Colorado   34316   1704         –         5527
7                Connecticut   46976   4338         –            –
8                   Delaware   12293    512      6778            –
9       District of Columbia   10569    561      1465            –
10                   Florida  244151   4102         –        15150
11                   Georgia  111211   2965         –        11919
12                      Guam    1272      6       179            –
13                    Hawaii    1012     19       746          116
14                     Idaho    8222     94      2886          350
15                  Illinois  151767   7144         –            –
16                   Indiana   49560   2698     36788         7139
17                      Iowa   31906    725     24242            –
18                    Kansas   17618    282         –         1269
19                  Kentucky   17526    623      4785         2662
20                 Louisiana   66435   3296     43026            –
21                     Maine    3440    110      2787          354
22                  Maryland   70497   3246         –        10939
23             Massachusetts  111110   8296     88725        10985
24                  Michigan   73403   6225     52841            –
25                 Minnesota   38606   1511     33907         4112
26               Mississippi   31257   1114     22167         2881
27                  Missouri   24985   1077         –            –
28                   Montana    1249     23       678           89
29                  Nebraska   20053    286     14641         1224
30                    Nevada   22930    537         –            –
31             New Hampshire    5914    382      4684          558
32                New Jersey  174628  15479     31014            –
33                New Mexico   14549    539      6181         2161
34                  New York  400299  32307     71371            –
35            North Carolina   81331   1479     55318            –
36              North Dakota    3858     89      3350          218
37  Northern Mariana Islands      31      2        19            –
38                      Ohio   57956   2927         –         7292
39                  Oklahoma   16362    399     12432         1676
40                    Oregon   10402    218      2846         1069
41              Pennsylvania   93876   6880         –            –
42               Puerto Rico    8714    157         –            –
43              Rhode Island   16991    960         –         1922
44            South Carolina   47214    838         –            –
45              South Dakota    7105     97      6062          689
46                 Tennessee   51509    646     31020         2860
47                     Texas  240111   3013    122996         9610
48            Virgin Islands     112      6        79            –
49                      Utah   25563    190     14448         1565
50                   Vermont    1251     56      1022            –
51                  Virginia   66740   1881         –         9549
52                Washington   38517   1370         –         4463
53             West Virginia    3461     95      2518            –
54                 Wisconsin   35318    805     25542         3574
55                   Wyoming    1675     20      1172          253

解决原始问题:

  • data 是从 data_table.tbody.findAll('tr', recursive=False)[1].findAll('td', recursive=False) 生成的空列表
    • data = data_table.tbody.findAll('tr', recursive=False)[1]然后data = [v for v in data.get_text().split('\n') if v],你会得到headers。
      • data 的输出将是 ['U.S. state or territory[i]', 'Cases[ii]', 'Deaths', 'Recov.[iii]', 'Hosp.[iv]', 'Ref.']
  • 由于 data_tables 是通过 data 迭代生成的,因此它也是空的。
  • header1是由迭代data_tables[0]生成的,所以IndexError是因为data_tables是空的。