【发布时间】:2018-11-03 02:05:00
【问题描述】:
这个简单的代码让urlparse 变得疯狂,它没有正确获取主机名,而是将其设置为None:
from urllib.parse import urlparse
parsed = urlparse("google.com/foo?bar=8")
print(parsed.hostname)
我错过了什么吗?
【问题讨论】:
标签: python python-3.x urlparse
这个简单的代码让urlparse 变得疯狂,它没有正确获取主机名,而是将其设置为None:
from urllib.parse import urlparse
parsed = urlparse("google.com/foo?bar=8")
print(parsed.hostname)
我错过了什么吗?
【问题讨论】:
标签: python python-3.x urlparse
只是为了给 Muadh 的回答添加更多背景信息。使用 urlparse 查看这两个变体的输出:
>>> parsed = urlparse("google.com/foo?bar=8")
>>> parsed
ParseResult(scheme='',
netloc='',
path='google.com/foo',
params='',
query='bar=8',
fragment='')
并指定完整路径
>>> parsed = urlparse("http://google.com/foo?bar=8")
>>> parsed
ParseResult(scheme='http',
netloc='google.com',
path='/foo',
params='',
query='bar=8',
fragment='')
【讨论】:
google.com/foo?bar=8 是一个相对 URL,也就是一个带有“查询”的“路径”。也许您将google.com 视为主机名,但它不一定是(python 怎么知道?)
URL 由协议或方案(“https:”、“ftp:”等)、主机(“//example.com”)、路径、查询、片段组成。
所以 urlparse 是最好的猜测,对协议和主机返回 None。
【讨论】:
根据https://www.rfc-editor.org/rfc/rfc1738#section-2.1:
方案名称由一系列字符组成。小写 字母“a”--“z”、数字和字符加号(“+”)、句点(“.”)、 和连字符(“-”)是允许的。为了弹性,程序解释 URL 应将大写字母视为等同于小写 方案名称(例如,允许“HTTP”和“http”)。
使用之前答案中给出的建议,我编写了这个辅助函数,可以用来代替urllib.parse.urlparse():
#!/usr/bin/env python3
import re
import urllib.parse
def urlparse(address):
if not re.search(r'^[A-Za-z0-9+.\-]+://', address):
address = 'tcp://{0}'.format(address)
return urllib.parse.urlparse(address)
url = urlparse('localhost:1234')
print(url.hostname, url.port)
此函数的先前版本称为urllib.parse.urlparse(address),如果找不到,则添加“tcp”方案;但是,如果您将用户名传递给“user:pass@localhost:1234”之类的内容,则会将用户名解释为方案。
【讨论】:
要使其正常工作,您必须包含协议标识符 (http://)。这对我有用:
parsed = urlparse("https://www.google.com/foo?bar=8")
print(parsed.hostname)
这里的输出是:www.google.com(这似乎是预期的)。更多关于如何使用urlparsehere可以阅读。
希望对你有所帮助!
【讨论】:
urlparse 的链接引用了python2。 urlparse 在 python3 中的导入方式不同