In a For Loop, using bs4, how would this function return a df (as a column) and insert it into a final giant df?

Viewed 32

For the most part, I've made a scraper using bs4 and a For Loop. I was wondering how to get the final contents of each "For Loop Grab" and put them into a final dataframe.

This is my current code:

from urllib.request import Request, urlopen
import bs4 as soup
from numpy.lib.utils import source
import pandas as pd

df = pd.read_excel('C:/Users/Jacob/Downloads/CEF Tickers.xlsx', sheet_name='Sheet1')

#Read in a list of tickers from a spreadsheet

tickers_list = df['Ticker'].tolist()

#final dataframe
data = pd.DataFrame(columns=tickers_list)


for ticker in tickers_list:

#Opening the website
        source = urlopen(Request(f'https://www.cefconnect.com/fund/{ticker}' , headers={'User-Agent': 'Mozilla/5.0'}))
        
        site = soup.BeautifulSoup(source,'lxml')
        #Getting the exact table
        table = site.find('table', attrs={'id':'ContentPlaceHolder1_cph_main_cph_main_ucPerformance_gvPast20'})

        table_rows = table.find_all('tr')
#Building the df with the table
        table8 = []
        for tr in table_rows:
            td = tr.find_all('td')
            row = [tr.text for tr in td]
            table8.append(row)
        df8 = pd.DataFrame(table8, columns=["Period","Price Return", "NAV Return", "Category Price Return", "Category NAV Return"])
        df8 = pd.DataFrame.transpose(df8)
        del df8[0]

        new_header = df8.iloc[0].astype(str)
        df8 = df8[1:]
        df8.columns = new_header

#Making the df into 1 line and then transposing it into a column
        df8 = df8.unstack().to_frame().sort_index(level=1).T
        df8.columns = df8.columns.map('_'.join)
        df8.set_index([f'{ticker}'], inplace = True)
        df8 = pd.DataFrame.transpose(df8)
        data.append(df8)

Here is a sample set of tickers:

["NIE", "ZTR", "SCD", "GLV"]

When I run this I get:

KeyError: "None of ['NIE'] are in the columns"

But when I run them individually, it works.

I'm still a beginner so forgive me if I'm missing something obvious but for the life of me, I don't understand why this doesn't work.

Thank you for your time.

1 Answers

You can use pandas.read_html to load a <table> into a dataframe. For example:

import requests
import pandas as pd
from bs4 import BeautifulSoup


headers = {
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0"
}

tickers_list = ["NIE", "ZTR", "SCD", "GLV"]

all_dfs = []
for ticker in tickers_list:
    print("Downloading ticker {}".format(ticker))
    soup = BeautifulSoup(
        requests.get(
            f"https://www.cefconnect.com/fund/{ticker}", headers=headers
        ).content,
        "html.parser",
    )
    df = pd.read_html(
        str(
            soup.select_one(
                "#ContentPlaceHolder1_cph_main_cph_main_ucPerformance_gvPast20"
            )
        )
    )[0]
    df["Ticker"] = ticker
    all_dfs.append(df)

final_df = pd.concat(all_dfs)
print(final_df)
final_df.to_csv("data.csv")

Prints:

   Return Year    Price      NAV Category - Price Category - NAV Ticker
