【Python爬虫】8大模块md文档从0到scrapy高手,第8篇:反爬与反反爬和验证码处理

本文主要学习一下关于爬虫的相关前置知识和一些理论性的知识,通过本文我们能够知道什么是爬虫,都有那些分类,爬虫能干什么等,同时还会站在爬虫的角度复习一下http协议。

Python爬虫和Scrapy全套笔记直接地址: 请移步这里


共 8 章,37 子模块


反爬与反反爬

本阶段本文主要学习爬虫的反爬及应对方法。

常见的反爬手段和解决思路

学习目标
  1. 了解 服务器反爬的原因
  2. 了解 服务器常反什么样的爬虫
  3. 了解 反爬虫领域常见的一些概念
  4. 了解 反爬的三个方向
  5. 了解 常见基于身份识别进行反爬
  6. 了解 常见基于爬虫行为进行反爬
  7. 了解 常见基于数据加密进行反爬

1 服务器反爬的原因

  • 爬虫占总PV(PV是指页面的访问次数,每打开或刷新一次页面,就算做一个pv)比例较高,这样浪费钱(尤其是三月份爬虫)。

三月份爬虫是个什么概念呢?每年的三月份我们会迎接一次爬虫高峰期,有大量的硕士在写论文的时候会选择爬取一些往网站,并进行舆情分析。因为五月份交论文,所以嘛,大家都是读过书的,你们懂的,前期各种DotA,LOL,到了三月份了,来不及了,赶紧抓数据,四月份分析一下,五月份交论文,就是这么个节奏。

  • 公司可免费查询的资源被批量抓走,丧失竞争力,这样少赚钱。

数据可以在非登录状态下直接被查询。如果强制登陆,那么可以通过封杀账号的方式让对方付出代价,这也是很多网站的做法。但是不强制对方登录。那么如果没有反爬虫,对方就可以批量复制的信息,公司竞争力就会大大减少。竞争对手可以抓到数据,时间长了用户就会知道,只需要去竞争对手那里就可以了,没必要来我们网站,这对我们是不利的。

  • 状告爬虫成功的几率小

爬虫在国内还是个擦边球,就是有可能可以起诉成功,也可能完全无效。所以还是需要用技术手段来做最后的保障。

2 服务器常反什么样的爬虫

  • 十分低级的应届毕业生

应届毕业生的爬虫通常简单粗暴,根本不管服务器压力,加上人数不可预测,很容易把站点弄挂。

  • 十分低级的创业小公司

现在的创业公司越来越多,也不知道是被谁忽悠的然后大家创业了发现不知道干什么好,觉得大数据比较热,就开始做大数据。分析程序全写差不多了,发现自己手头没有数据。怎么办?写爬虫爬啊。于是就有了不计其数的小爬虫,出于公司生死存亡的考虑,不断爬取数据。

  • 不小心写错了没人去停止的失控小爬虫

有些网站已经做了相应的反爬,但是爬虫依然孜孜不倦地爬取。什么意思呢?就是说,他们根本爬不到任何数据,除了httpcode是200以外,一切都是不对的,可是爬虫依然不停止这个很可能就是一些托管在某些服务器上的小爬虫,已经无人认领了,依然在辛勤地工作着。

  • 成型的商业对手

这个是最大的对手,他们有技术,有钱,要什么有什么,如果和你死磕,你就只能硬着头皮和他死磕。

  • 抽风的搜索引擎

大家不要以为搜索引擎都是好人,他们也有抽风的时候,而且一抽风就会导致服务器性能下降,请求量跟网络攻击没什么区别。

3 反爬虫领域常见的一些概念

因为反爬虫暂时是个较新的领域,因此有些定义要自己下:

  • 爬虫:使用任何技术手段,批量网站信息的一种方式。关键在于批量。

  • 反爬虫:使用任何技术手段,阻止别人批量自己网站信息的一种方式。关键也在于批量。

  • 误伤:在反爬虫的过程中,错误的将普通用户识别为爬虫。误伤率高的反爬虫策略,效果再好也不能用。

  • 拦截:成功地阻止爬虫访问。这里会有拦截率的概念。通常来说,拦截率越高的反爬虫策略,误伤的可能性就越高。因此需要做个权衡。

  • 资源:机器成本与人力成本的总和。

