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

news/2025/2/5 8:09:52/

手动数据延迟加载,真的可以反爬虫
爬虫训练场项目,加速更新中,专栏清单参考 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.ppmy.cn/news/8904.html

相关文章

c++版369寝室

描述&#xff1a;369 寝室是比较特殊的寝室&#xff0c;因为别的寝室都住了四个人&#xff0c;而 369 寝室只有三个人。也因为这个原因&#xff0c;寝室里的三位同学感情特别好。但是&#xff0c;毕业在即&#xff0c;三位小伙伴马上要分别。为了在未来的某个日子可以见面&…

第二个岳云鹏,跨年晚会含泪主持,成为一道最靓丽的风景

中国人自古讲究&#xff1a;百善孝入先&#xff0c;尤其是对于娱乐圈的明星来说&#xff0c;孝心和爱心更是他们成功的根本。 在这方面&#xff0c;德云社的小岳岳走在了前列&#xff0c;他用自己的孝心和爱心感动了粉丝&#xff0c;也收获了无数的鲜花和掌声。小岳岳的爱心体现…

【学习】domain adaptation、BERT

文章目录一、domain adaptation领域适应domain shiftdomain adversarial training![在这里插入图片描述](https://img-blog.csdnimg.cn/26ef051b6a6148cbadb2dc6a9067fce2.png)domain generalization二、自监督学习多语言BERT的跨语言能力交叉学科能力用人工数据进行预训练一、…

信息数智化招采系统源码——信息数智化招采系统

​ 信息数智化招采系统 服务框架&#xff1a;Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 前端架构&#xff1a;VUE、Uniapp、Layui、Bootstrap、H5、CSS3 涉及技术&#xff1a;Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、…

计算机视觉实战----AlexNet网络及使用colab跑YoloV5代码

系列文章目录 文章目录系列文章目录前言一、用colab薅羊毛二、使用百度飞浆操作三、二、使用步骤1.引入库2.读入数据总结前言 一、用colab薅羊毛 Colaboratory 简称“Colab”&#xff0c;是 Google Research 团队开发的一款产品。在 Colab 中&#xff0c;任何人都可以通过浏览…

React-Router6路由相关一(路由的基本使用、重定向、NavLink·、路由表、嵌套路由)(七)

系列文章目录 第一章&#xff1a;React基础知识&#xff08;React基本使用、JSX语法、React模块化与组件化&#xff09;&#xff08;一&#xff09; 第二章&#xff1a;React基础知识&#xff08;组件实例三大核心属性state、props、refs&#xff09;&#xff08;二&#xff0…

Docker进阶(中)

docker 进阶&#xff08;中&#xff09;docker提交镜像等命令docker 镜像原理docker 私有库&推送到私有库容器数据卷docker 安装常规软件docker提交镜像等命令 再这个谈这个docker 提交这个镜像之前我们先补充一下上一篇博客没有谈到的命令。再这里说一下。我们之前谈到的…

剑指offer----C语言版----第七天

目录 1. 旋转数组中的最小数字 1.1 题目描述 1.2 思路一 1.3 思路二 1.4 小试牛刀 1. 旋转数组中的最小数字 原题链接&#xff1a; 剑指 Offer 11. 旋转数组的最小数字 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-…