Search code examples
pythonpandasbeautifulsouphtml-parsing

"How to fix 'AttributeError: 'NoneType' object has no attribute 'tbody'' error in Python?


I expected a csv file created with in my desktop directory.

import requests from bs4 import BeautifulSoup import pandas as pd

url = "https://basketball.realgm.com/ncaa/conferences/Big-12- 
Conference/3/Kansas/54/nba-players"

# get permission
response = requests.get(url)

# access html files
soup = BeautifulSoup(response.text, 'html.parser')

 # creating data frame
columns = ['Player', 'Position', 'Height', 'Weight', 'Draft Year', 'NBA 
Teams', 'Years', 'Games Played','Points Per Game', 'Rebounds Per Game', 
'Assists Per Game']

df = pd.DataFrame(columns=columns)

table = soup.find(name='table', attrs={'class': 'tablesaw','data- 
tablesaw-mode':'swipe','id': 'table-6615'}).tbody

trs = table.find('tr')

# rewording html

for tr in trs:
   tds = tr.find_all('td')
   row = [td.text.replace('\n', '')for td in tds]
   df = df.append(pd.Series(row, index=columns), ignore_index=True)


df.to_csv('kansas_player', index=False)

I expected a csv file created with in my desktop directory.


Solution

  • Looks like by your way the soup.find(...) can not find 'table', and that's might be why you get a None type returned, here is my change and you can tailor it to cope with you csv export need:

    from bs4 import BeautifulSoup
    import urllib.request
    
    url = "https://basketball.realgm.com/ncaa/conferences/Big-12-Conference/3/Kansas/54/nba-players"
    
    # get permission
    response = urllib.request.urlopen(url)
    
    # access html files
    html = response.read()
    soup = BeautifulSoup(html)
    table = soup.find("table", {"class": "tablesaw"})
    

    At this point, you can return full table content as: enter image description here

    From there on, you can easily extract the table row information by such as:

    for tr in table.findAll('tr'):
        tds = tr.find_all('td')
        row = [td.text.replace('\n', '')for td in tds]
        .....
    

    Now each row would look like: enter image description here

    Finally, you can write each row into the csv with or without the pandas, your call then.