爬虫-------字体反爬

目录

一、了解什么是字体加密

二. 定位字体位置

三. python处理字体

1. 工具库

2. 字体读取

3. 处理字体

案例1:起点 

案例2:字符偏移:

5请求数据 - 发现偏移量

5.4 多套字体替换

套用模板

版本1

版本2

四.项目实战

1. 采集目标

2. 逆向结果

一、了解什么是字体加密

字体加密是页面和前端字体文件想配合完成的一个反爬策略。通过css对其中一些重要数据进行加密,使我们在代码获取的和在页面上看到的数据是不同的。

前端人员通过使用font-face来达到这个目的,font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中。而font-face的格式为:

@font-face {font-family: <FontName>;      # 定义字体的名称。             src: <source> [<format>][,<source> [<format>]]*;  # 定义该字体下载的网址,包括ttf,eof,woff格式等
}

二. 定位字体位置

  • 字体加密会有个映射的字体文件
  • 可以在元素面板搜索@font-face会通过这个标签指定字体文件,可以直接在页面上搜索,找到他字体的网址
  • 可以直接把字体文件下载下来, 文件可以一般需要自己修改后缀(网页的字体后缀一般选用woff)
    1. TTF:这是Windows操作系统使用的唯一字体标准,macintosh计算机也用truetype字体作为系统字体。
    2. OTF:这是一种开放的字体格式,支持Unicode字符集,可以在多种操作系统和设备上使用。
    3. FON:这是Windows 95及之前版本使用的字体格式。
    4. TTC:这是一种字体集合格式,包含多个字体文件,可以一次性安装多个字体。
    5. SHX:这是CAD系统自带的一种字体文件,符合了CAD的文字标准,但不支持中文等亚洲语言文字。
    6. EOT:这是早期网页浏览器使用的字体格式,但现在已经很少使用。
    7. WOFF:这是一种网页字体格式,可以在网页中使用,也可以转换为.TTF格式用于桌面应用。
  • 查看字体文件
    • 在线字体解析网站:在线字体编辑器-JSON在线编辑器
    • 可以直接把文件拖动到在线网址

我们抓包一个字体文件,在Font那一列,复制这个url到浏览器就可以下载下来

对应页面的数字。页面源码的字符前缀是&#x,woff文件的前缀是uni

三. python处理字体

1. 工具库
pip install fontTools  # 使用这个包处理字体文件
2. 字体读取
from fontTools.ttLib import TTFont
# 加载字体文件:
font = TTFont('file.woff')
# 转为xml文件:可以用来查看字体的字形轮廓、字符映射、元数据等字体相关的信息
font.saveXML('file.xml')

3. 字体读取

from fontTools.ttLib import TTFont
# 加载字体文件:
font = TTFont('file.woff')
kv = font.keys()
print(kv)

字体文件不仅包含字形数据和点信息,还包括字符到字形映射、字体标题、命名和水平指标等,这些信息存在对应的表中:

然后一些常见方法见 Python_FontTools使用-CSDN博客

3. 处理字体

如果想要把自定义的字体文字变化为系统能够识别的内容,就需要获取自定义字体与通用字体的映射规则,经过转化后就能得到正常文字信息。

字体解密的大致流程:

先找到字体文件的位置,查看源码大概就是xxx.woff这样的文件

重复上面那个操作,将两个字体文件保存下来

用上面的软件或者网址打开,并且通过 Python fontTools 将字体文件解析为 xml 文件

根据字体文件解析出来的 xml 文件与类似上面的字体界面找出相同内容的映射规律(重点)

在 Python 代码中把找出的规律实现出来,让你的代码能够通过这个规律还原源代码与展示内容的映射

案例1:起点 

