Nant
Nant

Reputation: 569

Get content of table in BeautifulSoup

I have the following table on a website which I am extracting with BeautifulSoup This is the url (I have also attached a picture enter image description here

Ideally I would like to have each company in one row in csv however I am getting it in different rows. Please see picture attached.

enter image description here

I would like it to have it like in field "D" but I am getting it in A1,A2,A3...

This is the code I am using to extract:

def _writeInCSV(text):
    print "Writing in CSV File"
    with open('sara.csv', 'wb') as csvfile:
        #spamwriter = csv.writer(csvfile, delimiter='\t',quotechar='\n', quoting=csv.QUOTE_MINIMAL)
        spamwriter = csv.writer(csvfile, delimiter='\t',quotechar="\n")

        for item in text:
            spamwriter.writerow([item])

read_list=[]
initial_list=[]


url="http://www.nse.com.ng/Issuers-section/corporate-disclosures/corporate-actions/closure-of-register"
r=requests.get(url)
soup = BeautifulSoup(r._content, "html.parser")

#gdata_even=soup.find_all("td", {"class":"ms-rteTableEvenRow-3"})

gdata_even=soup.find_all("td", {"class":"ms-rteTable-default"})




for item in gdata_even:
    print item.text.encode("utf-8")
    initial_list.append(item.text.encode("utf-8"))
    print ""

_writeInCSV(initial_list)

Can someone help please ?

Upvotes: 4

Views: 700

Answers (2)

WGS
WGS

Reputation: 14169

Since @alecxe has already provided an amazing answer, here's another take using the pandas library.

import pandas as pd

url = "http://www.nse.com.ng/Issuers-section/corporate-disclosures/corporate-actions/closure-of-register"
tables = pd.read_html(url)

tb1 = tables[0] # Get the first table.
tb1.columns = tb1.iloc[0] # Assign the first row as header.
tb1 = tb1.iloc[1:] # Drop the first row.
tb1.reset_index(drop=True, inplace=True) # Reset the index.

print tb1.head() # Print first 5 rows.
# tb1.to_csv("table1.csv") # Export to CSV file.

Result:

In [5]: runfile('C:/Users/.../.spyder2/temp.py', wdir='C:/Users/.../.spyder2')
0                 Company       Dividend    Bonus     Closure of Register  \
0  Nigerian Breweries Plc          N3.50      Nil   5th - 11th March 2015   
1           Forte Oil Plc          N2.50  1 for 5    1st – 7th April 2015   
2          Nestle Nigeria         N17.50      Nil         27th April 2015   
3       Greif Nigeria Plc        60 kobo      Nil  25th - 27th March 2015   
4       Guaranty Bank Plc  N1.50 (final)      Nil         17th March 2015   

0          AGM Date     Payment Date  
0     13th May 2015    14th May 2015  
1   15th April 2015  22nd April 2015  
2     11th May 2015    12th May 2015  
3   28th April 2015     5th May 2015  
4  ​31st March 2015  31st March 2015  

In [6]: 

Upvotes: 1

alecxe
alecxe

Reputation: 473873

Here is the idea:

  • read the header cells from the table
  • read all the other rows from the table
  • zip all the data row cells with headers producing a list of dictionaries
  • use csv.DictWriter() to dump to csv

Implementation:

import csv
from pprint import pprint

from bs4 import BeautifulSoup
import requests

url = "http://www.nse.com.ng/Issuers-section/corporate-disclosures/corporate-actions/closure-of-register"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

rows = soup.select("table.ms-rteTable-default tr")
headers = [header.get_text(strip=True).encode("utf-8") for header in rows[0].find_all("td")]

data = [dict(zip(headers, [cell.get_text(strip=True).encode("utf-8") for cell in row.find_all("td")]))
        for row in rows[1:]]

# see what the data looks like at this point
pprint(data)

with open('sara.csv', 'wb') as csvfile:
    spamwriter = csv.DictWriter(csvfile, headers, delimiter='\t', quotechar="\n")

    for row in data:
        spamwriter.writerow(row)

Upvotes: 3

Related Questions