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

news2025/1/11 20:07:54

基于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 codecs

dir_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 Vexnum
    falsefiles={}
    idx=0
    start = 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() - start
            sys.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)
                continue
            try:
                links = []
                for link in text['link']:
                    if link+'.json' in Vexname:
                        links.append(link)
                text['link'] = links.copy()
            except:
                pass
            finally:
                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 += 1
    print('正在删除错误文件及链接...')
    Vexnum -= len(falsefiles)
    checknum=0
    checkfalse=0
    for 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() - start
        sys.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]
                    continue
                for link in text['link']:
                    link += '.json'
                    NewValue[Vexname.index(link)] += Value[i] / count
        for i in range(Vexnum):
            NewValue[i] = NewValue[i] / (iter + 1) + Value[i] * (iter / (iter + 1))
        Value=NewValue.copy()
    return Value


def 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 = '=' * 100
    b = ' ' * 0
    c = 100
    dur = time.perf_counter() - start
    sys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))
    sys.stdout.flush()
    print('\nPageRank计算完毕,正在往JSON中写入数据...')
    max = {}
    for file in Vexname:  # 将PageRank写入JSON
        with 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 gc

import elasticsearch
import numpy as np
import paddle.fluid as fluid

dir_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 data

def batch_reader(Json_list,json_path):
    datas = []
    gc.collect()
    json_files = []
    falsefiles = []
    datas.clear()
    falsefiles.clear()
    json_files.clear()
    start = time.perf_counter()
    i=0
    scale = 100
    for 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() - start
            sys.stdout.write("\r{:^3.0f}%[{}=>{}]{:.2f}s".format(c, a, b, dur))
            sys.stdout.flush()
        i+=1
        with open(os.path.join(json_path, file), "r", encoding='utf-8') as f:
            try:
                text = json.load(f)
            except:
                falsefiles.append(file)
                continue
            json_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 = '=' * 100
    b = ' ' * 0
    c = 100
    dur = time.perf_counter() - start
    sys.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:')
    # 获取结果概率最大的label
    start = 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() - start
            sys.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] += 1
        with open(json_files[i], 'r', encoding='utf-8') as load_f:
            try:
                text = json.load(load_f)
            except:
                continue
        text['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 = '=' * 100
    b = ' ' * 0
    c = 100
    dur = time.perf_counter() - start
    sys.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=500
    if len(Json_list)>batch_size:
        Json_batch=0
        print('当前文本数量为{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 += a
    else:
        batch_reader(Json_list,json_path)


if __name__ == '__main__':
    run()

4.系统展示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

查找路由器的管理后台ip【通用找IP】

需求&#xff1a; 刚刚搞了个【小米】路由器&#xff0c;我想进路由的管理后台&#xff0c;提示&#xff1a;安装xx的路由管家&#xff0c;我不想安装 但是无法找到这个管理后台。 而且我是用这个路由作为中继&#xff0c;那么这个路由的ip就会经常更换 尝试通过网上搜索引擎来…

混合专家模型 (MoE)笔记摘要

ref&#xff1a; https://huggingface.co/blog/zh/moe#%E4%BB%80%E4%B9%88%E6%98%AF%E6%B7%B7%E5%90%88%E4%B8%93%E5%AE%B6%E6%A8%A1%E5%9E%8B 简短总结 混合专家模型 (MoEs): 与稠密模型相比&#xff0c; 预训练速度更快 与具有相同参数数量的模型相比&#xff0c;具有更快的…

01 Oracle自学环境搭建

1 Oracle12C安装 1.1 下载 官网地址&#xff1a;https://www.oracle.com/ 解压安装包 运行安装程序 1.2 安装 配置安全更新 软件更新 安装选项 系统类 Oracle主目录用户选择 使用现有windows用户&#xff1a;如果选择该项&#xff0c;则需要指定没有管理权限的用户。 创建新Wi…

【Python】Python与C的区别

文章目录 语句结束符代码块表示变量声明函数定义注释格式Python的标识符数据输入input()函数数据输出print()函数 语句结束符 C 语言 C 语言中每条语句必须以分号;结束。例如&#xff0c;int a 10;、printf("Hello, World!");。分号是语句的一部分&#xff0c;用于…

安科瑞 Acrel-1000DP 分布式光伏监控系统在工业厂房分布式光伏发电项目中的应用

吕梦怡 18706162527 摘 要&#xff1a;常规能源以煤、石油、天然气为主&#xff0c;不仅资源有限&#xff0c;而且会造成严重的大气污染&#xff0c;开发清洁的可再生能源已经成为当今发展的重要任务&#xff0c;“节能优先&#xff0c;效率为本”的分布式发电能源符合社会发…

逆向 易九批 最新版 爬虫逆向 x-sign ......

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; # 欢迎交流 wjxch1004

TensorFlow Quantum快速编程(高级篇)

五、实战:量子分类器应用 5.1 数据准备 在实战构建量子分类器时,数据准备是基石环节。选用鸢尾花数据集,这一经典数据集在机器学习领域应用广泛,其涵盖了三种鸢尾花品种的样本,每个样本包含花萼长度、花萼宽度、花瓣长度、花瓣宽度四个特征。鉴于本次构建二分类量子分类…

maven高级(day15)

Maven 是一款构建和管理 Java 项目的工具 分模块设计与开发 所谓分模块设计&#xff0c;顾名思义指的就是我们在设计一个 Java 项目的时候&#xff0c;将一个 Java 项目拆分成多 个模块进行开发。 分模块设计我们在进行项目设计阶段&#xff0c;就可以将一个大的项目拆分成若干…

android studio根据包名获取当前安装包信息

package com.example.myapplication2;import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.util.Log;/**** 获取版本信息*/ public class SystemHelper {/*** 获取本地软件版本号*/public stat…

安卓硬件加速hwui

安卓硬件加速 本文基于安卓11。 从 Android 3.0 (API 级别 11) 开始&#xff0c;Android 2D 渲染管道支持硬件加速&#xff0c;这意味着在 View 的画布上执行的所有绘图操作都使用 GPU。由于启用硬件加速所需的资源增加&#xff0c;你的应用程序将消耗更多内存。 软件绘制&am…

口碑很好的国产LDO芯片,有哪些?

在几乎任何一个电路设计中&#xff0c;都可能会使用LDO&#xff08;低压差线性稳压器&#xff09;这个器件。 虽然LDO不是什么高性能的IC&#xff0c;但LDO芯片市场竞争异常激烈。最近几年&#xff0c;诞生了越来越多的精品国产LDO&#xff0c;让人看得眼花缭乱。 业内人士曾经…

实训云上搭建集群

文章目录 1. 登录实训云1.1 实训云网址1.2 登录实训云 2. 创建网络2.1 网络概述2.2 创建步骤 3. 创建路由器3.1 路由器名称3.1 创建路由器3.3 查看网络拓扑 4. 连接子网5. 创建虚拟网卡5.1 创建原因5.2 查看端口5.3 创建虚拟网卡 6. 管理安全组规则6.1 为什么要管理安全组规则6…

win32汇编环境,怎么进行乘法运算的

;运行效果 ;win32汇编环境,怎么进行乘法运算的 ;基础知识&#xff0c;重新复习一下。 ;首先需明白字节的概念。1个字节是8位&#xff0c;al和ah都是8位的&#xff0c;8位之中每位要么是0&#xff0c;要么是1&#xff0c;假如8位都是1&#xff0c;就是16进制的FF&#xff0c;也就…

opencv的NLM去噪算法

NLM&#xff08;Non-Local Means&#xff09;去噪算法是一种基于图像块&#xff08;patch&#xff09;相似性的去噪方法。其基本原理是&#xff1a; 图像块相似性&#xff1a;算法首先定义了一个搜索窗口&#xff08;search window&#xff09;&#xff0c;然后在该窗口内寻找…

poi处理多选框进行勾选操作下载word以及多word文件压缩

一、场景 将数据导出word后且实现动态勾选复选框操作 eg: word模板 导出后效果&#xff08;根据数据动态勾选复选框&#xff09; 二、解决方案及涉及技术 ① 使用poi提供的库进行处理&#xff08;poi官方文档&#xff09; ② 涉及依赖 <!-- excel工具 --><depen…

【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录前言 &#x1f343;一、实体对象更新1.1 单条与批量1.2 不更新某列1.3 只更新某列1.4 NULL列不更新1.5 无主键/指定列…

征战越南电商直播,SD - WAN 专线赋能企业带货新征程

在当今数字化商业浪潮中&#xff0c;越南电商市场正经历着蓬勃发展与激烈变革。根据 Sapo Technology Joint Stock Company 对全国 15,000 名卖家的深度调查&#xff0c;2024 年零售业务的直播领域呈现出多元竞争态势。Facebook Live 强势占据多渠道或仅在线销售卖家总直播会话…

Android Studio创建新项目并引入第三方jar、aar库驱动NFC读写器读写IC卡

本示例使用设备&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1bbW3AUC&ftt&id615391857885 一、打开Android Studio,点击 File> New>New project 菜单&#xff0c;选择 要创建的项目模版&#xff0c;点击 Next 二、输入项目名称…

创业企业如何吸引投资?-中小企实战运营和营销工作室博客

创业企业如何吸引投资&#xff1f;-中小企实战运营和营销工作室博客 创业企业吸引投资需要从多个方面入手&#xff0c;包括打磨自身项目、做好商业展示、拓展融资渠道、有效对接资本等&#xff0c;以下是具体的方法&#xff1a; 一&#xff1a;打磨创业项目 1&#xff0c;明…

donet (MVC)webAPI 的接受json 的操作

直接用对象来进行接收&#xff0c;这个方法还不错的。 public class BangdingWeiguiJiluController : ApiController{/// <summary>/// Json数据录入错误信息/// </summary>/// <param name"WeiguiInfos"></param>/// <returns></r…