Python:urllib.urlencode正在逃避我的东西*两次*

时间:2013-02-26 20:12:42

标签: python urlencode urllib

...但它并没有两次以相同的方式逃避

我正在尝试将gpg的ASCII输出上传到网站。所以,到目前为止,我所获得的位只是查询表,向我显示它获得的数据,然后在对其进行HTTP POST请求编码后向我显示:

cnx = connect()
sql = ("SELECT Data FROM SomeTable")
cursor = cnx.cursor()
cursor.execute(sql)
for (data) in cursor:
        print "encoding : %s" % data
        postdata = urllib.urlencode( { "payload" : data } ) 
        print "encoded as %s" % postdata

...但我得到的是:

encoding : -----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.12 (GNU/Linux)
.... etc...

encoded as payload=%28u%27-----BEGIN+PGP+MESSAGE-----%5CnVersion%3A+GnuPG+v1.4.12+... etc ...

需要注意的部分是新线不会像我期望的那样变成%0A。相反,它们以某种方式被转换为“\ n”,然后反斜杠被转义为%5C,因此换行符变为“%5Cn”。更奇怪的是,数据前面带有%28u%27 ,它出现在“(u'”。

奇怪的是,如果我只是做一个基本测试:

data = "1\n2"
print data
print urllib.urlencode( { "payload" : data } )

我得到了我的期望,换行转为%0A ......

1
2
payload=1%0A2

所以,我的预感是从mysql查询返回的数据元素与我的文字“1 \ n2”(可能是1元素的dict ... dunno)不是同一种字符串,但我不知道让Python功夫知道如何检查它。

有人知道这里发生了什么,以及我如何解决这个问题?如果没有,有关如何通过HTTP发布此内容以及所有内容正确转义的建议吗?

1 个答案:

答案 0 :(得分:0)

假设connect()是来自某个DB-API 2.0兼容数据库接口的函数(如内置sqlite3或最受欢迎的mysql接口),{{1}迭代for (data) in cursor:个对象,而不是字符串。

当您将其打印出来时,您实际上是在打印Row(通过将其传递给str(data)格式)。如果你想编码相同的东西,你必须编码%s

但是,更好的方法是首先将行作为行(一列)处理,而不是依靠str(data)来执行您想要的操作。

PS,如果你试图依靠元组解包来使str成为每一行的第一个元素,你就错了:

data

......与:

相同
for (data) in cursor:

如果你想要一个单元素for data in cursor: ,你需要一个逗号:

tuple

(如果你愿意,你也可以添加parens,但无论如何它们仍然没有任何区别。)

具体来说,迭代游标将调用可选的__iter__方法,该方法返回游标本身,然后循环调用next方法,这与调用for data, in cursor: 的方法相同。直到结果集用尽,并且fetchone被记录为返回“单个序列”,其类型未定义。在大多数实现中,这是一种特殊的行类型,如sqlite3.Row,可以像fetchone()一样进行访问,但对于以表格格式打印,允许按名称访问等方式具有特殊语义