0          YTD   16.49%   20.88%          -10.00%         -3.61%    NIE
1         2019   31.06%   26.09%           29.77%         22.10%    NIE
2         2018   -5.70%   -3.76%           -8.36%         -4.98%    NIE
3         2017   23.69%   16.79%           21.52%         14.50%    NIE
4         2016   11.31%    9.14%           17.59%         13.14%    NIE
5         2015   -5.89%   -1.42%           -9.73%         -7.35%    NIE
6         2014   13.05%    7.31%           11.82%          9.17%    NIE
7         2013   26.06%   25.15%           19.53%         19.58%    NIE
8         2012   13.91%   11.84%           13.72%         13.14%    NIE
9         2011   -8.53%   -2.95%            1.24%          3.22%    NIE
10        2010   17.44%   15.33%           15.07%         13.03%    NIE
11        2009   47.91%   43.66%           43.70%         32.32%    NIE
12        2008  -37.54%  -38.48%          -44.21%        -40.86%    NIE
0          YTD  -23.06%   -7.52%          -15.54%         -9.20%    ZTR
1         2019   59.58%   30.14%           32.69%         22.80%    ZTR
2         2018  -23.48%  -17.43%          -18.78%        -12.01%    ZTR
3         2017   25.10%   22.57%           28.74%         18.14%    ZTR
4         2016   28.99%   15.63%            8.69%          9.54%    ZTR
5         2015   -7.53%   -4.55%           -7.10%         -4.69%    ZTR
6         2014   24.67%   12.66%            7.81%          6.00%    ZTR
7         2013    7.08%   14.39%           21.98%         22.48%    ZTR
8         2012   17.68%   15.29%           18.62%         18.00%    ZTR
9         2011    5.74%    6.29%           -4.51%         -3.46%    ZTR
10        2010   53.75%   48.54%           28.97%         26.03%    ZTR
11        2009   35.12%   26.42%           62.84%         38.80%    ZTR
12        2008  -68.93%  -65.18%          -49.30%        -44.22%    ZTR
13        2007  -44.78%  -41.41%              NaN            NaN    ZTR
14        2006   43.67%   25.40%              NaN            NaN    ZTR
0          YTD  -23.71%  -16.42%          -15.54%         -9.20%    SCD
1         2019   59.11%   38.71%           32.69%         22.80%    SCD
2         2018  -15.39%  -10.43%          -18.78%        -12.01%    SCD
3         2017   14.65%    7.78%           28.74%         18.14%    SCD
4         2016   18.27%   13.03%            8.69%          9.54%    SCD
5         2015  -19.90%  -16.01%           -7.10%         -4.69%    SCD
6         2014   13.37%   12.76%            7.81%          6.00%    SCD
7         2013   26.19%   33.39%           21.98%         22.48%    SCD
8         2012   18.35%   14.32%           18.62%         18.00%    SCD
9         2011    6.45%    4.84%           -4.51%         -3.46%    SCD
10        2010   26.30%   14.83%           28.97%         26.03%    SCD
11        2009   42.20%   29.52%           62.84%         38.80%    SCD
12        2008  -50.71%  -44.43%          -49.30%        -44.22%    SCD
13        2007   11.05%    7.41%              NaN            NaN    SCD
14        2006   19.04%   14.88%              NaN            NaN    SCD
15        2005    5.28%    8.90%              NaN            NaN    SCD
0          YTD   -1.42%   -1.22%          -15.54%         -9.20%    GLV
1         2019   22.25%   13.22%           32.69%         22.80%    GLV
2         2018  -16.15%  -10.39%          -18.78%        -12.01%    GLV
3         2017   22.36%   19.26%           28.74%         18.14%    GLV
4         2016    0.40%   -1.87%            8.69%          9.54%    GLV
5         2015    0.80%   -4.13%           -7.10%         -4.69%    GLV
6         2014    6.55%    4.04%            7.81%          6.00%    GLV
7         2013   21.59%   21.02%           21.98%         22.48%    GLV
8         2012   17.57%   15.31%           18.62%         18.00%    GLV
9         2011  -12.26%  -10.31%           -4.51%         -3.46%    GLV
10        2010   12.33%   12.11%           28.97%         26.03%    GLV
11        2009   55.58%   43.41%           62.84%         38.80%    GLV
12        2008  -45.66%  -40.74%          -49.30%        -44.22%    GLV
13        2007    8.33%   15.57%              NaN            NaN    GLV
14        2006  -10.08%    7.04%              NaN            NaN    GLV
15        2005   35.66%   23.52%              NaN            NaN    GLV

And saves data.csv:

enter image description here

Related