23. 反爬案例:不登录不给,要数据请先登录我的站点

news/2024/11/7 12:44:33/

登录之后,可以查看数据,是部分站点常用规则,本篇博客将在爬虫训练场中实现该需求。

文章目录

    • 安装必备模块
    • 建立 models
    • 建立 login_form 表单文件
      • flask_wtf 中 FlaskForm 类
    • 建立登录视图函数
    • 配置 login.html 页面

安装必备模块

实现 Python Flask 项目的登录,最需要的模块是 flask-login,除此之外,还需要用到以下三个模块:

  • flask-wtf:该模块用于在 Flask 应用程序中处理 Web 表单的功能。
  • wtf:用于跟踪和报告程序崩溃的功能;
  • werkzeug:Web 服务器和 Web 应用程序的功能,包括 HTTP 处理和 WSGI 支持。

模块全部安装完毕,首先要做的准备工作是在 MySQL 数据库中建立 users 表,结构相对简单,仅包含 2 个字段即可。
23. 反爬案例:不登录不给,要数据请先登录我的站点

建立 models

数据库表建立完毕,可以在 app 目录下创建 login_model.py 文件,并输入模型代码。

from werkzeug.security import generate_password_hash, check_password_hashfrom flask_login import UserMixin
from app import dbclass User(UserMixin, db.Model):__tablename__ = "users"id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(20), unique=True)password_hash = db.Column(db.String(128))@propertydef password(self):# 设置密码的属性为只写raise AttributeError('密码不能读取')@password.setterdef password(self, password):# 当类初始化时自动调用,把 password 的值转换为 hash 值self.password_hash = generate_password_hash(password)def verify_password(self, password) -> bool:# 登录时验证密码return check_password_hash(self.password_hash, password)

这里用到的几个核心函数说明如下:

flask_login 中 UserMixin 类说明

UserMixin 类可以被用户类继承。 这个类包含了一些必要的属性和方法,以便于 Flask-Login 来管理登录状态,如 is_authenticated, is_active, is_anonymous 以及 get_id。用户需要实现的只需要继承 UserMixin,然后实现它的函数 get_id() 即可。

werkzeug.security 中的两个函数 generate_password_hash(), check_password_hash()

Werkzeug.security 模块提供了两个主要的函数,用于生成和验证密码哈希:

  • generate_password_hash(password, method='sha256', salt_length=8):这个函数用于生成密码哈希。参数 password 是需要加密的明文密码, method 参数用于指定使用的哈希算法, 默认为 'sha256',salt_length 为指定盐的长度;
  • check_password_hash(hashed_password, password):这个函数用于检查给定的明文密码和哈希值是否匹配。参数 hashed_password 是上面 generate_password_hash() 函数生成的哈希值,password 是需要校验的密码。

建立 login_form 表单文件

app 目录建立 login_form.py,然后输入如下代码。

from flask_wtf import FlaskForm
from wtforms.validators import DataRequired, Length
from wtforms import StringField, SubmitField, PasswordField# 定义的表单都需要继承自FlaskForm
class UserForm(FlaskForm):username = StringField('用户名', validators=[DataRequired(), Length(3, 15)])password = PasswordField('密码', validators=[DataRequired(), Length(5, 15)])submit = SubmitField('登录')

由于 flask_wtf 模块用于处理表单,所以我们自定义一个表单。

上述代码涉及的知识点如下所示。

flask_wtf 中 FlaskForm 类

Flask-WTF 是 Flask 框架中的一个扩展库,主要用于构建和处理 HTML 表单。在 Flask-WTF 中,FlaskForm 类是一个非常重要的类,它是所有表单类的基类。

FlaskForm 类提供了一些基础的功能,包括验证,渲染,和 CSRF 保护等功能。通常,我们会定义一个继承于 FlaskForm 的自定义表单类来处理特定的表单。

例如上述代码,我们集成 FlaskForm 创建了一个表单对象,用于处理用户的登录信息,并且通过在类中使用 Flask-WTF 内置的字段类和验证器来验证用户的输入。

除此之外,还可以在模板中可以使用 {{form.csrf_token}} 生成隐藏的 csrf_token

建立登录视图函数

打开 routes.py 文件,在其中添加登录视图函数,首先将 UserForm() 实例化的对象传递到模板中,后续可以在 login.html 中直接进行渲染。

@app.route("/login", methods=['GET', 'POST'])
def login():form = UserForm()if form.validate_on_submit():# 查询用户信息user = User.query.filter_by(username=form.username.data).first()if user is not None:if user.verify_password(form.password.data):flash('登录成功')login_user(user)  # login_user 的参数为要登录的用户return redirect(request.args.get('next') or url_for('school.login_list_school'))flash('登录失败')return render_template('login.html', form=form)

既然已经开始修改 routes.py 文件,那再这里需要首先实例化 LoginManager 类 ,该类用于管理用户登录状态。

然后使用 init_app() 函数将 LoginManager 类对象绑定到指定 Flask 应用上。


from flask_login import LoginManager,login_user# use login manager to manage session
login_manager = LoginManager(app)
login_manager.login_view = 'login'  # 设置登录页面# 回调函数,用来加载用户
@login_manager.user_loader  #
def load_user(id):'''用于加载用户'''return User.query.get(int(id))

