为一个名称urllib2发送多个值

时间:2013-08-13 06:02:29

标签: python html request urllib2

我试着提交一个有复选框的网页,我需要选中其中10个复选框

问题是,当我尝试将它们分配到dict中的一个名称时,它只分配最后一个不是全部10个

所以我在这里如何做到这一点是请求代码:

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()

这有效,但我只发送"selected_itmes[]"的一个值当我在Web调试代理中查看实际请求时,它为"selected_items[]"发送多个值,但我不知道如何用python < / p>

请帮助谢谢!!

2 个答案:

答案 0 :(得分:11)

问题与urlencode无关;这是一个Python dict不能为同一个键保存多个值。您可以在print发送forms之前看到这一点 - selected_items[]只有一个值。那个值被编码得很好。

正如the documentation所解释的那样,有两种解决方法。

首先,您可以将一系列值附加到一个键,并使用doseq=True标志:

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

或者,您可以传递一系列两元素元组而不是映射:

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

(您也可以使用允许重复键的自定义Mapping类型,而不是标准dict,但这可能是过度的。特别是因为构建这样的自定义{{1}的常用方法} type是通过传递一系列键值对...)

答案 1 :(得分:0)

您可以通过创建一个类并使其返回相同的字符串来完成此操作。 在python3中:

import urllib.parse

class Value(object):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name

params = {Value("selected_items[]"): "one",
Value("selected_items[]"): "two"}

data = urllib.parse.urlencode(params)
print(data)

输出是:

selected_items%5B%5D=one&selected_items%5B%5D=two

解决方案是taken from here