一、读取cookieshtml
import http.cookiejar as cj,urllib.request as request cookie = cj.CookieJar() handler = request.HTTPCookieProcessor(cookie) opener = request.build_opener(handler) response = opener.open('http://www.bigdata17.com') for item in cookie: print(item.name + "=" + item.value)
二、将cookies保存在文件中python
filename = 'baidu_cookies.txt' cookies = cj.MozillaCookieJar(filename) handler = request.HTTPCookieProcessor(cookies) opener = request.build_opener(handler) response = opener.open('http://www.baidu.com') cookies.save(ignore_discard=True,ignore_expires=True)
三、处理异常nginx
URLError和HTTPError类,两个类是父子关系,HTTPError会返回错误代码,两个类均可以处理request模块产生的异常,这两个都有一个reason属性,用于记录出现异常的缘由 URLError处理异常:json
from urllib import request,error try: response = request.urlopen('http://www.bigdata17.com/index.htm') except error.URLError as e: print(e.reason)
HTTPError处理异常: 这个类是专门处理http请求的异常,http请求会返回一个请求代码,所以HTTPError会有一个code属性。另外HTTP请求会有包含请求头信息,因此HTTPError还包含一个headers属性。HTTPError继承自URLError类,所以也包含有reason属性。 代码:浏览器
try: response = request.urlopen('http://www.bigdata17.com/index.htm') except error.HTTPError as e: print(e.reason) print(e.code) print(e.headers)
四、解析连接
urllib库中的parse类提供了不少用于解析连接的方法。 urlparse()方法是专门用于解析连接的,咱们先看这个方法的返回值:服务器
from urllib.parse import urlparse result = urlparse('http://www.bigdata17.com') print(result)
上面的代码返回的结果:cookie
ParseResult(scheme='http', netloc='www.bigdata17.com', path='', params='', query='', fragment='')
可见urlparse()方法返回的是ParseResult类,这个了有6个属性,分别是scheme、netloc、path、params、query和fragment。其中scheme表明的是协议,有http,https,ftp等协议类型。netloc是网站域名,path是要访问的网页名称。params是表明参数。query查询参数,fragment是锚点。网络
urlparse()方法是如何将一个连接映射到上面的6个参数中呢? 继续看下一段代码:app
from urllib.parse import urlparse result = urlparse('http://www.bigdata17.com/22.html;user=bigdata17?id=10#content') print(result)
运行的结果以下:socket
ParseResult(scheme='http', netloc='www.bigdata17.com', path='/22.html', params='user=bigdata17', query='id=10', fragment='content')
可见从连接开始为://止,是scheme。从://开始到一个/位置,是netloc域名。从/开始到;分号为止是path,访问页面的路径。;开始到?为止是params参数。从?问号开始到#井号结束时query查询参数。最后是fragment锚点参数。
五、urlopen()方法
该方法返回的是HTTPResponse对象:
import urllib.request as request response = request.urlopen('http://www.bigdata17.com') print(response) <http.client.HTTPResponse object at 0x000002A9655BBF28>
HTTPResponse对象有read(),getheaders()等方法。
经过read()方法能够读取网页的信息:
import urllib.request as request response = request.urlopen('http://www.bigdata17.com') print(response.read().decode('utf-8'))
使用该方法时要注意网站使用的编码格式,配合decode()方法一块儿使用,不然会出现乱码。像百度用的是utf-8,网易用的是gbk。
getHeaders()方法返回的是网页的头信息:
import urllib.request as request response = request.urlopen('http://www.bigdata17.com') print(response.getheaders()) 结果: [('Server', 'nginx/1.12.2'), ('Date', 'Mon, 12 Nov 2018 15:45:22 GMT'), ('Content-Type', 'text/html'), ('Content-Length', '38274'), ('Last-Modified', 'Thu, 08 Nov 2018 00:35:52 GMT'), ('Connection', 'close'), ('ETag', '"5be384e8-9582"'), ('Accept-Ranges', 'bytes')]
继续看urlopen()方法有哪些参数:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
其中url是必须传递的参数,其余的参数不是必须传递的。data用于将数据传输到咱们要爬取的网站上,例如用户名、密码、验证码等。timeout是设置请求超时时间。
data参数的用法:
>>> import urllib.parse as parse >>> import urllib.request as request >>> data = bytes(parse.urlencode({'username': 'bigdata17'}), encoding='utf8') >>> print(data) b'username=bigdata17' >>> response = request.urlopen('http://httpbin.org/post', data=data) >>> print(response.read()) b'{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "username ": "bigdata17"\n }, \n "headers": {\n "Accept-Encoding": "identity", \n "Connection": "close", \n "Content-Length": "18", \n "Content-Type": "appl ication/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.7"\n }, \n "json": null, \n "origin": "183.134.52.58", \n "url": "http://httpbin.org/post"\n}\n'
使用data传输数据时,必须将urlencode方法将data的数据转换为bytes类型。
在使用urlopen方法时,若是不使用data参数,则使用的get方式传送数据,若是使用了data参数,则是以post的方式传送数据。post的方式必须保证要爬取的网站上有相应的方法(上面代码要爬取的网址是http://httpbin.org/post,post就是要处理咱们经过data参数传输数据的方法),不然会报urllib.error.HTTPError: HTTP Error 404: NOT FOUND的错误。
timeout参数的用法:
该参数是用于设置请求超时时间,省得出现网络故障或服务器异常时咱们的爬虫程序长时间等:
import urllib.request as request response = request.urlopen('http://www.bigdata17.com', timeout=1) print(response.read())
若是将timeout设置为0.01,则会报以下的错误:
socket.timeout: timed out During handling of the above exception, another exception
设置请求头信息:
请求的头信息通常对带有浏览器的信息,不少网站根据请求头信息来判断该请求是正常的浏览器发起的仍是由爬虫发起的。设置爬虫头信息方法:
from urllib import request, parse url = 'http://httpbin.org/post' headers = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 'Host': 'httpbin.org' } dict = { 'name': 'bigdata17' } data = bytes(parse.urlencode(dict), encoding='utf8') req = request.Request(url=url, data=data, headers=headers, method='POST') response = request.urlopen(req) print(response.read().decode('utf-8'))
设置代理: 若是一个ip过于频繁的访问某一个网站时,根据反爬虫措施,会限制该IP的访问。咱们能够经过urllib提供的ProxyHandler方法来设置代理:
import urllib.request proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.bigdata17.com:3128/'}) proxy_auth_handler = urllib.request.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('https://accounts.douban.com/login?alias=&redir=https%3A%2F%2Fwww.douban.com%2F&source=index_nav&error=1001')