这里要切记,人力成本也是资源,而且比机器更重要。因为,根据摩尔定律,机器越来越便宜。而根据IT行业的发展趋势,程序员工资越来越贵。因此,通常服务器反爬就是让爬虫工程师加班才是王道,机器成本并不是特别值钱。

4 反爬的三个方向

  • 基于身份识别进行反爬

  • 基于爬虫行为进行反爬

  • 基于数据加密进行反爬

5 常见基于身份识别进行反爬

1 通过headers字段来反爬

headers中有很多字段,这些字段都有可能会被对方服务器拿过来进行判断是否为爬虫

1.1 通过headers中的User-Agent字段来反爬

  • 反爬原理:爬虫默认情况下没有User-Agent,而是使用模块默认设置
  • 解决方法:请求之前添加User-Agent即可;更好的方式是使用User-Agent池来解决(收集一堆User-Agent的方式,或者是随机生成User-Agent)

1.2 通过referer字段或者是其他字段来反爬

  • 反爬原理:爬虫默认情况下不会带上referer字段,服务器端通过判断请求发起的源头,以此判断请求是否合法
  • 解决方法:添加referer字段

1.3 通过cookie来反爬

  • 反爬原因:通过检查cookies来查看发起请求的用户是否具备相应权限,以此来进行反爬
  • 解决方案:进行模拟登陆,成功cookies之后在进行数据爬取
2 通过请求参数来反爬

请求参数的方法有很多,向服务器发送请求,很多时候需要携带请求参数,通常服务器端可以通过检查请求参数是否正确来判断是否为爬虫

2.1 通过从html静态文件中请求数据(github登录数据)

  • 反爬原因:通过增加请求参数的难度进行反爬
  • 解决方案:仔细分析抓包得到的每一个包,搞清楚请求之间的联系

2.2 通过发送请求请求数据

  • 反爬原因:通过增加请求参数的难度进行反爬
  • 解决方案:仔细分析抓包得到的每一个包,搞清楚请求之间的联系,搞清楚请求参数的来源

2.3 通过js生成请求参数

  • 反爬原理:js生成了请求参数
  • 解决方法:分析js,观察加密的实现过程,通过js2pyjs的执行结果,或者使用selenium来实现

2.4 通过验证码来反爬

  • 反爬原理:对方服务器通过弹出验证码强制验证用户浏览行为
  • 解决方法:打码平台或者是机器学习的方法识别验证码,其中打码平台廉价易用,更值得推荐

6 常见基于爬虫行为进行反爬

1 基于请求频率或总请求数量

爬虫的行为与普通用户有着明显的区别,爬虫的请求频率与请求次数要远高于普通用户

1.1 通过请求ip/账号单位时间内总请求数量进行反爬

  • 反爬原理:正常浏览器请求网站,速度不会太快,同一个ip/账号大量请求了对方服务器,有更大的可能性会被识别为爬虫
  • 解决方法:对应的通过购买高质量的ip的方式能够解决问题/购买个多账号

1.2 通过同一ip/账号请求之间的间隔进行反爬

  • 反爬原理:正常人操作浏览器浏览网站,请求之间的时间间隔是随机的,而爬虫前后两个请求之间时间间隔通常比较固定同时时间间隔较短,因此可以用来做反爬
  • 解决方法:请求之间进行随机等待,模拟真实用户操作,在添加时间间隔后,为了能够高速数据,尽量使用代理池,如果是账号,则将账号请求之间设置随机休眠

1.3 通过对请求ip/账号每天请求次数设置阈值进行反爬

  • 反爬原理:正常的浏览行为,其一天的请求次数是有限的,通常超过某一个值,服务器就会拒绝响应
  • 解决方法:对应的通过购买高质量的ip的方法/多账号,同时设置请求间随机休眠
2 根据爬取行为进行反爬,通常在爬取步骤上做分析

2.1 通过js实现跳转来反爬

  • 反爬原理:js实现页面跳转,无法在源码中下一页url
  • 解决方法: 多次抓包条状url,分析规律

2.2 通过蜜罐(陷阱)爬虫ip(或者代理ip),进行反爬

  • 反爬原理:在爬虫链接进行请求的过程中,爬虫会根据正则,xpath,css等方式进行后续链接的提取,此时服务器端可以设置一个陷阱url,会被提取规则,但是正常用户无法,这样就能有效的区分爬虫和正常用户
  • 解决方法: 完成爬虫的编写之后,使用代理批量爬取测试/仔细分析响应内容结构,找出页面中存在的陷阱

