17. 老板让我手动控制网页渲染速度,说这能反爬虫?我信了。

news2024/12/29 8:40:11

手动数据延迟加载,真的可以反爬虫
爬虫训练场项目,加速更新中,专栏清单参考 pachong.vip
本次案例需要的代码量特别小,所以咱们再 Nginx 中也进行一下相关配置

文章目录

    • 页面逻辑实现
    • 接口逻辑实现
    • 延迟实现,time.sleep() 和 Nginx 配置

页面逻辑实现

这篇博客主要实现一个慢响应爬虫,即模拟网速缓慢时,该如何处理采集程序。

正式实现前,依旧是实现基础页面,本次案例前端使用 Bootstrap5 构建,案例采用 9 部香港经典电影作为数据储备。

快速搭建出视图函数和视图页面,清单如下。

  • app/slow/index.py:用户编写视图相关函数。
  • app/templates/slow/index.html:视图相关代码。

其中 index.html 文件用于实现电影列表,我们可以用可以使用 Bootstrap 的网格系统来创建电影列表。例如,你可以使用 .col-4 类创建一个 3 列的电影列表:

<div class="row">
  <div class="col-4">
    <div class="card">
      <img src="movie1.jpg" class="card-img-top" alt="Movie 1">
      <div class="card-body">
        <h5 class="card-title">Movie 1</h5>
        <p class="card-text">Movie 1 description</p>
      </div>
    </div>
  </div>
  <div class="col-4">
   ……
  </div>
  <div class="col-4">
    ……
  </div>
</div>

在上述代码的基础上,完善卡片信息,补齐电影资料。

<div class="card">
   <img src="{{url_for('static',filename='images/movie/1.jpg')}}"
         class="img-fluid" alt="Movie 1">
    <div class="card-body">
        <h5 class="card-title">无间道</h5>
        <p class="card-text">
            作为香港警探电影系列的巅峰之作,无间道由刘德华、梁朝伟、黄秋生等实力影帝主演,它作为刘德华十大经典电影之一,主要讲述了黑社会的卧底故事,情节反转再反转,非常值得重复观看。</p>
        <button type="button" movieid="1" class="show_movie btn btn-primary">
            详细
        </button>

    </div>
</div>

图片素材,可以去 GitCode 获取,除此之外,给 <img> 标签还增加了 .img-fluid 类,该类可以让图像自适应容器大小,并保持宽度为 100%。

注意上述代码我们使用了一个【详细按钮】,该按钮可以唤醒一个模态弹窗,对应的JS代码如下所示。

$('.show_movie').on('click',function(){
     showModal();
});
function showModal() {

   $('#movieModal').modal('show');
}

其中 $('#movieModal') 调用的 DIV 对象内容如下所示。

<div class="modal fade" id="movieModal">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">

            <!-- 模态标题 -->
            <div class="modal-header">
                <h4 class="modal-title movie_title">加载中……</h4>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>

            <!-- 模态主体 -->
            <div class="modal-body text-center">
                <div class="spinner-border text-primary d-none"></div>
                <p class="movie_body">加载中……</p>
            </div>

            <!-- 模态页脚 -->
            <div class="modal-footer">
                <button type="button" class="btn btn-danger" data-bs-dismiss="modal">关闭</button>
            </div>

        </div>
    </div>
</div>

基础内容增加完毕,实现页面请求部分代码,我们采用 jQuery 的 $.get() 方法发送 HTTP get 请求获取数据,基本格式如下所示。

$.get(url, data, callback, dataType);

其参数说明如下所示。

  • url是请求的 URL;
  • data 是要发送到服务器的数据;
  • callback 是服务器响应后执行的回调函数;
  • dataType 是服务器响应的数据类型,可以是 “html”, “xml”, “json”, “jsonp” 等。

下面是一个示例,用 $.get方法从服务器获取 JSON 格式的数据:

$.get('/data.json', function(data) {
  console.log(data);
}, 'json');

简写格式如下所示:

$.get('/data.json', function(data) {
  console.log(data);
});

这样,数据类型就默认为 "text",不需要手动指定。

data 参数是要发送到服务器的数据。它可以是以下几种类型之一:

  • 字符串:表示查询字符串,例如"name=xiangpica&age=20"
  • 对象:表示查询字符串的键/值对,例如{ name: "xiangpica", age: 20 }
  • 函数:表示返回查询字符串的函数,例如 function() { return "name=xiangpica&age=20"; }

