基于Python实现的通用小规模搜索引擎

基于Python实现的通用小规模搜索引擎

1.项目简介

1.1背景

《信息内容安全》网络信息内容获取技术课程项目设计

  • 一个至少能支持10个以上网站的爬虫程序,且支持增量式数据采集;并至少采集10000个实际网页;
  • 针对采集回来的网页内容, 能够实现网页文本的分类;
  • 可进行重复或冗余网页的去重过滤;
  • 对经去冗以后的内容建立倒排索引;
  • 采用PageRank算法实现搜索结果的排序;
  • 支持自然语言的模糊检索;
  • 可实现搜索结果的可视化呈现。
  • 可以在线记录每次检索的日志,井可对日志数据进统计分析和关联挖掘。

1.2运行环境

  • 平台:全平台
  • jdk 1.8.0
  • ElasticSearch 7.4.0
  • Python 3.6 及以上
    • 安装依赖模块
      • PageRank算法、AI文本分类与上传
> pip install paddlepaddle numpy elasticsearch
      • 数据的爬取与预处理
> pip install requests bs4

1.3运行步骤

安装配置ElasticSearch并启动
  • 下载 并解压Elasticsearch,详细步骤自行搜索
    • 可以从 apt 和 yum 的软件仓库安装,也可以使用 Windows MSI 安装包安装
  • 安装 IK 中文分词器,详细步骤自行搜索
  • 创建索引