2.3 通过假数据反爬

  • 反爬原理:向返回的响应中添加假数据污染数据库,通常家属剧不会被正常用户看到
  • 解决方法: 长期运行,核对数据库中数据同实际页面中数据对应情况,如果存在问题/仔细分析响应内容

2.4 阻塞任务队列

  • 反爬原理:通过生成大量垃圾url,从而阻塞任务队列,降低爬虫的实际工作效率
  • 解决方法: 观察运行过程中请求响应状态/仔细分析源码垃圾url生成规则,对URL进行过滤

2.5 阻塞网络IO

  • 反爬原理:发送请求响应的过程实际上就是下载的过程,在任务队列中混入一个大文件的url,当爬虫在进行该请求时将会占用网络io,如果是有多线程则会占用线程
  • 解决方法: 观察爬虫运行状态/多线程对请求线程计时/发送请求钱

2.6 运维平台综合审计

  • 反爬原理:通过运维平台进行综合管理,通常采用复合型反爬虫策略,多种手段同时使用
  • 解决方法: 仔细观察分析,长期运行测试目标网站,检查数据采集速度,多方面处理

7 常见基于数据加密进行反爬

1 对响应中含有的数据进行特殊化处理

通常的特殊化处理主要指的就是css数据偏移/自定义字体/数据加密/数据图片/特殊编码格式等

1.1 通过自定义字体来反爬 下图来自猫眼电影电脑版

  • 反爬思路: 使用自有字体文件
  • 解决思路:切换到手机版/解析字体文件进行翻译

1.2 通过css来反爬 下图来自猫眼去哪儿电脑版

  • 反爬思路:源码数据不为真正数据,需要通过css位移才能产生真正数据
  • 解决思路:计算css的偏移

1.3 通过js动态生成数据进行反爬

  • 反爬原理:通过js动态生成
  • 解决思路:解析关键js,获得数据生成流程,模拟生成数据

