爬虫入门
爬虫
爬虫的本质
模拟方式发送http请求,获取数据。
学习内容
-
模拟发送http请求
-
requests模块
-
selenium模块
-
解析爬下来的数据
-
存入数据库内
-
爬虫框架 scrapy
requests模块介绍
使用python发送http请求就需要用到requests模块
,requests模块封装了urllib3。
安装
pip3.8 install requests
使用
有的网址发送请求,不返回数据是因为做了反爬
import requests # 导入模块
res = requests.get('https://www.cnblogs.com/LiaJi/p/17216659.html')
get 第一个参数就是url ,第二个参数时params
print(res.text) # text可以转成字符串
requests在地址栏中带参数
- 直接拼在url后面
res = requests.get('https://www.cnblogs.com/LiaJi/p/17216659.html?name=lxj')
- 放在参数params里
res = requests.get('https://www.cnblogs.com/LiaJi/p/17216659.html',params={'name':'lxj'})
print(res.url) #https://www.cnblogs.com/LiaJi/p/17216659.html?name=lxj
url编码和解码
地址栏中携带参数如果是中文会自动编码。我们模拟发送请求的返回的url有时候也会编码
编码
from urllib.parse import quote,unquote
res=quote('李阿鸡')
# %E6%9D%8E%E9%98%BF%E9%B8%A1
解码
res= unquote('%E6%9D%8E%E9%98%BF%E9%B8%A1')
print(res)
# 李阿鸡
携带请求头
反爬措施之一就是验证请求头中有没有参数
http发送请求,请求头中有一个很重要的参数叫user-agent
user-agent
表明了客户端类型是什么。里面包含了操作系统,浏览器及版本。
我们在后端也可以在中间件
里用request.META
拿到user-agent
来判断是否是爬虫。
我们可以携带该参数。网址就可以不禁止访问。
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
res = requests.get('http://www.zongheng.com/',headers=headers)
print(res.text)
请求头里还有
cookie
referer:
跳转前的链接地址
作用于 反爬
的参数
当我们爬取一个网址是如果不携带该参数可能没有数据返回
Cache-Control:no-cache
是否启用缓存
Connection:keep-alive
,keep-alive就是保持链接(持久链接)。
http协议有版本,现在主流是1.1 ,老版0.9, 新版2.0
http是基于TCP的一个可靠传输,如果建立一个http链接底层就是创建了一个tcp链接,tcp底层会三次握手。请求响应结束就会 四次挥手。 每次发送一次请求都是一个循环。
1.1版本 新增了keep-alive
持久链接,之后就不断开底层的tcp链接,底层三次握手之后在一定时间内不会断开链接,在这段时间内如果再次发送请求还会走这个链接。 有过期时间的
2.x比1.1x多了 多路复用
,1.1虽然可以多个请求使用同一个链接但是得等一个链接走完了才能走下一个链接。 多路复用
可以在一次tcp传输数据包过程中有多个http请求。效率变得更高。
post请求
模拟发送post请求,有些链接需要登录才能访问,我们可以登录后在检查Network里的post请求的payload看到。携带的数据。
import requests
# 还要携带ser-agent cookie 还有data参数
headers = {
'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'Cookie':''
}
data={
# 在网页Network里的post请求的payload看到
'linkId': '38067633'
}
res = requests.post('https://dig.chouti.com/link/vote',headers=headers,data=data)
print(res.text)
补充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'
})
自动登录
模拟登录的目的就是为了拿到登录后的cookie,后续可以自动下单
import requests
# 下面的内容可以在网站点一下登录后查看post请求里的payload
data = {
'username': '616564099@qq.com',
'password': 'lqz123',
'captcha': '3343',
'remember': 1,
'ref': 'http://aa7a.cn/',
'act': 'act_login'
}
res = requests.post('http://aa7a.cn/user.php', data=data)
print(res.text)
# res响应对象,响应中含有登陆成功的cookie
print(res.cookies) # RequestsCookieJar 跟字典一样
# 拿这个cookie发送请求就是登录状态
# 携带cookie的第二种方式cookies=res.cookies
res1 = requests.get('http://aa7a.cn/',cookies=res.cookies)
# 判断账号存不存在页面里,存在说明登录成功
print('616564099@qq.com' in res1.text)
requests.session的使用。
会自动携带登录后的cookie
import requests
data = {
'username': '616564099@qq.com',
'password': 'lqz123',
'captcha': '3343',
'remember': 1,
'ref': 'http://aa7a.cn/',
'act': 'act_login'
}
# 得到session对象后就不用requests发送请求了
session=requests.session()
res = session.post('http://aa7a.cn/user.php', data=data)
print(res.text)
# 会自动保持登录状态,自动携带登录后的cookie
res1 = session.get('http://aa7a.cn/')
print('616564099@qq.com' in res1.text)
响应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) # 响应编码格式
编码问题
有的网站,打印res.text发现乱码,我们请求回来的二进制转成了字符串默认用utf8转
response.encoding='gbk'
再打印res.text它就用gbk转码
下载图片,视频
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)
"""iter_content()一行一行读 """