你总是用 Python 进行网络抓取吗?那么,你一定也和我一样,对 Urllib、Urllib3 和 Requests 这三者之间哪个是最好的 HTTP 客户端感到困惑。
是的,在 Python 编程中,处理 HTTP 请求是一个常见的需求。
Python 提供了多种库来实现这一功能,Urllib、Urllib3 和 Requests 是其中最常用的三个库。
它们有什么特别之处?哪个适合你?
它们各自都有独特的功能和优缺点。开始阅读这篇文章,找出答案吧!
库UrllibUrllib3Requests是否需要安装否是是速度中等快中等响应处理通常需要解码步骤不需要额外的解码步骤不需要额外的解码步骤连接池不支持支持支持易用性语法复杂,学习曲线陡峭易用易用,更适合初学者
1. Urllib
Urllib 是 Python 标准库的一部分,用于处理 URL,不需要安装任何额外的库。
当你使用 Urllib 发送请求时,它返回的是响应对象的字节数组。然而,我必须说,它返回的字节数组需要额外的解码步骤,这对于初学者来说可能具有挑战性。
Urllib 有什么特别之处?
urllib
允许通过低级接口进行更精细的控制,但这也意味着需要编写更多代码。因此,用户通常需要手动处理 URL 编码、请求头设置和响应解码。
但不要紧张!Urllib 提供了基本的 HTTP 请求功能,例如 GET 和 POST 请求,它还支持 URL 解析、编码和解码。
优缺点
优点:
- 不需要额外安装。因为它是 Python 标准库的一部分,使用时不需要安装任何额外的库。
- 功能全面。支持处理 URL 请求、响应和解析。
缺点:
- 复杂度高。发送请求和处理响应的步骤繁琐。
- 需要手动处理字节数组。返回的响应需要手动解码,增加了额外步骤。
Urllib 可以用于什么?
Urllib
适用于 简单任务,例如 HTTP 请求,特别是在你不想安装第三方库时。
它也可以用于 学习和理解底层原理。用户可以用它来学习和理解 HTTP 请求的底层实现。
然而,由于
urllib
缺乏连接池管理、默认压缩和 JSON 处理等高级功能,对于复杂的 HTTP 请求来说,它的使用相对繁琐。
2. Urllib3
Urllib3
提供了高级抽象,包括请求 API、连接池、默认压缩、JSON 编码和解码等。
使用这些功能非常简单!你只需几行代码就能自定义 HTTP 请求。
Urllib3
使用 C 扩展来提高性能,因此 在这三者中速度最快。
Urllib3 有什么特别之处?
Urllib3
提供了更高级的接口。它还支持连接池、自动重试、SSL 配置和文件上传等高级功能:
- 连接池:管理连接池,减少重复的 TCP 连接开销。
- 重试机制:自动重试请求,提高稳定性。
- 默认压缩:支持请求和响应数据的压缩和解压。
- JSON 支持:虽然不是内置功能,但可以与 JSON 模块结合使用来处理 JSON 数据。
- SSL 验证:提供更好的 SSL 支持和配置选项。
优缺点
优点:
- 高级功能更多。比
urllib
提供了更多高级功能,如连接池、文件分块上传、重试请求等。 - 更易用。语法比
urllib
简单,减少了编码复杂度。
缺点:
- 需要安装。需要使用 pip 安装
urllib3
(pip install urllib3
)。
Urllib3 可以用于什么?
用户可以将
urllib3
用于一些 复杂的 HTTP 请求,例如处理并发请求、连接池管理等。
Urllib3
也适用于一些需要更高性能和稳定性的需求。
3. Requests
Requests
是一个流行的 HTTP 请求库。它以简单的 API 设计和强大的功能而闻名,使与网络的交互变得非常容易。
通过
Requests
发送 HTTP 请求将变得非常简单和直观。此外,它还具有处理 cookie、会话、代理设置和 JSON 数据等内置功能,确保了用户友好的体验。
它还有一些强大的功能:
- 简单的 API:提供最简单和易用的接口,因此 HTTP 请求非常直观。
- 连接池:内置连接池管理。
- 默认压缩:自动处理请求和响应的压缩。
- JSON 支持:处理 JSON 数据非常方便,因为它内置了 JSON 编码和解码功能。
- 丰富的功能:包括文件上传、流式下载、会话持久化等。
优缺点
优点:
- 最简洁和友好的语法。
Requests
提供了最简单和最易理解的 API,因此发送 HTTP 请求非常容易。 - **内置
urllib3
**。底层使用urllib3
,结合了高性能和高级功能,同时隐藏了复杂性。 - 普及度和社区支持。由于广泛使用,有大量文档、教程和社区支持。
缺点:
- 需要安装。需要使用 pip 安装
Requests
(pip install requests
)。 - 尽管功能丰富,由于其高级抽象,其 性能相对较慢。
Requests 可以用于什么?
Requests
适用于几乎所有 HTTP 请求场景,尤其是网络爬虫和 API 请求。由于其简洁的语法和丰富的文档,它也特别适合初学者。
性能比较
根据基准测试结果,这三者在 100 次迭代中的性能如下:
Urllib
第二快:平均请求时间为 1.18 秒。虽然是纯 Python 实现,但由于其底层实现,性能较好。Urllib3
最快:平均请求时间为 0.33 秒。这归功于其 C 扩展和高效的连接池管理。Requests
最慢:平均请求时间为 1.73 秒。但其易用性和丰富的功能弥补了这一缺点。
选择建议
- 如果你想 尽可能少地依赖外部库 且项目 需求简单,可以 **选择
urllib
**。它是标准库的一部分,不需要单独安装。 - 如果你需要 高性能和高级功能 并且不介意做一些 技术操作,
urllib3
是一个不错的选择。 - 如果你追求 最少的代码 和一个高度 易用的接口,特别是处理复杂的 HTTP 请求时,**
requests
是理想的选择**。它是最用户友好的库,广泛用于网络爬虫和 API 请求。
两种有效的方法避免抓取时被封锁
许多网站集成了反爬虫系统来检测和封锁自动化脚本,如网络抓取工具。因此,绕过这些封锁以访问数据至关重要!
一种避免检测的方法是使用 Nstbrowser 避免 IP 封锁。Urllib 和 urllib3 也内置了在 HTTP 请求中添加代理的能力。
方法 1:使用 Nstbrowser 绕过反爬虫系统
在开始之前,你需要满足一些条件:
- 成为 Nstbrowser 的用户。
- 获取 Nstbrowser 的 API Key。
- 本地运行 Nstbrowserless 服务
以下是具体步骤。我们将以抓取亚马逊网站上一个页面的内容标题为例。
如果我们需要抓取以下网页的 h3 标题内容:
我们应该运行以下代码:
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
async def main
():
async with async_playwright() as p:
browser = await p.chromium.connect_over_cdp(
'wss://browser.nstbrowser.io/v1/{workspace}/{project-id}/{API Key}')
page = await browser.new_page()
# 这里输入抓取目标页面的URL
url = 'https://www.amazon.com/s?bbn=16225007011&rh=n%3A16225007011%2Cn%3A' \
'18464062011&dc&fst=as%3Aoff&qid=1614317724&rnid=16225007011&ref=lp_16225007011_nr_n_7'
await page.goto(url)
# 提取 h3 标题内容
titles = await page.query_selector_all('h3')
for title in titles:
print(await title.inner_text())
await browser.close()
if __name__ == '__main__':
import asyncio
asyncio.get_event_loop().run_until_complete(main())
在运行此代码之前,请确保:
- 你已经安装了 Playwright。
- 你已经启动了 Nstbrowserless 服务。
- 将代码中的 {workspace}、{project-id} 和 {API Key} 替换为你的实际值。
方法 2:使用 urllib 和 urllib3 避免 IP 封锁
在这部分中,我们将使用
urllib
和
urllib3
来避免 IP 封锁,演示如何在 HTTP 请求中添加代理。
以下是一些示例代码,展示了如何为
urllib
和
urllib3
设置代理:
示例:使用
urllib
设置代理
import urllib.request
proxy = urllib.request.ProxyHandler({
'http': 'http://your-proxy-server:port',
'https': 'https://your-proxy-server:port'
})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
# 发送 HTTP 请求
response = urllib.request.urlopen('http://www.example.com')
print(response.read().decode('utf-8'))
示例:使用
urllib3
设置代理
import urllib3
http = urllib3.ProxyManager('http://your-proxy-server:port')
# 发送 HTTP 请求
response = http.request('GET', 'http://www.example.com')
print(response.data.decode('utf-8'))
这两种方法将有助于你在使用网络抓取时避免 IP 封锁。
总结
Urllib
、
Urllib3
和
Requests
各有优缺点。根据项目的不同需求和复杂性,你可以选择最适合的 HTTP 客户端。
如果你的需求很简单,且不想安装额外的库,选择
Urllib
。如果你需要高性能和高级功能,选择
Urllib3
。如果你需要一个简单易用的 HTTP 客户端,特别适合网络爬虫和 API 请求,选择
Requests
。
同时,避免 IP 封锁的方法也很重要。可以使用 Nstbrowser 避免 IP 封锁,或者使用 Urllib 和 Urllib3 内置的代理功能。
希望这篇文章能帮助你在网络抓取时作出更好的选择!
版权归原作者 wellshake 所有, 如有侵权,请联系我们删除。