Return one iteration of data across multiple, non-uniform tables in python (with bs4)?

Viewed 78

I'm trying to iterate through a series of tables with data that isn't entered uniformly across them. I'm using python & bs4.

These tables contain legislation information in them - when they were sent to the governor (or not), when they were signed (or not), when they were vetoed (or not).

I only want to return the following: (delivery/sign/vetoed & date). Or, (not delivered/not signed/not vetoed & no date). Problem is, when I iterate through the lists it goes through every row and returns results for every row. I want the code to stop when either scenario is fulfilled and only return on pair of results. See below:

        tablebody=soup.select_one(".table.c-bill--actions-table > tbody")
        for item in tablebody.select("td"):
            
            if "delivered to governor" in item.text:
                transfer_list.append("delivered to governor")
                transfer_list.append(item.find_previous("td").text)
            else:
                transfer_list.append("not delivered")
                transfer_list.append("no date")
                
        tablebody=soup.select_one(".table.c-bill--actions-table > tbody")
        for item in tablebody.select("td"):
            
            if "signed" in item.text:
                transfer_list.append("signed")
                transfer_list.append(item.find_previous("td").text)
                
            else:
                transfer_list.append("not signed")
                transfer_list.append("no date")
                             
        
        tablebody=soup.select_one(".table.c-bill--actions-table > tbody")
        for item in tablebody.select("td"):
            
            if "vetoed" in item.text:
                transfer_list.append("vetoed")
                transfer_list.append(item.find_previous("td").text)
                
            else:
                transfer_list.append("not vetoed")
                transfer_list.append("no date")

My current output looks like this:

 ['senate        Bill S3984',
  'Creates the crime of related use of a lethal or explosive device',
  'Liz Krueger',
  '(D, WF) 28th\xa0Senate District',
  'No votes for this bill.',
  'A2645',
  'not delivered',
  'no date',
  'not delivered',
  'no date',
  'not delivered',
  'no date',
  'not delivered',
  'no date',
  'not signed',
  'no date',
  'not signed',
  'no date',
  'not signed',
  'no date',
  'not signed',
  'no date',
  'not vetoed',
  'no date',
  'not vetoed',
  'no date',
  'not vetoed',
  'no date',
  'not vetoed',
  'no date'],

Any thoughts? I only need one iteration of (delivered,signed,vetoed) and the accompanying (date/no-date).

1 Answers

It's because it's checking each <td> item. There's a few ways to do it.

Just get all the items into a list and see if the item is present. Another way you could do it is put in additional logic checks:

   tablebody=soup.select_one(".table.c-bill--actions-table > tbody")
   
   check_list = [item.text.strip() for item in tablebody.select("td")]

    if "delivered to governor" in check_list:
        transfer_list.append("delivered to governor")
        i = check_list.index("delivered to governor")
        transfer_list.append(check_list[i+1])
        
    else:
        transfer_list.append("not delivered")
        transfer_list.append("no date")
        
    if "signed" in check_list:
        transfer_list.append("signed")
        i = check_list.index("signed")
        transfer_list.append(check_list[i+1])
        
    else:
        transfer_list.append("not signed")
        transfer_list.append("no date")
        
    if "vetoed" in check_list:
        transfer_list.append("vetoed")
        i = check_list.index("vetoed")
        transfer_list.append(check_list[i+1])
        
    else:
        transfer_list.append("not vetoed")
        transfer_list.append("no date")
Related