【问题标题】:Python: BeautifulSoup combine different table headers from same tablePython:BeautifulSoup 组合来自同一个表的不同表头
【发布时间】:2021-05-19 19:35:58
【问题描述】:

Python 新手,所以这可能是一个基本问题,但我有下表:

https://www.sports-reference.com/cfb/years/1991-passing.html

我想用BeautifulSoup 刮掉它,得到这样的输出:

Player School Conf all the way to TD under Rushing
Ty Detmer Brigham Young WAC 7
Player Two School Two Conf 2 5

问题 1:如果您查看上面的 URL,每 21 行都是应该忽略的标题行 问题2:“Rushing”似乎是另一个th所以我下面的代码和输出目前是这样的:

import requests
import lxml.html as lh
import pandas as pd
from bs4 import BeautifulSoup

data_universe = {}
years = list(range(1990,1991))
COLUMNS = ['Player', 'School', 'Conf', 'G', 'Cmp', 'Att', 'Pct', 'Yds', 'Y/A', 'AY/A', 'TD', 'Int', 'Rate', 'Rush_Att', 'Rush_Yds', 'Avg', 'Rush_TD']

for year in years:

  url = 'https://www.sports-reference.com/cfb/years/%s-passing.html' %year
  r = requests.get(url)
  soup = BeautifulSoup(r.content, 'html.parser')
  parsed_table = soup.find_all('table')[0]
  rows = parsed_table.find_all("tr") 

  cy_data = []
  for row in rows[2:]:
      cells = row.find_all("td")
      cells = cells[0:18] 
      cy_data.append([cell.text for cell in cells]) # For each "td" tag, get the text inside it
  cy_data = pd.DataFrame(cy_data, columns=COLUMNS)
  pd.set_option("display.max_rows", None, "display.max_columns", None)
  print(cy_data.head())

输出:

如何像在网站上一样在数据框中整齐地格式化此表?

【问题讨论】:

    标签: python pandas dataframe beautifulsoup html-parsing


    【解决方案1】:

    您可以使用read_html 将html 表格直接加载到pandas 中,无需使用BeautifulSoup。然后,您可以通过删除顶部标题行和中间表标题行来处理数据框:

    df = pd.read_html('https://www.sports-reference.com/cfb/years/1991-passing.html')[0]
    df.columns = df.columns.droplevel(0) # drop top header row
    df = df[df['Rk'].ne('Rk')] # remove mid-table header rows 
    

    输出:

    |    |   Rk | Player         | School        | Conf     |   G |   Cmp |   Att |   Pct |   Yds |   Y/A |   AY/A |   TD |   Int |   Rate |   Att |   Yds |   Avg |   TD |
    |---:|-----:|:---------------|:--------------|:---------|----:|------:|------:|------:|------:|------:|-------:|-----:|------:|-------:|------:|------:|------:|-----:|
    |  0 |    1 | Ty Detmer      | Brigham Young | WAC      |  12 |   249 |   403 |  61.8 |  4031 |  10   |   10.4 |   35 |    12 |  168.5 |    75 |   -30 |  -0.4 |    4 |
    |  1 |    2 | Rick Mirer     | Notre Dame    | Ind      |  12 |   132 |   234 |  56.4 |  2117 |   9   |    8.7 |   18 |    10 |  149.2 |    75 |   306 |   4.1 |    9 |
    |  2 |    3 | J.J. Joe       | Baylor        | SWC      |  11 |   109 |   206 |  52.9 |  1853 |   9   |    7.9 |    7 |     8 |  131.9 |   116 |   147 |   1.3 |    6 |
    |  3 |    4 | Shane Matthews | Florida       | SEC      |  11 |   218 |   361 |  60.4 |  3130 |   8.7 |    8   |   28 |    18 |  148.8 |    50 |    10 |   0.2 |    1 |
    |  4 |    5 | Marvin Graves  | Syracuse      | Big East |  11 |   131 |   221 |  59.3 |  1912 |   8.7 |    7.3 |   10 |    11 |  136.9 |    99 |  -148 |  -1.5 |    1 |
    

    【讨论】:

    • 嗯,谢谢,但是当我这样做时,我仍然会在第一个“Att”列之后得到反斜杠,它像上面的输出一样将其拆分
    • 什么意思?输出的格式?只需运行 df.head() 而不是 print(df.head())。
    • 啊酷。我不知道.droplevel()。您也可以通过df = pd.read_html('https://www.sports-reference.com/cfb/years/1991-passing.html', header=1)[0] 立即获得.read_html() 中的1 级
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    相关资源
    最近更新 更多