import re
import requestsurl = 'https://www.qidian.com/rank/yuepiao/'
headers = {'Cookie': '_yep_uuid=16401b3f-da18-36f9-250b-44791c444165; e1=%7B%22l6%22%3A%22%22%2C%22pid%22%3A%22qd_P_rank_19%22%2C%22eid%22%3A%22%22%2C%22l1%22%3A5%7D; e2=%7B%22l6%22%3A%22%22%2C%22pid%22%3A%22qd_P_rank_19%22%2C%22eid%22%3A%22%22%2C%22l1%22%3A5%7D; newstatisticUUID=1689595424_1606659668; _csrfToken=6aCHItSuH6xVc1FVDCb7nGXnnDYFr6r6UdurzC7a; fu=801177549; traffic_utm_referer=; Hm_lvt_f00f67093ce2f38f215010b699629083=1689595425; Hm_lpvt_f00f67093ce2f38f215010b699629083=1689595425; _ga=GA1.2.225339841.1689595425; _gid=GA1.2.485020634.1689595425; _ga_FZMMH98S83=GS1.1.1689595425.1.1.1689595594.0.0.0; _ga_PFYW0QLV3P=GS1.1.1689595425.1.1.1689595594.0.0.0','Host': 'www.qidian.com','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
}response = requests.get(url=url, headers=headers)
# print(response.text)with open('乱码.html', mode='w', encoding='utf-8') as f:f.write(response.text)"""下载字体文件"""
# format\('eot'\); src: url\('(.*?)'\) format\('woff'\), url\('
font_results = re.findall("format\('eot'\); src: url\('(.*?)'\) format\('woff'\), url\('",response.text,re.S)print('解析到的字体地址: ', font_results)
font_link = font_results[0]response_font = requests.get(url=font_link).content  # 字体文件是二进制数据|with open('qidian.woff', mode='wb') as f:f.write(response_font)print('字体文件下载完成.........')"""解析字体文件"""
from fontTools.ttLib import TTFontfont_path = 'qidian.woff'  # 字体文件路径
base_font = TTFont(font_path)# # 将字体关系保存为 xml 格式
# base_font.saveXML('font.xml')map_list = base_font.getBestCmap()
print('字体文件读取出来的规则:', map_list)eng_2_num = {'period': ".",'two': '2','zero': '0','five': '5','nine': "9",'seven': '7','one': '1','three': '3','six': '6','four': '4','eight': '8'
}for key in map_list.keys():map_list[key] = eng_2_num[map_list[key]]print('最终的字体映射规则:', map_list)"""替换字体"""
with open('乱码.html', mode='r', encoding='utf-8') as f:old_html = f.read()new_html = old_htmlfor key, value in map_list.items():# 在循环中每一次替换结果用相同的变量覆盖掉new_html = new_html.replace('&#' + str(key) + ';', value)print(key, value, sep='|')with open('替换以后的数据.html', mode='w', encoding='utf-8') as f:f.write(new_html)print('替换完成.......')

案例2:字符偏移:

案例网址:https://sh.ziroom.com/z/

分析流程:他所有的内容均在网页源代码中,不用去寻找api接口,皆大欢喜,但它的价格是css加密过的,即点击styles中的不显示红框中的内容,它的价格就会发生变化,复制它的url地址,会发现是一张雪碧图(爬取的价格图片背景像雪碧,所以叫做雪碧图),它的价格是根据像素点的变化,定位雪碧图的不同数字显示的。

实现思路:获得图片,通过图片识别,将像素点(偏移量)根雪碧图的数字一一对应,爬取像素点(偏移量),将识别出来的数字替换偏移量显示价格,实现价格的爬取。(css反爬一般都是通过这种位移的方式来保护它的数据的)

原文链接:https://blog.csdn.net/weixin_43612602/article/details/135322875

  • 通过上述分析,咱们已经知道在网页前端中是通过一张图片,根据偏移量在图片中显示价格数字的。因此我们只需要把字体图片和价格的偏移量提取出来还原数据即可。
5请求数据 - 发现偏移量

构建字体映射规则

字体的偏移量数据我们可以在标签中可以看到,根据偏移量数据在字体文件图片中定位到特定的位置显示数字。因此我们需要分析每一个字体图片中每个字的偏移规则,然后使用OCR识图模块识别文字,将其字体关系一一映射出来。

通过分析,偏移量的偏移规律从-0px 开始,每个字体数字偏移间隔为 -21.4px ,分析思路如下图:

  • 因为字体文件是一张图片,而且每次都会随时动态改变字体顺序,因此咱们可以使用识图OCR模块识图,不管怎么变,我们都会实时识别,具体代码如下所示:
import pprint
import reimport ddddocr
import parsel
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
}def send_request(url):"""@param url: 请求地址@return: 字体图片地址, 解析后的数据"""response = requests.get(url=url, headers=headers)html_data = response.textwith open('数据偏移的网页.html', mode='w', encoding='utf-8') as f:f.write(html_data)"""解析字体图片地址"""# <span class="num" style="background-image: url(//static8.ziroom.com/phoenix/pc/images/price/new-list/48d4fa3aa7adf78a1feee05d78f33700.png);background-position: -149.8px"></span># <span.*?style="background-image: url\((.*?)\);background-position:.*?"></span>font_url = re.findall('<span.*?style="background-image: url\((.*?)\);background-position:.*?"></span>',html_data,re.S)[0]font_url = 'https:' + font_url# print('字体图片地址:', font_url)"""解析数据"""data_list = []selector = parsel.Selector(html_data)divs = selector.css('.Z_list-box>div')for div in divs:names = div.css('h5>a::text').get()if not names:  # 页面中有一个数据是广告continuemove_list = []  # 字体偏移量列表nums = div.css('span.num')for num in nums:num_str = num.get()num_result = re.findall('background-position: (.*?)"', num_str, re.S)[0]move_list.append(num_result)data_list.append({'names': names, 'price_list': move_list})return font_url, data_listdef get_font(font_url, font_rule):"""请求字体图片数据, 构建字体映射规则@param font_url: 字体图片地址@param font_rule: 分析出来的字体偏移规则@return: 返回字体映射规则"""font_data = requests.get(url=font_url, headers=headers).contentwith open('font.png', mode='wb') as f:f.write(font_data)"""ddddocr识别图片文字"""ocr = ddddocr.DdddOcr(beta=True)  # 指定识别模型res = ocr.classification(font_data)print('字体图片识别结果:', res)"""构建字体映射规则"""font_rules = dict(zip(font_rule, res))return font_rulesif __name__ == '__main__':"""发送请求, 解析图片地址和需要解密的字体数据"""font_url, data_list = send_request('https://sh.ziroom.com/z/')print('字体图片地址:', font_url)print('解析后的数据:', data_list)"""请求字体图片数据, 构建字体映射规则"""# 分析出来的字体偏移规则move = ['-0px', '-21.4px', '-42.8px', '-64.2px', '-85.6px', '-107px', '-128.4px', '-149.8px', '-171.2px','-192.6px']mapping = get_font(font_url, move)print('字体映射规则:', mapping)"""
pillow报错可以参考 https://blog.csdn.net/light2081/article/details/131517132
"""

替换字体后,发现有的数据任然替换不了,后续通过分析发现某些页面中会有多套字体图片引用,每套字体的偏移规则不一样,后续通过分析每套字体偏移规则刷字体替换即可,思路和上诉情况一样。

5.4 多套字体替换
import pprint
import re
import ddddocr
import parsel
import requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
}def decode_text(mapping, datas):"""替换字体数据@param mapping: 字体映射规则@param datas: 数据@return: 替换后的数据"""for data in datas:ret_list = []  # 存放偏移结果替换数据for move in data['price_list']:print('偏移量:', move)value = mapping.get(move, move)  # 字典有uni这个键就获取其值, 没有就返回设置的默认值charret_list.append(value)# 重写数据data['price_list'] = ret_listreturn datasdef get_font(font_url, font_rule):"""请求字体图片数据, 构建字体映射规则@param font_url: 字体图片地址@param font_rule: 分析出来的字体偏移规则@return: 返回字体映射规则"""font_data = requests.get(url=font_url, headers=headers).contentwith open('font.png', mode='wb') as f:f.write(font_data)"""ddddocr识别图片文字"""ocr = ddddocr.DdddOcr(beta=True)  # 指定识别模型res = ocr.classification(font_data)print('字体图片识别结果:', res)"""构建字体映射规则"""font_rules = dict(zip(font_rule, res))return font_rulesdef send_request(url):"""@param url: 请求地址@return: 字体图片地址, 解析后的数据"""response = requests.get(url=url, headers=headers)html_data = response.textwith open('数据偏移的网页.html', mode='w', encoding='utf-8') as f:f.write(html_data)"""解析字体图片地址"""# <span class="num" style="background-image: url(//static8.ziroom.com/phoenix/pc/images/price/new-list/48d4fa3aa7adf78a1feee05d78f33700.png);background-position: -149.8px"></span># <span.*?style="background-image: url\((.*?)\);background-position:.*?"></span>font_url = re.findall('<span.*?style="background-image: url\((.*?)\);background-position:.*?"></span>',html_data,re.S)###################################################################################################################################################################################  修改font_url_set = set(['https:' + res for res infont_url])  ##########################################################################################################################  修改###################################################################################################################################################################################  修改# print('字体图片地址:', font_url)"""解析数据"""data_list = []selector = parsel.Selector(html_data)divs = selector.css('.Z_list-box>div')for div in divs:names = div.css('h5>a::text').get()if not names:  # 页面中有一个数据是广告continuemove_list = []  # 字体偏移量列表nums = div.css('span.num')for num in nums:num_str = num.get()num_result = re.findall('background-position: (.*?)"', num_str, re.S)[0]move_list.append(num_result)data_list.append({'names': names, 'price_list': move_list})return font_url_set, data_listif __name__ == '__main__':# """发送请求, 解析图片地址和需要解密的字体数据"""# font_url, data_list = send_request('https://sh.ziroom.com/z/')# print('字体图片地址:', font_url)# print('解析后的数据:', data_list)## """请求字体图片数据, 构建字体映射规则"""# # 分析出来的字体偏移规则# move = ['-0px', '-21.4px', '-42.8px', '-64.2px', '-85.6px', '-107px', '-128.4px', '-149.8px', '-171.2px', '-192.6px']# mapping = get_font(font_url, move)# print('字体映射规则:', mapping)## """替换字体数据, 得到最终结果"""# result = decode_text(mapping, data_list)# pprint.pprint(result)"""解决第二套字体""""""发送请求, 解析图片地址和需要解密的字体数据"""# 修改函数解析字体图片地址代码逻辑: (列表推导式加https协议)+(集合去重字体图片地址) -->代码注释修改部分font_url_set, data_list = send_request('https://sh.ziroom.com/z/p45/')print('字体图片地址:', font_url_set)print('解析后的数据:', data_list)"""通过循环去刷字体, 替换"""grey_rule = ['-0px', '-15px', '-30px', '-45px', '-60px', '-75px', '-90px', '-105px', '-120px', '-135px']yellow_rule = ['-0px', '-21.4px', '-42.8px', '-64.2px', '-85.6px', '-107px', '-128.4px', '-149.8px', '-171.2px','-192.6px']red_rule = ['-0px', '-20px', '-40px', '-60px', '-80px', '-100px', '-120px', '-140px', '-160px', '-180px']# 通过分析发现有三套字体 --> 一个是价格删除线的灰色字体, 一个是黄色字体, 一个是红色字体, 且字体顺序会发生改变for font_url in font_url_set:if 'new-list' in font_url:  # 黄色字体地址中包含 new-list 字符串, 由此做判断逻辑mapping = get_font(font_url, yellow_rule)  # 黄色字体映射规则data_list = decode_text(mapping, data_list)  # 替换字体, 覆盖上面 data_list 变量# pprint.pprint(data_list)if 'list_red' in font_url:  # 红色字体地址中包含 list_red-list 字符串, 由此做判断逻辑mapping = get_font(font_url, red_rule)  # 红色字体映射规则data_list = decode_text(mapping, data_list)  # 替换字体, 覆盖上面 data_list 变量# pprint.pprint(data_list)if 'list_grey' in font_url:mapping = get_font(font_url, grey_rule)  # 灰色字体映射规则data_list = decode_text(mapping, data_list)  # 替换字体, 覆盖上面 data_list 变量pprint.pprint(data_list)

套用模板

3.代码实现

版本1

速度较慢,在我本机上实测30秒完成识别

只需在 jiexi_fontFile 函数中输入对应的字体的路径即可

import time
import ddddocr
import io
import matplotlib.pyplot as plt
from fontTools.ttLib import TTFont
from fontTools.pens.freetypePen import FreeTypePendef jiexi_fontFile(filepath):start_time=time.time()font = TTFont(filepath)  # 解析字体文件fontdata=font.getGlyphSet()dic = {}  # 保存识别结果的字典ocr = ddddocr.DdddOcr(beta=True,show_ad=False)    # ocr识别字体for n, v in font.getBestCmap().items():glyph = fontdata[v]pen = FreeTypePen(None)  # 实例化Pen子类glyph.draw(pen)  # 画出字形轮廓b = pen.array()iodata = io.BytesIO()plt.imshow(b)plt.axis('off')  # 禁用坐标轴plt.savefig(iodata, format='PNG')plt.close()result = ocr.classification(iodata.getvalue())    # 识别结果dic[n] = resultprint(n,'——>',result)print('耗时:',time.time()-start_time)print('长度:',len(dic))return dicprint(jiexi_fontFile('96fc7b50b772f52.woff2'))

版本2

速度更快,在我本机上实测4秒完成识别

只需在 identify_word 函数中输入对应的字体的路径即可

import time
import ddddocr
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from fontTools.ttLib import TTFontdef font_to_img(_code, font_path):"""将每个字体画成图片:param _code:字体的数字码点:param font_path:字体文件路径:return: 每个字体图片对象"""img_size = 1024img = Image.new('1', (img_size, img_size), 255)draw = ImageDraw.Draw(img)font = ImageFont.truetype(font_path, int(img_size * 0.7))txt = chr(_code)bbox = draw.textbbox((0, 0), txt, font=font)x = bbox[2] - bbox[0]y = bbox[3] - bbox[1]draw.text(((img_size - x) // 2, (img_size - y) // 7), txt, font=font, fill=0)return imgdef identify_word(font_path):""":param font_path:字体文件地址:return:字体印射规则"""font = TTFont(font_path)ocr = ddddocr.DdddOcr(beta=True)font_mapping = {}for cmap_code, glyph_name in font.getBestCmap().items():bytes_io = BytesIO()pil = font_to_img(cmap_code, font_path)pil.save(bytes_io, format="PNG")word = ocr.classification(bytes_io.getvalue())  # 识别字体print(f'数字Unicode:{[cmap_code]}-{[glyph_name]}-识别结果:{word}')# 构建字体印射规则font_mapping[cmap_code] = word"""去除字体印射识别为空的键值对"""del_key = []  # 收集要删除的键for key, value in font_mapping.items():if not value:del_key.append(key)for i in del_key:font_mapping.pop(i)return font_mapping  # 返回字体印射规则s_t = time.time()
mapping = identify_word('96fc7b50b772f52.woff2')
print('耗时:', time.time() - s_t)
print('长度:', len(mapping))
print('字体印射规则:', mapping)

四.项目实战

1. 采集目标
  • 目标网址:互联网IT实习_互联网IT实习生招聘信息 – 实习僧
2. 逆向结果
import requests
from lxml import etree
import re
from fontTools.ttLib import TTFont
​
​
class SXS():def __init__(self):self.url = 'https://www.shixiseng.com/interns?keyword=%E4%BA%92%E8%81%94%E7%BD%91IT&city=%E5%85%A8%E5%9B%BD&type=intern&from=menu'self.headers = {"authority": "www.shixiseng.com","accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","accept-language": "zh-CN,zh;q=0.9","cache-control": "no-cache","pragma": "no-cache","sec-ch-ua": "^\\^Not","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "^\\^Windows^^","sec-fetch-dest": "document","sec-fetch-mode": "navigate","sec-fetch-site": "none","sec-fetch-user": "?1","upgrade-insecure-requests": "1","user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"}
​def get_data(self):res = requests.get(self.url, headers=self.headers)ttf = 'https://www.shixiseng.com' + \re.findall('">@font-face {    font-family: myFont;    src: url\((.*?)\);}', res.text)[0]font = requests.get(ttf)with open('file.woff', 'wb')as f:f.write(font.content)with open('index.html', 'w', encoding='utf-8')as f:f.write(res.text)
​def get_font_data(self):font_dict = {}font = TTFont('file.woff')# print(font.getBestCmap())for k, v in font.getBestCmap().items():if v[3:]:content = "\\u00" + v[3:] if len(v[3:]) == 2 else "\\u" + v[3:]real_content = content.encode('utf-8').decode('unicode_escape')k_hex = hex(k)# 网页返回的字体是以&#x开头  ,换成以这个开头,下面代码就是直接替换real_k = k_hex.replace("0x", "&#x")font_dict[real_k] = real_content# print(font_dict)return font_dict
​def parse_data(self, font_dict):
​with open('index.html', encoding='utf-8')as f:data = f.read()
​for k, v in font_dict.items():# print(k, v)data = data.replace(k, v)html_Data = etree.HTML(data)div_list = html_Data.xpath('//div[@class="clearfix intern-detail"]')for i in div_list:comp = i.xpath('./div/p/a[@class="title ellipsis"]/text()')[0]price = i.xpath('.//span[@class="day font"]/text()')[0]title = i.xpath('.//div[@class="f-l intern-detail__job"]/p/a[1]/text()')[0]print(comp, price, title)
​def main(self):data = self.get_data()# print(data)font_dict = self.get_font_data()self.parse_data(font_dict)
​
​
if __name__ == '__main__':sxs = SXS()sxs.main()
​

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

transformer模型写诗词

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

【计算机网络】章节 知识点总结

一、计算机网络概述 1. 计算机网络向用户提供的两个最重要的功能&#xff1a;连通性、共享 2. 因特网发展的三个阶段&#xff1a; 第一阶段&#xff1a;从单个网络 ARPANET 向互联网发展的过程。1983 年 TCP/IP 协议成为 ARPANET 上的标准协议。第二阶段&#xff1a;建成三级…

【微服务】不同微服务之间用户信息的获取和传递方案

如何才能在每个微服务中都拿到用户信息&#xff1f;如何在微服务之间传递用户信息&#xff1f; 文章目录 概述利用微服务网关做登录校验网关转微服务获取用户信息openFeign传递微服务之间的用户信息 概述 要在每个微服务中获取用户信息&#xff0c;可以采用以下几种方法&#…

【p2p、分布式,区块链笔记 Torrent】WebTorrent 的lt_donthave插件

扩展实现 https://github.com/webtorrent/lt_donthave/blob/master/index.js /*! lt_donthave. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */// 导入所需模块 import arrayRemove from unordered-array-remove // 用于从数组中删除元素的函数 i…

兰空图床配置域名访问

图床已经创建完毕并且可以访问了&#xff0c;但是使用IP地址多少还是差点意思&#xff0c;而且不方便记忆&#xff0c;而NAT模式又没法直接像普通服务器一样DNS解析完就可以访问。 尝试了很多办法&#xff0c;nginx配置了半天也没配好&#xff0c;索性直接重定向&#xff0c;反…

Sophos | 网络安全

在 SophosLabs 和 SophosAI 的威胁情报、人工智能和机器学习的支持下&#xff0c;Sophos 提供广泛的高级产品和服务组合&#xff0c;以保护用户、网络和端点免受勒索软件、恶意软件、漏洞利用、网络钓鱼和各种其他网络攻击。Sophos 提供单一的集成式基于云的管理控制台 Sophos …

STM32外设之SPI的介绍

### STM32外设之SPI的介绍 SPI&#xff08;Serial Peripheral Interface&#xff09;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;主要用于EEPROM、FLASH、实时时钟、AD转换器等外设的通信。SPI通信只需要四根线&#xff0c;节约了芯片的管脚&#x…

基于 Transformer 的语言模型

基于 Transformer 的语言模型 Transformer 是一类基于注意力机制&#xff08;Attention&#xff09;的模块化构建的神经网络结构。给定一个序列&#xff0c;Transformer 将一定数量的历史状态和当前状态同时输入&#xff0c;然后进行加权相加。对历史状态和当前状态进行“通盘…

图数据库| 2 、大数据的演进和数据库的进阶——从数据到大数据、快数据,再到深数据

时至今日&#xff0c;大数据已无处不在&#xff0c;所有行业都在经受大数据的洗礼。但同时我们也发现&#xff0c;不同于传统关系型数据库的表模型&#xff0c;现实世界是非常丰富、高维且相互关联的。此外&#xff0c;我们一旦理解了大数据的演进历程以及对数据库进阶的强需求…

深度学习笔记10-多分类

多分类和softmax回归 在多分类问题中&#xff0c;一个样本会被划分到三个或更多的类别中&#xff0c;可以使用多个二分类模型或一个多分类模型&#xff0c;这两种方式解决多分类问题。 1.基于二分类模型的多分类 直接基于二分类模型解决多分类任务&#xff0c;对于多分类中的每…

一篇文章入门docker!

文章目录 DockerUbuntu 下 docker 安装安装docker运行docker Docker的常用命令帮助命令镜像命令容器命令其他常用命令小结 分层理解一、Docker镜像的分层结构二、UnionFS与镜像分层三、镜像层的具体内容四、镜像分层的好处五、容器层与镜像层的关系 如何提交一个自己的镜像 Doc…

鸿蒙(Harmony)实现滑块验证码

在Android和ios两端已经使用的滑块验证码框架还未适配鸿蒙版&#xff0c;于是需要自己去实现类似如下的滑块验证码&#xff1a; 那么实现这样的验证码主要涉及到几个内容&#xff1a; 1、自定义弹窗 2、base64图片转换 3、滑动组件与滑块的联动&#xff0c;以及横移距离转换…

什么是嵌入式操作系统?

什么是嵌入式操作系统? 想象一下&#xff0c;如果一个智能设备&#xff0c;比如你口袋里的智能手机&#xff0c;是一个有头脑的机器人&#xff0c;那么嵌入式操作系统&#xff08;Embedded Operating System&#xff0c;简称EOS&#xff09;就相当于这个机器人的大脑。它告诉机…

后台管理系统窗体程序:评论管理

目录 评论管理的功能介绍&#xff1a; 1、进入页面 2、页面内的各种功能设计 &#xff08;1&#xff09;网页内的表格 &#xff08;2&#xff09;拒绝按钮&#xff0c;批准按钮 &#xff08;3&#xff09;删除按钮 &#xff08;4&#xff09;页面翻页跳转按钮 一、网页设计​…

nginx代理 proxy_pass

一、location 包含 location /api/ {proxy_pass http://127.0.0.1:85;} 二、location 不包含 location /api/ {proxy_pass http://127.0.0.1:85/;} 三、locaion 包含 location /api {proxy_pass http://127.0.0.1:85;}四、location 包含 location /api {proxy_pass http://127.…

InnoDB 存储引擎<七>通用表空间+临时表空间

目录 通⽤表空间 - General Tablespace 临时表空间 - Temporary Tablespaces 通⽤表空间 - General Tablespace 对应磁盘上的文件需要用户手动创建 1.通⽤表空间的作⽤和特性&#xff1f; 解答问题&#xff1a; 1.作用&#xff1a;可以把数据量比较小且强相关的表&#xff…

乐维网管平台(五):如何精准定位网络终端设备

在当今数字化高度发展的时代&#xff0c;网络已经成为企业和组织运营的关键基础设施。而在网络管理领域&#xff0c;终端定位技术正发挥着越来越重要的作用。 一、什么是终端定位 终端定位是网络管理中的关键环节&#xff0c;从本质上讲&#xff0c;它是一种精确确定网络终端…

企业邮箱后缀设置指南,轻松融入公司品牌

邮箱后缀指""后域名&#xff0c;本文介绍如何添加公司名作为后缀&#xff0c;以Zoho邮箱为例&#xff0c;需注册账号、购买域名、配置DNS、添加自定义域名、创建账号。Zoho邮箱安全可靠、个性化定制、易于管理&#xff0c;提供不同定价方案&#xff0c;并给出客户端配…

【D3.js in Action 3 精译_039】4.3 D3 面积图的绘制方法及其边界标签的添加

当前内容所在位置&#xff1a; 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建&#xff08;上篇&#xff09; 4.1.1 D3 中的边距约定&#xff08;中篇&#xff09;4.1.2 坐标轴的生成&#xff08;中篇&#xff09; 4.1.2.1 比例尺的声明&#xff08;中篇&#xff09;4.1…

时序动作定位 | 基于层次结构潜在注意模型的弱监督动作定位(ICCV 2023)

<Weakly-Supervised Action Localization by Hierarchically-structured Latent Attention Modeling> 这篇文章的标题是《Weakly-Supervised Action Localization by Hierarchically-structured Latent Attention Modeling》,作者是Guiqin Wang等人,来自西安交通大学和…