V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
cwlmxwb
V2EX  ›  Python

Python 和浏览器 POST 数据时编码出现不同,求帮助

  •  
  •   cwlmxwb · 2016-05-30 18:26:22 +08:00 · 3997 次点击
    这是一个创建于 2881 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想用 python 模拟向某个网站 POST 数据,我使用 python 将需要 POST 的数据执行下面的代码后: post_to_short_url = { 'url':'http://djaa.cn/shopUrl.php?shopName=%s&shopUrl=%s&userid=%s'%(name, urls, userid), 'a':'6', 'b':'5' } data = urllib.parse.urlencode(post_to_short_url).encode(encoding='UTF-8') print (data)

    然后结果是: a=6&url=http%3A%2F%2Fdjaa.cn%2FshopUrl.php%3FshopName%3D%E6%89%8B%E6%9C%BA%E5%A4%A9%E7%8C%AB%E5%95%86%E5%93%81%E8%AF%A6%E6%83%85%26shopUrl%3Dhttps%3A%5C%2F%5C%2Fdetail.m.tmall.com%5C%2Fitem.htm%3Fid%3D531548555213%26userid%3D298841&b=5 这一串就是 Python 要向服务器 POST 的数据

    然后我又使用火狐浏览器 POST 一样的数据,然后用 HttpFox 来抓包分析,结果看到浏览器像服务器 POST 的数据是: url=http%3A%2F%2Fdjaa.cn%2FshopUrl.php%3FshopName%3D%E6%89%8B%E6%9C%BA%E5%A4%A9%E7%8C%AB%E5%95%86%E5%93%81%E8%AF%A6%E6%83%85%26shopUrl%3Dhttps%253A%252F%252Fdetail.m.tmall.com%252Fitem.htm%253Fid%253D531548555213%26userid%3D298841&a=6&b=5

    然后我仔细对比了下两个 POST 的异同,发现: 1 : python 把冒号:编码成%3A ,把反斜杠编码成%5C2F 2 :浏览器把冒号:编码成%253A ,把反斜杠编码成%252F

    然后查看了下浏览器的编码方式 UTF-8 ,而 Python 也用了 UTF-8 方式编码然后结果却不一样

    谁可以帮我分析下 /(ㄒoㄒ)/~~

    12 条回复    2016-05-31 11:21:51 +08:00
    hrong
        1
    hrong  
       2016-05-30 18:34:07 +08:00 via Android
    用别的库试试?
    gulucn
        2
    gulucn  
       2016-05-30 18:41:09 +08:00 via Android
    python 的 shortUrl 的值应该先 urlencode ?
    yejinmo
        3
    yejinmo  
       2016-05-30 18:46:23 +08:00 via Android
    我也碰见过这种情况,没查出结果,于是就手动 replace 了😂
    cwlmxwb
        4
    cwlmxwb  
    OP
       2016-05-30 18:53:02 +08:00 via iPhone
    @yejinmo 你是哪个版本的 py
    yangtukun1412
        5
    yangtukun1412  
       2016-05-30 18:58:18 +08:00
    >>> urllib.parse.urlencode({'url': 'http://www.baidu.com'})
    'url=http%3A%2F%2Fwww.baidu.com'
    >>> urllib.parse.urlencode({'url': urllib.parse.quote_plus('http://www.baidu.com')})
    'url=http%253A%252F%252Fwww.baidu.com'
    kfll
        6
    kfll  
       2016-05-30 18:58:33 +08:00
    post_to_short_url = { 'url':'http://djaa.cn/shopUrl.php?shopName=%s&shopUrl=%s&userid=%s'%(name, urllib.parse.urlencode(urls).encode(encoding='UTF-8'), userid), 'a':'6', 'b':'5' }
    data = urllib.parse.urlencode(post_to_short_url).encode(encoding='UTF-8')
    print (data)
    wadahana
        7
    wadahana  
       2016-05-30 19:06:42 +08:00
    % 25 是 %的二次编码。 %252F = urlencode(%2F) = urlencode(urlencode(/))
    %5C % 2F 是"\/“转义 后的编码
    andrewliu117
        8
    andrewliu117  
       2016-05-30 19:32:01 +08:00
    @wadahana 说得正确,“%”编号以后是 %25 ,所以%3A 编码后,就变成了%25 + 3A = %253A
    cwlmxwb
        9
    cwlmxwb  
    OP
       2016-05-30 19:37:06 +08:00 via iPhone
    @yangtukun1412 按照你这个方法已经解决问题啦,非常感谢
    cwlmxwb
        10
    cwlmxwb  
    OP
       2016-05-30 19:38:16 +08:00 via iPhone
    @wadahana 嗯嗯 需要先用 replacereplace 函数去掉斜杠
    hahastudio
        11
    hahastudio  
       2016-05-30 19:51:03 +08:00
    这个 URL 对参数多次转化,按照浏览器给的,应该是这样的:
    第一层 API ,三个参数:
    url, a, b
    url 里是第二层,实际上就是把一个普通的带参数的 URL encode 了。它里面有两个参数:
    shopName, shopUrl
    然后 shopUrl 跟 第一层的 url 一样,把一个普通的 URL encode 了。它里面有两个参数:
    id, userid

    所以如果你要模拟请求,那就拼的过程跟这个一样就好了
    zoosucker
        12
    zoosucker  
       2016-05-31 11:21:51 +08:00
    用 Chrome copy as curl 然后 到这里 http://curl.trillworks.com/ 自动产生请求试试?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   878 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 21:32 · PVG 05:32 · LAX 14:32 · JFK 17:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.