python 基本库的使用(一)
使用 urllib
在 Python 2 中,有 urllib 和 urllib2 两个库来实现请求的发送。 而在 Python 3 中,已经不存在 urllib2 这个库了 , 统一为 urllib;
- request : 它是最基本的 HTTP 请求模块,可以用来模拟发送请求。 就像在浏览器里输入网挝 然后回车一样,只需要给库方法传入 URL 以及额外的参数,就可以模拟实现这个过程了。
- error: 异常处理模块,如果出现请求错误, 我们可以捕获这些异常,然后进行重试或其他操 作以保证程序不会意外终止。
- parse: 一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、 合并等。
- robotparser:主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不 可以爬,它其实用得比较少
urllib.request.urlopen(url, data=None, [ timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
,data则表示可以带的参数,timeout表示可设置超时时间,data参数是可选的
# 抓取全书网首页
import urllib.request
response = urllib.request.urlopen('http://www.quanshuwang.com/');
# 由于utf-8在转码的时候会乱码,因此这里使用gbk中文编码,在不同网站使用不同的编码方式
print(response.read().decode('gbk' ,'strict'));
# 获取请求类型
print(type(response)) # <class 'http.client.HTTPResponse'>
print(response.status) # status属性获取请求返回的状态
# 主要包含 read() 、 readinto()、 getheader(name)、 getheaders() 、 fileno()等方法,以及 msg、 version、 status 、 reason 、 debuglevel、 ιlosed 等属性。
使用高级点的Request
利用 urlopen()方法可以实现最基本请求的发起,但这几个简单的参数并不足以构建个完整的请求 如果请求中需要加入 Headers 等信息,就可以利用更强大的 Request 类来构建;
class urllib.request.Request ( url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None);
url 必传,其他参数可选
第二个参数 data 如果要传,必须传 bytes
(字节流)类型的 如果它是字典,可以先用
urllib.parse
模块里的 urlencode()
编码
第三个参数 headers
是一个字典,它就是请求头,我们可以在构造请求时通过 headers 参数直
接构造,也可以通过调用请求实例的 add_header()
方法添加
import urllib .request
request = urllib.request.Request('http://www.quanshuwang.com/')
response = urllib .request.urlopen(request)
print(response.read().decode ('gbk'))
以下代码只是举个例子
from urllib import request, parse
# 请求地址
url = 'http://www.quanshuwang.com/'
headers = {
# 伪装为火狐
'User-Agent': 'Mozilla/4.0 (compatible; MSIE S. S; Windows NT)',
# 请求主题
'Host':'www.quanshuwang.com'
}
dict = {
'name':'Alan'
}
data= bytes(parse.urlencode(dict), encoding='gbk')
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response. read(). decode('gbk'))
另外, headers 也可以用 add_header ()方法来添加:
req = request.Request(url=url, data=data, method= 'POST')
req .add_header('User-Agent','Mozilla/4 .0 (compatible; MSIE 5.5; Windows NT )')
urllib.request.Request 的高级用法
在构造请求的同时,有时候还需要对Cookie和代理做设置以及处理,urllib.request提供了BaseHandler的类,下面还有一堆子类,子类继承了父类;
HITPDefaultErrorHandler :用于处理 HTTP响应错误,错误都会抛出HTTP Error 类型的异常。
HTTPRedirectHandler:用于处理重定向。
HTTPCookieProcessor:用于处理Cookies。
ProxyHandler :用于设置代理,默认代理为空。
HTTPasswordMgr :用于管理密码,它维护了用户名和密码的表。密码
HTTPBasicAuthHandler:用于管理认证,如果一个链接打开时需要认证,那么可以用它来解 决认证问题。需要认证
处理需要登录验证的界面简单实例代码如下:
# 引入密码Handler类,请求类以及错误打印日志类
from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError
username ='18022788898'
password ='KUNLIN001'
url = 'http://192.168.111.120:8082/#/login'
# 用于密码用户名验证的对象
p = HTTPPasswordMgrWithDefaultRealm()
# 利用密码验证这个对象的add_password方法来登录
p.add_password(None, url, username, password)
auth_handler = HTTPBasicAuthHandler(p)
# 类似 urllib.urlopen,输出一致,成功发送请求
opener = build_opener(auth_handler)
try:
result = opener.open(url)
html = result.read().decode('utf-8')
print(html)
except URLError as e: print(e.reason)
添加代理
from urllib.error import URLError
from urllib.request import ProxyHandler, build opener
proxy _handler = ProxyHandler({
'http':'http://127.o.o.1:9743',
'https':'https://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
try:
response = opener.open('https://www.baidu.com')
print(response.read().decode('utf-8'))
except URLError as e: print(e.reason)
# [WinError 10061] 由于目标计算机积极拒绝,无法连接。 可能是被反爬了,可以换个网址试试
添加Cookie
我们必须声明一个 CookieJar对象。接下来,就需要利用HTTPCookieProcessor 来构建一个
Handler,最后利用 build_opener()方法构建出Opener,执行open()函数即可
import http.cookiejar, urllib.request
# 拿取cookie
cookie = http.cookiejar.MozillaCookieJar()
#构建Handler
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler )
response = opener.open('http://www.baidu.com')
for item in cookie:
print(item.name+'='+item.value)
# ===============================================================================
import http.cookiejar, urllib.request
# 定义文件名
filename = 'cookies.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler )
response = opener. open ('https://www.baidu.com')
# 存储cookie到本地
cookie.save(ignore_discard=True, ignore_expires=True)
for item in cookie:
print(item.name+'='+item.value)
LWPCookieJar 同样可以读取和保存 Cookies ,但是保存的格式和 MozillaCookieJar 不一样, 它会保存成 libwww-perl(LWP)格式的 Cookies 文件 。
要保存成 LWP 格式的 Cookies 文件,可以在声明时就改为: cookie = http.cookiejar.LWPCookieJar(filename);
利用LWPCookieJar生产的set-Cookie文件还可以使用来获取百度的首页源码,其实含义是可以通过这种方式来获取到cookie
import http.cookiejar, urllib.request
# 定义文件名
filename = 'cookies.txt'
# 利用本地的这个cookies.txt文件来获取cookie
cookie = http.cookiejar.LWPCookieJar(filename)
cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler )
response = opener.open ('https://www.baidu.com')
# 存储cookie到本地
print (response .read().decode('utf-8'))
URLError
URL Error 类来自 urllib 库的 error 模块,它继承自 OS Error 类,是 error 异常模块的基类,由 request 模块生的异常都可以通过捕获这个类来处理。
from urllib import request,error
try:
response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.URLError as e:
print(e.reason) # Not Found
HTIPError
它是 URL Error 的子类,专 门用来处理 HTTP 请求错误,比如认证请求失败等 。 它有如下 3 个属性。
from urllib import request,error
try:
response = request.urlopen('https://cuiqingcai.com/index.htm')
except error.HTTPError as e:
print(e.reason,e.code,e.headers,seq='\n')
# 超时提醒
import socket
import urllib.request
import urllib.error
try:
response = urllib.request.urlopen ('https://www.baidu.com', timeout=0.01)
except urllib.error.URLError as e:
print(type(e.reason))
if isinstance(e.reason,socket.timeout):
print('TIME OUT')