1.4 通过数据图片化反爬

  • 58同城短租](https://baise.58.com/duanzu/38018718834984x.shtml)
  • 解决思路:通过使用图片解析引擎从图片中解析数据

1.5 通过编码格式进行反爬

  • 反爬原理: 不适用默认编码格式,在响应之后通常爬虫使用utf-8格式进行解码,此时解码结果将会是乱码或者报错
  • 解决思路:根据源码进行多格式解码,或者真正的解码格式

小结

  • 掌握 常见的反爬手段、原理以及应对思路

反爬与反反爬

本阶段本文主要学习爬虫的反爬及应对方法。

验证码处理

学习目标
  1. 了解 验证码的相关知识
  2. 掌握 图片识别引擎的使用
  3. 了解 常见的打码平台
  4. 掌握 通过打码平台处理验证码的方法

1.图片验证码

1.1 什么是图片验证码

  • 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。

1.2 验证码的作用

  • 防止恶意破解密码、刷票、论坛灌水、刷页。有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试,实际上使用验证码是现在很多网站通行的方式(比如招商银行的网上个人银行,百度社区),我们利用比较简易的方式实现了这个功能。虽然登录麻烦一点,但是对网友的密码安全来说这个功能还是很有必要,也很重要。

1.3 图片验证码在爬虫中的使用场景

  • 注册
  • 登录
  • 频繁发送请求时,服务器弹出验证码进行验证

1.4 图片验证码的处理方案

  • 手动输入(input) 这种方法仅限于登录一次就可持续使用的情况
  • 图像识别引擎解析 使用光学识别引擎处理图片中的数据,目前常用于图片数据提取,较少用于验证码处理
  • 打码平台 爬虫常用的验证码解决方案

2.图片识别引擎

OCR(Optical Character Recognition)是指使用扫描仪或数码相机对文本资料进行扫描成图像文件,然后对图像文件进行分析处理,自动识别文字信息及版面信息的软件。

2.1 什么是tesseract
  • Tesseract,一款由HP实验室开发由Google维护的开源OCR引擎,特点是开源,免费,支持多语言,多平台。
  • 项目地址:https://github.com/tesseract-ocr/tesseract
2.2 图片识别引擎环境的安装

1 引擎的安装

  • mac环境下直接执行命令
brew install --with-training-tools tesseract
  • windows环境下的安装 可以通过exe安装包安装,下载地址可以从GitHub项目中的wiki找到。安装完成后记得将Tesseract 执行文件的目录加入到PATH中,方便后续调用。

  • linux环境下的安装

sudo apt-get install tesseract-ocr

2 Python库的安装

  
  
# PIL用于打开图片文件
  
  
pip/pip3 install pillow

  
  
# pytesseract模块用于从图片中解析数据
  
  
pip/pip3 install pytesseract
2.3 图片识别引擎的使用
  • 通过pytesseract模块的 image_to_string 方法就能将打开的图片文件中的数据提取成字符串数据,具体方法如下
from PIL import Image
import pytesseract

im = Image.open()

result = pytesseract.image_to_string(im)

print(result)
2.4 图片识别引擎的使用扩展
  • tesseract简单使用与训练
  • 其他ocr平台
微软Azure 图像识别:https://azure.microsoft.com/zh-cn/services/cognitive-services/computer-vision/
  有道智云文字识别:http://aidemo.youdao.com/ocrdemo
  阿里云图文识别:https://www.aliyun.com/product/cdi/
  腾讯OCR文字识别:https://cloud.tencent.com/product/ocr

3 打码平台

1.为什么需要了解打码平台的使用

现在很多网站都会使用验证码来进行反爬,所以为了能够更好的数据,需要了解如何使用打码平台爬虫中的验证码

2 常见的打码平台
  1. 云打码:http://www.yundama.com/

能够解决通用的验证码识别

  1. 极验验证码智能识别辅助:http://jiyandoc.c2567.com/

能够解决复杂验证码的识别

3 云打码的使用

下面以云打码为例,了解打码平台如何使用

3.1 云打码官方接口

下面代码是云打码平台提供,做了个简单修改,实现了两个方法:

  1. indetify:传入图片的响应二进制数即可
  2. indetify_by_filepath:传入图片的路径即可识别

其中需要自己配置的地方是:

username = 'whoarewe' # 用户名

password = '***' # 密码

appid = 4283 # appid

appkey = '02074c64f0d0bb9efb2df455537b01c3' # appkey

codetype = 1004 # 验证码类型

云打码官方提供的api如下:

  
  
#yundama.py
  
  
import requests
import json
import time

class YDMHttp:
    apiurl = 'http://api.yundama.com/api.php'
    username = ''
    password = ''
    appid = ''
    appkey = ''

    def __init__(self, username, password, appid, appkey):
        self.username = username
        self.password = password
        self.appid = str(appid)
        self.appkey = appkey

    def request(self, fields, files=[]):
        response = self.post_url(self.apiurl, fields, files)
        response = json.loads(response)
        return response

    def balance(self):
        data = {'method': 'balance', 'username': self.username, 'password': self.password, 'appid': self.appid,
                'appkey': self.appkey}
        response = self.request(data)
        if (response):
            if (response['ret'] and response['ret'] < 0):
                return response['ret']
            else:
                return response['balance']
        else:
            return -9001

    def login(self):
        data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.appid,
                'appkey': self.appkey}
        response = self.request(data)
        if (response):
            if (response['ret'] and response['ret'] < 0):
                return response['ret']
            else:
                return response['uid']
        else:
            return -9001

    def upload(self, filename, codetype, timeout):
        data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.appid,
                'appkey': self.appkey, 'codetype': str(codetype), 'timeout': str(timeout)}
        file = {'file': filename}
        response = self.request(data, file)
        if (response):
            if (response['ret'] and response['ret'] < 0):
                return response['ret']
            else:
                return response['cid']
        else:
            return -9001

    def result(self, cid):
        data = {'method': 'result', 'username': self.username, 'password': self.password, 'appid': self.appid,
                'appkey': self.appkey, 'cid': str(cid)}
        response = self.request(data)
        return response and response['text'] or ''

    def decode(self, filename, codetype, timeout):
        cid = self.upload(filename, codetype, timeout)
        if (cid > 0):
            for i in range(0, timeout):
                result = self.result(cid)
                if (result != ''):
                    return cid, result
                else:
                    time.sleep(1)
            return -3003, ''
        else:
            return cid, ''

    def post_url(self, url, fields, files=[]):
        # for key in files:
        #     files[key] = open(files[key], 'rb');
        res = requests.post(url, files=files, data=fields)
        return res.text 