data 是字符串或对象时,会将其转换为查询字符串并附加到 URL 的末尾。例如,对于以下代码:

$.get('/data', { name: "xiangpica", age: 20 }, function(data) {
  console.log(data);
});

实际发送的请求如下所示。

GET /data?name=xiangpica&age=20

如果 data 是函数,则会执行函数并使用其返回值作为查询字符串。例如,对于以下代码:

$.get('/data', function() { return "name=xiangpica&age=20"; }, function(data) {
  console.log(data);
});

实际发送的请求如下所示。

GET /data?name=xiangpica&age=20

当然,你也可以不使用 data 参数,直接发送空的 GET 请求。例如:


$.get('/data', function(data) {
  console.log(data);
});

接口逻辑实现

前端页面构建完毕,就需要将API部分补齐,本次修改的文件是 slow/index.py 文件,其代码如下所示。

slow = Blueprint('slow', __name__, url_prefix='/slow')

movies = [{
    "name": "无间道",
    "release_time": "2002年12月12日",
    "company": "寰亚电影发行公司",
    "movie_type": "剧情、犯罪、警匪"
}, {
    "name": "青蛇",
    "release_time": "1993年11月4日",
    "company": "香港思远影业公司",
    "movie_type": "奇幻"

}, {
    "name": "喜剧之王",
    "release_time": "1999年02月13日",
    "company": "星辉海外有限公司",
    "movie_type": "剧情、喜剧、爱情"

}, {
    "name": "重庆森林",
    "release_time": "1994年07月14日",
    "company": "泽东电影有限公司",
    "movie_type": "剧情、悬疑、爱情"

}, {
    "name": "英雄本色",
    "release_time": "1986年8月2日",
    "company": "新艺城影业有限公司",
    "movie_type": "剧情、动作、犯罪、惊悚"

}, {
    "name": "倩女幽魂",
    "release_time": "1987年7月18日",
    "company": "新艺城影业有限公司",
    "movie_type": "爱情、奇幻、武侠、古装"
}, {
    "name": "花样年华",
    "release_time": "2000年9月29日",
    "company": "泽东电影公司",
    "movie_type": "剧情、文艺、爱情"
}, {
    "name": "大话西游系列",
    "release_time": "1995年2月4日",
    "company": "彩星电影公司",
    "movie_type": "喜剧、爱情、动作、奇幻、冒险"
}, {
    "name": "东成西就",
    "release_time": "1993年2月5日",
    "company": "泽东电影公司",
    "movie_type": "喜剧"
}]


@slow.route('/list')
def list_slow():
    return render_template('slow/index.html')


@slow.route('/detail')
def detail():
    movie_id = int(request.args.get("movie_id", 1))
    movie = movies[movie_id - 1]
    return jsonify(movie)

其中涉及两个路由配置,list 是列表页面,detail 是详情页面,后面主要控制该页面响应速度。

整体代码完成之后的效果如下所示。

在这里插入图片描述
前端弹窗接口调用部分JS代码如下所示,核心逻辑是请求 API,然后拼接响应数据。

$(function(){
    function showModal(movie_id) {

         var data =  {
                movie_id: movie_id
         }
        $.get('/slow/detail',data,function(res){

            $('.spinner-border').addClass('d-none');
            $('.movie_title').text(res.name);
            $('.movie_body').html('<p>上映时间: '+res.release_time+'</p><p>类型:  '+res.movie_type+'</p><p>出品公司: '+res.company+'</p>')
        })
        $('#movieModal').modal('show');
    }
    $('.show_movie').on('click',function(){
            var movie_id = $(this).attr('movieid');
            $('.movie_title').text('加载中……');
            $('.movie_body').text('加载中……');
            $('.spinner-border').removeClass('d-none');
            showModal(movie_id);

    });
});

延迟实现,time.sleep() 和 Nginx 配置

在延迟处理这一块,最简单的办法是调用 time 模块的 sleep() 函数,代码如下:

time.sleep(5) # 延迟 5 秒

第二种配置是采用 Nginx 控制请求次数,首先在服务器端的 Nginx 上找到配置文件 nginx.conf,然后在 httpserver 块中添加如下配置。

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;

