1、Flask整体框架流程回顾:
- 视图函数把数据返回给浏览器的方法有多种,其中一种就是通过模板Templates。
2、Flask插件介绍:
- Flask插件可以去官网查看,有很多。
- 插件安装流程:
- 1、通过pip指令在对应环境中下载插件
- 2、在项目的exts.py文件中初始化
- 3、使用
3、Flask的caching插件介绍:
- 这个插件是一个和缓存相关的插件,缓存经常用来保留那些经常被访问的临时数据。
4、钩子函数:
- 定义:钩子函数也叫做钩子或者中间件,是指在执行函数和目标函数之间挂载的函数,框架开发者给调用方提供了一个point-挂载点,是一种AOP切面编程思想。
- 通俗理解:就是在程序执行的过程中,设置钩子函数,可以拦截错误的访问,同时可以检查执行的数据。
- 常用的钩子函数:
- before_first_request:处理第一次请求之前执行。
- before_request:每次请求之前执行,通常用这个钩子函数预处理一些变量,实现反爬等。
- after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
- teardown_appcontext:当APP上下文被移除之后执行的函数,可以进行数据库的提交或者回滚。
5、结合Flask的caching插件和钩子函数制作一个简单的爬虫反扒工具:
- 项目预览
注意:这里项目用到的还是之前的项目模板,可以看下Python轻量级Web框架Flask(8)
- 需求:写一个简单爬虫,通过Flask模型中缓存插件和钩子函数制作一个反扒程序。
- 首先下载安装flask-caching(在环境的对应终端pip install flask-caching)
- 然后初始化(参考上面)
- 代码展示(这部分只会展示和模板中被修改部分的代码,其余文件代码参考模板)
exts:
from flask_sqlalchemy import SQLAlchemy # ORM
from flask_migrate import Migrate # 数据迁移
from flask_caching import Cache
db = SQLAlchemy()
migrate = Migrate()
cache = Cache(
config={'CACHE_TYPE': 'simple'} # 缓存类型
)
def init_exts(app):
db.init_app(app=app)
migrate.init_app(app=app,db=db)
cache.init_app(app=app)
views:
# 在views.py中放路由和视图函数
from flask import Blueprint, request
from .models import * #后面是用views来控制数据库的,所以要在views中导入models文件
from .exts import cache
import time
# 蓝图
blue = Blueprint('user', __name__)
@blue.route('/')
@cache.cached(timeout=10) # 缓存的有效时间是10秒
def index():
print('index')
time.sleep(3) # 第一次访问会等待3秒,返回值也会给到缓存,之后再访问就直接在缓存中获取返回值(不会再执行index了)
return 'index'
# 钩子函数
# defore_request:每次请求之前访问
@blue.before_request
def before(): # 钩子函数没有路由
print('before_request')
# request
print(request.path) # /
print(request.method) # GET
print(request.remote_addr) # 127.0.0.1(客户端ip)
# # 简单反爬(通过访问代理)
# print(request.user_agent)
# # 浏览器访问的user_agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
# # python爬虫访问的user_agent:python-requests/2.28.2 【运行spider文件之后的结果】
# if 'python' in request.user_agent.string:
# return '请不要使用python爬虫!该访问已被拦截'
# 通过ip的访问频率反爬:
ip = request.remote_addr
if cache.get(ip):
return '你的ip正在实施爬虫行为'
else:
# 对每个ip设置一个缓存,1秒内不让重复访问
cache.set(ip, 'value', timeout=1)
spider:
import requests
# res = requests.get('http://127.0.0.1:5000/')
# print(res.text) # index
# 频繁访问
for i in range(10):
res = requests.get('http://127.0.0.1:5000/')
print(res.text) # index