username = 'whoarewe' # 用户名

password = '***' # 密码

appid = 4283 # appid

appkey = '02074c64f0d0bb9efb2df455537b01c3' # appkey

filename = 'getimage.jpg' # 文件位置

codetype = 1004 # 验证码类型

  
  
# 超时
  
  
timeout = 60

def indetify(response_content):
    if (username == 'username'):
        print('请设置好相关参数再测试')
    else:
        # 初始化
        yundama = YDMHttp(username, password, appid, appkey)

        # 登陆云打码
        uid = yundama.login();
        print('uid: %s' % uid)

        # 查询余额
        balance = yundama.balance();
        print('balance: %s' % balance)

        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
        cid, result = yundama.decode(response_content, codetype, timeout)
        print('cid: %s, result: %s' % (cid, result))
        return result

def indetify_by_filepath(file_path):
    if (username == 'username'):
        print('请设置好相关参数再测试')
    else:
        # 初始化
        yundama = YDMHttp(username, password, appid, appkey)

        # 登陆云打码
        uid = yundama.login();
        print('uid: %s' % uid)

        # 查询余额
        balance = yundama.balance();
        print('balance: %s' % balance)

        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
        cid, result = yundama.decode(file_path, codetype, timeout)
        print('cid: %s, result: %s' % (cid, result))
        return result

if __name__ == '__main__':
    pass

4 常见的验证码的种类

4.1 url地址不变,验证码不变

这是验证码里面非常简单的一种类型,对应的只需要验证码的地址,然后请求,通过打码平台识别即可

4.2 url地址不变,验证码变化

这种验证码的类型是更加常见的一种类型,对于这种验证码,大家需要思考:

在登录的过程中,假设我输入的验证码是对的,对方服务器是如何判断当前我输入的验证码是显示在我屏幕上的验证码,而不是其他的验证码呢?

在网页的时候,请求验证码,以及提交验证码的时候,对方服务器肯定通过了某种手段验证我之前的验证码和最后提交的验证码是同一个验证码,那这个手段是什么手段呢?

很明显,就是通过cookie来实现的,所以对应的,在请求页面,请求验证码,提交验证码的到时候需要保证cookie的一致性,对此可以使用requests.session来解决


小结

  1. 了解 验证码的相关知识
  2. 掌握 图片识别引擎的使用
  3. 了解 常见的打码平台
  4. 掌握 通过打码平台处理验证码的方法

chrome浏览器使用方法介绍

学习目标
  1. 了解 新建隐身窗口的目的
  2. 了解 chrome中network的使用
  3. 了解 寻找登录接口的方法

1 新建隐身窗口

浏览器中直接打开网站,会自动带上之前网站时保存的cookie,但是在爬虫中首次页面是没有携带cookie的,这种情况如何解决呢?

使用隐身窗口,首次打开网站,不会带上cookie,能够观察页面的情况,包括对方服务器如何设置cookie在本地

2 chrome中network的更多功能

2.1 Perserve log

默认情况下,页面发生跳转之后,之前的请求url地址等信息都会消失,勾选perserve log后之前的请求都会被保留

2.2 filter过滤

在url地址很多的时候,可以在filter中输入部分url地址,对所有的url地址起到一定的过滤效果,具体位置在上面第二幅图中的2的位置

2.3 观察特定种类的请求

在上面第二幅图中的3的位置,有很多选项,默认是选择的all,即会观察到所有种类的请求

很多时候处于自己的目的可以选择all右边的其他选项,比如常见的选项:

  • XHR:大部分情况表示ajax请求
  • JS:js请求
  • CSS:css请求

但是很多时候我们并不能保证我们需要的请求是什么类型,特别是我们不清楚一个请求是否为ajax请求的时候,直接选择all,从前往后观察即可,其中js,css,图片等不去观察即可

不要被浏览器中的一堆请求吓到了,这些请求中除了js,css,图片的请求外,其他的请求并没有多少个

3 寻找登录接口

回顾之前人人网的爬虫我们找到了一个登陆接口,那么这个接口从哪里找到的呢?