在这里,$binary_remote_addr 是 Nginx 变量,表示客户端的 IP 地址,zone=mylimit:10m 表示将限制存储在名为 mylimit 的区域中,并且每个区域可以存储 10MB 的数据,rate=1r/s 表示请求速率为每秒 1 个请求。

接下来回到 Nginx 的通用配置文件 location 块中,添加如下内容。

location /slow/detail
{
 proxy_pass http://127.0.0.1:8787;
 proxy_set_header Host $host;
 limit_req zone=mylimit burst=1 nodelay;
}

这里最重要的配置为 limit_req zone=mylimit burst=1 nodelay;,其中 limit_req 指令是 Nginx 中的一个请求限制功能,用于限制对某个区域的请求的速率。

limit_req 指令有多个参数可以设置,常用的参数有:

  • zone:表示限制请求速率的区域名称。需要使用 limit_req_zone 指令先定义区域;
  • burst:表示请求速率的最大值(每秒请求数)。如果请求速率超过了这个值,则会被拒绝;
  • nodelay:表示请求速率的最小值(每秒请求数)。如果请求速率低于了这个值,则会被延迟响应。

在回过头来看一下刚刚的配置,zone=mylimit 表示使用名为 mylimit 的区域来限制请求速率,burst=1 表示请求速率的最大值是每秒 1 个请求,nodelay 表示请求速率的最小值是每秒 1 个请求。

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022年需求最大8种编程语言!(详细解读)

DevJobsScanner 在过去的 14 个月&#xff08;从 2021 年 10 月到 2022 年 11 月&#xff09;中分析了超过 1200 万个开发人员职位需求&#xff0c;并从其中挑选了明确需要编程语言的工作机会&#xff0c;得到了 2022 年最受欢迎的 8 种编程语言。 目前市场中需求最高的前八位…

数学建模学习笔记-算法(线性规划模型)-上

目录 线性规划问题 线性规划的matlab标准形式 解析 目标函数 约束条件 使用matlab的linprog函数来进行求解 线性规划问题 数学规划&#xff1a;安排现有资源安排生产&#xff0c;以取得最大效益的问题。 线性规划&#xff1a;目标函数和约束条件均为线性函数 在一组线性…

2023/1/2总结

今天AC了三个有关二叉树的题目&#xff1a; P1827 [USACO3.4] 美国血统 American Heritage_lxh0113的博客-CSDN博客 https://blog.csdn.net/lxh0113/article/details/128522831?spm1001.2014.3001.5502 P1030 [NOIP2001 普及组] 求先序排列_lxh0113的博客-CSDN博客 然后学…

web基础标签

标签分类&#xff1a; 文本标签&#xff1a; 文本标题标签&#xff1a;h1---h6 段落标签&#xff1a; p 水平线&#xff1a; <hr/> 换行符&#xff1a; <br/> 转义字符&#xff1a; 注释标签&#xff1a; <!--注释内容--> 无语义标签&#xff1a; 语义标签…

educoder数据结构与算法 线性表 第1关:实现一个顺序存储的线性表

本文已收录于专栏 &#x1f332;《educoder数据结构与算法_大耳朵宋宋的博客-CSDN博客》&#x1f332; &#x1f350;任务描述&#x1f350; 本关任务&#xff1a;实现 step1/Seqlist.cpp 中的SL_InsAt、SL_DelAt和SL_DelValue三个操作函数&#xff0c;以实现线性表中数据的插…

TypeScript中abstract抽象类、抽象成员

TypeScript也支持定义抽象类和抽象类成员。抽象类和抽象类成员都使用abstract关键字来定义 抽象类可以不包含抽象方法&#xff0c;但抽象方法必须存在于抽象类中抽象方法只能定义&#xff0c;不能实现&#xff0c;即没有函数体抽象类不能被直接使用&#xff0c;只能被继承&…

Spring Boot学习篇(五)

Spring Boot学习篇(五) mybatis-plus使用 1.1 配置pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:s…

《设计模式》代理模式

《设计模式》设计模式的基本原则 《设计模式》单例模式 《设计模式》工厂模式 《设计模式》原型模式 《设计模式》建造者模式 《设计模式》适配器模式 《设计模式》桥接模式 《设计模式》装饰者模式 《设计模式》组合模式 《设计模式》外观模式 《设计模式》享元模式 《设计模式…

