Tanvir Khan
Tanvir Khan

Reputation: 113

Scraping dynamically generated HTML table without an ID and Class with BeautifulSoup

I generated a table using Python Selenium and the source code of the generated table looks like the following (the code has

        <TABLE cellSpacing=0 cellPadding=0 width=806 border=0>
    <TBODY>
    <TR>          <TD width="603" height="25" colspan="4" align="center" bgcolor="#00596B">            
        <b><font color="#FFFFFF">Day End Summary from Jan 03, 2019 to Jan 01, 2019</font></b>             </TD>       </TR>

    <tr>
      <TD vAlign=top align=middle width="603" style="min-height:980px;">
        <table border="0" cellpadding="" width="603" bgcolor="#808000" cellspacing="1">
          <tr bgcolor="#D6D6D6" height="25">
            <td align="center"><font color="#000" size="2">#</font></td>
          <td align="center"><font color="#000" size="2">DATE</font></td>
          <td align="center"><font color="#000" size="2">TRADING CODE</font></td>
            <td align="center"><font color="#000" size="2">LTP*</font></td>
          <td align="center"><font color="#000" size="2">HIGH</font></td>
          <td align="center"><font color="#000" size="2">LOW</font></td>
          <td align="center"><font color="#000" size="2">OPENP*</font></td>
          <td align="center"><font color="#000" size="2">CLOSEP*</font></td>
          <td align="center"><font color="#000" size="2">YCP</font></td>
          <td align="center"><font color="#000" size="2">TRADE</font></td>
          <td align="center"><font color="#000" size="2">VALUE (mn)</font></td>
          <td align="center"><font color="#000" size="2">VOLUME</font></td>                
          </tr>

          <tr bgcolor="#FFFFFF" height="20">
            <td align="center"> <font face="Arial" style="size:11px;">1</font></td>
          <td align="center"> <font face="Arial" style="size:11px;">2019-01-03</font></td>
          <td align="left"><a href = "displayCompany.php?name=ACI" class='ab1'><font face="Arial" style="size:11px;">ACI</font></a></td>
          <td align="right"><font face="Arial" style="size:11px;">328.5</font></td>
          <td align="right"><font face="Arial" style="size:11px;">329.9</font></td>
          <td align="right"><font face="Arial" style="size:11px;">323</font></td>
          <td align="right"><font face="Arial" style="size:11px;">325.7</font></td>
          <td align="right"><font face="Arial" style="size:11px;">328.4</font></td>
          <td align="right"><font face="Arial" style="size:11px;">325.7</font></td>
          <td align="right"><font face="Arial" style="size:11px;">256</font></td>
          <td align="right"><font face="Arial" style="size:11px;">5.285</font></td>
          <td align="right"><font face="Arial" style="size:11px;">16,158</font></td>
          </tr>

          <tr bgcolor="#EFEFEF" height="20">
            <td align="center"> <font face="Arial" style="size:11px;">2</font></td>
          <td align="center"> <font face="Arial" style="size:11px;">2019-01-02</font></td>
          <td align="left"><a href = "displayCompany.php?name=ACI" class='ab1'><font face="Arial" style="size:11px;">ACI</font></a></td>
          <td align="right"><font face="Arial" style="size:11px;">325.5</font></td>
          <td align="right"><font face="Arial" style="size:11px;">328.8</font></td>
          <td align="right"><font face="Arial" style="size:11px;">324.3</font></td>
          <td align="right"><font face="Arial" style="size:11px;">326</font></td>
          <td align="right"><font face="Arial" style="size:11px;">325.7</font></td>
          <td align="right"><font face="Arial" style="size:11px;">327.6</font></td>
          <td align="right"><font face="Arial" style="size:11px;">289</font></td>
          <td align="right"><font face="Arial" style="size:11px;">7.443</font></td>
          <td align="right"><font face="Arial" style="size:11px;">22,851</font></td>
          </tr>

          <tr bgcolor="#FFFFFF" height="20">
            <td align="center"> <font face="Arial" style="size:11px;">3</font></td>
          <td align="center"> <font face="Arial" style="size:11px;">2019-01-01</font></td>
          <td align="left"><a href = "displayCompany.php?name=ACI" class='ab1'><font face="Arial" style="size:11px;">ACI</font></a></td>
          <td align="right"><font face="Arial" style="size:11px;">329.1</font></td>
          <td align="right"><font face="Arial" style="size:11px;">329.9</font></td>
          <td align="right"><font face="Arial" style="size:11px;">325.6</font></td>
          <td align="right"><font face="Arial" style="size:11px;">329.9</font></td>
          <td align="right"><font face="Arial" style="size:11px;">327.6</font></td>
          <td align="right"><font face="Arial" style="size:11px;">326.2</font></td>
          <td align="right"><font face="Arial" style="size:11px;">153</font></td>
          <td align="right"><font face="Arial" style="size:11px;">3.234</font></td>
          <td align="right"><font face="Arial" style="size:11px;">9,890</font></td>
          </tr>

        </table>

The link of the page is here Dhaka Stock Exchange Historical Price. Now, how can I extract the full table from here? The table seems not to have any ID and Class. I am completely new to HTML and web scraping and need to do it for a project that has a very tight schedule. Any kind of help would be appreciated.

Update: I could extract the required table with the following code- def extractdse(fdate, tday, instrument):

# load the driver
driver = webdriver.Chrome()

# load DSE data archive site
driver.get('https://www.dsebd.org/day_end_archive.php')

# deal with the pop up warning
try: 
    alert = driver.switch_to.alert
    alert.accept()
except NoAlertPresentException:
    print ("No alert here")

# from date
fdate=datetime.datetime.strptime(fdate, '%Y-%m-%d')
yr=str(fdate.year)
mn='0'+str(fdate.month)
dy='0'+str(fdate.day)

# to date
tday=datetime.datetime.strptime(tday, '%Y-%m-%d')
bdd='0'+str(tday.day)
bdm='0'+str(tday.month)
bdy=str(tday.year)

# beginning day
x=Select(driver.find_element_by_name("DayEndSumDate1_day"))
x.select_by_value(dy)

# beginning month
y=Select(driver.find_element_by_name("DayEndSumDate1_month"))
y.select_by_value(mn)

# beginning year
z=Select(driver.find_element_by_name("DayEndSumDate1_year"))
z.select_by_value(yr)

# end day
xp=Select(driver.find_element_by_name("DayEndSumDate2_day"))
xp.select_by_value(bdd)

# end month
yp=Select(driver.find_element_by_name("DayEndSumDate2_month"))
yp.select_by_value(bdm)

# end year
zp=Select(driver.find_element_by_name("DayEndSumDate2_year"))
zp.select_by_value(bdy)

# instrument
inst=Select(driver.find_element_by_name("Symbol"))
inst.select_by_visible_text(instrument)

# generate the table
driver.find_element_by_name("ViewDayEndArchive").click()

# extract the table
soup = BeautifulSoup(driver.page_source, 'html.parser')
tables = soup.find_all('table')
tt=tables[374]
#ti=pd.read_html(tt)
#tm=display_html(tt, raw=True)
#tx=pd.read_html(tt)
return(tt)

And now can extract the HTML code for the required table with-

extractdse('2019-01-01', '2019-01-03', 'ACI')

Now, is there any way to convert the HTML code into Pandas Dataframe?

Upvotes: 1

Views: 115

Answers (1)

Jack Fleeting
Jack Fleeting

Reputation: 24930

You probably should use pandas for this. Something like:

my_table = """
  [the code from your question]
 """

import pandas as pd

pad_table = pd.read_html(my_table)
pad_table

This should get you most of the way there.

Upvotes: 1

Related Questions