1.爬虫介绍
爬虫就是程序从互联网中各个网站上爬取数据(只能爬区我们能看到的数据),然后进行数据清洗(筛选),入库。
爬虫的本质:模拟http请求,获取数据,入库。
百度就是一个大爬虫,百度爬虫一刻不停的在互联网页面中爬取各个页面,爬取完之后保存在自己的数据库中。
模拟发送http请求可以使用:requests模块、selenium。爬虫框架:scrapy。
2.requests模块介绍、使用
使用request可以模拟浏览器发送请求(http),比起之前哟用到的urllib,request的api更加便捷(本质就是封装了urllib3)。
1.安装:
pip3 install requests
2.requests发送get请求
import requests
res = requests.get('https://www.cnblogs.com/')
print(res.text)
# 结果就是页面所有的html标签
3.requests携带参数
方式一:
res = requests.get('https://www.cnblogs.com/?name=max&age=18')
print(res.text)
# 执行结果和上面没区别
方式二:
res = requests.get('https://www.cnblogs.com',params={'name':'max','age':17})
print(res.text)
3.url编码解码
如果我们携带的参数是中文,在地址栏会做url的编码
res = requests.get('https://www.cnblogs.com/liuqingzheng/p/16005866.html',params={'name':"彭于晏",'age':19})
print(res.url) # https://www.cnblogs.com/liuqingzheng/p/16005866.html?name=%E5%BD%AD%E4%BA%8E%E6%99%8F&age=19
编码的关键字:quote,解码关键字:unquote
res = quote('爬虫')
print(res) # %E7%88%AC%E8%99%AB
print(unquote('%E7%88%AC%E8%99%AB')) # 爬虫
4.请求头
http请求头中重要的信息:User-Agent、Cookie、Connection
1.User-Agent
反扒的措施之一,就是从请求头中携带的信息进行删选。如果发现既不是浏览器也不是手机端,那么访问的客户端可能就是爬虫。在http的请求中,请求头中有一个很重要的参数User-Agent,这个参数表明了客户端类型:
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69
如果发送请求时没有携带这个请求头,后端就禁止访问。这里面注明了浏览器类型:Chrome,以及操作系统:Windows。我们可以在项目中利用这User-Agent在中间件中写一个检验措施,允许哪些浏览器或者操作系统可以访问。如果爬某个网站请求被禁止,可以有限加上该请求头信息再尝试。
那如何在爬虫措施中携带请求头呢?
headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'}
res = requests.get('https://dig.chouti.com/',headers=headers)
print(res.text)
2.Connect:keep-alive
http:版本1.1、0.9:2.x
0.9的http版本基于tcp,建立一个http连接会在底层创建一个tcp连接,这样很耗费资源。到http1.1时,请求头中增加了一个参数:keep-alive,如果有该参数,那么他们之间是一直保持连接的,相对于每次请求都建立一个tcp连接可以消耗更少的资源。2.x比1.x多了多路复用:一个数据包下可以包含多个数据流,多个数据可以并行发送,提高对带宽得得得利用率。
5.http协议各个版本区别
0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
1.0
增加了请求方式POST和HEAD;
请求行必须在尾部添加协议版本字段(http/1.0),每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;
同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求(默认短链接),当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keep-alive。
短连接:客户端和服务端进行收发数据的时候才进行连接,一次收发消息后就进行断开。优点:管理起来比较简单,存在的连接都是有用的连接
长连接:双方建立连接,一次读写之后不会主动断开。优点:省去了TCP连接和关闭的时间,节省了时间,频繁请求的用户适合长连接,缺点是如果有人恶意攻击,产生大量的长连接,会使服务器受损。所以可以关闭一些长时间不用的连接,以及限制客户端的最大连接数
1.1
1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。解决了1.0版本的keepalive问题,一个TCP连接可以允许多个HTTP请求;客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。
加入了管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性,进一步改善了HTTP协议的效率;举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
新增了请求方式PUT、PATCH、OPTIONS、DELETE等。
客户端请求的头信息新增了Host字段,用来指定服务器的域名。在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题(HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级);HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息
当前主流的协议版本还是HTTP/1.1版本。
多路复用:对于 HTTP/1.x,即使开启了长连接,请求的发送也是串行发送的,在带宽足够的情况下,对带宽的利用率不够,HTTP/2.0 采用了多路复用的方式,可以并行发送多个请求,提高对带宽的利用率。
详细请参考:https://juejin.cn/post/6974673084095660062
6.发送post请求携带数据
headers是请求头信息,data是请求体信息。从浏览器中的的network中找到需要向服务端发送什么请求携带什么参数,然后我们在这里模拟发送就可以了:
模拟点赞:
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',
'cookie':'' # 从请求头中拿到cookie
}
data = {'postId':'17213598','voteType': 'Digg','isAbandoned': 'true'}
res = requests.post('https://www.cnblogs.com/',data=data)
print(res)
7.自动登录,携带cookie的两种方式
import requests
# 现在网页上多登陆,查看向后端发送post请求携带的数据,模仿网页的数据向后端发送post请求
data = {
'username': '',
'password': '',
'captcha': '3456', # 验证码
'remember': 1,
'ref': 'http://www.aa7a.cn/', # 重定向地址
'act': 'act_login'
}
res = requests.post('http://www.aa7a.cn/user.php',data=data)
print(res.text)
# 响应中会有登录成功的的cookie,
print(res.cookies) # RequestsCookieJar 跟字典一样
# 拿着这个cookie,发请求,就是登录状态
# 访问首页,get请求,携带cookie,首页返回的数据一定会有 我的账号
# 携带cookie的两种方式 方式一是字符串,方式二是字典或CookieJar对象
# 方式二:放到cookie参数中
res1=requests.get('http://www.aa7a.cn/',cookies=res.cookies)
print('邮箱信息' in res1.text) # 如果结果是true说明密码正确,因为能拿到数据说明数据cookie是正确的
8.requests.session的使用
requests.session就是为了此后不用携带cookie,它会自动把cookie加入到session当中。
import requests
data = {
'username': '',
'password': '',
'captcha': '3456',
'remember': 1,
'ref': 'http://www.aa7a.cn/',
'act': 'act_login'
}
session = requests.session()
res = session.post('http://www.aa7a.cn/user.php', data=data)
print(res.text)
res1 = session.get('http://www.aa7a.cn/') # 自动保持登录状态,自动携带cookie
print('[email protected]' in res1.text)
9.补充post请求携带数据编码格式
import requests
# data对应字典,这样写,编码方式是urlencoded
requests.post(url='xxxxxxxx',data={'xxx':'yyy'})
# json对应字典,这样写,编码方式是json格式
requests.post(url='xxxxxxxx',json={'xxx':'yyy'})
# 终极方案,编码就是json格式
requests.post(url='',
data={'':1,},
headers={
'content-type':'application/json'
})
10.响应Response对象
# Response相应对象的属性和方法
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
}
respone=requests.get('http://www.jianshu.com',headers=headers)
# respone属性
print(respone.text) # 响应体转成了字符串
print(respone.content) # 响应体的二进制内容
print(respone.status_code) # 响应状态码
print(respone.headers) # 响应头
print(respone.cookies) # cookie是在响应头,cookie很重要,它单独做成了一个属性
print(respone.cookies.get_dict()) # cookieJar对象---》转成字段
print(respone.cookies.items()) # cookie的键值对
print(respone.url) # 请求地址
print(respone.history) # 不用关注
print(respone.encoding) # 响应编码格式
11.编码问题
# 有的网站,打印
res.text --->发现乱码---》请求回来的二进制---》转成了字符串---》默认用utf8转---》
response.encoding='gbk'
再打印res.text它就用gbk转码
13 下载图片,视频
import requests
# res=requests.get('http://pic.imeitou.com/uploads/allimg/230224/7-230224151210-50.jpg')
# # print(res.content)
# with open('美女.jpg','wb') as f:
# f.write(res.content)
#
res=requests.get('https://vd3.bdstatic.com/mda-pcdcan8afhy74yuq/sc/cae_h264/1678783682675497768/mda-pcdcan8afhy74yuq.mp4')
with open('致命诱惑.mp4','wb') as f:
for line in res.iter_content():
f.write(line)
标签:http,请求,res,爬虫,print,requests,连接
From: https://www.cnblogs.com/ERROR404Notfound/p/17219157.html