Search code examples
pythonhtmlrequesturllib2

Sending multiple values for one name urllib2


im trying so submit a webpage that has checkboxes and i need up to 10 of these checkboxes checked

the problem is when i try to assign them to one name in a dict it only assigns the last one not all 10

so how can i do this here is the request code:

forms = {"_ref_ck": ref,
         "type": "create",
         "selected_items[]": sel_itms[0],
         "selected_items[]": sel_itms[1],
         "selected_items[]": sel_itms[2],
         "selected_items[]": sel_itms[3],
         "selected_items[]": sel_itms[4],
         "selected_items[]": sel_itms[5],
         "selected_items[]": sel_itms[6],
         "selected_items[]": sel_itms[7],
         "selected_items[]": sel_itms[8],
         "selected_items[]": sel_itms[9]

         }
data = urllib.urlencode(forms)
req = urllib2.Request('http://www.neopets.com/island/process_tradingpost.phtml',data)
res = self.opener.open(req)
html =  res.read()

this works but i only sends one value for "selected_itmes[]" when i look at the actual request in a web debugging proxy it sends multiple values for "selected_items[]" but i dont know how to do it with python

please help Thank you!!


Solution

  • The problem has nothing to do with urlencode; it's that a Python dict can't hold multiple values for the same key. You can see this by printing out forms before you send it—there's only one value there for selected_items[]. That one value gets encoded just fine.

    As the documentation explains, there are two ways around this.

    First, you can attach a sequence of values to one key, and use the doseq=True flag:

    forms = {"_ref_ck": ref,
         "type": "create",
         "selected_items[]": sel_itms[:10]
         }
     data = urllib.urlencode(forms, doseq=True)
    

    Alternatively, you can pass a sequence of two-element tuples instead of a mapping:

    forms = (("_ref_ck", ref),
             ("type", "create"),
             ("selected_items[]", sel_itms[0]),
             ("selected_items[]", sel_itms[1]),
             # ...
             )
    data = urllib.urlencode(forms)
    

    (You can also use a custom Mapping type that allows repeated keys, instead of a standard dict, but that's probably overkill. Especially since the usual way to construct such a custom Mapping type is by passing it a sequence of key-value pairs…)