Python-Requests,从字符串中提取url参数
Posted
技术标签:
【中文标题】Python-Requests,从字符串中提取url参数【英文标题】:Python-Requests, extract url parameters from a string 【发布时间】:2015-04-04 10:02:27 【问题描述】:我正在使用这个很棒的库 requests
来维护 python 2 和 3 的兼容性并简化我的应用程序请求管理。
我有一个案例,我需要解析一个 url 并替换它的一个参数。例如:
http://example.com?param1=a&token=TOKEN_TO_REPLACE¶m2=c
我想得到这个:
http://example.com?param1=a&token=NEW_TOKEN¶m2=c
有了urllib
,我可以这样实现:
from urllib.parse import urlparse
from urllib.parse import parse_qs
from urllib.parse import urlencode
url = 'http://example.com?param1=a&token=TOKEN_TO_REPLACE¶m2=c'
o = urlparse(url)
query = parse_qs(o.query)
if query.get('token'):
query['token'] = ['NEW_TOKEN', ]
new_query = urlencode(query, doseq=True)
url.split('?')[0] + '?' + new_query
>>> http://example.com?param2=c¶m1=a&token=NEW_TOKEN
您如何使用requests
库实现相同的目标?
【问题讨论】:
【参考方案1】:您不能为此使用requests
;如果为参数传递了 Python 结构,则库 构建 此类 URL,但不提供任何工具来解析它们。这不是该项目的目标。
坚持urllib.parse
方法解析出参数。有了字典或键值元组列表后,只需将其传递给 requests
即可再次构建 URL:
try:
# Python 3
from urllib.parse import urlparse, parse_qs
except ImportError:
# Python 2
from urlparse import urlparse, parse_qs
o = urlparse(url)
query = parse_qs(o.query)
# extract the URL without query parameters
url = o._replace(query=None).geturl()
if 'token' in query:
query['token'] = 'NEW_TOKEN'
requests.get(url, params=query)
urlparse
和parse_qs
函数在 Python 2 和 3 中都可以获取,如果遇到异常,只需调整导入位置即可。
在 Python 3 上的演示(没有导入异常保护)来演示 URL 已构建:
>>> from urllib.parse import urlparse, parse_qs
>>> url = "http://httpbin.org/get?token=TOKEN_TO_REPLACE¶m2=c"
>>> o = urlparse(url)
>>> query = parse_qs(o.query)
>>> url = o._replace(query=None).geturl()
>>> if 'token' in query:
... query['token'] = 'NEW_TOKEN'
...
>>> response = requests.get(url, params=query)
>>> print(response.text)
"args":
"param2": "c",
"token": "NEW_TOKEN"
,
"headers":
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.5.1 CPython/3.4.2 Darwin/14.1.0"
,
"origin": "188.29.165.245",
"url": "http://httpbin.org/get?token=NEW_TOKEN¶m2=c"
【讨论】:
@Gab:我已经更新了这篇文章,以阐明如何保持 Python 2 和 3 之间的兼容性;两个版本中都存在相同的功能,只是在不同的位置。requests
对此无能为力。
实际上,我更详细地检查了请求网站和 github 文件夹,看来您是对的。 +1 最后使用requests
库显示代码的简化版本!
Martijn,你应该更新这个答案。此函数可作为 requests.utils.urlparse
使用(实际上是相同的函数,它来自 compat
which comes from this file)并且我认为自 2017 年以来一直存在。
@Boris requests.compat
模块不是公共 API 的一部分。它基本上完成了我的回答,但这并不意味着您可以依靠它继续这样做。它只被导入requests.utils
,因为该模块中的实现需要它。换句话说,它存在的唯一原因是作为实现细节。
@MartijnPieters 我不确定。据我所知,该模块中的所有功能都没有记录,但它说“该模块提供了在请求中使用的实用功能,也可用于外部消费”。我想如果这是他们将用下划线导入的想法import urlparse as _urlparse
【参考方案2】:
仅使用requests
:
query = requests.utils.urlparse(url).query
params = dict(x.split('=') for x in query.split('&'))
if 'token' in params:
params['token'] = 'NEW_TOKEN'
requests.get(url, params=params)
【讨论】:
我认为可能还需要requests.utils.unquote
,以防止发送空格、“%20”等字符。以上是关于Python-Requests,从字符串中提取url参数的主要内容,如果未能解决你的问题,请参考以下文章
XHR 请求在 Scrapy 中失败,但在 python-requests 中有效