网页不同渲染方式的应对与反爬机制的处理——python爬虫
文章目录
- 写在前面
- 爬虫习惯
- web 网页渲染方式
- 服务器渲染
- 客户端渲染
- 反爬机制
- 使用session对象
- 使用cookie
- 让请求头信息更丰富
- 使用代理和随机延迟
写在前面
本文是对前两篇文章所介绍的内容的补充,在了解前两篇文章——《爬虫入门与requests库的使用》和《BeautifulSoup 库的使用》,对python 爬虫理论上的介绍后,再看本文,你将会有更加深刻的理解(大佬随意🎉
)。
爬虫习惯
在了解requests库
和BeautifulSoup 库
后,我们需要知道一些关于爬虫开发习惯和原则,以此来应对网页不同的渲染方式。
web 网页渲染方式
首先,要知道一般情况,web网页
会有两种渲染方法:
- 服务器渲染:在服务器那边,直接将
数据
与html页面代码
整合在一起,返回给浏览器-----在浏览器上的页面源代码
中能够找到对应的数据。 - 客户端渲染: 第一次请求服务器,只要一个
html
的骨架,第二次请求才会拿到对应的数据
,然后由客户端(浏览器)将html
和数据
整合在一起,展示出来-----在浏览器上的页面源代码
中找不到对应的数据。
服务器渲染
其次,BeautifulSoup 库
是用来处理爬取到的页面源代码(html
)的,若要爬取到网页源代码,就要知道其对应url
:
如上图所示,红框处不仅有url还有对应的参数信息
,以上方式适用于服务器渲染,即在页面源代码中找得到数据。
客户端渲染
另外一种情况就是客户端渲染,其依靠于浏览器抓包工具,如下图:
若想要爬取到上述红框
的数据,需要知道其对应的url,如下:
上图中的url
后面也携带了参数,但是我们一般不看,因为不方便,我们一般采用如下方式查看参数:
最重要的原则是:以上两个方式,
能直接爬取到数据,绝不爬取html页面
!!!
反爬机制
一般的网站都会有反爬机制,当我们通过爬虫进行爬取网站数据时,可能会触发该网站的反爬机制,通常情况下,返回状态码<403>,就表明触发了反爬机制,在反爬机制下,爬虫是无法再继续获取数据的,必须要用户亲自登录该网站才行,为此,我们必须尽可能地避免触发网站的反爬机制,而避免的方法有以下几种。
使用session对象
尽可能地使用Session(会话)对象来封装爬虫,而不是直接使用requests库来封装爬虫。
Session(会话) 的主要作用:
- 自动管理Cookie
当我们访问需要登录的网站时,首次登录后服务器会返回 Cookies
,后续请求需携带这些 Cookies
以维持登录状态。
而有了Session
后,Session
就可以自动保存和发送 Cookies
,无需手动处理。
session = requests.Session()
#创建一个持久化的会话对象# 向指定网址发送登录请求(自动保存 Cookies)
session.post("https://example.com/login", data={"user": "admin", "pass": "123"})
# post——提交用户名(user)和密码(pass)等参数
# 用Session对象发送post登录请求,Session对象可以自动接收并存储服务器返回的Cookies# 后续请求通过Session对象发出,请求将自动携带 Cookies
response = session.get("https://example.com/dashboard")
- 持久化公共参数
当我们有多个请求都需要相同的 Headers
(请求头)、超时时间
、认证信息
或代理
时,可以使用Session对象,一次性设置参数,所有通过 该Session对象
发起的请求自动继承这些参数。
session = requests.Session() #创建一个session对象session.headers.update({"User-Agent": "My Crawler/1.0"})
# 向session对象中添加一个请求头session.proxies = {"http": "http://10.10.1.10:3128"}
# 向session对象中添加一个代理# 所有请求自动携带 请求头 和代理
session.get("https://example.com/page1")
session.get("https://example.com/page2")
- 复用 TCP 连接(性能优化)
当我们高频次请求同一服务器时,重复建立和断开 TCP 连接会浪费资源,这个时候,我们可以通过Session
对象来对TCP连接进行复用,通过复用连接,可以减少延迟并提升效率。
# 未使用 Session:每次请求新建连接
for _ in range(10):requests.get("https://example.com") # 10 次独立连接# 使用 Session:复用同一连接(推荐使用)
with requests.Session() as session:for _ in range(10):session.get("https://example.com") # 更高效
4.保持请求上下文
某些网站会检查请求的连贯性(如反爬机制),我们可以通过session对象
来模拟浏览器行为,保持一致的上下文(如Referer、Cookies)。
注意事项:
- 会话对象需合理关闭(推荐用
with
语句管理资源)。- 如果请求不同网站且无需共享参数,直接使用
requests.get()
更轻量
使用cookie
提前登录你要爬取的网站,通过浏览器抓包,在你的登录后的任意请求的请求头中找到"cookie"
的字段或者在响应头中找到"set-cookie"
字段,将cookie
复制到你的代码中,作为爬虫伪装的请求头的一部分。
- 如上图,cookie的形式:
cookie名 = cookie值
,上图红框内有很多cookie
,有些是目标网站的,有些是第三方平台的。这里面不是所有cookie
都必须需要,其核心的cookie
为dbcl2
+ck
(登录相关)、bid
(反爬基础)。 - 此外,cookie的获取,还可以通过代码来实现:
response.cookies
,该代码作用是返回要爬取的网页的所有的cookie
。
如上图所示,只有一个cookie,cookie名为"bid"
,其值为tk6VyicFk4E
。
一般请求头中有了
cookie
,服务器就会默认此请求是一个用户发出的,而不是爬虫。
让请求头信息更丰富
对于爬虫伪装的请求头,信息要越丰富越好,一般必须有这两个字段"referer"
和
"User-Agent"
,其余字段视情况判断是否添加。
关于"User-Agent"
字段,可以使用 fake_useragent
库生成随机浏览器"User-Agent"
,这样能够增大绕开机制的可能。
from fake_useragent import UserAgent
import requestsua = UserAgent()
headers = {'User-Agent': ua.random} #随机生成的UA
response = requests.get(url, headers=headers)
注意:使用
fake_useragent
库生成随机浏览器头,可能会生成移动端,windows端,linux端
等不同的浏览器头,有些网站会根据不同的浏览器头返回不同的页面,这个时候,爬虫可能会失效(因为同一个url返回了不同页面,导致爬取失败)
使用代理和随机延迟
短时间高频请求触发会触发网站对该 IP地址的封禁,因此,我们要控制访问频率。
import requests
import time
import randomproxies = {"http": "http://10.10.1.10:3128", # 假设此为有效代理"https": "http://10.10.1.10:1080",
}# 随机延迟(1~3秒)
time.sleep(random.uniform(1, 3))response = requests.get(url, headers=headers, proxies=proxies)
注意:
- 以上,是一些常用的基本的绕开反爬机制的方法,但并不是全部,具体采用哪个方法,要根据你要爬取的网站的具体情况来判断。
- 各个方法之间,也不是独立的,可以相互配合使用,提高绕开反爬机制的可能。
相关文章:

