如何检查给定的链接(url)是指向文件还是另一个网页?
我的意思是:
目前,我正在做一个非常棘手的多步骤检查,它还需要相对于绝对链接进行转换,如果缺少则添加http前缀,并删除“#”锚链接/参数才能正常工作。我还不确定是否将所有可能存在的页面扩展名列入白名单。
import re
def check_file(url):
try:
sub_domain = re.split('\/+', url)[2] # part after '2nd slash(es)''
except:
return False # nothing = main page, no file
if not re.search('\.', sub_domain):
return False # no dot, no file
if re.search('\.htm[l]{0,1}$|\.php$|\.asp$', sub_domain):
return False # whitelist some page extensions
return True
tests = [
'https://www.stackoverflow.com',
'https://www.stackoverflow.com/randomlink',
'https:////www.stackoverflow.com//page.php',
'https://www.stackoverflow.com/page.html',
'https://www.stackoverflow.com/page.htm',
'https://www.stackoverflow.com/file.exe',
'https://www.stackoverflow.com/image.png'
]
for test in tests:
print(test + '\n' + str(check_file(test)))
# False: https://www.stackoverflow.com
# False: https://www.stackoverflow.com/randomlink
# False: https:////www.stackoverflow.com//page.php
# False: https://www.stackoverflow.com/page.html
# False: https://www.stackoverflow.com/page.htm
# True: https://www.stackoverflow.com/file.exe
# True: https://www.stackoverflow.com/image.png
是否有针对此问题的单一正则表达式匹配解决方案或具有已建立函数的库来实现?我想可能有人在我之前遇到过这个问题,但是不幸的是,我在这里找不到解决方案。
答案 0 :(得分:3)
urlparse
是你的朋友。
from urllib.parse import urlparse
def check_file(url):
path = urlparse(url).path # extract the path component of the URL
name = path.rsplit('/', 1)[-1] # discard everything before the last slash
if '.' not in name: # if there's no . it's definitely not a file
return False
ext = path.rsplit('.', 1)[-1] # extract the file extension
return ext not in {'htm', 'html', 'php', 'asp'}
可以使用pathlib
模块进一步简化此操作:
from urllib.parse import urlparse
from pathlib import PurePath
def check_file(url):
path = PurePath(urlparse(url).path)
ext = path.suffix[1:]
if not ext:
return False
return ext not in {'htm', 'html', 'php', 'asp'}
答案 1 :(得分:2)
Aran-Fey的回答在行为良好的网页上效果很好,该网页占网络的99.99%。但是没有规则说以特定扩展名结尾的URL必须解析为特定类型的内容。配置不当的服务器可能会返回html来访问名为“ example.png”的页面,或者会返回mpeg来访问名为“ example.php”的页面,或者内容类型和文件扩展名的任何其他组合。>
获取URL的内容类型信息的最准确方法是实际访问该URL并检查其标头中的内容类型。大多数http接口库都有一种只从站点检索标头信息的方法,因此即使对于非常大的页面,此操作也应相对较快。例如,如果您使用的是requests
,则可以这样做:
import requests
def get_content_type(url):
response = requests.head(url)
return response.headers['Content-Type']
test_cases = [
"http://www.example.com",
"https://i.stack.imgur.com/T3HH6.png?s=328&g=1",
"http://php.net/manual/en/security.hiding.php",
]
for url in test_cases:
print("Url:", url)
print("Content type:", get_content_type(url))
结果:
Url: http://www.example.com
Content type: text/html; charset=UTF-8
Url: https://i.stack.imgur.com/T3HH6.png?s=328&g=1
Content type: image/png
Url: http://php.net/manual/en/security.hiding.php
Content type: text/html; charset=utf-8