Urllib库和URLError库的异常处理

Urllib 库是 Python 一个用于操作 URL 的模块, Python3 中合并了 Python2.X 中的 Urllib2 和 Urllib 库,成为 Urllib 库

通过Urllib爬取网页

import urllib.request

file=urllib.request.urlopen("http://www.baidu.com")
data=file.read()
dataline=file.readline()
#print(dataline)
#print(data)

fhandle=open("D:/1.html","wb")
fhandle.write(data)
fhandle.close()

filname=urllib.request.urlretrieve("http://www.baidu.com",filename="D:/2.html")
urllib.request.urlcleanup()
print(file.info)

file.read() 读取文件的全部内容 返回字符串变量
file.readlines() 全部内容 返回列表变量,读取全文推荐这种方式
file.readline() 读取文件的一行内容

urlretrieve() 函数可以直接把网页下载到本地目录,目录要提前建好


模拟浏览器

Urllib 的 urlopen() 函数不支持一些 HTTP 的高级功能,修改报头一般用以下两个函数:
1. urllib.request.build_opener()
2. urllib.request.add_header()

urllib.request.build_opener() :

设置好字典 headers={‘xxx’:’yyyy’}

opener=urllib.request.build_opener() #创建自定义opener对象
opener.addheaders=[headers] # 设置好头信息
data=opener.open(url).read()
urllib.request.add_header() :
req=urllib.request.Request(url) #创建 Request 对象
req.add_header('字段名':'字段值') #设置报头
data=urllib.request.urlopen(req).read()

代理服务器设置:

import urllib.request


def use_proxy(proxy_addr, url):
    kv = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Mobile Safari/537.36'}
    kv = urllib.parse.urlencode(kv).encode('utf-8') #转码

    proxy = urllib.request.ProxyHandler({'http': proxy_addr})
    opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
    urllib.request.install_opener(opener)

    data = urllib.request.urlopen(url, data=kv).read().decode('utf-8')
    return data

proxy_addr = '某个代理地址'
url = 'http://www.baidu.com'
data = use_proxy(proxy_addr, url)
print(data[-50:])

注意报头转换为 utf-8
以及代理服务器的设置

第一个参数为代理信息,第二个参数为 urllib.request.HTTPHandler 类

proxy = urllib.request.ProxyHandler({'http': proxy_addr}) #设置代理信息
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler) 
urllib.request.install_opener(opener)

DebugLog 实战

没什么好说的,打印调试日志
设置好参数,还是要创建 opener 对象

#边爬边打印debuglog
import urllib.request
httphd=urllib.request.HTTPHandler(debuglevel=1)
httpshd=urllib.request.HTTPSHandler(debuglevel=1)
opener=urllib.request.build_opener(httphd,httpshd)
urllib.request.install_opener(opener)
data=urllib.request.urlopen('http://www.baidu.com')
print(data.read()[-50:])

URLError 实战

产生 URLError 的原因主要有:

  1. 连接不上服务器
  2. 远程 URL 不存在
  3. 无网络
  4. 出发了子类 HTTPError

简要描述一下HTTPError 的状态码以及意义:

  • 200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
  • 301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
  • 302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  • 304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
  • 403 (禁止) 服务器拒绝请求。
  • 404 (未找到) 服务器找不到请求的网页。
  • 500 (服务器内部错误) 服务器遇到错误,无法完成请求。
  • 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。

    代码:

import urllib.request
import urllib.error

try:
    urllib.request.urlopen('https://www.google.com', timeout=1) #故意设置到某网站
except urllib.error.URLError as e:
    if hasattr(e, 'code'):
        print(e.code)
    if hasattr(e, 'reason'):
        print(e.reason)

'''
 if '测试' in 对象: 
 这种形式必须要可迭代的对象才能使用
     if 'reason' in e: # Wrong!
        print(e.reason)
'''

需要注意的是 HTTPError 是 URLError 的子类,而HTTPError 没有 code 的方法,当然可以通过写两个 except: 解决,代码中的办法也是可以的,然后 in 的使用必须用在可迭代的对象,不能随便用 (:з」∠)

猜你喜欢

转载自blog.csdn.net/joovo/article/details/80153344