http://www.renren.com

3.1 寻找action对的url地址

可以发现,这个地址就是在登录的form表单中action对应的url地址,回顾前端的知识点,可以发现就是进行表单提交的地址,对应的,提交的数据,仅仅需要:用户名的input标签中,name的值作为键,用户名作为值,密码的input标签中,name的值作为键,密码作为值即可

思考:

如果action对应的没有url地址的时候可以怎么做?

3.2 通过抓包寻找登录的url地址

通过抓包可以发现,在这个url地址和请求体中均有参数,比如uniqueTimestamprkey以及加密之后的password

这个时候我们可以观察手机版的登录接口,是否也是一样的

可以发现在手机版中,依然有参数,但是参数的个数少一些,这个时候,我们可以使用手机版作为参考,下一节来学习如何分析js


小结

  1. 使用隐身窗口的主要目的是为了避免首次打开网站携带cookie的问题

  2. chrome的network中,perserve log选项能够在页面发生跳转之后任然能够观察之前的请求

  3. 确定登录的地址有两种方法:

    • 寻找from表单action的url地址
    • 通过抓包

未完待续 下一期下一章

全套笔记直接地址: 请移步这里

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot实现电子招投标系统【项目源码】计算机毕业设计

基于springboot实现电子招投标系统演示 SpringBoot框架 SpringBoot是一个全新开源的轻量级框架。基于Spring4.0设计&#xff0c;其不仅继承了Spring框架原来有的优秀特性&#xff0c;而且还通过简化配置文件来进一步简化了Spring应用的整个搭建以及开发过程。另外在原本的Spri…

【学习篇】Linux中grep、sed、awk

Linux 文本处理三剑客 – awk, sed, grep grep过滤文本 https://zhuanlan.zhihu.com/p/561445240 grep 是 Linux/Unix 系统中的一个命令行工具&#xff0c;用于从文件中搜索文本或字符串。grep 代表全局正则表达式打印。当我们使用指定字符串运行 grep 命令时&#xff0c;如…

游戏开发团队配置与协作流程

游戏开发技术图谱 - 知乎 游戏制作的流程是什么啊&#xff1f; - 知乎 系统策划&#xff1a;一张图梳理游戏系统的生产流程 - 知乎 游戏开发入门&#xff08;十一&#xff09;游戏引擎架构-CSDN博客

数据结构与算法编程题15

设计一个算法&#xff0c;通过遍历一趟&#xff0c;将链表中所有结点的链接方向逆转&#xff0c;仍利用原表的存储空间。 #include <iostream> using namespace std;typedef int Elemtype; #define ERROR 0; #define OK 1;typedef struct LNode {Elemtype data; …

安装MySQL搭建论坛

课前默写&#xff1a; 1、nginx配置文件的区域有哪些 ①全局区域 ②events区域 ③http区域 2、区域模块的作用 全局区域模块主要是用户和工作进程 events区域模块配置最大连接数时需先配置:vim /etc/limits.conf 因为系统默认最大是1024 http区域模块&#xff1a;代理地…

HTML的学习

知己知彼百战不殆 打算学习一下javascript 所以先从基础的html语言开始 其实就是头部 和身体 头部控制整个 html的语言 title等 <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"width…

vue项目引入element-plus

文章目录 引入框架遇到的问题引入的时候&#xff0c;报错 ...(reading replace)...报错&#xff1a;The template root requires ...eslint报错&#xff1a; 运行 引入框架 使用add引入 遇到的问题 引入的时候&#xff0c;报错 …(reading ‘replace’)… Cannot read prop…

Springboot将多个图片导出成zip压缩包