PUT http://127.0.0.1/page
{"settings": {"number_of_shards": "5","number_of_replicas": "0"},"mappings": {"properties": {"title": {"type": "text","analyzer": "ik_max_word"},"weight": {"type": "double"},"content" : {"type" : "text","analyzer": "ik_max_word"},"content_type": {"type": "text"},"url": {"type": "text","analyzer": "ik_max_word"},"update_date": {"type": "date","format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}}}
}
  • 启动 ElasticSearch ,在 bash 中执行 bin/elasticsearch 或者在 Windows 的 cmd、powershell 执行 bin\elasticsearch.bat
启动Web服务
> cd WebApp
> java -jar *.jar

数据的爬取与预处理
> cd DataCrawler
> python crawler.py

计算PageRank值
> cd DataProcess
> python PageRank.py

利用AI进行文本分类并上传至ES
> cd DataProcess/Text_Classification
> python Classify.py

2.需求分析

2.1数据描述

2.1.1 静态数据

变量名

描述

thread_accoun

线程个数

initial_url

种子页面

2.1.2 动态数据

变量名

描述

类型

restricted_domain

限定域名

列表

banned_domain

禁止域名

列表

thread_account

线程个数

整型

total_pages

限定页面个数

整型

2.1.3索引数据字典

页面(page)信息索引:

数据项名称

含义

别名

类型

备注

title

网站标题

text

使用ik_max_word

分词

weight

PageRank值

pr值,PR值

double

content

网站中的内容

text

使用ik_max_word

分词

content_type

网站中的内容分类

text

文化, 娱乐, 体育, 财经, 房产, 汽车, 教育, 科技, 国际, 证券

url

网站的链接

text

使用ik_max_word

分词

update_date

数据更新的时间

date

yyyy-MM-dd HH:mm:ss

||yyyy-MM-dd

||epoch_millis

2.2. 数据采集

种子 url 数据从 init_url 列表中选取,并按照顺序,依次以各个 url 为起点进行递归的数据采集

爬取数据的url需要限制在 restricted_url 列表里面

2.3功能需求

2.3.1 数据爬取与预处理功能

利用Python爬虫,执行以下步骤:

  1. 开始
  2. 选取一个链接作为起点
  3. 如果爬取的网页总数达到要求,则结束,否则执行第 4 步
  4. 爬取指定链接的相关信息,并获取当前网站中的所有链接
  5. 对 4 中获取的网站中的所有链接中的每一条数据,执行过程3

爬取网站如下信息,详细描述见3.4. 索引数据字典

  • title
  • content
  • content_type
  • update_date
  • url
  • link(当前网站中包含的所有链接,用于计算pr值)
2.3.2. 计算 PageRank 功能

根据link计算爬取下来的每个网站的PageRank值,迭代次数为50次。解决pr值呈周期性变化的问题。将pr值作为网站重要程度的指标,并补充到网站信息中

2.3.3. AI 文本分类并提交到 ES 功能

利用深度学习,分析每个页面的content的类别。将类别补充到网站信息中,同时删除网站信息中不再使用的link项,形成最终数据(参考3.4. 索引数据字典),并上传至ES,供用户交互功能调用。

2.3.4. 用户交互功能

设计WebApp,用户通过浏览器访问页面。用户提交搜索信息后,判断合法性,不合法则返回ERROR界面提示用户。如果合法,则后端代码从本地 ES 中查询数据,处理后将结果分条显示到前端。同时通过限制单个ip每分钟的访问次数来简单防御用户恶意搜索。

2.4. 性能需求

2.4.1. 数据精确度

对数据精确度要求不高,主要数据为:

项目

限制

爬取的数据总量

每小时查询一下数据总量

查询结果数量

匹配的所有结果数

数据更新日期

精确到分钟即可

2.4.2. 时间特性

项目

限制

每爬取 1 万个网页耗时

30 分钟以内

计算 1 万个网页的pr值耗时

10 分钟以内

对 1 万个网页内容进行AI 进行文本分类并上传至ES耗时

10 分钟以内

Web 首页打开耗时

5 秒以内

查询结果页面打开耗时

5 秒以内

2.5. 运行需求

2.5.1. 用户界面

用户通过浏览器访问,有两个页面,一个是主页,只有简单的输入框提供用户搜索;另一个是一般界面,提供高级搜索功能,并显示搜索结果。

2.5.2. 主页

控件

作用

布局

图标

显示Logo

居中

|输入框|接收用户输入的关键字|Logo图标下偏左
|按钮|提交用户输入的关键字,并返回搜索结果|输入框右|

2.5.3. 搜索结果界面

该界面分为三个部分,导航条、搜索结果、信息展示。这三个部分布局如下

部分

位置

height

width

导航条

顶部

50px

100%

搜索结果

导航条左下部

auto

70%

信息展示

导航条右下部

auto

30%

导航条部分

以下控件从左向右依次(顺序可以任意)在导航条中排列

控件

作用

输入框

接收用户输入的关键字

输入框

可以输入域名,将搜索结果限制在该域名内

数字输入框

查询结果分页显示,该框指示跳转到指定的搜索结果页

选择框

允许用户选择匹配方式:标题和内容(默认)、仅标题、仅内容

选择框

选择搜索结果的排序方式:倒排索引(默认)、 PageRank 排序

按钮

提交用户输入的所有数据,并返回搜索结果

搜索结果部分

将搜索结果以list的形式展示出来,每个list item显示匹配的网站的如下数据

  • 标题
  • 内容
  • url
  • 类别
  • PageRank值
  • 更新时间

在list结尾,显示分页组件,使用户可以点击跳转,样式如下:

<

1

2

3

4

5

6

>

信息展示部分

展示一些必要信息,如:

  • 本次查询耗时
  • 查询结果数
  • 数据库中的数据总数
  • 等等

2.5.4 软件接口

接口名

描述

所在模块

调用方式

init_first_time()

初次启动调用此接口

crawler.py

内部调用

get_result(url)

得到目标 url 的页面

crawler.py

内部调用

spider_thread()

爬虫线程

crawler.py

内部调用

main()

主任务执行线程

crawler.py

crawler.main()

init()

去掉所有未在 url 中出现的 link 及错误文件

PageRank.py

内部调用

Rank(Value, start)

计算PageRank

PageRank.py

内部调用

run()

程序运行方法

PageRank.py

PageRank.run()

get_data(sentence)

获取已爬取数据

Classify.py

内部调用

batch_reader(json_list,json_path)

利用AI进行文本分类

Classify.py

Classify.batch_reader()

2.5.5. 故障处理

各个功能模块如果出问题,会出现以下情况:

模块

出故障后

简单排查

爬虫

数据不再更新

检查网络,检查内存资源是否不足

PageRank计算

数据不再更新

检查内存资源和CPU资源是否不足

AI 文本分类

数据不再更新

检查内存资源和CPU资源是否不足

ElasticSearch

前端无法获取查询结果

问题比较复杂

WebApp

无法访问网站

问题比较复杂

其中,后两个模块出问题会造成严重问题,如果重启不能解决问题的话,采用如下措施

模块

故障排除

终极方法

ElasticSearch

①java环境是否正确
②是否开启了9200端口
③9200端口是否被占用
④插件是否出错
⑤机器资源是否不足

在其他机器上部署,并修改WebApp使其到该机器上获取服务

WebApp

①端口是否被占用
②java环境是否正确
③ElasticSearch是否正常运行
④机器资源是否不足

在其他机器上部署,并修改域名解析,将域名解析到新机器上

2.6. 其他需求

2.6.1. 可维护性
  • 网络爬虫设置了黑名单和白名单,可以限制爬取的范围。
  • 各个功能分离开,协同工作。同时,只要不修改数据格式,各个模块的修改不会影响其他模块
2.6.2. 可移植性
  • WebApp 使用 Spring boot 框架开发,打包后只有一个jar包,可以在任何有java环境的机器上部署
  • 其他功能都用python实现,可以部署在任何有python环境的机器上
  • ElasticSearch 支持分布式部署,可以部署在任意平台
2.6.3. 数据完整性
  • ElasticSearch 支持分布式,会自动将数据备份在不同节点。如果某个节点出了故障,不会破坏数据,也不会影响程序的查询结果

3.代码展示

import os
import sys
import json
import numpy as np
import time
import codecsdir_path = os.path.split(os.path.realpath(sys.argv[0]))[0] + '/../RawData'print(dir_path)
Vexname = list(os.listdir(dir_path))
Vexnum = len(Vexname)
epoch = 50# 初始化,去掉所有未在url中出现的link以及错误文件
def init():global Vexnumfalsefiles={}idx=0start = time.perf_counter()for file in Vexname:if idx % 100 == 0:a = '=' * int(idx / Vexnum * 100)b = ' ' * (100 - int(idx / Vexnum * 100))c = int(idx / Vexnum * 100)dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()with codecs.open(os.path.join(dir_path, file), 'r', encoding='utf-8') as load_f:try:text = json.load(load_f)except:falsefiles[file]=Vexname.index(file)-len(falsefiles)continuetry:links = []for link in text['link']:if link+'.json' in Vexname:links.append(link)text['link'] = links.copy()except:passfinally:if 'link' in text:text['link'].clear()else:text['link'] = []with codecs.open(os.path.join(dir_path, file), 'w', encoding='utf-8') as dump_f:json.dump(text, dump_f, ensure_ascii=False,indent=4)idx += 1print('正在删除错误文件及链接...')Vexnum -= len(falsefiles)checknum=0checkfalse=0for file in list(falsefiles.keys()):os.remove(os.path.join(dir_path,file))Vexname.remove(file)for i in range(checknum,falsefiles[file]):with codecs.open(os.path.join(dir_path, Vexname[i]), 'r', encoding='utf-8') as load_f:text = json.load(load_f)try:for falsefile in list(falsefiles.keys())[checkfalse:]:if falsefile in text['link']:text['link'].remove(falsefile)except:text['link'].clear()with codecs.open(os.path.join(dir_path, Vexname[i]), 'w', encoding='utf-8') as dump_f:json.dump(text, dump_f, ensure_ascii=False,indent=4)checknum += falsefiles[file]checkfalse += 1# 计算PageRank
def Rank(Value, start):NewValue=np.zeros(Vexnum,dtype=np.double)for iter in range(1,epoch):a = '=' * int(iter / epoch * 100)b = ' ' * (100 - int(iter / epoch * 100))c = int(iter / epoch * 100)dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()for i in range(Vexnum):with open(os.path.join(dir_path, Vexname[i]), 'r', encoding='utf-8') as load_f:text = json.load(load_f)count = len(text['link'])if count == 0:NewValue[i] = Value[i]continuefor link in text['link']:link += '.json'NewValue[Vexname.index(link)] += Value[i] / countfor i in range(Vexnum):NewValue[i] = NewValue[i] / (iter + 1) + Value[i] * (iter / (iter + 1))Value=NewValue.copy()return Valuedef run():print('开始计算PageRank...')print('数据初始化...')init()Value = np.ones(len(Vexname),dtype=np.double)*(1000.0/Vexnum)print('错误文件删除完毕!')print('正在计算PageRank(迭代次数{})...'.format(epoch))start = time.perf_counter()Value = Rank(Value, start)a = '=' * 100b = ' ' * 0c = 100dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()print('\nPageRank计算完毕,正在往JSON中写入数据...')max = {}for file in Vexname:  # 将PageRank写入JSONwith open(os.path.join(dir_path, file), 'r', encoding='utf-8') as load_f:text = json.load(load_f)with open(os.path.join(dir_path, file), 'w', encoding='utf-8') as dump_f:text['weight'] = Value[Vexname.index(file)]max[file] = text['weight']json.dump(text, dump_f, ensure_ascii=False,indent=4)print('数据写入完毕...')if __name__ == '__main__':run()

# 导入必要的包
import json
import os
import sys
import time
import math
import gcimport elasticsearch
import numpy as np
import paddle.fluid as fluiddir_path = os.path.dirname(os.path.realpath(__file__))
# 用训练好的模型进行预测并输出预测结果
# 创建执行器
place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())save_path = os.path.join(dir_path, 'infer_model/')# 从模型中获取预测程序、输入数据名称列表、分类器
[infer_program, feeded_var_names, target_var] = fluid.io.load_inference_model(dirname=save_path, executor=exe)# 主机
host = "py7hon.com:9200"# 建立 elasticsearch 连接
try:es = elasticsearch.Elasticsearch(hosts=host)
except Exception as e:print(e)exit()# 获取数据
def get_data(sentence):# 读取数据字典with open(os.path.join(dir_path, 'dict_txt.txt'), 'r', encoding='utf-8') as f_data:dict_txt = eval(f_data.readlines()[0])dict_txt = dict(dict_txt)# 把字符串数据转换成列表数据keys = dict_txt.keys()data = []for s in sentence:# 判断是否存在未知字符if not s in keys:s = '<unk>'data.append((np.int64)(dict_txt[s]))return datadef batch_reader(Json_list,json_path):datas = []gc.collect()json_files = []falsefiles = []datas.clear()falsefiles.clear()json_files.clear()start = time.perf_counter()i=0scale = 100for file in Json_list:if i % 100 == 0:a = '=' * int(i / len(Json_list) * 100)b = ' ' * (scale - int(i / len(Json_list) * 100))c = int(i / len(Json_list) * 100)dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()i+=1with open(os.path.join(json_path, file), "r", encoding='utf-8') as f:try:text = json.load(f)except:falsefiles.append(file)continuejson_files.append(os.path.join(json_path, file))json_text = text['content']data = get_data(json_text)datas.append(data)for file in falsefiles:os.remove(os.path.join(dir_path, file))file_count = len(Json_list) - len(falsefiles)a = '=' * 100b = ' ' * 0c = 100dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()print('\n文本数据获取完毕,共计{0}条文本数据,有效数据{2}条,无效数据{1}条(已删除)!'.format(len(Json_list),len(falsefiles),file_count))print('AI正在加载分类模型...')# 获取每句话的单词数量base_shape = [[len(c) for c in datas]]# 生成预测数据tensor_words = fluid.create_lod_tensor(datas, base_shape, place)# 执行预测result = exe.run(program=infer_program,feed={feeded_var_names[0]: tensor_words},fetch_list=target_var)print('模型加载完毕!')# 分类名称names = ['文化', '娱乐', '体育', '财经', '房产', '汽车', '教育', '科技', '国际', '证券']count = np.zeros(10)print('AI正在对文本数据进行分类并上传至ES:')# 获取结果概率最大的labelstart = time.perf_counter()for i in range(file_count):if i % 100 == 0:a = '=' * int(i / file_count * 100)b = ' ' * (scale - int(i / file_count * 100))c = int(i / file_count * 100)dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()lab = np.argsort(result)[0][i][-1]# print('预测结果标签为:%d,  名称为:%s, 概率为:%f' % (lab, names[lab], result[0][i][lab]))count[lab] += 1with open(json_files[i], 'r', encoding='utf-8') as load_f:try:text = json.load(load_f)except:continuetext['content_type'] = names[lab]id = json_files[i].split('\\')[-1].split('.')[0]#try:del text['link']response = es.index(index='page', doc_type='_doc', id=id, body=text)#except Exception:# print("\n" + "数据 " + id + " 插入失败,错误信息:" + response)# with open(os.path.join(json_path,json_files[i].split('\\')[-1]),'w') as dump_f:#     json.dump(text,dump_f)a = '=' * 100b = ' ' * 0c = 100dur = time.perf_counter() - startsys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))sys.stdout.flush()print("\n" + "%d条文本数据分类结束!已全部上传至ES" % (file_count))def run():# 获取图片数据print('AI正在获取文本数据...')json_path = os.path.realpath(__file__) + '/../../../RawData'Json_list = os.listdir(json_path)batch_size=500if len(Json_list)>batch_size:Json_batch=0print('当前文本数量为{0}条,正在分批处理...'.format(len(Json_list)))for batch_id in range(math.ceil(len(Json_list)/batch_size)):a=(batch_size if batch_size<(len(Json_list)-Json_batch) else len(Json_list)-Json_batch)print('正在处理第{0}批,数量为{1}...'.format(batch_id+1,a))batch_reader(Json_list[Json_batch:Json_batch+a],json_path)Json_batch += aelse:batch_reader(Json_list,json_path)if __name__ == '__main__':run()

4.系统展示

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

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

相关文章

鸿蒙面试 2025-01-10

写了鉴权工具&#xff0c;你在项目中申请了那些权限&#xff1f;&#xff08;常用权限&#xff09; 位置权限 &#xff1a; ohos.permission.LOCATION_IN_BACKGROUND&#xff1a;允许应用在后台访问位置信息。 ohos.permission.LOCATION&#xff1a;允许应用访问精确的位置信息…

【硬件测试】基于FPGA的BPSK+帧同步系统开发与硬件片内测试,包含高斯信道,误码统计,可设置SNR

目录 1.硬件片内测试效果 2.算法涉及理论知识概要 2.1 bpsk 2.2 帧同步 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.硬件片内测试效果 本文是之前写的文章 《基于FPGA的BPSK帧同步系统verilog开发,包含testbench,高斯信道,误…

MySQL 视图 存储过程与存储函数

第十四章_视图、第十五章 _存储过程与存储函数 1.常见的数据库对象 1. 表&#xff08;Table&#xff09; 用于存储结构化数据的基本对象&#xff0c;由行&#xff08;记录&#xff09;和列&#xff08;字段&#xff09;组成。 2. 视图&#xff08;View&#xff09; 基于一…

Chrome_60.0.3112.113_x64 单文件版 下载

单文件&#xff0c;免安装&#xff0c;直接用~ Google Chrome, 免費下載. Google Chrome 60.0.3112.113: Chrome 是 Google 開發的網路瀏覽器。它的特點是速度快,功能多。 下载地址: https://blog.s3.sh.cn/thread-150-1-1.htmlhttps://blog.s3.sh.cn/thread-150-1-1.html

CTFshow—文件包含

Web78-81 Web78 这题是最基础的文件包含&#xff0c;直接?fileflag.php是不行的&#xff0c;不知道为啥&#xff0c;直接用下面我们之前在命令执行讲过的payload即可。 ?filephp://filter/readconvert.base64-encode/resourceflag.php Web79 这题是过滤了php&#xff0c;…

python学opencv|读取图像(二十九)使用cv2.getRotationMatrix2D()函数旋转缩放图像

【1】引言 前序已经学习了如何平移图像&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;二十七&#xff09;使用cv2.warpAffine&#xff08;&#xff09;函数平移图像-CSDN博客 在此基础上&#xff0c;我们尝试旋转图像的同时缩放图像。 【2】…

24下半年软考「单独划线」合格标准已公布!

2024年下半年计算机技术与软件专业技术资格考试单独划线地区合格标准已公布&#xff01; 其中初级和中级单独划线地区合格标准各科目均为39分&#xff0c;高级各科目为40分&#xff0c;符合单独划线地区的同学可以去申请证书了。 一、证书效力 在单独划线地区报名参加相关职业…

Linux第一课:c语言 学习记录day06

四、数组 冒泡排序 两两比较&#xff0c;第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮&#xff1a;i 0 n&#xff1a;n个数&#xff0c;比较 n-1-i 次 4 5 3 2 1 // 第一次比较 j 0 4 3 5 2 1 // 第二次比较 j 1 4 3 2 5 1 // 第三次比较 j 2 4 3 2 1 5 // …

前端用json-server来Mock后端返回的数据处理

<html><body><div class"login-container"><h2>登录</h2><div class"login-form"><div class"form-group"><input type"text" id"username" placeholder"请输入用户名&q…

是德科技M9010A PXIe 机箱+M9037A模块,台式应用的理想之选

Keysigh是德科技M9010A PXIe 机箱M9037A模块 M9010A PXIe 10 插槽 Gen 3 机箱提供***的灵活性、兼容性和性能&#xff0c;而且外形更小巧&#xff0c;是台式应用的理想之选。它拥有 8 个 PXIe 混合插槽&#xff0c;使系统设计人员能够更灵活地混合和搭配 PXIe 和混合兼容模块的…

【算法刷题】leetcode hot 100 滑动窗口

文章目录 3. 无重复字符的最长子串438. 找到字符串中所有字母异位词总结 3. 无重复字符的最长子串 leetcode&#xff1a;https://leetcode.cn/problems/longest-substring-without-repeating-characters/?envTypestudy-plan-v2&envIdtop-100-liked 滑动窗口 &#xff0…

企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布

概述 workerman/rabbitmq 是一个异步RabbitMQ客户端&#xff0c;使用AMQP协议。 RabbitMQ是一个基于AMQP&#xff08;高级消息队列协议&#xff09;实现的开源消息组件&#xff0c;它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…

基于SpringBoot的洗浴管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数&#xff0c;实现直流无刷电机控制&#x…

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种&#xff0c;按照数据传送方式可分为串行通信和并行通信&#xff1b; 按照通信的数据同步方式&#xff0c;可分为异步通信和同步通信&#xff1b; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…

oracle位运算、左移右移、标签算法等

文章目录 位运算基础与或非同或同或应用场景 异或异或应用场景 什么是真值表 oracle基础函数创建bitor(按位或)函数bitnot(按位非)函数bitxor(按位异或)函数左移函数BITSHIFT()函数(实测不可用&#xff0c;废弃掉该方案)右移函数(略&#xff0c;有此场景吗?) 实际应用资质字典…

VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署

近期有个工作需求是进行 YOLOv8 模型的 C 部署&#xff0c;部署环境如下 系统&#xff1a;WindowsIDE&#xff1a;VS2015语言&#xff1a;COpenCV 4.5.0OnnxRuntime 1.15.1 0. 预训练模型保存为 .onnx 格式 假设已经有使用 ultralytics 库训练并保存为 .pt 格式的 YOLOv8 模型…

python无需验证码免登录12306抢票 --selenium(2)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 [TOC](python无需验证码免登录12306抢票 --selenium(2)) 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 就在刚刚我抢的票&#xff1a;2025年1月8日…

本地手集博客id“升级”在线抓取——简陋版——(2024年终总结1.1)

我之前每每发布笔记都用csv纯文本记录&#xff0c;一个机缘巧得文章列表api实现在线整理自已的文章阅读量数据。 (笔记模板由python脚本于2025年01月10日 18:48:25创建&#xff0c;本篇笔记适合喜欢钻牛角尖的coder翻阅) 【学习的细节是欢悦的历程】 Python官网&#xff1a;htt…

工业 4G 路由器赋能远程医疗,守护生命线

在医疗领域&#xff0c;尤其是偏远地区的医疗救治场景中&#xff0c;工业 4G 路由器正发挥着无可替代的关键作用&#xff0c;宛如一条坚韧的 “生命线”&#xff0c;为守护患者健康持续赋能。 偏远地区医疗资源相对匮乏&#xff0c;常常面临着专业医生短缺、诊疗设备有限等困境…