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 的原因主要有:
- 连接不上服务器
- 远程 URL 不存在
- 无网络
- 出发了子类 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 的使用必须用在可迭代的对象,不能随便用 (:з」∠)