基础内容
Http协议(HyperText Transfer Protocol,超文本传输协议),是一种发布和接收HTML页面的方法,服务器端口号是80端口;Https协议是Http协议的加密版本,在Http下加入了SSL层,服务器端口号是443端口。
url 详解
URL是Uniform Resource Locator的简写,统一资源定位符。
scheme://host:port/path/?query-string=xxx#anchor
- scheme:访问的协议,一般为http、https、FTP
- host:主机名,域名
- port:端口号
- path:查找路径
- query-string:查询字符串
- anchor:锚点,前端用来做页面定位,现在前后端分离的项目也用锚点来做导航
常见的请求头参数
- User-Agent:浏览器名称
- Referer:表明当前这个请求是从哪个URL过来的
- Cookie:http协议是无状态的,一般登录后才能访问的网站就需要发送cookie信息
常见的状态响应码
- 200: 请求正常
- 301: 永久重定向
- 302: 临时重定向
- 400: 请求的url在服务器上找不到
- 403: 服务器拒绝访问,权限不够
- 500: 服务器内部错误
Cookie
Cookie:网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(不同的浏览器有不同的存储大小,一般不超过4KB)
- cookie的格式:Set-Cookie: NAME=VALUE; Expires/Max-age=DATE; Path=PATH; Domain=DOMAIN_NAME; SECURE
- NAME:cookie的名字
- VALUE:cookie的值
- Expires:cookie的过期时间
- Path:cookie作用的路径
- Domain:cookie作用的域名
- SECURE:是否只在https协议下起作用
urllib库
Python3中的urllib库中,所有和网络请求相关的方法都集成到了urllib.request模块中
- urlopen()方法: 对url基本的请求
- url:请求的url
- data:请求的data,如果设置了这个值,那么将变为POST请求
- 返回值是一个http的响应对象,有一些方法:read(size)、readline()、readlines()、getcode()等,具体功能如函数名所说。使用这些方法后,可能还有些编码,我们可以在后面加入decode(‘utf-8’)进行解码。如:response.read().decode(‘utf-8’)
- Request类:如果在请求url要加入一些请求参数,就要用这个类来实现
- 指定以下headers这个参数就行
- 但通过这个请求网址之后返回的对象,仍然要用urlopen()来打开,再用urlopen()返回的对象来读取内容
urlretrieve()方法: 将请求的网址内容保存到指定文件,用来下载文件时可用
- url: 请求的网址
- filename: 保存的文件名
编码和解码的方法,还有url解析的方法,都在urllib.parse模块当中编码:
- urlencode()方法:可以把字典数据转化为URL编码的数据
- quote()方法:把字符串数据转化为十六进制编码
- 解码:
- parse_qs()方法:可以将经过编码的URL进行解码
url解析:可以对url的各个组成部分进行分割
- urlparse()方法和urlsplit()方法:两个方法都可以对url进行解析,基本上一模一样,唯一的区别在urlparse里有params属性,而urlsplit里没有这个属性
ProxyHandler处理器(代理设置):更改我们请求的ip地址常用的代理有:
- 西刺免费代理IP:http://www.xicidaili.com
- 快代理:http://www.kuaidaili.com
- 代理云:http://www.dailiyun.com
# 使用代理时
url = 'https://httpbin.org/ip'
# 先使用ProxyHandler,传入代理构建一个handler
handler = request.ProxyHandler({'https': '114.239.0.112:9999'})
# 使用handler构建一个opener
opener = request.build_opener(handler)
# 使用opener去发送一个请求
resp = opener.open(url)
print(resp.read())
Requests库
Get请求基本使用样例
import requests
# 设置一个请求头
header = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
# 添加一个请求参数
kw = {'wd': '中国'}
# params 接收一个字典或字符串查询参数,字典类型自动转化为url编码,不再需要urlencode()
response = requests.get("https://www.baidu.com/s", headers=header, params=kw)
# 请求的url
print(response.url)
# 请求的编码
print(response.encoding)
# 查询响应内容
# print(response.text) # 返回unicode格式数据(字符串类型)
# print(response.content) # 返回字节流数据
# print(response.content.decode('utf-8')) # 当使用text属性时乱码可以自行指定编码方式
Post请求基本使用样例
import requests
# 设置一个请求头
header = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
# 石墨文档登录的url
url = 'https://shimo.im/lizard-api/auth/password/login'
# 提交的数据
data = {
'mobile': '+8600000000000',
'password': '*************'
}
response = requests.post(url, headers=header, data=data)
print(response.text)
这里只是一个样例演示,石墨文档在登录时确实使用了POST请求,但请求之后还有一步验证码,所以一样无法登录成功。但使用requests库的POST请求带参数的基本写法如上所示。
使用代理基本使用样例
import requests
# 设置一个请求头
header = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
url = 'https://httpbin.org/ip'
resp = requests.get(url)
print(resp.text)
# 加入代理
proxy = {
'http': '112.111.217.230:9999'
}
response = requests.get(url, proxies=proxy)
print(response.text)
如样例中所示,使用代理只需要添加一个 proxies 参数即可
Cookie基本使用样例
import requests
# 美食杰个人动态页面访问地址
url = 'https://i.meishi.cc/'
header = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
'cookie': 'BAIDU_SSP_lcr=https://www.meishij.net/; Hm_lvt_01dd6a7c493607e115255fdsb7e72de5f40=1620293038; UM_distinctid=17940fdb143243-0537e8cfedb43b-192e1a0c-100200-17940fdb144bf; CNZZDATA1259001544=996200574-1620288841-https%3A%2F%2Fwww.meishij.net%2F|1620288841; __SessHandler=d8498cc568566a711d6f729c92f3e11b; last_update_time=1620293120; loginId=13686422; MSCookieKey=f4104ac7f9c5030a6171b8da08ab694d.13686422; Hm_lpvt_01dd6a7c493607e115255b7e72de5f40=1620293168'
}
response = requests.get(url, headers=header)
print(response.text)
print(response.cookies) # 响应对象的cookie是一个RequestsCookieJar对象
print(response.cookies.get_dict()) # 以字典的形式打印响应里的cookie
使用requests,也可以达到共享cookie的目的,我们可以使用session对象
import requests
# 美食杰登录的地址
login_url = 'https://i.meishi.cc/login_t.php'
hander = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36'
}
data = {
'username': '1097566154@qq.com',
'login_type': 2,
'password': 'wq15290884759.'
}
# 使用session创建一个会话对象完成登录操作,登录完成后session就有了cookie信息
# 这个网站登录在2021年5月份使用的是get请求
session = requests.session()
session.get(login_url, headers=hander, params=data)
# 我的收藏链接
url = 'https://i.meishi.cc/collected.php'
response = session.get(url, headers=hander)
print(response.text)
在上面这个例子中,使用了session进行请求,先模拟登录拿到了cookie,就可以再携带这个cookie去访问个人收藏了
处理不信任的SSL证书
当我们直接访问某个网站,其SSL证书不被信任,会出现如下情况
import requests
response = requests.get('https://inv-veri.chinatax.gov.cn/')
print(response.text)
# --------------------报错如下-----------------------
requests.exceptions.SSLError: HTTPSConnectionPool(host='inv-veri.chinatax.gov.cn', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1123)')))
处理这种情况时,我们只需要将参数 verify 设置为 False就可以正常访问了
import requests
response = requests.get('https://inv-veri.chinatax.gov.cn/', verify=False)
print(response.content.decode('utf-8'))