广州番禺Python爬虫小班周末班培训
第四期线下Python爬虫小班周末班已经开课了,授课详情请点击:http://chipscoco.com/?id=232
6.2.1 urllib的四大组件
urllib是Python中的一个内置package,其由以下四大模块组成:
模块名 | 描述 |
urllib.request | 打开和读取url |
urllib.parse | 解析url |
urllib.robotparser | 解析robots.txt文件 |
urllib.error | 包含urilib.request模块抛出的异常 |
使用urllib中的某一个模块,直接在脚本中导入即可,例如导入urllib.request:
# 导入request模块 import urllib.request
在本节教程中,主要讲解编写爬虫程序常用的request,parse以及error模块。
6.2.2 url读取:urllib.request
urllib.request模块基于HTTP/1.1,在向服务端发起请求时,会在请求头中包含Connection:close的请求字段。
在HTTP/1.1协议中,客户端与服务端默认使用长连接,客户端如需保持短连接方式(请求处理完毕后立即关闭连接),需要在请求中指定Connection字段值为close。
现对request模块中的常用操作进行讲解:
(1) urllib.request.urlopen
该函数用来打开url:
urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, context=None)
描述 | |
url | http url,可为字符串或request对象(urllib.request.Request) |
data | 发送额外的数据给http服务器,须为bytes类型,默认为None。 |
timeout | 可选的请求超时参数,没有传递时会使用一个默认的超时时间,仅用于http,https,ftp连接 |
context | ssl.SSLContext实例,用来定义SSL的传输选项,默认为None |
cafile,capath | cafile指向一个PEM格式的CA证书文件,capath则指向一个包含一系列PEM格式的CA证书文件的目录 |
urlopen代码实例-抓取Python官网首页:
# 导入request模块 import urllib.request # python官网的url url = 'http://python.org/' with urllib.request.urlopen(url) as response: # urlopen方法返回的是一个字节流对象,需通过decode方法转换为字符串 html = response.read().decode('utf-8')
调用urlopen方法时,默认发起的是GET请求,如需提交数据给服务端,需通过data参数进行传递,此时发起的是POST请求。通过Python中的字典类型,可快速地构建提交的数据,然后再调用urllib.parse的urlencode方法,将其转换为字符串。
代码实例-提交数据给服务端:
import urllib.parse # 以下url并不存在,读者可使用tornado快速搭建一个本地服务器来进行测试 url = ‘http://localhost:8090/login’ values = {'name' : 'chipscoco', 'password': 'forget'} data = urllib.parse.urlencode(values) # 必须传递字节流类型 data = data.encode('utf-8') with urllib.request.urlopen(url, data=data) as response: the_response = response.read().decode('utf-8')
使用Request类可以对http请求进行更细粒度的控制,比如请求头,请求方法。
urllib.request.Request(url,data=None,headers={},origin_req_host=None, unverifiable=False, method=None)
参数名 | 描述 |
url | 有效的url字符串 |
data | 发送额外的数据给http服务器,须为bytes类型,默认为None。 |
字典类型,用来定义HTTP请求头 | |
origin_req_host | 定义源服务器的主机名或ip地址 |
unverifiable | 用来指定用户的请求是否无法验证,默认为False |
method | 用来指定HTTP的请求方法,字符串类型,例如:HEAD,GET,POST |
urllib.request.Request对象常用方法:
方法名 | 描述 |
get_method | 返回Request对象的http请求方法 |
add_header | 添加http请求头 |
has_header | 判断Request对象是否包含某请求头 |
代码实例-为爬虫程序设置UA:
import urllib.request # 以下url并不存在,读者可将其替换为真实的网页url url = 'http://www.justtest.com' # Chrome浏览器的UA user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.57' # 设置爬虫程序的UA,可在一定程度上防止被服务端反爬 headers = {'User-Agent': user_agent} req = urllib.request.Request(url=url, headers=headers) with urllib.request.urlopen(req) as response: the_page = response.read()
(2) urllib.request.build_opener
该函数用来构建一个OpenerDirector对象:build_opener([handler, ...])
OpenerDirector对象会链式地按序处理在build_opener方法中传递的处理器,处理器需为BaseHandler,或其子类。OpenerDirector对象常用方法:
方法名 | 描述 |
add_handler(self,handler) | 添加URL处理器 |
open(self, fullurl, data=None) | 打开完整的url |
Python所提供的常用url处理器:
处理器 | 描述 |
HTTPRedirectHandler | 用于发起重定向请求 |
HTTPCookieProcessor | 用于处理HTTP Cookies |
ProxyHandler | 用于发起代理请求 |
HTTPPasswordMgr | 保存用户的账号和密码,以发起需授权验证的请求 |
HTTPBasicAuthHandler | 用于web客户端授权验证 |
HTTPSHandler | 用于发起https请求 |
在第四章中讲到了cookie, 通过cookie可以保存用户登录的状态信息。在本小节代码实例中,通过http.cookiejar来保存登录成功后的cookie信息,通过HTTPCookieProcessor来处理HTTP Cookie请求。
代码实例-模拟登录chipscoco:
import urllib.request import urllib.parse import http.cookiejar # 以下为薯条老师博客的登录url login_url = 'http://chipscoco.com/zb_users/plugin/YtUser/cmd.php?act=verify'# Chrome浏览器的UA user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.57' headers = {'User-Agent': user_agent} # 构造一个form data, username为登录的用户名,edtPassWord为加密后的登录密码 form_data = {"username":"test", "edtPassWord":"47ec2dd791e31e2ef2076caf64ed9b3d"} # 对字典对象进行url编码,由于Request中的data需传递bytes类型,故还需执行encode方法 login_form_data = urllib.parse.urlencode(form_data).encode("utf-8") req = urllib.request.Request(url=login_url, headers=headers, data=login_form_data) # 构造一个cookiejar对象来保存cookie信息 cookiejar = http.cookiejar.CookieJar() cookie_processor = urllib.request.HTTPCookieProcessor(cookiejar) opener = urllib.request.build_opener(cookie_processor) opener.open(req) for item in cookiejar: print(item.name + '=' + item.value)
www.chipscoco.com为薯条老师的个人博客(使用z-blog搭建的简单博客),为方便同学们进行模拟登录才开放的测试账号。在实际的模拟登录中,需要同学们找出网站的登录接口,及其请求参数,分析接口的请求过程,对参数的加密方式等,这样才可以实现自动登录。关于如何分析网站的登录接口,如何对接口进行数据抓包等,可复习第五章中的内容。
6.2.3 url解析:urllib.parse
(1) urllib.parse.urlparse
使用urlparse函数可以方便地解析出url中的协议类型,主机名,端口号,请求路径等信息:
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
描述 | |
urlstring | 待解析的url字符串 |
scheme | 指定解析的url地址的scheme,仅当url中没有scheme时才需传递 |
allow_fragments | 默认为True, 会解析url中的分片标识。为False时,url中的分片标识不会被解析。 |
函数返回一个包含6个元素的命名元组,各元素可通过索引或属性名进行访问。命名元组的属性名如下表所示:
属性名 | 描述 |
scheme | url地址的scheme |
netloc | url的网络位置,比如常见的域名:端口号 |
path | url中的请求路径 |
params | url中请求路径后的参数 |
query | url中的查询参数 |
fragment | url中的锚定位,即HTML中的分片标识 |
代码实例-解析HTTP URL:
>>> from urllib.parse import urlparse
>>> url = urlparse('http://www.test.com:8090/index.html?language=Python&language=C++')
>>> url
ParseResult(scheme='http', netloc='www.test.com:8090', path='/index.html', params='', query='language=Python&language=C++', fragment='')
>>> url.netloc
'www.test.com:8090'
>>> url.path
'/index.html'
>>> url.query
'language=Python&language=C++'
通过命名元组的query属性可以返回查询参数,如需对查询参数进一步解析,可以使用urllib.parse.parse_qs方法:
>>> import urllib
>>> urllib.parse.parse_qs(url.query)
{'language': ['Python', 'C ']}
以上代码均在Python交互模式中进行测试。
(2) urllib.parse.urlencode
urlencode函数用来将映射类型或二维的元组类型转换为通过'&'分隔的url编码:
urllib.parse.urlencode(query, doseq=False, safe='',encoding=None,errors=None,quote_via=quote_plus)
属性名 | 描述 |
query | 表示映射类型(例如字典)或二维的元组对象 |
doseq | 默认为False,为True时表示二维元组中的每一个元素(元组)中的第二个元素为一个序列,例如(('language',('c++','python'))) |
safe | 传递给quote_via所指定的url编码函数,用来指定某字符不需要编码 |
encoding | 传递给quote_via所指定的url编码函数,用来指定字符编码 |
errors | 传递给quote_via所指定的url编码函数,用来指定发生编码错误时该如何处理 |
quote_via | 默认为quote_plus函数,用来生成url编码,quote_plus函数会将空白字符编码为+号,将/编码为%2F |
关于urlencode的使用,可以查看5.1.2节中的代码实例:模拟登录chipscoco。如需将字符串类型进行url编码及解码,可以使用urllib.parse.quote,urllib.parse.unquote函数,前者用来生成字符串的url编码,后者用来将url编码解码为字符串。关于函数的具体用法,可查找官方文档,或直接在Python交互模式中使用help来查找。
6.2.4 url异常:urllib.error
urllib.error 模块为urllib.request所引发的异常定义了如下异常类:
异常类 | 描述 |
URLError | urllib.error中的异常类的基类,属性reason描述了异常原因 |
HTTPError | code属性表示HTTP状态码,reason属性表示引起异常的原因 |
ContentTooShortError | 此异常会在 urlretrieve()函数检测到已下载的数据量小于期待的数据量(由 Content-Length请求头指定的长度)时被引发 |
代码实例-捕获url异常:
import urllib.parse from urllib.error import HTTPError # 以下url并不存在,读者可使用tornado快速搭建一个本地服务器来进行测试 url = ‘http://localhost:8090/login’ values = {'name' : 'chipscoco', 'password': 'forget'} data = urllib.parse.urlencode(values) # 必须传递字节流类型 data = data.encode('utf-8') try: response = urllib.request.urlopen(url, data=data) except HTTPError as e: print(e.code, e.reason)
6.2.5 知识要点
(1) urllib是Python中的一个内置package,用来处理url的读取及解析。其由以下四大模块组成 :urllib.request,urllib.parse,urllib.robotparser,urllib.error。
(2) 在HTTP/1.1协议中,客户端与服务端默认使用长连接,客户端如需保持短连接方式(请求处理完毕后立即关闭连接),需要在请求中指定Connection字段值为close。
6.2.6 课后习题
(1) Python后端工程师高薪就业班,月薪10K-15K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪10K-20K, 免费领取课程大纲
(4) Python大数据工程师就业班,月薪12K-25K,免费领取课程大纲
扫码免费领取学习资料: