【问题标题】:Best way to parse a URL query string解析 URL 查询字符串的最佳方法
【发布时间】:2012-04-24 04:19:27
【问题描述】:

在 python 中,从 URL 查询字符串(例如,通过表单附加到 URL 的数据)中解析数据的最佳方法是什么?我的目标是接受表单数据并将其显示在同一页面上。我研究了几种方法,但这些方法并不完全符合我的要求。

我正在创建一个简单的 Web 服务器,目的是了解套接字。此 Web 服务器仅用于测试目的。

GET /?1pm=sample&2pm=&3pm=&4pm=&5pm= HTTP/1.1
Host: localhost:50000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost:50000/?1pm=sample&2pm=&3pm=&4pm=&5pm=

【问题讨论】:

  • 您是要从头开始编写解析,还是什么?
  • stackoverflow.com/questions/1349367/… 或 stackoverflow.com/questions/4685217/parse-raw-http-headers 有什么问题。您没有向我们提供有关缺少其他方法的足够信息。你有一两个示例标题吗?
  • 这些帖子都没有“错误”。根据我过去的编程经验,我倾向于在第二个链接中做类似的事情,比如正则表达式。但是,我想问一下是否有更简单的方法可以做到这一点,因为这是我的第一个 python 程序。
  • 在我看来您在谈论 URL 查询字符串,而不是 HTTP 标头。您可能需要更新您的问题以反映这一点。

标签: python string http webserver


【解决方案1】:

这里是一个使用python3的例子urllib.parse:

from urllib.parse import urlparse, parse_qs
URL='https://someurl.com/with/query_string?i=main&mode=front&sid=12ab&enc=+Hello'
parsed_url = urlparse(URL)
parse_qs(parsed_url.query)

输出:

{'i': ['main'], 'enc': [' Hello '], 'mode': ['front'], 'sid': ['12ab']}

python2 的注意事项:from urlparse import urlparse, parse_qs

查看:https://pythonhosted.org/six/#module-six.moves.urllib.parse

【讨论】:

【解决方案2】:

urllib.parse 模块是你的朋友:https://docs.python.org/3/library/urllib.parse.html

查看urllib.parse.parse_qs(解析查询字符串,即通过 GET 发送到服务器的表单数据或通过 POST 发布的表单数据,至少对于非多部分数据)。还有cgi.FieldStorage 用于解释多部分数据。

要解析 HTTP 交互的其余部分,请参阅RFC2616,这是 HTTP/1.1 协议规范。

【讨论】:

  • 我不是在为他写剧本。他特别询问了如何解析查询数据,至少这是我在字里行间读到的,即使这些实际上不是 HTTP 标头。但我懒得对此发表评论。
  • 我并不是建议你应该为他编写脚本,但 urlparse 只是这个难题的一小部分。
  • 对于他提供的信息量,仅此而已。具体来说,如果您实际上指的是 HTTP 标头:他是否使用实际上允许您获取未解释的 HTTP 标头(通过某些流)的网络服务器?他是否使用 WSGI(其中 HTTP 标头由框架解释)?平淡无奇的 CGI,你必须在哪里解释环境并希望最好?随便。
  • urlparse 看起来是一个很棒的资源。标题非常简单,我已将其添加到原始问题中。我相信你可以猜到,我最初的想法是将 get 行解析为字符串数组。
  • 你想写一个网络服务器吗?还是某种形式的数据包检查/检查器?
【解决方案3】:

如果您需要查询字符串中的唯一键,请使用 dict() 和 parse_qsl()

import urllib.parse
urllib.parse.urlparse('https://someurl.com/with/query_string?a=1&b=2&b=3').query
    a=1&b=2&b=3
urllib.parse.parse_qs('a=1&b=2&b=3');
    {'a': ['1'], 'b': ['2','3']}
urllib.parse.parse_qsl('a=1&b=2&b=3')
    [('a', '1'), ('b', '2'), ('b', '3')]
dict(urllib.parse.parse_qsl('a=1&b=2&b=3'))
    {'a': '1', 'b': '3'}

【讨论】:

  • 重要的是要注意从 tuple 到 dict 结果的转换不考虑 b 有两个值,一个会被忽略。不知道parse_qsl,很好的补充。
【解决方案4】:

内置于 python 2.7

>>> from urlparse import parse_qs
>>> parse_qs("search=quint&tags=python")
{'search': ['quint'], 'tags': ['python']}

【讨论】:

    【解决方案5】:

    仅适用于没有导入的一行快速原型 CGI 变量,显然不是最好的,但可能很有用。

    agrs = dict(item.split('=') for item in env['QUERY_STRING'].split('&') if item)
    

    【讨论】:

    • 如果查询字符串中的任何参数是 URL 编码的,这将中断。 URL 的“手动解析”是许多安全问题的根源。
    • 确实为什么“仅用于原型设计”的警告发布它是为了展示没有任何导入的快速解析
    猜你喜欢
    • 2010-11-15
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    相关资源
    最近更新 更多