除此之外,还需要增加 load_user() 函数,该函数用于加载用户,关于 Flask-Login 的详细用法,可以参考下述博客。
Python flask 框架使用 flask-login 模块,来学习一下吧

配置 login.html 页面

打开 login.html 文件,输入如下代码,完成最后收尾工作。

{% extends "base.html" %} {% block style %}
<style type="text/css">.required:after {content: "*";color: red;}
</style>
{% endblock style %} {% block script %}
<scripttype="text/javascript"src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.0.min.js"
></script>
<script type="text/javascript">$(document).ready(function () {$('[data-toggle="tooltip"]').tooltip();});
</script>{% endblock script %} {% block content %}
<div class="container"><div class="row justify-content-center"><div class="col-md-6 mt-5 mb-5 p-5 border border-success shadow-lg  "><h1 class="text-primary">登录窗口</h1><form action="{{ url_for('login') }}" method="POST" class="mt-4"><div class="form-group"><span class="required"> {{ form.username.label }} </span>:{{form.username(class="form-control",placeholder="请输入用户名",data_toggle="tooltip",title="测试账号:xiangpica")}}<small id="username_help" class="form-text text-muted">用户名至少3个字符</small></div><div class="form-group"><span class="required"> {{ form.password.label }} </span> : {{form.password(class="form-control",placeholder="请输入密码",data_toggle="tooltip",title="测试密码:123456")}} <br /></div><div class="form-group">{{ form.submit(class="btn btn-primary" ) }}</div>{{ form.csrf_token }}</form></div></div>
</div>{% endblock %}

运行代码,得到如下登录窗口。

23. 反爬案例:不登录不给,要数据请先登录我的站点

本案例到此结束,已更新到 爬虫训练场 欢迎大家访问学习。
项目同步到代码仓库 https://gitcode.net/hihell/spider_playground

📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 828 篇原创博客

从订购之日起,案例 5 年内保证更新

  • ⭐️ Python 爬虫 120,点击订购 ⭐️
  • ⭐️ 爬虫 100 例教程,点击订购 ⭐️

http://www.ppmy.cn/news/11496.html

相关文章

springboot:接手老项目,领导让更新数据库说明文档,如何3分钟完成任务

0 引言 最新在重新整理老项目的文档&#xff0c;其中数据库说明文档上一版更新还是在1年多前&#xff0c;文档中的数据结构说明与当前数据库严重脱节&#xff0c;所以更新数据库说明文档已经是迫在眉睫的事情了。 因为项目是一个比较大型且“年长‘的项目&#xff0c;涉及了多…

Java异常情况了解

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏&#xff1a;JavaSE 作者介绍&#xff1a;大三学生&#xff0c;希望一起进步~ 文章目录 目录 文章目录 一、异常结构体系 二、异常分类 三、异常处理 3.1异常抛出 3.2 异常捕获 四.【面试题】 五、题目练习…

4509. 归一化处理

Powered by:NEFU AB-IN Link 文章目录4509. 归一化处理题意思路代码4509. 归一化处理 题意 第26次CCF计算机软件能力认证 在机器学习中&#xff0c;对数据进行归一化处理是一种常用的技术。 将数据从各种各样分布调整为平均值为 0、方差为 1 的标准分布&#xff0c;在很多情况…

前端笔试选择题——day3

前端笔试选择题——day3 输出什么 const obj {a:one, b:two, c:three} console.log(obj) // {a:"three", b:"two"}解析&#xff1a; 如果对象有两个具有相同名称的键&#xff0c;则将替换原有的值 将会发生什么 let config {alert:setInterval(() > {…

Linux-终端命令行

终端(Terminal)命令行仅仅是一个工具&#xff0c;对于命令有许多&#xff0c;而且随着嵌入式领域不断开发&#xff0c;命令会越来越多&#xff0c;我们只需要去了解常用的即可。 对于创建或删除一个文件夹&#xff0c;清理终端&#xff0c;下载文件等等都可以在终端命令行输入…

二叉平衡树之AVL树【手动实现代码】

目录 1、AVL树的概念 2、AVL树定义节点 3、AVL树的插入 4、AVL树的旋转 4.1、新节点插入较高左子树的左侧——右单旋 4.2、新节点插入较高右子树的右侧——左单旋 4.3、新节点插入较高左子树的右侧——左右双旋 4.4、新节点插入较高右子树的左侧——右左双旋 5、AVL树…

计算最大公约数和最小公倍数被Java程序员用代码写出来啦

沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、前言 嘿&#xff0c;怎么突然讲到最大公约数了&#xff1f; 这么想你肯定是没有好好阅读前面章节中讲到的RSA算法&#xff0c;对于与欧拉结果计算的互为质数的公钥e&#xff0c;其实就需…

为ABP新增手机验证模块

当前手机验证基本是标配&#xff0c;但Abp自身并没有实现这个功能&#xff0c;于是有了通过自定义模块实现的想法。 经过研究&#xff0c;发现要实现这个&#xff0c;只要重写和替换包含ReplaceEmailToUsernameOfInputIfNeeds方法的类就可以了。但要实现这个&#xff0c;首先要…