Python urllib库实战指南:从基础用法到高级配置
本文详解Python中urllib库的核心功能,涵盖urlopen发送请求、urlencode处理参数、quote编码中文、定制Headers规避403、POST提交表单、urlretrieve下载文件、代理IP设置及Cookie会话保持。通过Python3代码示例,解析常见网络操作场景与异常处理机制。
urllib库概述
urllib是Python标准库中用于处理URL操作的核心模块,在进行网页抓取或API调用时,它是开发者经常依赖的工具之一。
随着Python版本的迭代升级,urllib模块内部包的层级结构发生了显著变化,不同版本间的调用方式存在差异。
urllib库版本对照速查表
|
Python2.X |
Python3.X |
|
urllib |
urllib.request, urllib.error, urllib.parse |
|
urllib2 |
urllib.request, urllib.error |
|
urllib2.urlopen |
urllib.request.urlopen |
|
urllib.urlencode |
urllib.parse.urlencode |
|
urllib.quote |
urllib.request.quote |
|
urllib2.Request |
urllib.request.Request |
|
urlparse |
urllib.parse |
|
urllib.urlretrieve |
urllib.request.urlretrieve |
|
urllib2.URLError |
urllib.error.URLError |
|
cookielib.CookieJar |
http.CookieJar |
作为Python内置的URL操作库,urllib与requests、httplib2等第三方库功能相似,但urllib无需额外安装,适合轻量级场景。
在Python 2.x版本中,URL操作功能分散在urllib和urllib2两个模块中;而在Python 3.x中,这些功能被统一整合至urllib模块下。通过查阅上述对照表,开发者可以快速定位不同版本下的对应方法,从而编写兼容代码。
鉴于Python 3.x在中文编码支持方面比Python 2.x更加完善且友好,下文将主要基于Python 3.x环境来演示urllib库的常见用法。
发送HTTP请求
import urllib.request r = urllib.request.urlopen(http://www.python.org/)
首先导入urllib.request模块,调用urlopen()函数向指定URL发起请求,该函数将返回一个http.client.HTTPResponse类型的响应对象。
在调用urlopen()时,可以通过timeout参数设置等待响应的最大秒数,超时后将抛出异常。此外,还可以利用r.info() 获取响应头信息,通过r.getcode()获取HTTP状态码,以及通过r.geturl()获取当前请求的实际URL(包括重定向后的地址)。
读取响应内容
import urllib.request url = "http://www.python.org/" with urllib.request.urlopen(url) as r: r.read()
调用r.read()方法可将服务器返回的响应内容读取至内存,这通常对应网页的源代码(可通过浏览器“查看网页源代码”功能验证)。读取到的字符串可能需要根据编码格式进行decode() 操作,以获取正确的文本内容。
传递URL参数
import urllib.request
import urllib.parse
params = urllib.parse.urlencode({'q': 'urllib', 'check_keywords': 'yes', 'area': 'default'})
url = "https://docs.python.org/3/search.html?{}".format(params)
r = urllib.request.urlopen(url)
为了向URL的查询字符串传递数据,可以将参数字典通过urlencode()函数进行编码处理。
编码后的params变量是一个字符串,其中字典的每个键值对之间以'&'符号连接,例如:'q=urllib&check_keywords=yes&area=default'
最终构建的完整URL示例为:https://docs.python.org/3/search.html?q=urllib&check_keywords=yes&area=default
需要注意的是,urlopen()函数本身也支持直接接收构建好的URL字符串。对于简单的GET请求,开发者可以不使用urlencode()进行编码,而是手动拼接URL后直接发起请求。不过,使用编码方法能使代码结构更清晰、模块化程度更高。
处理中文参数
import urllib.request
searchword = urllib.request.quote(input("请输入要查询的关键字:"))
url = "https://cn.bing.com/images/async?q={}&first=0&mmasync=1".format(searchword)
r = urllib.request.urlopen(url)
以调用Bing图片接口查询关键字q为例,如果直接将中文字符串传入URL,会导致编码错误。此时,应使用quote()函数对中文字符进行URL编码;若需还原,则可使用unquote()进行解码。
定制请求头(Headers)
import urllib.request
url = 'https://docs.python.org/3/library/urllib.request.html'
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
'Referer': 'https://docs.python.org/3/library/urllib.html'
}
req = urllib.request.Request(url, headers=headers)
r = urllib.request.urlopen(req)
在爬取某些网站时,可能会遇到403 Forbidden错误,这通常是因为服务器对请求的Headers进行了身份验证。例如,urllib默认发送的User-Agent为“Python-urllib/X.Y”(X为主版本号,Y为副版本号),这容易被服务器识别为非浏览器请求并拦截。因此,我们需要通过urllib.request.Request()函数构建Request对象,并传入字典形式的Headers属性,以模拟真实浏览器的行为。
获取正确的Headers信息,可以通过浏览器的开发者工具(如“检查”功能中的Network标签)查看网络请求,或使用Fiddler、Wireshark等抓包分析软件获取。
除了上述方法,还可以使用urllib.request.build_opener()或req.add_header()方法来定制请求头,具体实现可参考官方示例文档。
在Python 2.x环境中,通常结合使用urllib和urllib2模块:urllib.urlencode()用于对URL参数进行编码,urllib2.Request()用于构建Request对象以定制请求头,最后统一通过urllib2.urlopen()发送请求。
处理POST请求
import urllib.request
import urllib.parse
url = 'https://passport.cnblogs.com/user/signin?'
post = {
'username': 'xxx',
'password': 'xxxx'
}
postdata = urllib.parse.urlencode(post).encode('utf-8')
req = urllib.request.Request(url, postdata)
r = urllib.request.urlopen(req)
在执行注册、登录等操作时,通常需要通过POST表单传递数据。
此时,需先分析页面结构,构建包含表单数据的字典post,并使用urlencode()进行编码处理,生成字符串。由于POST数据必须是bytes类型或file object,因此需指定'utf-8'编码格式进行转换。最后,通过Request()对象传递postdata,并使用urlopen()发送请求。
下载远程文件至本地
import urllib.request url = "https://www.python.org/static/img/python-logo.png" urllib.request.urlretrieve(url, "python-logo.png")
当需要爬取图片、视频等远程资源并保存到本地时,可以使用urlretrieve()函数。
该函数的第一个参数指定要下载的URL,第二个参数指定下载文件在本地保存的路径。
以下示例演示了如何将Python官网的logo下载到当前目录,函数执行后将返回一个包含文件名和响应头信息的元组(filename, headers)。
设置代理IP
import urllib.request
url = "https://www.cnblogs.com/"
proxy_ip = "180.106.16.132:8118"
proxy = urllib.request.ProxyHandler({'http': proxy_ip})
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
urllib.request.install_opener(opener)
r = urllib.request.urlopen(url)
频繁访问同一网站可能导致IP被服务器屏蔽,此时可通过设置代理IP来解决。
首先,从代理IP网站获取一个可用的IP地址,构建ProxyHandler()对象,将'http'协议和代理IP以字典形式作为参数传入,以配置代理服务器信息。接着,构建opener对象,将proxy和HTTPHandler类传入。通过installl_opener()将opener设置为全局,此后使用urlopen()发送请求时,系统将自动应用之前配置的代理信息。
异常处理机制
import urllib.request import urllib.error url = "http://www.balabalabala.org" try: r = urllib.request.urlopen(url) except urllib.error.URLError as e: if hasattr(e, 'code'): print(e.code) if hasattr(e, 'reason'): print(e.reason)
可以使用URLError类来处理与URL相关的异常。导入urllib.error模块后,捕获URLError异常。由于只有发生HTTPError异常(URLError的子类)时,异常对象e才具备状态码属性code,因此需要判断异常对象是否包含code属性。
Cookie会话保持
import urllib.request import http.cookiejar url = "http://www.balabalabala.org/" cjar = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar)) urllib.request.install_opener(opener) r = urllib.request.urlopen(url)
HTTP协议本身是无状态的,Cookie用于维持会话状态。例如,某些网站要求登录后才能访问特定页面。首次可通过提交POST表单登录,后续爬取该网站其他页面时,利用Cookie可保持登录状态,避免重复提交表单。
首先,构建CookieJar()对象cjar,再使用HTTPCookieProcessor()处理器处理cjar,并通过build_opener()构建opener对象,将其设置为全局。最后,通过urlopen()发送请求,系统会自动携带Cookie信息。
总结
以上内容涵盖了urllib库的主要应用场景。希望本文能为读者的学习或工作提供参考,如有任何疑问,欢迎留言交流,感谢支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













