Search code examples
pythonhtmlinputbeautifulsoupmechanize

extract label value for checkbox input object with beautiful soup instead of mechanize in python


New to mechanize and BeautifulSoup and am loving it.

I used the prototypical way of opening a URL with mechanize, and I now have the returned object:

    def OpenURL(URL, USERAGENT):
        br = Browser()# Create a browser
        br.set_handle_robots(False)   # no robots
        br.set_handle_refresh(False)  # can sometimes hang without this
        br.addheaders = [('User-agent', USERAGENT)]
        #open the URL
        result = br.open(URL)# Open the login page
        return result

In my returned result, I have an input object of type "checkbox", name "BoxName". The checkbox has a label. The HTML looks like this:

    <input type="checkbox" name="BoxName" checked="checked" disabled="disabled" />
    <label for="BoxName">DESIREDTEXT</label>

I am able to get the DESIREDTEXT with mechanize as follows: (code paraphrased to save space)

    if control.type == "checkbox": 
        for item in control.items:
            if(control.name == "BoxName"):
                DESIREDTEXT = str([label.text  for label in item.get_labels()])

Is there an equivalent way to get the label text value with BeautifulSoup? I am happy to use mechanize to retrieve it, but I just wondered if BeautifulSoup had the ability as well.

addendum **

HTML from source:

    <input id="ctl00_ContentPlaceHolder1_chkCheckedIn" type="checkbox" name="ctl00$ContentPlaceHolder1$chkCheckedIn" checked="checked" disabled="disabled" />
    <label for="ctl00_ContentPlaceHolder1_chkCheckedIn">Checked-In 1/17/2013 1:23:01 AM</label>

This is the code where Inbox.read() outputs all the HTML. I verified that the label is there:

    soup = BeautifulSoup(Inbox.read())
print soup.find('label',{'for': 'ctl00_ContentPlaceHolder1_chkCheckedIn'}).text

This is my error:

    AttributeError                            Traceback (most recent call last)

/usr/local/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where) 176 else: 177 filename = fname --> 178 builtin.execfile(filename, *where)

/home/ubuntu/testAffinity.py in () 133 from BeautifulSoup import BeautifulSoup 134 soup = BeautifulSoup(Inbox.read()) --> 135 print soup.find('label',{'for': 'ctl00_ContentPlaceHolder1_chkCheckedIn'}).text 136 137

AttributeError: 'NoneType' object has no attribute 'text'

Not sure what I'm missing here, but it has to be simple. I notice that the 'for' value is different than the checkbox "name" value. I tried using the checkbox "name" value but received the same error.

** after upgrade to bs4

133 from bs4 import BeautifulSoup 134 soup = BeautifulSoup(Inbox.read()) --> 135 print soup.find('label',{'for': 'ctl00_ContentPlaceHolder1_chkCheckedIn'}).text 136 137

AttributeError: 'NoneType' object has no attribute 'text'

**post upgrade to 4 I printed soup. The attribute is correct. The label is in the html from the print soup.

    <input checked="checked" disabled="disabled" id="ctl00_ContentPlaceHolder1_chkCheckedIn" name="ctl00$ContentPlaceHolder1$chkCheckedIn" type="checkbox"/>
    <label for="ctl00_ContentPlaceHolder1_chkCheckedIn">Checked-In 1/17/2013 1:23:01 AM</label>

Solution

  • Yes, just give it a try:

    soup.find('label',{'for':'BoxName'}).text
    

    with your function it would look like:

    html = OpenURL(URL, USERAGENT).read()
    soup = BeautifulSoup(html)
    print soup.find('label',{'for':'BoxName'}).text