{site_name}

{site_name}

🌜 搜索

Python urllib.request 模块提供了一种用于打开URL(Uni

Python 𝄐 0
python urllib.quote,python2.7 urllib,python urllib urlopen,python urllib2 post,python urllib urlencode,python url请求
Python urllib.request 模块提供了一种用于打开URL(Uniform Resource Locator)的方式。但是它存在以下限制:

1. 安全性限制:为了防止恶意代码攻击,urllib.request 在默认情况下不允许访问本地文件系统或使用非安全协议(如 ftp ),除非显式地开启相关选项。

2. 性能限制:在同步模式下请求网络资源时,urllib.request 会阻塞当前线程,因此对于大量并发请求而言,采用异步框架(如 asyncio )可以获得更好的性能表现。

3. 服务器限制:某些服务器可能会拒绝 urllib.request 发送的请求,例如反爬虫机制、访问频率限制等。

下面是一些相应的例子:

1. 使用 urllib.request 打开一个本地文件:

python
import urllib.request

url = 'file:///etc/passwd' # 本地文件路径
response = urllib.request.urlopen(url) # 报错:urllib.error.URLError: <urlopen error [Errno 13] Permission denied: '/etc/passwd'>


解决方法:开启 allow_local_addresses 选项

python
import urllib.request

url = 'file:///etc/passwd' # 本地文件路径
opener = urllib.request.build_opener(urllib.request.FileHandler(), urllib.request.HTTPSHandler())
response = opener.open(url, allow_local_addresses=True)
content = response.read()
print(content) # b'root:x:0:0:root:/root:/bin/bash\n...'


2. 使用 urllib.request 打开一个 ftp 链接:

python
import urllib.request

url = 'ftp://ftp.example.com/' # ftp 访问链接
response = urllib.request.urlopen(url) # 报错:urllib.error.URLError: <urlopen error ftp protocol requires an "ftp.username" attribute>


解决方法:指定用户名和密码

python
import urllib.request

url = 'ftp://ftp.example.com/' # ftp 访问链接
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, url, 'username', 'password')
handler = urllib.request.FTPHandler(password_mgr)
opener = urllib.request.build_opener(handler)
response = opener.open(url)
content = response.read()
print(content) # b'Directory: /pub/\n...\n'


3. 使用 asyncio 框架发送并发请求:

python
import asyncio
import urllib.request

async def fetch(url):
response = await loop.run_in_executor(None, urllib.request.urlopen, url)
content = response.read()
print(f"{url} content length: {len(content)}")

loop = asyncio.get_event_loop()
urls = ['https://www.google.com', 'https://www.facebook.com', 'https://www.amazon.com']
tasks = [fetch(url) for url in urls]
loop.run_until_complete(asyncio.gather(*tasks))


在上述代码中,我们使用 asyncio 框架发送了三个并发请求,通过 run_in_executor 方法将同步的 urlopen 方法转换为异步形式,从而提高性能。