Springboot将多个图片导出成zip压缩包 将多个图片导出成zip压缩包 /*** 判断时间差是否超过6小时* param startTime 开始时间* param endTime 结束时间* return*/public static boolean isWithin6Hours(String startTime, String endTime) {// 定义日期时间格式DateTimeFormatt…

【深度学习】学习率及多种选择策略

学习率是最影响性能的超参数之一&#xff0c;如果我们只能调整一个超参数&#xff0c;那么最好的选择就是它。相比于其它超参数学习率以一种更加复杂的方式控制着模型的有效容量&#xff0c;当学习率最优时&#xff0c;模型的有效容量最大。本文从手动选择学习率到使用预热机制…

单元测试-java.lang.NullPointerException

报错信息 java.lang.NullPointerException 空指针异常 空对象引用 来源 对Controller层进行单元测试&#xff0c;解决完Spring上下文报错后继续报错。 解决 在测试方法执行前要为字段完成对象的注入&#xff0c;否则就报空指针异常。 测试例子 public class SysUserContr…

NX二次开发UF_CAM_update_list_object_customization 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_update_list_object_customization Defined in: uf_cam.h int UF_CAM_update_list_object_customization(tag_t * object_tags ) overview 概述 This function provids the…

Ubuntu 1.84.2Visual Studio Code 下载配置与vscode查看内存Hex Editor插件,简单易懂

目录 前言 一 首先我为啥要重装Vs Code呢&#xff1f; 二 下载1.84.2Visual Studio Code 三 配置Vscode终端字体 四 安装插件 前言 这是一篇将老版本的VsCode下载至最新版的博文&#xff0c;从下载到调试全篇 一 首先我为啥要重装Vs Code呢&#xff1f; 因为我想安装这个…

【HMS Core】推送问题的小九九

【问题描述1】 不在华为应用市场上架&#xff0c;是否可以使用推送服务&#xff0c;申请自分类&#xff1f; 【解决方案】 目前使用推送服务不强制要求上架&#xff0c;不上架也可正常使用、申请自分类权限。 【问题描述2】 数据存储位置改变后&#xff0c;自分类权限申请按…

148W+奖池!目标检测、图像分类新赛事!2023无锡国际人工智能算法大赛赛题详解来了!

各位人工智能卓越的推动者们&#xff0c;我们诚邀您参与【2023年无锡国际人工智能算法大赛】&#xff0c;探索未来AI创新的巅峰之战&#xff01; 报名链接&#xff1a;极市开发者平台-计算机视觉算法开发落地平台-极市科技 【大赛进程】 12月11日12:00&#xff1a;报名及初…

JAVA小游戏“飞翔的小鸟”

第一步是创建项目 项目名自拟 第二步创建个包名 来规范class 再创建一个包 来存储照片 如下&#xff1a; 代码如下&#xff1a; package game; import java.awt.*; import javax.swing.*; import javax.imageio.ImageIO;public class Bird {Image image;int x,y;int width…

SageMath安装

Sagemath工具是免费开源的&#xff0c;针对数学计算的一个工具。 网页版免安装&#xff1a;https://sagecell.sagemath.org/ Sagemath是根据Linux系统编写的&#xff0c;所以Windows上使用的话&#xff0c;会创建一个Linux系统运行。 1. 安装 Windows本地安装参考&#xff1…

多线程的实现方式

点击链接返回标题-> Java线程的学习-CSDN博客 第一种方式&#xff0c;继承Thread类 Thread类是java.lang包下的类&#xff0c;是多线程经常需要使用的类。 ①通过自定义子类去继承Thread类&#xff0c;并重写其中的run()方法。 class myThread extends Thread {//自定义子类…

(5秒解决)ImportError: attempted relative import with no known parent package

寻找了很多方法&#xff0c;发现大家把事情讲的复杂了。我这里用最简单的办法来解决父包引用找不到的问题。 报错提示&#xff1a;ImportError: attempted relative import with no known parent package 先给大家看看我的目录结构&#xff0c;model.py和test目录在同一级。tra…

Ubuntu 23.10 服务器版本 ifconfig 查不到网卡 ip(已解决)

文章目录 1、问题描述2、 解决方案 1、问题描述 服务器&#xff1a;ubuntu 23.10 经常会遇到虚拟机添加仅主机网卡后&#xff0c;通过 ifconfig 无法获取其网卡 ip 2、 解决方案 修改网卡配置文件&#xff1a; # 进入网卡配置文件目录 cd /etc/netplan # 备份原始文件 cp …

C/C++ 递归指数型枚举

个人主页&#xff1a;仍有未知等待探索_C语言疑难,数据结构,小项目-CSDN博客 专题分栏&#xff1a;算法_仍有未知等待探索的博客-CSDN博客 目录 一、前言 二、递归指数型枚举 1、题目信息 题目描述 输入格式 输出格式 样例 提示 2、解析 3、代码 一、前言 之前进行枚举…