HTML5和CSS3 WEB技术开发

HTML5和CSS3 WEB技术开发 B站视频参考&#xff1a;https://www.bilibili.com/video/BV1H44y1k7ze/ 课程目标&#xff1a; 使用HTML5进行网站布局使用CSS3进行网站美化开发精美的商业网站 第一章 HTML5基础 概念&#xff1a; ​ 网页 &#xff1a;互联网的基础&#xff0c;网…

requests请求库(爬取)

文章目录requests模块链接拼接&#xff08;params参数&#xff09;UA伪装&#xff08;headers参数&#xff09;POST请求页面局部信息爬取&#xff08;GET&#xff09;爬取国家药品监督管理监督总局中基于中华人民共和国化妆品生产许可证相关数据爬取图片爬虫分类通用爬虫&#…

分布式存储从FastDFS切换到Minio

什么是Minio 基于官网的介绍如下&#xff1a;MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。 从官网的介绍可以看出Minio是一款和FastDFS类似的工具&#xff0c;分布式存储系统。目前在使…

运行MAT项目环境配置中出现的问题及参考方案

MAT项目是用于修复图片中缺失的部分&#xff1a;及为图像中缺失的区域产生视觉吸引力和语义适当的内容。 项目链接&#xff1a;GitHub - fenglinglwb/MAT: MAT: Mask-Aware Transformer for Large Hole Image InpaintingMAT: Mask-Aware Transformer for Large Hole Image Inp…

国内有没有可以全职远程办公的程序员工作?

明作为一个曾经靠兼职开发远程办公来赚钱的程序员&#xff0c;既碰到过无良甲方&#xff0c;开发完了不结尾款&#xff0c;最后通过法律手段才解决问题&#xff1b;也接过自称甲方的中介单&#xff0c;耗费心力拿到尾款&#xff0c;最后发现人家拿的钱比自己还多......这一路兼…

方格取数--数字三角形dp问题

项目场景&#xff1a; 线性dp 数字三角形类问题 问题描述 设有 NN 的方格图&#xff0c;我们在其中的某些方格中填入正整数&#xff0c;而其它的方格中则放入数字0。如下图所示&#xff1a; 某人从图中的左上角 A 出发&#xff0c;可以向下行走&#xff0c;也可以向右行走&am…

WebGL及Threejs学习介绍

一、学习背景及实现的效果 这十年来Web得到了飞速的发展&#xff0c;随着WebGL的普及&#xff0c;网页的表现能力越来越强大&#xff0c;网页上已经可以开始做出很多复杂的动画、精美的效果&#xff1b;还能通过WebGL在网页中绘制高性能的3d图形。随着浏览器的性能和网络、带宽…

github实用搜索技巧

github搜索指令教程一. in:根据某个关键词来进行检索1.关键词:name: 项目名称description : 项目描述readme : 项目帮助文档语法 &#xff1a;language:xx(检索什么语言的内容)组合检索二.根据stars||forks||pushed关键字查找1.数量范围: xxx关键词 stars:>或者:<2.区间范…

Pytorch 数据操作

神经网络所处理的数据类型都为tensor类型数据&#xff0c;我们首先需要导入库torch import torch 使用 arange 创建一个行向量 x。这个行向量包含以0开始的前12个整数&#xff0c;它们默认创建为整数。除非额外指定&#xff0c;新的张量将存储在内存中&#xff0c;并采用基于…

进程替换心得

进程替换 1️⃣ 什么是进程替换 1.我们想让子进程不执行父进程部分代码&#xff0c;执行新的程序时我们需要进行进程替换。 ** 程序替换的原理 ** &#xff1a; 将磁盘中的程序&#xff0c;加载入内存结构。重新建立页表映射&#xff0c;谁执行程序替换就程序建立谁的映射(子…

redis 的 java 客户端

Jedis 客户端 1&#xff09;引入依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&…

【Vim】Vim 常用编辑操作

目录 正则表达式 vim 命令 vim的工作模式 撤销修改、重做与保存 光标移动命令 文本插入操作 文本删除操作 文本复制、剪切与粘贴 文本的修改与替换 多窗口操作 正则表达式 简单地说&#xff0c;正则表达式是一种符号表示法&#xff0c;用于识别文本模式。在某种程度上…