1 添加头信息
1.1 User-Agent
有些网站,如果你按照urllib.request.urlopen(‘https://www.baidu.com’) 这种方式打开,服务器有可能不会响应,所以要完全模仿浏览器访问,我们需要加入User-Agent信息,示例代码如下:
from urllib import request req = request.Request('https://www.baidu.com') req.add_headers('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0') ① response = request.urlopen(req)
①通过 Request.add_header(key, val)添加字典形式的头信息,不能传多个头信息,前面的会被后面的覆盖。User-Agent 首部包含了一个特征字符串,用来让网络协议的对端来识别发起请求的用户代理软件的应用类型、操作系统、软件开发商以及版本号。如何获取User-Agetn信息呢?
可以用火狐或者谷歌浏览器,F12打开调试模式,我用的火狐,截图如下:
1.2 Referer
Referer 首部包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 首部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。有些服务器会识别headers中的referer是不是它自己,如果不是,不会响应,所以我们还可以在headers中加入referer。
可以打开F12看下Referer具体效果,我手动输入网址打开百度后,头信息如下:
我在直接点击网页上的新闻连接,看下头信息内容:
是不是多了Referer,显示来源页面是我手动打开的百度首页。
添加Referer方式与添加User-Agent一样,如下:
略 req.add_headers('Referer', 'https://www.baidu.com') 略
2 ProxyHandler
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) ① opener = urllib.request.build_opener(proxy_handler) ② # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html') ③
①创建一个代理处理器ProxyHandler,接收的参数类型为字典{‘协议’: ‘代理ip: 端口’}
②从一个proxy_handler程序列表中创建一个opener对象,urllib.request.urlopen()函数实际上是使用的是默认的opener,这里相当于定制了自己的opener
③通过opener对象打开url
3 异常处理urllib.error
urllib.error模块定义了由urllib.request引起的异常的异常类。基本的异常类是URLError。
3.1 URLError
URLError是OSError的一个子类,HTTPError是URLError的一个子类我们先来看URLError异常
# -*- coding: utf-8 -*- from urllib import request from urllib import error if __name__ == "__main__": req = request.Request('http://www.demo.com') try: response = request.urlopen(req) html = response.read().decode('utf-8') print(html) except error.URLError as e: print(e.reason)
执行结果返回如下图:
3.2 HTTPError异常
# -*- coding: utf-8 -*- from urllib import request from urllib import error if __name__ == '__main__': req = request.Request('http://mirrors.163.com/centos/7.4.1708/isos/x86_64/sha2sum.txt') try: response = request.urlopen(req) except error.HTTPError as e: print(e)
执行文件结果:
3.3 urllib.error.ContentTooShortError
urllib.error.ContentTooShortError异常是因为文件下载不完全导致的错误,这个错误不好复现,就简单举例说明:
# -*- coding: utf-8 -*- from urllib import request from urllib import error if __name__ == "__main__": req = request.Request('https://download.demo.com') filename = 'E:/test3.txt' try: request.urlretrieve(req, filename) except error.ContentTooShortError as e: print(e)
3.4 HTTPError和URLError同时使用
同时使用,需要将HTTPError放在URLError的前面,因为HTTPError是URLError的一个子类。如果URLError放在前面,出现HTTP异常会先响应URLError,这样HTTPError就捕获不到错误信息了。
如果不用上面的方法,也可以使用hasattr函数判断URLError的属性,如果含有reason属性表明是URLError,如果含有code属性表明是HTTPError。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/54646.html