网页不同渲染方式的应对与反爬机制的处理——python爬虫
文章目录 写在前面爬虫习惯web 网页渲染方式服务器渲染客户端渲染 反爬机制使用session对象使用cookie让请求头信息更丰富使用代理和随机延迟 写在前面 本文是对前两篇文章所介绍的内容的补充,在了解前两篇文章——《爬虫入门与requests库的使用》和《BeautifulSou…...

高级电影感户外街拍人像摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!
调色介绍 高级电影感户外街拍人像摄影后期 Lr 调色,是运用 Adobe Lightroom 软件,对户外街拍的人像照片进行后期处理,以塑造出具有电影质感的独特视觉效果。此调色过程借助 Lr 丰富的工具与功能,从色彩、光影、对比度等多维度着手…...
JAVA设计模式——(三)桥接模式
JAVA设计模式——(三)桥接模式(Bridge Pattern) 介绍理解实现武器抽象类武器实现类涂装颜色的行为接口具体颜色的行为实现让行为影响武器修改武器抽象类修改实现类 测试 适用性 介绍 将抽象和实现解耦,使两者可以独立…...
类加载器与jvm的内存
1. 类加载器与内存的关系 类加载器的字节码放在方法区(元空间)中,同时类加载器加载类后类的信息(成员变量、成员方法及修饰符等)存放在方法区中。类的信息所占内存的回收要同时满足两个条件:类的实例被回收…...
docker 配置代理
说明:该方法仅对 docker 程序本身拉取镜像的时候有效,对命令行无效。 docker 配置代理有 2 中方法 1.Daemon configuration 直接在 /etc/docker/daemon.json 文件中配置 {"proxies": {"http-proxy": "http://proxy.example.…...

【硬核干货】JetBrains AI Assistant 干货笔记
快进来抄作业,小编呕心沥血整理的 JetBrains AI Assistant 超干货笔记! 原文链接:【硬核干货】JetBrains AI Assistant 干货笔记 关于晓数神州 晓数神州坚持以“客户为中心”的宗旨,为客户提供专业的解决方案和技术服务ÿ…...

Linux部署ragflow,从安装docker开始~
安装docker https://download.docker.com/linux/static/stable/x86_64/docker-28.0.1.tgz #首先创建一个文件夹,存放我们需要的各类文件,并切换到该目录 mkdir /project && cd /project #此时我们的工作目录已经切换到刚刚创建的文件夹下了,接…...
施磊老师基于muduo网络库的集群聊天服务器(七)
文章目录 数据表字符集问题支持中文和英文**为什么使用 utf8mb4?** 推荐 查看整个表, 再单独修改 客户端群组功能创建群组添加群组群组聊天接收在线群组消息接收离线群组消息补充服务器事件处理器补充服务器查询群组列表问题解决测试 目前报错总结目前为止最恶心的错…...

多态以及多态底层的实现原理
本章目标 1.多态的概念 2.多态的定义实现 3.虚函数 4.多态的原理 1.多态的概念 多态作为面对三大特性之一,它所指代的和它的名字一样,多种形态.但是这个多种形态更多的指代是函数的多种形态. 多态分为静态多态和动态多态. 静态多态在前面已经学习过了,就是函数重载以及模板,…...

使用Go语言实现轻量级消息队列
文章目录 一、引言1.1 消息队列的重要性1.2 为什么选择Go语言1.3 本文实现的轻量级消息队列特点 二、核心设计2.1 消息队列的基本概念2.1.1 消息类型定义2.1.2 消息结构设计 2.2 架构设计2.2.1 基于Go channel的实现方案2.2.2 单例模式的应用2.2.3 并发安全设计 2.3 消息发布与…...
Vue3后代组件多祖先通讯设计方案
在 Vue3 中,当需要设计一个被多个祖先组件使用的后代组件的通讯方式时,可以采用以下方案(根据场景优先级排序): 方案一:依赖注入(Provide/Inject) 响应式上下文 推荐场景ÿ…...

路由与OSPF学习
【路由是跨网段通讯的必要条件】 路由指的是在网络中,数据包从源主机传输到目的主机的路径选择过程。 路由通常涉及以下几个关键元素: 1.路由器:是一种网络设备,负责将数据包从一个网络传输到另一个网络。路由器根据路由表来决定…...

CUDA编程之Grid、Block、Thread线程模型
一、线程模型:Grid、Block、Thread概念 1. 层级定义 Thread(线程) CUDA中最基本的执行单元,对应GPU的单个CUDA核心(SP)。每个线程独立执行核函数指令,拥有独立的寄存器和局部内存空间。 Block(线程块) 由多个线程组成(通常为32的倍数),是逻辑上的并…...
postgres 导出导入(基于数据库,模式,表)
在 PostgreSQL 中,导出和导入数据库、模式(schema)或表的数据可以使用多种工具和方法。以下是常用的命令和步骤,分别介绍如何导出和导入整个数据库、特定的模式以及单个表的数据。 一、导出数据 1. 使用 pg_dump 导出整个数据库…...

小学数学出题器:自动化作业生成
小学数学出题器是专为教师、家长设计的自动化作业生成工具,通过预设参数快速生成符合教学要求的练习题,大幅降低备课与辅导压力。跨平台兼容:支持 Windows 系统免安装运行(解压即用)。免费无广告:永…...
systemctl 命令详解与常见问题解决
在 Linux 系统中,service 命令和 chkconfig 命令一直用于管理服务,但随着 systemd 的引入,systemctl 命令逐渐成为主流。systemctl 命令不仅功能强大,而且使用简单。本文将详细介绍 systemctl 命令的作用以及常见问题的解决方法。…...
12.桥接模式:思考与解读
原文地址:桥接模式:思考与解读 更多内容请关注:7.深入思考与解读设计模式 引言 在软件设计中,尤其是在处理复杂系统时,你是否遇到过这样的情况:你的系统中有多个功能模块,而这些功能模块需要与不同的平台…...

卷积神经网络迁移学习:原理与实践指南
引言 在深度学习领域,卷积神经网络(CNN)已经在计算机视觉任务中取得了巨大成功。然而,从头开始训练一个高性能的CNN模型需要大量标注数据和计算资源。迁移学习(Transfer Learning)技术为我们提供了一种高效解决方案,它能够将预训练模型的知识…...
Centos虚拟机远程连接缓慢
文章目录 Centos虚拟机远程连接缓慢1. 问题:SSH远程连接卡顿现象2. 原因:SSH服务端DNS检测机制3. 解决方案:禁用DNS检测与性能调优3.1 核心修复步骤3.2 辅助优化措施 4. 扩展认识:SSH协议的核心机制4.1 SSH工作原理4.2 关键配置文…...

Spark与Hadoop之间的联系和对比
(一)Spark概述 Apache Spark 是一个快速、通用、可扩展的大数据处理分析引擎。它最初由加州大学伯克利分校 AMPLab 开发,后成为 Apache 软件基金会的顶级项目。Spark 以其内存计算的特性而闻名,能够在内存中对数据进行快速处理&am…...
C++学习笔记(三十九)——STL之删除算法
STL 算法分类: 类别常见算法作用排序sort、stable_sort、partial_sort、nth_element等排序搜索find、find_if、count、count_if、binary_search等查找元素修改copy、replace、replace_if、swap、fill等修改容器内容删除remove、remove_if、unique等删除元素归约for…...
C++——Lambda表达式
在C中,Lambda表达式是一种匿名函数对象,它允许你在代码中直接定义一个函数,而不需要提前声明一个单独的函数。Lambda表达式是从C11标准开始引入的,它极大地增强了C语言的灵活性和表达能力,尤其在处理函数对象、回调函数…...

基于线性LDA算法对鸢尾花数据集进行分类
基于线性LDA算法对鸢尾花数据集进行分类 1、效果 2、流程 1、加载数据集 2、划分训练集、测试集 3、创建模型 4、训练模型 5、使用LDA算法 6、画图3、示例代码 # 基于线性LDA算法对鸢尾花数据集进行分类# 基于线性LDA算法对鸢尾花数据集进行分类 import numpy as np import …...

【Deepseek基础篇】--v3基本架构
目录 MOE参数 1.基本架构 1.1. Multi-Head Latent Attention多头潜在注意力 1.2.无辅助损失负载均衡的 DeepSeekMoE 2.多标记预测 2.1. MTP 模块 论文地址:https://arxiv.org/pdf/2412.19437 DeepSeek-V3 是一款采用 Mixture-of-Experts(MoE&…...
从爬楼梯到算法世界:动态规划与斐波那契的奇妙邂逅
从爬楼梯到算法世界:动态规划与斐波那契的奇妙邂逅 在算法学习的旅程中,总有一些经典问题让人印象深刻。“爬楼梯问题”就是其中之一,看似简单的题目,却蕴藏了动态规划与斐波那契数列的深刻联系。今天,我就以这个问题…...

centos7使用yum快速安装最新版本Jenkins-2.462.3
Jenkins支持多种安装方式:yum安装、war包安装、Docker安装等。 官方下载地址:https://www.jenkins.io/zh/download 本次实验使用yum方式安装Jenkins LTS长期支持版,版本为 2.462.3。 一、Jenkins基础环境的安装与配置 1.1:基本…...

【vue】【element-plus】 el-date-picker使用cell-class-name进行标记,type=year不生效解决方法
typedete,自定义cell-class-name打标记效果如下: 相关代码: <el-date-pickerv-model"date":clearable"false":editable"false":cell-class-name"cellClassName"type"date"format&quo…...

c++11新特性随笔
1.统一初始化特性 c98中不支持花括号进行初始化,编译时会报错,在11当中初始化可以通过{}括号进行统一初始化。 c98编译报错 c11: #include <iostream> #include <set> #include <string> #include <vector>int main() {std:…...
Linux字符设备驱动开发的详细步骤
1. 确定主设备号 手动指定:明确设备号时,使用register_chrdev_region()静态申请(需确保未被占用)。动态分配:通过alloc_chrdev_region()由内核自动分配主设备号(更灵活,推…...
Nginx 二进制部署与 Docker 部署深度对比
一、核心概念解析 1. 二进制部署 通过包管理器(如 apt/yum)或源码编译安装 Nginx,直接运行在宿主机上。其特点包括: 直接性:与操作系统深度绑定,直接使用系统库和内核功能 。定制化:支持通过编译参数(如 --with-http_ssl_module)启用或禁用模块,满足特定性能需求 。…...