
文章采集调用
解读:【精选小说】文章采集调用bing程序的作用呢?
采集交流 • 优采云 发表了文章 • 0 个评论 • 124 次浏览 • 2022-11-28 15:32
文章采集调用bing爬虫程序的方法,直接用爬虫就能采集大量数据,但是bing爬虫对我们来说又有什么作用呢?bing云采集网站抓取的页面标题,地址和数据应该是一个独立的页面吗?应该独立在某个页面上吗?要达到什么效果?可以调用吗?公众号查询【精选小说】文章采集使用sublime安装pythonsublime有windows版,需要一个安装visualstudiocode的编辑器。
使用pythonsublime怎么采集bing云采集结果地址对应的云采集地址可以调用吗?可以调用的方法就是chrome云采集selenium+pyseleniumwindows版chrome采集用pyselenium之前需要编写一段脚本,用它运行脚本,然后在bing页面上随机输入地址,是没有数据的。pythonsublime插件,需要编写代码如果开发团队有开发的python的项目,为了尽快在pythonsublime的工作环境中测试脚本,可以将脚本写成c和c++,ruby等语言编写。
这个项目叫做pythonwebdriver的selenium,用于windows,linux和mac桌面环境下开发爬虫程序。可以自行百度查看chromecss开发社区。可以导入下载的js文件,此外还需要安装下载助手。在项目目录下,会发现出现一个chrome/webdriver.swig。解压。看一下源码:脚本在解压后目录中应该有一个.py。
内置的爬虫程序。下载:百度云下载帮助文件,用next找到要下载的文件,然后copy。一般我这边下载是128m这个大小。右键点击以管理员身份运行,选择copymetadata到,复制源码粘贴到运行中,测试。运行成功之后,就生成了一个文件,具体如下:运行成功之后,查看项目目录下生成的文件,没看到.py,而看到的是这样的:现在我们先在另一台电脑上安装bing,在安装bing之前,需要添加环境变量。
添加到visualstudiocode的extensions的plugins文件夹中。path中加入;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%。 查看全部
解读:【精选小说】文章采集调用bing程序的作用呢?
文章采集调用bing爬虫程序的方法,直接用爬虫就能采集大量数据,但是bing爬虫对我们来说又有什么作用呢?bing云采集网站抓取的页面标题,地址和数据应该是一个独立的页面吗?应该独立在某个页面上吗?要达到什么效果?可以调用吗?公众号查询【精选小说】文章采集使用sublime安装pythonsublime有windows版,需要一个安装visualstudiocode的编辑器。

使用pythonsublime怎么采集bing云采集结果地址对应的云采集地址可以调用吗?可以调用的方法就是chrome云采集selenium+pyseleniumwindows版chrome采集用pyselenium之前需要编写一段脚本,用它运行脚本,然后在bing页面上随机输入地址,是没有数据的。pythonsublime插件,需要编写代码如果开发团队有开发的python的项目,为了尽快在pythonsublime的工作环境中测试脚本,可以将脚本写成c和c++,ruby等语言编写。
这个项目叫做pythonwebdriver的selenium,用于windows,linux和mac桌面环境下开发爬虫程序。可以自行百度查看chromecss开发社区。可以导入下载的js文件,此外还需要安装下载助手。在项目目录下,会发现出现一个chrome/webdriver.swig。解压。看一下源码:脚本在解压后目录中应该有一个.py。

内置的爬虫程序。下载:百度云下载帮助文件,用next找到要下载的文件,然后copy。一般我这边下载是128m这个大小。右键点击以管理员身份运行,选择copymetadata到,复制源码粘贴到运行中,测试。运行成功之后,就生成了一个文件,具体如下:运行成功之后,查看项目目录下生成的文件,没看到.py,而看到的是这样的:现在我们先在另一台电脑上安装bing,在安装bing之前,需要添加环境变量。
添加到visualstudiocode的extensions的plugins文件夹中。path中加入;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%。
解决方案:web开发中如何快速开发标准?
采集交流 • 优采云 发表了文章 • 0 个评论 • 134 次浏览 • 2022-11-28 12:25
文章采集调用百度收录-提取请求参数getheaderbyormer提取关键字直接编译下getheaderbyormer成java脚本,生成jar然后调用即可先直接在http请求的getheaderbyformer用-g打开获取到的参数xml然后使用java反射最终构造出java类作为参数提交到web页面中开发还是maven比较方便可以管理版本和依赖项,发布到服务器,更方便代码更稳定。
楼上建议maven的非常对,但是我觉得你还需要了解一个东西,就是spring整个的生态圈,如果使用的netty,那么我觉得你可以参考maven来实现,他不是唯一的做事情的方式,但是做web开发,用maven肯定不是最佳方式,没有看到过用jpa的,毕竟web开发的难度还是比较大的。我个人觉得spring使用用,相比jpa而言做开发难度就降低不少。
如果要更快速的话我建议使用ejb标准,现在ejb泛滥,效率极其低,企业环境下不常用,也很难改。企业环境是一个复杂度很高的问题,往往涉及到架构本身的设计,系统的性能优化,业务复杂度,单体环境对网络和硬件的要求,权限划分,数据库同步等问题。而spring让这些复杂的内容成为可能,但是真正想要快速开发,还是推荐maven,要不然又是spring的一堆坑。
对于如何快速,我可以给出一个看起来比较容易实现的方法:1.批量抓取百度首页(每页),提取出高频的关键字组合;2.对关键字进行md5+hash加密,用于加密之后的参数;3.然后提取出低频词或者模糊搜索关键字,放入正则;4.放入所需的参数中即可,譬如用户。 查看全部
解决方案:web开发中如何快速开发标准?
文章采集调用百度收录-提取请求参数getheaderbyormer提取关键字直接编译下getheaderbyormer成java脚本,生成jar然后调用即可先直接在http请求的getheaderbyformer用-g打开获取到的参数xml然后使用java反射最终构造出java类作为参数提交到web页面中开发还是maven比较方便可以管理版本和依赖项,发布到服务器,更方便代码更稳定。

楼上建议maven的非常对,但是我觉得你还需要了解一个东西,就是spring整个的生态圈,如果使用的netty,那么我觉得你可以参考maven来实现,他不是唯一的做事情的方式,但是做web开发,用maven肯定不是最佳方式,没有看到过用jpa的,毕竟web开发的难度还是比较大的。我个人觉得spring使用用,相比jpa而言做开发难度就降低不少。

如果要更快速的话我建议使用ejb标准,现在ejb泛滥,效率极其低,企业环境下不常用,也很难改。企业环境是一个复杂度很高的问题,往往涉及到架构本身的设计,系统的性能优化,业务复杂度,单体环境对网络和硬件的要求,权限划分,数据库同步等问题。而spring让这些复杂的内容成为可能,但是真正想要快速开发,还是推荐maven,要不然又是spring的一堆坑。
对于如何快速,我可以给出一个看起来比较容易实现的方法:1.批量抓取百度首页(每页),提取出高频的关键字组合;2.对关键字进行md5+hash加密,用于加密之后的参数;3.然后提取出低频词或者模糊搜索关键字,放入正则;4.放入所需的参数中即可,譬如用户。
解决方案:最简单的方法,优采云 采集后直接导入到wordpress的数据库
采集交流 • 优采云 发表了文章 • 0 个评论 • 118 次浏览 • 2022-11-28 12:24
采集后直接导入到wordpress的数据库
很多人用wordpress做网站,用优采云
采集
,但不会发布。这里有一个简单的方法,可以瞬间将采集
到的内容直接发布到wordpress
优点:简单、快速、一目了然。
缺点:发布文章的分类标签需要手动编辑。
更适合纯文本,或者像尴尬百科这样的笑话网站
不谈采集
,只谈出版,
这里是最简单的演示,只发布内容和标题,要发布其他内容,照着做即可。
首先找到默认模板:
然后将模板更改为这样的东西,
这段代码是怎么来的?了解数据库的人一看就会知道。如果你不懂数据库,叫你哥是一种简单的方式。空间带的mysql数据库有运行界面phpmyadmin,一般空间都有。打开找到wp-post表,插入一条数据:这条数据,只填content和title
, 其他留空
然后点击执行,你会看到这样一段代码:
插入 `DatabaseName`.`wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status` , `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count `) VALUES (NULL, '0', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '内容 xxxxxxx', '标题 XXXXXXXX', '', '发布', '打开', '打开', '', '', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', ' ', '0', '', '0', '发布', '', '0');
替换:数据库名称 -> 你的数据库名称
汇总:Python如何采集关键词数据
对于SEO来说,关键词的排名对网站优化起着决定性的作用。关键词排名、流量来源、同行网站数据都可以通过SEO查询。常见的爱站站长工具、站长工具和5118都是不错的网站。
当然现在5118更全面,应用更广泛!
在数据和功能上,5118很强大!
可以的话就付钱!
5118的抗爬还是很不错的!
需要登录领取,发现5118更新了一次!
比如登录账号需要经过滑块验证码的反爬限制,关键词索引等数据以图片加密的形式展示。这人渣破解不了,就怕了。.
不过有些数据还是可以参考的!所以,让 python 起来!
打听一下设计网站,关键词设计迷信现状
抓取网址:
如果您不是付费会员,您只能查看前100页的数据!
很多数据都是反爬限制,有点可惜!
虽然5118会员登录有滑块验证码,但是cookies登录还是非常好用的!
我们手动添加 cookie 以登录以采集
所需数据。
几个关键点:
1.添加协议头
headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': ua,
'X-Requested-With': 'XMLHttpRequest',
}
自行添加ua和cooikes!
当然这是一个完整的协议头,有些可以删掉,大家可以自己试试!
2. zip函数的使用及格式化数据处理
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
3.排名波动的处理
通过源码查询可以知道,绿色表示排名上升,红色表示排名下降。这里有一个判断就搞定了!
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
4. 关键词 将数据写入csv
写了一个案例,发现了两个参考案例
import csv
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#参考一
def write_csv(self):
path = "aa.csv"
with open(path, 'a+') as f:
csv_write = csv.writer(f)
data_row = ["1", "2"]
<p>
csv_write.writerow(data_row)
# 参考二
def wcsv(self):
csvfile = open('csvtest.csv', 'w')
writer = csv.writer(csvfile)
writer.writerow(['keywords'])
data = [
('1', 'http://www.xiaoheiseo.com/', '小黑'),
('2', 'http://www.baidu.com/', '百度'),
('3', 'http://www.jd.com/', '京东')
]
writer.writerows(data)
csvfile.close()
</p>
5、查询网站相关关键词数据,写入excel表格
使用第三方库, xlsxwriter
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
由于页码也是js生成的,所以没有找到,所以自己输入页码!
输入查询网站的URL格式为:抓取后数据存储文件使用主域名!
附上完整代码:
#5118网站关键词数据获取
import requests
from lxml import etree
from urllib.parse import unquote
import xlsxwriter
import time
import csv
class C5118(object):
def __init__(self,url,nums):
self.keyword_datas=[]
self.data_lists=[]
self.index_links_hrefs=[]
self.headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': UA,
'X-Requested-With': 'XMLHttpRequest',
}
self.post_url=url
self.file_name=url.split('.')[1]
self.pagenums=nums
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
<p>
#获取数据
def get_data(self,pagenum):
url="https://www.5118.com/seo/baidupc"
params={
'isPager': 'true',
'viewtype': '2',
'days': '90',
'url': self.post_url,
'orderField': 'Rank',
'orderDirection': 'asc',
'pageIndex': pagenum, #页码
'catalogName': '',
}
response=requests.post(url,params=params,headers=self.headers)
time.sleep(1)
print(response.status_code)
doc=etree.HTML(response.content.decode('utf-8'))
keywords= doc.xpath('//tr[@class="list-row"]/td[1]/a/text()') #关键词
print(keywords)
self.keyword_datas.extend(keywords)
ranks = doc.xpath('//tr[@class="list-row"]/td[2]/a') #排名
titles = doc.xpath('//tr[@class="list-row"]/td[5]/a/text()') #网页标题
links=doc.xpath('//tr[@class="list-row"]/td[5]/a/@href') #网页链接
index_links=doc.xpath('//tr[@class="list-row"]/td[7]/a/@href') #长尾词数量链接
self.index_links_hrefs.extend(index_links)
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
self.data_lists.append(data)
time.sleep(4)
return self.data_lists
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
def main(self):
for i in range(1,self.pagenums+1):
print(f'>>> 正在采集第{i}页关键词数据...')
self.get_data(i)
print("数据采集完成!")
self.write_keywords()
self.write_to_xlsx()
if __name__=="__main__":
url = "www.shejipi.com"
nums=100
spider=C5118(url,nums)
spider.main()
</p> 查看全部
解决方案:最简单的方法,优采云
采集后直接导入到wordpress的数据库
很多人用wordpress做网站,用优采云
采集
,但不会发布。这里有一个简单的方法,可以瞬间将采集
到的内容直接发布到wordpress
优点:简单、快速、一目了然。
缺点:发布文章的分类标签需要手动编辑。
更适合纯文本,或者像尴尬百科这样的笑话网站
不谈采集
,只谈出版,

这里是最简单的演示,只发布内容和标题,要发布其他内容,照着做即可。
首先找到默认模板:
然后将模板更改为这样的东西,

这段代码是怎么来的?了解数据库的人一看就会知道。如果你不懂数据库,叫你哥是一种简单的方式。空间带的mysql数据库有运行界面phpmyadmin,一般空间都有。打开找到wp-post表,插入一条数据:这条数据,只填content和title
, 其他留空
然后点击执行,你会看到这样一段代码:
插入 `DatabaseName`.`wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status` , `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count `) VALUES (NULL, '0', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '内容 xxxxxxx', '标题 XXXXXXXX', '', '发布', '打开', '打开', '', '', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', ' ', '0', '', '0', '发布', '', '0');
替换:数据库名称 -> 你的数据库名称
汇总:Python如何采集关键词数据
对于SEO来说,关键词的排名对网站优化起着决定性的作用。关键词排名、流量来源、同行网站数据都可以通过SEO查询。常见的爱站站长工具、站长工具和5118都是不错的网站。
当然现在5118更全面,应用更广泛!
在数据和功能上,5118很强大!
可以的话就付钱!
5118的抗爬还是很不错的!
需要登录领取,发现5118更新了一次!
比如登录账号需要经过滑块验证码的反爬限制,关键词索引等数据以图片加密的形式展示。这人渣破解不了,就怕了。.
不过有些数据还是可以参考的!所以,让 python 起来!
打听一下设计网站,关键词设计迷信现状
抓取网址:
如果您不是付费会员,您只能查看前100页的数据!
很多数据都是反爬限制,有点可惜!
虽然5118会员登录有滑块验证码,但是cookies登录还是非常好用的!
我们手动添加 cookie 以登录以采集
所需数据。
几个关键点:
1.添加协议头
headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': ua,
'X-Requested-With': 'XMLHttpRequest',
}
自行添加ua和cooikes!
当然这是一个完整的协议头,有些可以删掉,大家可以自己试试!
2. zip函数的使用及格式化数据处理
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
3.排名波动的处理
通过源码查询可以知道,绿色表示排名上升,红色表示排名下降。这里有一个判断就搞定了!
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
4. 关键词 将数据写入csv
写了一个案例,发现了两个参考案例
import csv
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#参考一
def write_csv(self):
path = "aa.csv"
with open(path, 'a+') as f:
csv_write = csv.writer(f)
data_row = ["1", "2"]
<p>

csv_write.writerow(data_row)
# 参考二
def wcsv(self):
csvfile = open('csvtest.csv', 'w')
writer = csv.writer(csvfile)
writer.writerow(['keywords'])
data = [
('1', 'http://www.xiaoheiseo.com/', '小黑'),
('2', 'http://www.baidu.com/', '百度'),
('3', 'http://www.jd.com/', '京东')
]
writer.writerows(data)
csvfile.close()
</p>
5、查询网站相关关键词数据,写入excel表格
使用第三方库, xlsxwriter
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
由于页码也是js生成的,所以没有找到,所以自己输入页码!
输入查询网站的URL格式为:抓取后数据存储文件使用主域名!
附上完整代码:
#5118网站关键词数据获取
import requests
from lxml import etree
from urllib.parse import unquote
import xlsxwriter
import time
import csv
class C5118(object):
def __init__(self,url,nums):
self.keyword_datas=[]
self.data_lists=[]
self.index_links_hrefs=[]
self.headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': UA,
'X-Requested-With': 'XMLHttpRequest',
}
self.post_url=url
self.file_name=url.split('.')[1]
self.pagenums=nums
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
<p>

#获取数据
def get_data(self,pagenum):
url="https://www.5118.com/seo/baidupc"
params={
'isPager': 'true',
'viewtype': '2',
'days': '90',
'url': self.post_url,
'orderField': 'Rank',
'orderDirection': 'asc',
'pageIndex': pagenum, #页码
'catalogName': '',
}
response=requests.post(url,params=params,headers=self.headers)
time.sleep(1)
print(response.status_code)
doc=etree.HTML(response.content.decode('utf-8'))
keywords= doc.xpath('//tr[@class="list-row"]/td[1]/a/text()') #关键词
print(keywords)
self.keyword_datas.extend(keywords)
ranks = doc.xpath('//tr[@class="list-row"]/td[2]/a') #排名
titles = doc.xpath('//tr[@class="list-row"]/td[5]/a/text()') #网页标题
links=doc.xpath('//tr[@class="list-row"]/td[5]/a/@href') #网页链接
index_links=doc.xpath('//tr[@class="list-row"]/td[7]/a/@href') #长尾词数量链接
self.index_links_hrefs.extend(index_links)
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
self.data_lists.append(data)
time.sleep(4)
return self.data_lists
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
def main(self):
for i in range(1,self.pagenums+1):
print(f'>>> 正在采集第{i}页关键词数据...')
self.get_data(i)
print("数据采集完成!")
self.write_keywords()
self.write_to_xlsx()
if __name__=="__main__":
url = "www.shejipi.com"
nums=100
spider=C5118(url,nums)
spider.main()
</p>
解决方案:基于K8S部署filebeat及logstash并输出到java程序中
采集交流 • 优采云 发表了文章 • 0 个评论 • 112 次浏览 • 2022-11-27 23:46
从 K8S 集群采集
容器日志并集中存储。
溶液:
1、守护进程集
运行文件节拍
作为守护进程,Filebeat 会在 JAVA 程序中采集
通过 logstash 发送的日志,然后由 JAVA 程序对其进行处理并集中存储。
2、边车
每个 POD 都增加了一个额外的 Filebeat 容器,Filebeat 读取相应的日志,并通过日志共享将其发送到 JAVA 程序。
这两种方法可以共存而不会发生冲突。DaemonSet 方法采集容器的标准输出,如果有特殊要求,可以通过 sidecar 方法自定义采集日志。
下面介绍了用于采集
容器日志的 daemonSet 方法的内容:
首先粘贴 K8S 部署的 yaml 文件:
# 创建账户
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager
namespace: kube-system
---
# 创建角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager-role
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- nodes
- namespaces
- events
- pods
verbs:
- get
- list
- watch
---
# 账户与角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: itsm-node-manager-role-binding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: itsm-node-manager-role
subjects:
- kind: ServiceAccount
name: itsm-node-manager
namespace: kube-system
---
# 创建logstash配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: logstash-config
namespace: kube-system
data:
logstash.yml: 'config.reload.automatic: true'
pipeline.conf: |-
input {
beats {
port => 5044
codec => json
}
}
filter {
}
output {
http {
http_method => "post"
format => "json"
# 此处配置程序的url路径,java代码会在下面贴出来。如果调用的是集群内部的程序,可以采用和filebeat一样的域名方式
url => "http://192.168.0.195:8080/cont ... ot%3B
content_type => "application/json"
}
}
---
# 创建logstash
apiVersion: apps/v1
kind: Deployment
metadata:
name: logstash
namespace: kube-system
labels:
server: logstash-7.10.1
spec:
selector:
matchLabels:
<p>
k8s-app: logstash
template:
metadata:
creationTimestamp: null
labels:
k8s-app: logstash
name: logstash
spec:
containers:
- image: elastic/logstash:7.10.1
imagePullPolicy: IfNotPresent
name: logstash
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /usr/share/logstash/config/logstash.yml
name: logstash-config
readOnly: true
subPath: logstash.yml
- mountPath: /usr/share/logstash/pipeline/logstash.conf
name: logstash-config
readOnly: true
subPath: pipeline.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: dockerpull
volumes:
- configMap:
defaultMode: 420
name: logstash-config
name: logstash-config
---
# 创建logstash service
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: logstash
name: logstash
namespace: kube-system
spec:
type: ClusterIP
selector:
k8s-app: logstash
ports:
- port: 5044
protocol: TCP
targetPort: 5044
---
# 创建filebeat配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: filebeat-config
namespace: kube-system
data:
filebeat.yml: |-
filebeat.autodiscover:
providers:
- type: kubernetes
host: ${NODE_NAME}
hints.enabled: true
hints.default_config:
type: container
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
processors:
- add_cloud_metadata:
- add_host_metadata:
output.logstash:
hosts: ["logstash.kube-system.svc.cluster.local:5044"] # kubectl -n logs get svc
enabled: true
---
# 创建filebeat守护进程
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
labels:
server: filebeat-7.10.1
spec:
selector:
matchLabels:
name: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
creationTimestamp: null
labels:
name: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: elastic/filebeat:7.10.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
- mountPath: /var/log
name: varlog
readOnly: true
restartPolicy: Always
serviceAccount: itsm-node-manager
serviceAccountName: itsm-node-manager
volumes:
- configMap:
defaultMode: 384
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- hostPath:
path: /var/log
type: ""
name: varlog
- hostPath:
path: /opt/filebeat/data
type: DirectoryOrCreate
name: data
</p>
这是将多个部署信息放在一个 YAML 文件中,用“---”分隔。
以下是 JAVA 代码片段:
@Api(tags = "服务日志控制类")
@Slf4j
@RestController
@RequestMapping("/containerLog")
public class ContainerLogController {
@Autowired
private ContainerLogService containerLogService;
@ApiOperation(value = "容器日志写入接口",produces = "application/json", response = String.class)
@PostMapping("insert")
public Result insert(HttpServletRequest httpServletRequest){
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try {
br = httpServletRequest.getReader();
String str;
while ((str=br.readLine())!=null){
sb.append(str);
}
containerLogService.insert(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return Result.newSuccess();
}
}
此时,您可以获取 logstash 发送的日志信息,并且容器日志均为 JSON 格式。
您可以在三个位置扩展以满足您的需求:
1. 文件节拍采集
规则
2. 日志存储过滤规则
3. 程序处理逻辑
最佳实践:pytest文档83 - 把收集的 yaml 文件转 Item 用例并运行
前言
上一篇文章通过用例采集
挂钩pytest_collect_file采集
YAML 文件,但只采集
用例,无法执行。
接下来,详细解释如何将 yaml 文件的内容转换为要执行的 Item 用例。
pytest_collect_file 采集
钩子
准备 YAML 文件内容 test_login.yml
name: login case1<br />request:<br /> url: http://127.0.0.1:8000/api/v1/login/<br /> method: POST<br /> headers:<br /> Content-Type: application/json<br /> json:<br /> username: test<br /> password: 123456
首先将集合钩子写 conftest.py
def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return pytest.File.from_parent(parent, path=file_path)
如果采集
到 yaml 文件中,则返回 pytest。File.from_parent(父级,路径=file_path),运行时将报告错误
============================================ ERRORS ============================================<br />_____________________________ ERROR collecting case/test_login.yml _____________________________<br />venv\lib\site-packages\_pytest\runner.py:339: in from_call<br /> result: Optional[TResult] = func()<br />venv\lib\site-packages\_pytest\runner.py:370: in <br /> call = CallInfo.from_call(lambda: list(collector.collect()), "collect")<br />venv\lib\site-packages\_pytest\nodes.py:536: in collect<br /> raise NotImplementedError("abstract")<br />E NotImplementedError: abstract<br />=================================== short test summary info ====================================<br />ERROR case/test_login.yml - NotImplementedError: abstract<br />!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!
该错误在 nodes.py 文件的 collect() 方法中报告,因此请在 nodes.py 中找到采集
器
class Collector(Node):<br /> """Collector instances create children through collect() and thus<br /> iteratively build a tree."""<br /><br /> class CollectError(Exception):<br /> """An error during collection, contains a custom message."""<br /><br /> def collect(self) -> Iterable[Union["Item", "Collector"]]:<br /> """Return a list of children (items and collectors) for this<br /> collection node."""<br /> raise NotImplementedError("abstract")
由于 collect() 方法
为空,它直接引发异常 NotImplementError(“abstract”),因此我们需要覆盖 collect() 方法
YamlFile 重写 collect()。
对应于 YamlFile 类,继承 ytest。文件,它覆盖 collect() 方法
class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield pytest.Item.from_parent(self, name=raw.get('name'), values=raw)
再次运行 pytest
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />item = <br /><br /> def pytest_runtest_call(item: Item) -> None:<br /> _update_current_test_var(item, "call")<br /> try:<br /> del sys.last_type<br /> del sys.last_value<br /> del sys.last_traceback<br /> except AttributeError:<br /> pass<br /> try:<br />> item.runtest()<br /><br />venv\lib\site-packages\_pytest\runner.py:167:<br />_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />self = <br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br />> raise NotImplementedError("runtest must be implemented by Item subclass")<br />E NotImplementedError: runtest must be implemented by Item subclass<br /><br />venv\lib\site-packages\_pytest\nodes.py:733: NotImplementedError
这次发生的错误在 runner.py 文件中报告,并且通过执行 runtest() 方法 NotImplementError(“runtest 必须由 Item 子类实现”)引发的异常
)。
看到这里,就意味着用例 Item 已经生成,并且在执行时,没有定义执行 yaml 文件的方法,因此报告了一个错误
所以我在 nodes.py 中找到了 Item(Node) 类
class Item(Node):<br /> """A basic test invocation item.<br /><br /> Note that for a single function there might be multiple test invocation items.<br /> """<br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br /> raise NotImplementedError("runtest must be implemented by Item subclass")
接下来,您需要重写 Item 中的运行测试以执行用例
重写项目的运行测试
您最终看到执行yaml文件的简短版本的界面用例 conftest.py 如下
import pytest<br />import requests<br />import yaml<br />from pathlib import Path<br /><br />def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return YamlFile.from_parent(parent, path=file_path)<br /><br />class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield YamlTest.from_parent(self, name=raw.get('name'), values=raw)<br /><br />class YamlTest(pytest.Item):<br /> def __init__(self, name, parent, values):<br /> super(YamlTest, self).__init__(name, parent)<br /> self.name = name<br /> self.values = values<br /> self.s = requests.session()<br /><br /> def runtest(self) -> None:<br /> """运行用例"""<br /> request_data = self.values["request"]<br /> response = self.s.request(**request_data)<br /> print("\n", response.text)
输入pytest,您可以看到yaml文件作为用例执行 查看全部
解决方案:基于K8S部署filebeat及logstash并输出到java程序中
从 K8S 集群采集
容器日志并集中存储。
溶液:
1、守护进程集
运行文件节拍
作为守护进程,Filebeat 会在 JAVA 程序中采集
通过 logstash 发送的日志,然后由 JAVA 程序对其进行处理并集中存储。
2、边车
每个 POD 都增加了一个额外的 Filebeat 容器,Filebeat 读取相应的日志,并通过日志共享将其发送到 JAVA 程序。
这两种方法可以共存而不会发生冲突。DaemonSet 方法采集容器的标准输出,如果有特殊要求,可以通过 sidecar 方法自定义采集日志。
下面介绍了用于采集
容器日志的 daemonSet 方法的内容:
首先粘贴 K8S 部署的 yaml 文件:
# 创建账户
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager
namespace: kube-system
---
# 创建角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager-role
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- nodes
- namespaces
- events
- pods
verbs:
- get
- list
- watch
---
# 账户与角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: itsm-node-manager-role-binding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: itsm-node-manager-role
subjects:
- kind: ServiceAccount
name: itsm-node-manager
namespace: kube-system
---
# 创建logstash配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: logstash-config
namespace: kube-system
data:
logstash.yml: 'config.reload.automatic: true'
pipeline.conf: |-
input {
beats {
port => 5044
codec => json
}
}
filter {
}
output {
http {
http_method => "post"
format => "json"
# 此处配置程序的url路径,java代码会在下面贴出来。如果调用的是集群内部的程序,可以采用和filebeat一样的域名方式
url => "http://192.168.0.195:8080/cont ... ot%3B
content_type => "application/json"
}
}
---
# 创建logstash
apiVersion: apps/v1
kind: Deployment
metadata:
name: logstash
namespace: kube-system
labels:
server: logstash-7.10.1
spec:
selector:
matchLabels:
<p>

k8s-app: logstash
template:
metadata:
creationTimestamp: null
labels:
k8s-app: logstash
name: logstash
spec:
containers:
- image: elastic/logstash:7.10.1
imagePullPolicy: IfNotPresent
name: logstash
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /usr/share/logstash/config/logstash.yml
name: logstash-config
readOnly: true
subPath: logstash.yml
- mountPath: /usr/share/logstash/pipeline/logstash.conf
name: logstash-config
readOnly: true
subPath: pipeline.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: dockerpull
volumes:
- configMap:
defaultMode: 420
name: logstash-config
name: logstash-config
---
# 创建logstash service
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: logstash
name: logstash
namespace: kube-system
spec:
type: ClusterIP
selector:
k8s-app: logstash
ports:
- port: 5044
protocol: TCP
targetPort: 5044
---
# 创建filebeat配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: filebeat-config
namespace: kube-system
data:
filebeat.yml: |-
filebeat.autodiscover:
providers:
- type: kubernetes
host: ${NODE_NAME}
hints.enabled: true
hints.default_config:
type: container
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
processors:
- add_cloud_metadata:
- add_host_metadata:
output.logstash:
hosts: ["logstash.kube-system.svc.cluster.local:5044"] # kubectl -n logs get svc
enabled: true
---
# 创建filebeat守护进程
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
labels:
server: filebeat-7.10.1
spec:
selector:
matchLabels:
name: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
creationTimestamp: null

labels:
name: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: elastic/filebeat:7.10.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
- mountPath: /var/log
name: varlog
readOnly: true
restartPolicy: Always
serviceAccount: itsm-node-manager
serviceAccountName: itsm-node-manager
volumes:
- configMap:
defaultMode: 384
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- hostPath:
path: /var/log
type: ""
name: varlog
- hostPath:
path: /opt/filebeat/data
type: DirectoryOrCreate
name: data
</p>
这是将多个部署信息放在一个 YAML 文件中,用“---”分隔。
以下是 JAVA 代码片段:
@Api(tags = "服务日志控制类")
@Slf4j
@RestController
@RequestMapping("/containerLog")
public class ContainerLogController {
@Autowired
private ContainerLogService containerLogService;
@ApiOperation(value = "容器日志写入接口",produces = "application/json", response = String.class)
@PostMapping("insert")
public Result insert(HttpServletRequest httpServletRequest){
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try {
br = httpServletRequest.getReader();
String str;
while ((str=br.readLine())!=null){
sb.append(str);
}
containerLogService.insert(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return Result.newSuccess();
}
}
此时,您可以获取 logstash 发送的日志信息,并且容器日志均为 JSON 格式。
您可以在三个位置扩展以满足您的需求:
1. 文件节拍采集
规则
2. 日志存储过滤规则
3. 程序处理逻辑
最佳实践:pytest文档83 - 把收集的 yaml 文件转 Item 用例并运行
前言
上一篇文章通过用例采集
挂钩pytest_collect_file采集
YAML 文件,但只采集
用例,无法执行。
接下来,详细解释如何将 yaml 文件的内容转换为要执行的 Item 用例。
pytest_collect_file 采集
钩子
准备 YAML 文件内容 test_login.yml
name: login case1<br />request:<br /> url: http://127.0.0.1:8000/api/v1/login/<br /> method: POST<br /> headers:<br /> Content-Type: application/json<br /> json:<br /> username: test<br /> password: 123456
首先将集合钩子写 conftest.py
def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return pytest.File.from_parent(parent, path=file_path)
如果采集
到 yaml 文件中,则返回 pytest。File.from_parent(父级,路径=file_path),运行时将报告错误
============================================ ERRORS ============================================<br />_____________________________ ERROR collecting case/test_login.yml _____________________________<br />venv\lib\site-packages\_pytest\runner.py:339: in from_call<br /> result: Optional[TResult] = func()<br />venv\lib\site-packages\_pytest\runner.py:370: in <br /> call = CallInfo.from_call(lambda: list(collector.collect()), "collect")<br />venv\lib\site-packages\_pytest\nodes.py:536: in collect<br /> raise NotImplementedError("abstract")<br />E NotImplementedError: abstract<br />=================================== short test summary info ====================================<br />ERROR case/test_login.yml - NotImplementedError: abstract<br />!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!

该错误在 nodes.py 文件的 collect() 方法中报告,因此请在 nodes.py 中找到采集
器
class Collector(Node):<br /> """Collector instances create children through collect() and thus<br /> iteratively build a tree."""<br /><br /> class CollectError(Exception):<br /> """An error during collection, contains a custom message."""<br /><br /> def collect(self) -> Iterable[Union["Item", "Collector"]]:<br /> """Return a list of children (items and collectors) for this<br /> collection node."""<br /> raise NotImplementedError("abstract")
由于 collect() 方法
为空,它直接引发异常 NotImplementError(“abstract”),因此我们需要覆盖 collect() 方法
YamlFile 重写 collect()。
对应于 YamlFile 类,继承 ytest。文件,它覆盖 collect() 方法
class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield pytest.Item.from_parent(self, name=raw.get('name'), values=raw)
再次运行 pytest
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />item = <br /><br /> def pytest_runtest_call(item: Item) -> None:<br /> _update_current_test_var(item, "call")<br /> try:<br /> del sys.last_type<br /> del sys.last_value<br /> del sys.last_traceback<br /> except AttributeError:<br /> pass<br /> try:<br />> item.runtest()<br /><br />venv\lib\site-packages\_pytest\runner.py:167:<br />_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />self = <br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br />> raise NotImplementedError("runtest must be implemented by Item subclass")<br />E NotImplementedError: runtest must be implemented by Item subclass<br /><br />venv\lib\site-packages\_pytest\nodes.py:733: NotImplementedError
这次发生的错误在 runner.py 文件中报告,并且通过执行 runtest() 方法 NotImplementError(“runtest 必须由 Item 子类实现”)引发的异常

)。
看到这里,就意味着用例 Item 已经生成,并且在执行时,没有定义执行 yaml 文件的方法,因此报告了一个错误
所以我在 nodes.py 中找到了 Item(Node) 类
class Item(Node):<br /> """A basic test invocation item.<br /><br /> Note that for a single function there might be multiple test invocation items.<br /> """<br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br /> raise NotImplementedError("runtest must be implemented by Item subclass")
接下来,您需要重写 Item 中的运行测试以执行用例
重写项目的运行测试
您最终看到执行yaml文件的简短版本的界面用例 conftest.py 如下
import pytest<br />import requests<br />import yaml<br />from pathlib import Path<br /><br />def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return YamlFile.from_parent(parent, path=file_path)<br /><br />class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield YamlTest.from_parent(self, name=raw.get('name'), values=raw)<br /><br />class YamlTest(pytest.Item):<br /> def __init__(self, name, parent, values):<br /> super(YamlTest, self).__init__(name, parent)<br /> self.name = name<br /> self.values = values<br /> self.s = requests.session()<br /><br /> def runtest(self) -> None:<br /> """运行用例"""<br /> request_data = self.values["request"]<br /> response = self.s.request(**request_data)<br /> print("\n", response.text)
输入pytest,您可以看到yaml文件作为用例执行
分享文章:搜狐号文章图片解密还原 含调用例子
采集交流 • 优采云 发表了文章 • 0 个评论 • 128 次浏览 • 2022-11-27 19:58
任何参与该网站的人都应该采集
搜狐文章,但最近搜狐文章的图片已被加密。当你发送HTTP请求后想直接截取搜狐文章的正文,或者当你使用抓取软件时,发现搜狐文章的IMG图片路径是加密的???
仔细看看搜狐文章的文字 IMG 标签路径是加密的,但通过浏览器访问很正常,盲猜 JS 在起作用。
F12直接从裤裆,断点调整。一目了然,你可以看到它是AES加密,你知道加密方法。直接调用 CryptoJS 库进行解密!
CryptoJS 加密模块 AES ECB pkcs7 密钥是
js 调用示例:需要引用 CryptoJS 加密库
var key = CryptoJS.enc.Utf8.parse("www.sohu.com6666");
<p>
function AES_Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode</p>
干货教程:一分钟教你玩转手机回收小程序,源码+教程免费分享
在我们现在的生活中,最离不开的就是手机了。随着智能手机的不断普及,人们更换手机的频率也在不断加快,从而带动了二手手机回收市场的快速发展。在二手手机行业发展的今天,也诞生了很多手机回收小程序。今天我们就来介绍一下手机回收小程序的功能。
手机回收小程序功能介绍:
1.免费估价
用户可以在小程序中完成一系列系统问题,对手机进行智能估价,供用户参考和比较。
2.品类划分
除了手机,该平台还将涵盖笔记本、平板电脑、摄影器材等各类数码电子产品。种类型号齐全,满足更多用户的需求。
3.以旧换新
平台通过对旧机进行估价回收,让用户在平台购买新机时可以抵扣,让用户获得更大的优惠。
4.在线回收
通过在线估值测试后,实现快速恢复,让用户更快回款。
五、行业资讯
平台可以及时更新数字行业的动态和新闻,让用户更容易了解最新的数字资讯。
目前,二手手机行业的市场规模并不逊色于二手车、二手房。而相比之下,二手手机市场需求更为刚性,交易更为频繁。对于手机回收行业来说,小程序将拥有更广阔的市场空间。
今天分享的资源包括手机数码回收小程序源码+零基础新手教程。内容非常丰富,包括服务器和域名的配置、宝塔的安装、小程序的安装和启动等等,真正教你从零开始搭建。并正式推出了自己的小程序。
免费领取手机数码回收小程序源码流程:
1. 点赞+关注“解密小程序”
2.私信回复关键词:源码(可以免费领取)
如果资源失效,别着急,请联系小编补发!
感谢您的关注和支持。欢迎大家分享转发,让更多需要的朋友看到。未来我们也会努力分享更多优质的源码、教程等资料。希望大家继续关注!
《60分钟教你:从零开始搭建一个完整的小程序》
第一课:两种方式教你注册小程序账号
第二课:如何为小程序选择合适的服务器和域名?
第三课:十分钟教你快速搭建服务器环境
第四课:一键轻松搭建小程序第三方系统——微引擎
第五课:教你快速安装小程序应用
第六课:十分钟教你正式上线微信小程序 查看全部
分享文章:搜狐号文章图片解密还原 含调用例子
任何参与该网站的人都应该采集
搜狐文章,但最近搜狐文章的图片已被加密。当你发送HTTP请求后想直接截取搜狐文章的正文,或者当你使用抓取软件时,发现搜狐文章的IMG图片路径是加密的???
仔细看看搜狐文章的文字 IMG 标签路径是加密的,但通过浏览器访问很正常,盲猜 JS 在起作用。
F12直接从裤裆,断点调整。一目了然,你可以看到它是AES加密,你知道加密方法。直接调用 CryptoJS 库进行解密!

CryptoJS 加密模块 AES ECB pkcs7 密钥是
js 调用示例:需要引用 CryptoJS 加密库
var key = CryptoJS.enc.Utf8.parse("www.sohu.com6666");
<p>

function AES_Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode</p>
干货教程:一分钟教你玩转手机回收小程序,源码+教程免费分享
在我们现在的生活中,最离不开的就是手机了。随着智能手机的不断普及,人们更换手机的频率也在不断加快,从而带动了二手手机回收市场的快速发展。在二手手机行业发展的今天,也诞生了很多手机回收小程序。今天我们就来介绍一下手机回收小程序的功能。
手机回收小程序功能介绍:
1.免费估价
用户可以在小程序中完成一系列系统问题,对手机进行智能估价,供用户参考和比较。
2.品类划分
除了手机,该平台还将涵盖笔记本、平板电脑、摄影器材等各类数码电子产品。种类型号齐全,满足更多用户的需求。
3.以旧换新
平台通过对旧机进行估价回收,让用户在平台购买新机时可以抵扣,让用户获得更大的优惠。

4.在线回收
通过在线估值测试后,实现快速恢复,让用户更快回款。
五、行业资讯
平台可以及时更新数字行业的动态和新闻,让用户更容易了解最新的数字资讯。
目前,二手手机行业的市场规模并不逊色于二手车、二手房。而相比之下,二手手机市场需求更为刚性,交易更为频繁。对于手机回收行业来说,小程序将拥有更广阔的市场空间。
今天分享的资源包括手机数码回收小程序源码+零基础新手教程。内容非常丰富,包括服务器和域名的配置、宝塔的安装、小程序的安装和启动等等,真正教你从零开始搭建。并正式推出了自己的小程序。
免费领取手机数码回收小程序源码流程:
1. 点赞+关注“解密小程序”
2.私信回复关键词:源码(可以免费领取)

如果资源失效,别着急,请联系小编补发!
感谢您的关注和支持。欢迎大家分享转发,让更多需要的朋友看到。未来我们也会努力分享更多优质的源码、教程等资料。希望大家继续关注!
《60分钟教你:从零开始搭建一个完整的小程序》
第一课:两种方式教你注册小程序账号
第二课:如何为小程序选择合适的服务器和域名?
第三课:十分钟教你快速搭建服务器环境
第四课:一键轻松搭建小程序第三方系统——微引擎
第五课:教你快速安装小程序应用
第六课:十分钟教你正式上线微信小程序
测评:发布一个文章采集器大家试试,来者有分。
采集交流 • 优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-11-26 03:17
免费PHPCMS采集规则文章采集器采集百万数据
直接在本地电脑上运行该工具,(为什么要使用本地采集工具,因为在本地电脑上运行采集工具不会对服务器造成任何影响,最大限度地发挥服务器的性能,让网站打开速度更快,并且允许搜索引擎的抓取速度更快!使用SEO工具实现...
【站群必备】自动采集文章和伪原创文章后自动发布文章-一站式服务
很多人在做网站群的时候,往往要么请人帮忙写... 自动采集伪原创文章后自动发布文章的集成在线采集服务。简单易操作的面板,最快3分钟即可启动,可大幅提升。规模管理站群,每天可自动发布大量伪原创文章,并可选择...
50行代码教你打造公众号文章采集器
Alfred的女票是数据科学领域的新媒体运营官(没错,Alfred是程序员,Alfred有女票),每天阅读大量行业相关文章,把握行业动态,选择和生产相关...
【Wordpress】Wordpress插件自动采集
发布工具
安装好wordpress之后,就得开始发布文章了。由于之前的文章散落在各个平台上,要一篇一篇的复制,着实费时费力。所以,想要一劳永逸的解决这个问题,就必须要用到今天介绍的采集工具了。插件安装搜索:Fat Rat Coolect ...
免费PBootCMS采集支持聚合文章采集插件
Q:如何安装免费的PBOOT CMS采集插件?站长必备PBoot采集工具答:直接下载到本地电脑,双击直接运行!...答案:每天可采集百万条数据,支持单列采集发布,支持多列采集发布。Q:免费PBOOTCMS插件合集
技术文章:英文网站文章采集,英文文章采集批量翻译
英文网站文章采集
是我们常用的材料采集
方法,网站翻译我们可以通过页面浏览器自带的翻译进行,但是如何对我们采集
的文章进行本地批量翻译,您需要使用我们的批量翻译插件。
英文网站指定采集,
只需要进入我们的目标网站,简单的操作不需要切换IP即可进行,无论是英文、俄文、法文、日文、韩文等大小语种网站都可以进行视觉选择和采集操作,对于采集的文章,用自己的批量翻译,可以在发布到我们的网站或本地的条件下保留原创
语言标签和格式。
英文网站的推广也离不开SEO,除了素材的采集
,网站内容的日常及时更新,还需要进行相关的SEO优化。通过关键词挖掘,获取流行的实时下拉和长尾关键词及相关词,然后通过全网匹配采集来采集这些长尾词,得到高质量的爆款文章和热点文章。
当我们想要增加页面浏览量时,最好定位竞争较低的关键词——使它们更容易排名,我们将在 SERP 中看到更快的结果。可以帮助我们找到要定位的关键字。我们输入关键字,该工具将显示要定位的潜在关键字列表。
我们可以按关键字难度,国家,数量(每月访问者数量)等进行排序。如果我们使用此工具查找难度分数低的长尾关键字,我们将能够创建一个关键字列表来定位,我们可以自己使用或提供给我们的作家团队。
想象一下这样的场景:我们查看市场上的潜在网站,但我们想知道该网站是否有潜力在花钱之前快速(并且非常容易)改进。通常,我们必须做出估计并相信网站卖家对流量、收入、反向链接和关键字的说法;但是,使用英语网站抓取等工具可以让我们避免任何尴尬和代价高昂的错误。
我们可能会在软件中运行网站的域名,并接收数据和有价值信息的列表。例如,我们可以看到他们排名的关键字(更重要的是,他们没有排名)以及他们与竞争对手的匹配程度。
如果我们遇到未使用的关键字,但竞争对手确实如此,我们可以看到使用英语网站抓取工具创建内容并超越它们是多么容易。英文网站抓取工具为我们输入的任何搜索词提供详细数据,告诉我们与排名靠前的搜索词竞争是多么容易。
我们可能会遇到的另一种情况是找到一个在搜索结果中表现良好但没有良好内容或大量反向链接的网站。当这种情况发生时,这是一个好兆头,因为我们可以创建更好的内容,添加反向链接并获得更好的排名。
英文网站集合有一些价格计划,但即使是最便宜的计划也允许我们跟踪 100 个关键字。跟踪多个关键字意味着我们可以访问数据,并可以查看每个关键字的可视化屏幕和网站性能报告。我们可以在移动和桌面结果之间切换,并查看所有领先搜索引擎的日常活动。 查看全部
测评:发布一个文章采集器大家试试,来者有分。
免费PHPCMS采集规则文章采集器采集百万数据
直接在本地电脑上运行该工具,(为什么要使用本地采集工具,因为在本地电脑上运行采集工具不会对服务器造成任何影响,最大限度地发挥服务器的性能,让网站打开速度更快,并且允许搜索引擎的抓取速度更快!使用SEO工具实现...
【站群必备】自动采集文章和伪原创文章后自动发布文章-一站式服务

很多人在做网站群的时候,往往要么请人帮忙写... 自动采集伪原创文章后自动发布文章的集成在线采集服务。简单易操作的面板,最快3分钟即可启动,可大幅提升。规模管理站群,每天可自动发布大量伪原创文章,并可选择...
50行代码教你打造公众号文章采集器
Alfred的女票是数据科学领域的新媒体运营官(没错,Alfred是程序员,Alfred有女票),每天阅读大量行业相关文章,把握行业动态,选择和生产相关...
【Wordpress】Wordpress插件自动采集
发布工具

安装好wordpress之后,就得开始发布文章了。由于之前的文章散落在各个平台上,要一篇一篇的复制,着实费时费力。所以,想要一劳永逸的解决这个问题,就必须要用到今天介绍的采集工具了。插件安装搜索:Fat Rat Coolect ...
免费PBootCMS采集支持聚合文章采集插件
Q:如何安装免费的PBOOT CMS采集插件?站长必备PBoot采集工具答:直接下载到本地电脑,双击直接运行!...答案:每天可采集百万条数据,支持单列采集发布,支持多列采集发布。Q:免费PBOOTCMS插件合集
技术文章:英文网站文章采集,英文文章采集批量翻译
英文网站文章采集
是我们常用的材料采集
方法,网站翻译我们可以通过页面浏览器自带的翻译进行,但是如何对我们采集
的文章进行本地批量翻译,您需要使用我们的批量翻译插件。
英文网站指定采集,
只需要进入我们的目标网站,简单的操作不需要切换IP即可进行,无论是英文、俄文、法文、日文、韩文等大小语种网站都可以进行视觉选择和采集操作,对于采集的文章,用自己的批量翻译,可以在发布到我们的网站或本地的条件下保留原创
语言标签和格式。
英文网站的推广也离不开SEO,除了素材的采集
,网站内容的日常及时更新,还需要进行相关的SEO优化。通过关键词挖掘,获取流行的实时下拉和长尾关键词及相关词,然后通过全网匹配采集来采集这些长尾词,得到高质量的爆款文章和热点文章。

当我们想要增加页面浏览量时,最好定位竞争较低的关键词——使它们更容易排名,我们将在 SERP 中看到更快的结果。可以帮助我们找到要定位的关键字。我们输入关键字,该工具将显示要定位的潜在关键字列表。
我们可以按关键字难度,国家,数量(每月访问者数量)等进行排序。如果我们使用此工具查找难度分数低的长尾关键字,我们将能够创建一个关键字列表来定位,我们可以自己使用或提供给我们的作家团队。
想象一下这样的场景:我们查看市场上的潜在网站,但我们想知道该网站是否有潜力在花钱之前快速(并且非常容易)改进。通常,我们必须做出估计并相信网站卖家对流量、收入、反向链接和关键字的说法;但是,使用英语网站抓取等工具可以让我们避免任何尴尬和代价高昂的错误。

我们可能会在软件中运行网站的域名,并接收数据和有价值信息的列表。例如,我们可以看到他们排名的关键字(更重要的是,他们没有排名)以及他们与竞争对手的匹配程度。
如果我们遇到未使用的关键字,但竞争对手确实如此,我们可以看到使用英语网站抓取工具创建内容并超越它们是多么容易。英文网站抓取工具为我们输入的任何搜索词提供详细数据,告诉我们与排名靠前的搜索词竞争是多么容易。
我们可能会遇到的另一种情况是找到一个在搜索结果中表现良好但没有良好内容或大量反向链接的网站。当这种情况发生时,这是一个好兆头,因为我们可以创建更好的内容,添加反向链接并获得更好的排名。
英文网站集合有一些价格计划,但即使是最便宜的计划也允许我们跟踪 100 个关键字。跟踪多个关键字意味着我们可以访问数据,并可以查看每个关键字的可视化屏幕和网站性能报告。我们可以在移动和桌面结果之间切换,并查看所有领先搜索引擎的日常活动。
解决方案:微服务远程调用组件Feign的使用详解
采集交流 • 优采云 发表了文章 • 0 个评论 • 87 次浏览 • 2022-11-25 18:38
一、总结
我们知道目前最火、技术含量最高的技术就是SpringCloud微服务,那么今天一哥就带大家了解一下微服务的核心组件之一,Feign的基本使用及其工作机制。
二、Feign简介 一、概念
在学习如何使用Feign之前,我们先来了解一下什么是Feign。
Feign 是 Netflix 开发的声明式(目前由 Spring 维护)和模板化的 HTTP 客户端。Feign可以帮助我们更快速优雅的调用HTTP Api。
简单来说,Feign是一个远程服务调用的框架/工具,可以让开发者以更低耦合、更少代码、更快、更兼容的方式进行远程服务调用。
2.功能
了解了这些基本概念之后,接下来小编就带大家看看Feign组件是如何实现远程接口调用的。话不多说,我们直接上代码。
三、服务提供者 1、添加依赖
首先我们在父POM文件中添加核心依赖,如下:
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba-dependencies.version}
pom
import
然后在子POM文件中添加依赖如下:
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.配置文件
在 application.yml 文件中添加如下配置:
server:
port: 8090
spring:
application:
name: nacos-feign-example
cloud:
nacos:
discovery:
server-addr: 112.74.42.138:8848
3、创业班
项目的启动类代码如下:
@SpringBootApplication
public class NetflixFeignProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NetflixFeignProviderApplication.class, args);
}
}
4.控制层
我们可以写一个Controller控制器,定义web界面如下。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 模拟主键自增
*/
private AtomicInteger pk = new AtomicInteger();
<p>
@PostMappingpublic User save(@RequestBody User user) {
user.setUid(pk.incrementAndGet());
return user;
}
/**
* @param uid
* @return
*/@GetMapping("/{uid}")
public User user(@PathVariable("uid") int uid) {
return User.builder()
.uid(uid)
.username("admin")
.password("123456")
.build();
}
@GetMapping("/users")
public List users(@RequestHeader("token") String token) {
// 模拟从数据中获取数据
ArrayList users = new ArrayList();
for (int i = 1; i 查看全部
解决方案:微服务远程调用组件Feign的使用详解
一、总结
我们知道目前最火、技术含量最高的技术就是SpringCloud微服务,那么今天一哥就带大家了解一下微服务的核心组件之一,Feign的基本使用及其工作机制。
二、Feign简介 一、概念
在学习如何使用Feign之前,我们先来了解一下什么是Feign。
Feign 是 Netflix 开发的声明式(目前由 Spring 维护)和模板化的 HTTP 客户端。Feign可以帮助我们更快速优雅的调用HTTP Api。
简单来说,Feign是一个远程服务调用的框架/工具,可以让开发者以更低耦合、更少代码、更快、更兼容的方式进行远程服务调用。
2.功能
了解了这些基本概念之后,接下来小编就带大家看看Feign组件是如何实现远程接口调用的。话不多说,我们直接上代码。
三、服务提供者 1、添加依赖
首先我们在父POM文件中添加核心依赖,如下:
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba-dependencies.version}
pom
import
然后在子POM文件中添加依赖如下:
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.配置文件
在 application.yml 文件中添加如下配置:
server:
port: 8090
spring:
application:
name: nacos-feign-example
cloud:
nacos:
discovery:
server-addr: 112.74.42.138:8848
3、创业班
项目的启动类代码如下:
@SpringBootApplication
public class NetflixFeignProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NetflixFeignProviderApplication.class, args);
}
}
4.控制层
我们可以写一个Controller控制器,定义web界面如下。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 模拟主键自增
*/
private AtomicInteger pk = new AtomicInteger();
<p>

@PostMappingpublic User save(@RequestBody User user) {
user.setUid(pk.incrementAndGet());
return user;
}
/**
* @param uid
* @return
*/@GetMapping("/{uid}")
public User user(@PathVariable("uid") int uid) {
return User.builder()
.uid(uid)
.username("admin")
.password("123456")
.build();
}
@GetMapping("/users")
public List users(@RequestHeader("token") String token) {
// 模拟从数据中获取数据
ArrayList users = new ArrayList();
for (int i = 1; i
解决方案:支付宝小程序:人脸采集
采集交流 • 优采云 发表了文章 • 0 个评论 • 406 次浏览 • 2022-11-23 09:41
产品描述
人脸识别是公共服务场所提高业务效率和用户体验的新途径。人脸采集是指在获得用户充分授权认可、充分保护用户隐私的前提下,获取符合质量要求的活人。人脸图片用于后续比对、识别等操作,提升商户服务质量。核心功能包括:
用户界面
调用过程
应用场景
人脸应用广泛,可应用于以下场景:
场景
描述
拍摄证件照
小程序提供拍摄证件照的功能,光线角度好。
团餐
在校园点餐场景中,录入学生人脸,用于刷脸点餐。
不建议使用通过人脸采集小程序返回给开发者的真人照片与开发者自己的比对源图在安全性较差的比对算法下进行身份验证。如果开发者需要验证身份,请使用支付宝身份验证?或其他开放通道人脸认证产品。由于支付宝身份验证产品拥有完备的风控体系和更安全的后台活体检测算法,具有非常强的抗攻击和防误识别能力。
注意:
小程序“人脸认证”开放能力全面升级为“支付宝认证”,推荐开发者使用“支付宝认证”能力;已签约上线“人脸认证”的小程序可继续使用。
访问要求
注意:
计费方式
自由的
接入指南第一步:创建小程序
要在您的小程序中使用人脸抓拍功能,您需要先完成开发者注册并创建一个小程序。
第二步:添加功能
小程序创建完成后,开发者可以在“能力列表”部分点击“添加能力”,为创建的小程序添加能力,如下图;开发者勾选人脸采集能力后,点击右下角的确定完成添加。
第三步:承包能力
人脸采集功能需要签名才能生效。请点击功能列表右侧的“立即注册”。签约成功后,状态会置为“Active”,即可调用人脸采集接口。
第四步:集成并配置SDK
服务端SDK需要商家在自己的服务端系统中集成,用于后续服务端接口调用。
下载服务端SDK
为了方便开发者调用开放接口,我们提供开放平台服务端SDK,包括JAVA、PHP、NodeJS、Python、.NET五种语言,封装了签名&验证、HTTP接口请求等基础功能,请下载相应语言版本的SDK并导入到您的开发项目中。
接口调用配置
在调用 SDK 之前需要对其进行初始化。以JAVA代码为例:
AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
关键参数说明:
配置参数
示例值解释
如何获取/示例值
网址
支付宝网关(固定)
APPID
创建应用后生成APPID
获取查看创建应用程序
APP_PRIVATE_KEY
开发者私钥,由开发者自己生成
获取配置密钥
格式
参数返回格式,只支持json
json(固定)
字符集
编码集,支持GBK/UTF-8
开发者根据实际工程代码进行配置
ALIPAY_PUBLIC_KEY
支付宝公钥,由支付宝生成
有关详细信息,请参阅配置密钥
SIGN_TYPE
商户生成签名串使用的签名算法类型。目前支持RSA2和RSA,推荐使用RSA2
RSA2
接下来就可以使用alipayClient来调用具体的API了。AlipayClient只需要初始化一次,后续调用不同的API可以使用同一个alipayClient对象。
注意:
ISV/开发者可以通过第三方应用授权获取商家授权令牌(app_auth_token)作为请求参数,实现代表商家发起请求的能力。
第五步:调用接口
调用流程图
调用 JSAPI (faceVerify) 调用人脸采集。整个采集过程完全由人脸执行。采集完成后,通过回调函数返回采集结果。在采集过程中,客户端完成人脸采集过程和活体检测,然后将采集到的人脸特征数据上传到服务器进行进一步的活体检测,最后将采集结果返回给客户端。
调用查询接口(zoloz.identification.user.web.query)获取可信的采集结果。如果采集成功,可以通过该接口获取采集到的人脸照片。
主要步骤
版本要求:
调用接口my.ap.faceVerify,传入参数bizId和bizType,即可触发人脸采集。采集完成后,通过回调函数获取采集结果。
请注意,在 my.ap.faceVerify 调用返回之前,切记不要发起第二次 faceVerify 调用,否则会产生异常。例如,如果您的小程序通过单击页面上的按钮触发对 my.ap.faceVerify 的调用,请确保在调用返回之前禁用该按钮,以防止用户进行多次单击。
代码示例
my.ap.faceVerify({ bizId: '545689787654767653', //业务流水号,商户自行生成,需要保证唯一性,不超过64位 bizType: '1', //业务场景参数,‘1’代表人脸采集,请务必填写 useBackCamera: true, //传入此参数会唤起后置摄像头;非必填,不传默认唤起前置摄像头 success: (res) => { my.alert({ content: JSON.stringify(res), }); }, fail: (res) => { my.alert({ content: JSON.stringify(res), }); }});
成功认证结果示例
faceRetCode = 1000表示人脸采集成功,调用查询接口(zoloz.identification.user.web.query)可以成功获取照片,证明人脸采集成功。
{ faceRetCode: "1000", retCode: "OK_SUCCESS", retCodeSub: "Z5100", retMessageSub: "成功 (Z5100)", zimId: "7b6b72be1493cab72dd0a25877de329dd00"}undefined
注意retCode表示人脸识别可用成功,只有人脸识别可用时才能进行人脸采集。
调用人脸采集查询接口(zoloz.identification.user.web.query)获取人脸照片。以下请求示例代码以JAVA为例:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");ZolozIdentificationUserWebQueryRequest request = new ZolozIdentificationUserWebQueryRequest();request.setBizContent("{" +""biz_id":"5456897876546767654"," +""zim_id":"731be7f204a962b0486a9b64ea3050ae"," +""extern_param":"{"bizType":"1"}"" +"}");ZolozIdentificationUserWebQueryResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}undefined
成功响应的示例
如果采集成功,则imgStr对象中的值为人脸照片的base64编码字符串。
{ "zoloz_identification_user_web_query_response": { "code": "10000", "msg": "Success", "extern_info": "{"imgStr":"ApA4VVwOP1rqp8sotrcimna3c__9k","bizId":"5456897876546767654-doucao.wjp","zimMsg":"成功","zimCode":"Z5130"}" }, "sign": "SL1dSiE6XKKIta5w3ge3VSZE+71CdBtr8Ocw9WvRSZD3Tz6/vNaA2pWLBYdZcvrAHaMYa6J8V9c4nY3kdBK0EeU2afh+8CLTw6dnZfkO8tR5NOtJUb+M6qhxl0xKhpE+2GUonpCcJg1MHS0aMVXa/b6dhK/yZJQCdO1YnVNuzs8="}
失败响应示例
{ "zoloz_identification_user_web_query_response": { "code": "40004", "msg": "Business Failed", "sub_code": "INVALID_PARAMETER", "sub_msg": "参数有误抱歉,系统出错了,请您稍后再试 (Z5132)" }, "sign": "v/DjkviKs2ja3HO9ZZ94W8bcfAsLyRuGrZT/TlFm6FgGQv4qSm/94o1FjOaMCl/t8XIm89bBhk03PBJ099alDzjnj4RD6S9FYDV7CfjvHYjrzvVJzn47Gc1mWdOHZ38DFQLWIg1IbNKFmYdoR+NdY5nY/cwz3Al2wfEylvN1cbs="}
API列表
接口英文名称
接口说明
我的.ap.faceVerify
人脸合集
zoloz.identification.user.web.query
人脸采集结果查询
常见问题:如果一个用户有多个支付宝账户,调用人脸识别验证接口时返回的user_id是否相同?
A:首先返回用户上次使用的支付宝账号对应的user_id。
Q:真机调试报错 "retMessageSub":"{"error":4,"errorMessage":"Not authorized to call","message":"Not authorized to call","signature"怎么办: “N22104”}?
A:人脸抓拍功能需要在小程序后台添加人脸抓拍功能包并签约使用。请参考此文档访问指南
解决方案:可视化采集器(智能化采集)
目录:
1、视觉采集软件
使用CSS选择器的采集软件可以准确的提取我们的网页元素。从用户体验的角度来看,XPATH有一个可视化的操作页面,让我们上手非常容易,但是为什么CSS选择器一直被我们的采集软件占用,虽然CSS的使用比较复杂,但是可以准确的捕捉一些元素XPATH 无法定位的文件。
2.可视化数据采集
所以大部分采集软件都是XPATH和CSS并存
3、智能采集系统
从网页元素提取的角度来看,CSS选择器和XPath选择器是一样的。它们都帮助我们定位网页中的相关元素,只是在语法表达上有所区别。从用户的角度来看,通过视觉抓取页面,我们可以完成80%以上的网站宣传页面数据抓取,少部分可以通过CSS选择器来补充。两个选择器的组合使我们能够覆盖各种类型的网页。
4、智能信息采集
5、智能采集设备
在搜索结果中查看网页时,我们注意到它们在链接下方收录
一小段信息。这称为“描述”。描述是 SEO 的有用工具。简短、朗朗上口的描述有助于说服用户点击文章。虽然元描述并非我们网站的所有 SEO 方面都是最终的,但最好将它们分类以防止出现任何错误。
6、智能采集摄像系统
它们需要有特定的长度才能在搜索引擎结果中完整显示,并且它们需要对每个页面和 关键词 都是唯一的
7.实时采集可视化工具
优化我们的内容,当我们制定内容 SEO 策略时,我们可能认为越多越好。定期发布新内容有助于吸引新访问者访问我们的网站并保持人们的参与度。然而,大多数时候,答案不是数量,而是质量。
8.数据采集
和可视化
这就是内容优化发挥作用的地方。这是查看我们网站上现有内容并询问“我如何才能更好地优化它?”的过程。这通常并不意味着重写整篇文章。相反,它涉及考虑内容的某些方面。我们是否选择了正确的字数?查看涵盖同一主题的成功文章并检查其字数。
9.如何持续采集
可视化
10、智能数据采集控制器
我们是否尽可能有效地使用 关键词?找到合适的 关键词 是内容营销的重要组成部分。但密度也很重要。确保避免过度使用 关键词。关键词 的更多实例并不意味着它的排名更好 - 事实上恰恰相反。
我们是否涵盖相关主题?最好的文章涵盖多个用户查询。查找其他相关主题以收录
在我们的文章中。在我们花时间优化一个页面之后,我们会想知道它的表现如何。SEO Tools 的 CSS 文章抓取软件使我们能够访问 SEO。活动进度更新。
我们可能已经努力为我们的网站创建内容,但如果我们要获得 SEO 回报,用户需要坚持下去。搜索引擎将“停留时间”描述为其主要的 SEO 优先事项之一。顾名思义,这是用户停留在页面上并阅读它的时候。文章时间
结合CSS选择器和XPATH选择器的文章合集软件分享到此结束。通过简单准确的网页内容提取,我们可以快速获取我们需要的公共数据和内容,从而提高我们的工作效率。如果你喜欢这篇文章,不妨采集
点赞。您的支持是博主不断更新的动力。
主题测试文章,仅供测试使用。发布者:小新SEO,转载请注明出处: 查看全部
解决方案:支付宝小程序:人脸采集
产品描述
人脸识别是公共服务场所提高业务效率和用户体验的新途径。人脸采集是指在获得用户充分授权认可、充分保护用户隐私的前提下,获取符合质量要求的活人。人脸图片用于后续比对、识别等操作,提升商户服务质量。核心功能包括:
用户界面
调用过程
应用场景
人脸应用广泛,可应用于以下场景:
场景
描述
拍摄证件照
小程序提供拍摄证件照的功能,光线角度好。
团餐
在校园点餐场景中,录入学生人脸,用于刷脸点餐。
不建议使用通过人脸采集小程序返回给开发者的真人照片与开发者自己的比对源图在安全性较差的比对算法下进行身份验证。如果开发者需要验证身份,请使用支付宝身份验证?或其他开放通道人脸认证产品。由于支付宝身份验证产品拥有完备的风控体系和更安全的后台活体检测算法,具有非常强的抗攻击和防误识别能力。
注意:
小程序“人脸认证”开放能力全面升级为“支付宝认证”,推荐开发者使用“支付宝认证”能力;已签约上线“人脸认证”的小程序可继续使用。
访问要求
注意:
计费方式
自由的
接入指南第一步:创建小程序
要在您的小程序中使用人脸抓拍功能,您需要先完成开发者注册并创建一个小程序。
第二步:添加功能
小程序创建完成后,开发者可以在“能力列表”部分点击“添加能力”,为创建的小程序添加能力,如下图;开发者勾选人脸采集能力后,点击右下角的确定完成添加。
第三步:承包能力
人脸采集功能需要签名才能生效。请点击功能列表右侧的“立即注册”。签约成功后,状态会置为“Active”,即可调用人脸采集接口。
第四步:集成并配置SDK
服务端SDK需要商家在自己的服务端系统中集成,用于后续服务端接口调用。
下载服务端SDK

为了方便开发者调用开放接口,我们提供开放平台服务端SDK,包括JAVA、PHP、NodeJS、Python、.NET五种语言,封装了签名&验证、HTTP接口请求等基础功能,请下载相应语言版本的SDK并导入到您的开发项目中。
接口调用配置
在调用 SDK 之前需要对其进行初始化。以JAVA代码为例:
AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
关键参数说明:
配置参数
示例值解释
如何获取/示例值
网址
支付宝网关(固定)
APPID
创建应用后生成APPID
获取查看创建应用程序
APP_PRIVATE_KEY
开发者私钥,由开发者自己生成
获取配置密钥
格式
参数返回格式,只支持json
json(固定)
字符集
编码集,支持GBK/UTF-8
开发者根据实际工程代码进行配置
ALIPAY_PUBLIC_KEY
支付宝公钥,由支付宝生成
有关详细信息,请参阅配置密钥
SIGN_TYPE
商户生成签名串使用的签名算法类型。目前支持RSA2和RSA,推荐使用RSA2
RSA2
接下来就可以使用alipayClient来调用具体的API了。AlipayClient只需要初始化一次,后续调用不同的API可以使用同一个alipayClient对象。
注意:
ISV/开发者可以通过第三方应用授权获取商家授权令牌(app_auth_token)作为请求参数,实现代表商家发起请求的能力。
第五步:调用接口

调用流程图
调用 JSAPI (faceVerify) 调用人脸采集。整个采集过程完全由人脸执行。采集完成后,通过回调函数返回采集结果。在采集过程中,客户端完成人脸采集过程和活体检测,然后将采集到的人脸特征数据上传到服务器进行进一步的活体检测,最后将采集结果返回给客户端。
调用查询接口(zoloz.identification.user.web.query)获取可信的采集结果。如果采集成功,可以通过该接口获取采集到的人脸照片。
主要步骤
版本要求:
调用接口my.ap.faceVerify,传入参数bizId和bizType,即可触发人脸采集。采集完成后,通过回调函数获取采集结果。
请注意,在 my.ap.faceVerify 调用返回之前,切记不要发起第二次 faceVerify 调用,否则会产生异常。例如,如果您的小程序通过单击页面上的按钮触发对 my.ap.faceVerify 的调用,请确保在调用返回之前禁用该按钮,以防止用户进行多次单击。
代码示例
my.ap.faceVerify({ bizId: '545689787654767653', //业务流水号,商户自行生成,需要保证唯一性,不超过64位 bizType: '1', //业务场景参数,‘1’代表人脸采集,请务必填写 useBackCamera: true, //传入此参数会唤起后置摄像头;非必填,不传默认唤起前置摄像头 success: (res) => { my.alert({ content: JSON.stringify(res), }); }, fail: (res) => { my.alert({ content: JSON.stringify(res), }); }});
成功认证结果示例
faceRetCode = 1000表示人脸采集成功,调用查询接口(zoloz.identification.user.web.query)可以成功获取照片,证明人脸采集成功。
{ faceRetCode: "1000", retCode: "OK_SUCCESS", retCodeSub: "Z5100", retMessageSub: "成功 (Z5100)", zimId: "7b6b72be1493cab72dd0a25877de329dd00"}undefined
注意retCode表示人脸识别可用成功,只有人脸识别可用时才能进行人脸采集。
调用人脸采集查询接口(zoloz.identification.user.web.query)获取人脸照片。以下请求示例代码以JAVA为例:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");ZolozIdentificationUserWebQueryRequest request = new ZolozIdentificationUserWebQueryRequest();request.setBizContent("{" +""biz_id":"5456897876546767654"," +""zim_id":"731be7f204a962b0486a9b64ea3050ae"," +""extern_param":"{"bizType":"1"}"" +"}");ZolozIdentificationUserWebQueryResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}undefined
成功响应的示例
如果采集成功,则imgStr对象中的值为人脸照片的base64编码字符串。
{ "zoloz_identification_user_web_query_response": { "code": "10000", "msg": "Success", "extern_info": "{"imgStr":"ApA4VVwOP1rqp8sotrcimna3c__9k","bizId":"5456897876546767654-doucao.wjp","zimMsg":"成功","zimCode":"Z5130"}" }, "sign": "SL1dSiE6XKKIta5w3ge3VSZE+71CdBtr8Ocw9WvRSZD3Tz6/vNaA2pWLBYdZcvrAHaMYa6J8V9c4nY3kdBK0EeU2afh+8CLTw6dnZfkO8tR5NOtJUb+M6qhxl0xKhpE+2GUonpCcJg1MHS0aMVXa/b6dhK/yZJQCdO1YnVNuzs8="}
失败响应示例
{ "zoloz_identification_user_web_query_response": { "code": "40004", "msg": "Business Failed", "sub_code": "INVALID_PARAMETER", "sub_msg": "参数有误抱歉,系统出错了,请您稍后再试 (Z5132)" }, "sign": "v/DjkviKs2ja3HO9ZZ94W8bcfAsLyRuGrZT/TlFm6FgGQv4qSm/94o1FjOaMCl/t8XIm89bBhk03PBJ099alDzjnj4RD6S9FYDV7CfjvHYjrzvVJzn47Gc1mWdOHZ38DFQLWIg1IbNKFmYdoR+NdY5nY/cwz3Al2wfEylvN1cbs="}
API列表
接口英文名称
接口说明
我的.ap.faceVerify
人脸合集
zoloz.identification.user.web.query
人脸采集结果查询
常见问题:如果一个用户有多个支付宝账户,调用人脸识别验证接口时返回的user_id是否相同?
A:首先返回用户上次使用的支付宝账号对应的user_id。
Q:真机调试报错 "retMessageSub":"{"error":4,"errorMessage":"Not authorized to call","message":"Not authorized to call","signature"怎么办: “N22104”}?
A:人脸抓拍功能需要在小程序后台添加人脸抓拍功能包并签约使用。请参考此文档访问指南
解决方案:可视化采集器(智能化采集)
目录:
1、视觉采集软件
使用CSS选择器的采集软件可以准确的提取我们的网页元素。从用户体验的角度来看,XPATH有一个可视化的操作页面,让我们上手非常容易,但是为什么CSS选择器一直被我们的采集软件占用,虽然CSS的使用比较复杂,但是可以准确的捕捉一些元素XPATH 无法定位的文件。
2.可视化数据采集
所以大部分采集软件都是XPATH和CSS并存
3、智能采集系统
从网页元素提取的角度来看,CSS选择器和XPath选择器是一样的。它们都帮助我们定位网页中的相关元素,只是在语法表达上有所区别。从用户的角度来看,通过视觉抓取页面,我们可以完成80%以上的网站宣传页面数据抓取,少部分可以通过CSS选择器来补充。两个选择器的组合使我们能够覆盖各种类型的网页。
4、智能信息采集

5、智能采集设备
在搜索结果中查看网页时,我们注意到它们在链接下方收录
一小段信息。这称为“描述”。描述是 SEO 的有用工具。简短、朗朗上口的描述有助于说服用户点击文章。虽然元描述并非我们网站的所有 SEO 方面都是最终的,但最好将它们分类以防止出现任何错误。
6、智能采集摄像系统
它们需要有特定的长度才能在搜索引擎结果中完整显示,并且它们需要对每个页面和 关键词 都是唯一的
7.实时采集可视化工具
优化我们的内容,当我们制定内容 SEO 策略时,我们可能认为越多越好。定期发布新内容有助于吸引新访问者访问我们的网站并保持人们的参与度。然而,大多数时候,答案不是数量,而是质量。
8.数据采集
和可视化
这就是内容优化发挥作用的地方。这是查看我们网站上现有内容并询问“我如何才能更好地优化它?”的过程。这通常并不意味着重写整篇文章。相反,它涉及考虑内容的某些方面。我们是否选择了正确的字数?查看涵盖同一主题的成功文章并检查其字数。
9.如何持续采集
可视化

10、智能数据采集控制器
我们是否尽可能有效地使用 关键词?找到合适的 关键词 是内容营销的重要组成部分。但密度也很重要。确保避免过度使用 关键词。关键词 的更多实例并不意味着它的排名更好 - 事实上恰恰相反。
我们是否涵盖相关主题?最好的文章涵盖多个用户查询。查找其他相关主题以收录
在我们的文章中。在我们花时间优化一个页面之后,我们会想知道它的表现如何。SEO Tools 的 CSS 文章抓取软件使我们能够访问 SEO。活动进度更新。
我们可能已经努力为我们的网站创建内容,但如果我们要获得 SEO 回报,用户需要坚持下去。搜索引擎将“停留时间”描述为其主要的 SEO 优先事项之一。顾名思义,这是用户停留在页面上并阅读它的时候。文章时间
结合CSS选择器和XPATH选择器的文章合集软件分享到此结束。通过简单准确的网页内容提取,我们可以快速获取我们需要的公共数据和内容,从而提高我们的工作效率。如果你喜欢这篇文章,不妨采集
点赞。您的支持是博主不断更新的动力。
主题测试文章,仅供测试使用。发布者:小新SEO,转载请注明出处:
解决方案:labview100个实例之简单采集(2)
采集交流 • 优采云 发表了文章 • 0 个评论 • 131 次浏览 • 2022-11-23 08:27
目录
提示:文章写完后,目录可以
前言
之前做过一个很简单的程序,但总觉得不能体现labview真正的特点,所以打算做一个系列,让一些初学者容易理解这些。首先是模块化和功能封装的概念。
1.例子
这是一个完整的主程序框图,可以清楚的看到分为两大区域——“参数”设置区和“主界面”。主界面收录
四个区域,分别是修改频率较高的参数区、控制区(启停)、状态区和显示区。用于采集一段时间内的声音和电流信号。
运行效果为:
设置采集条件和数据存储路径,通过按钮控制采集的开始,程序按照指定的采样率采集一段时间的信号并保存时域数据(原创
数据,方便后期数据处理)。如果可能,你可以尝试运行一下来测试一下效果。
模块化与功能封装.zip-MCU文档资源-CSDN文库
2. 模块化与功能封装 1. 模块化
Labview的一大特点是程序往往以模块化的方式构建,也就是常说的子VI。
2.功能封装
如图所示,此时我们说这个程序使用了三个子VI,分别封装了采集、回放、存储三个功能。
在制作子VI时,需要明确需要封装的函数,输入输出的数据类型。在保证通用性的前提下,主程序框图应该是最简洁的。
总结
本例主要是简单说明Labview中子VI的功能以及函数封装的方便性。当我们创建一个子VI并赋予它特定的功能时,我们可以很方便地在项目的任何地方调用它,而不需要再次编辑重复的代码。
特别注意的是,当一个子VI被我们封装后,理论上我们可以直接在本程序中调用。但往往在一个大型项目中,一些子VI因为其功能而被频繁使用,我们需要考虑是否要重复调用它们。重复调用是指我们在某个时间多次调用同一个子VI,程序会等待并逐次执行每次调用,导致程序运行时间发生变化甚至数据冲突(因为一般一个子VI计算机只分配一块内存空间 同时调用时,我们不知道谁先调用并输出结果)。
我们可以在VI的属性——“执行”栏中将VI设置为可重入VI。这样,程序运行时,当在多个地方同时调用这个VI时,会创建不同的工作区,多个调用者的数据会分别存储,不会发生冲突和干扰。
★ 范例中提到的结构、文件、信号处理和信号分析的范例版本及后续计划为17版本,如需降级请及时联系我们。
解决方案:采购内容及技术要求
一、采购要求
一、项目建设背景
政府网站是现代政府在信息化条件下政府密切联系人民群众的重要桥梁,是网络时代政府履行职责的重要平台,是各级政府机关提供信息公开、回应关切、办事服务、互动交流的重要载体。近年来,党中央、国务院、四川省政府高度重视政府网站建设和管理工作,先后下发了多项关于加强政府网站建设的管理规定。从2015年4月起,国务院开展了全国政府网站普查工作,对政府网站的建设起到了前所未有的推动作用。
2017年5月,《国务院办公厅关于印发政府网站发展指引的通知》(国办发〔2017〕47号)发布,对政府网站集约化建设提出了详细的建设要求。德阳市政府网站集约化建设项目将以此为依据,并根据《四川省人民政府办公厅关于加强政府网站信息内容建设的实施意见》(川办发〔2015〕53号)和《德阳市人民政府办公室关于进一步做好“互联网+政务服务”有关工作的通知》(德办函〔2016〕99号)以及政府网站绩效考核的要求,以问题和需求为导向,以为民服务为根本宗旨,顺应公众的期盼,按照利企便民的原则,树立“以信息公开为基础、公共服务为核心”的理念,积极推进政府网站集约化平台建设、应用新技术拓展服务渠道,以增强网站用户体验、提高办事服务、实现信息共享,为公众提供优质、便捷、高效服务。
二、项目建设目标
根据国家和四川省政府网站绩效考核指标及其他相关政策文件中对“互联网+”环境下政府网站的定位,借鉴国内外领先政府网站的先进经验和趋势特点,以“技术先进、功能完备、服务智能、安全稳定”为建设原则,着重新技术应用,基于大数据平台,采用移动互联网等技术手段,建设德阳智慧型、实用化、个性化、集约化网站群管理平台,最终实现德阳市政府门户网站、40个市级部门网站(含德阳经开区网站、德阳高新区网站)、6个县(市、区)政府门户网站的集约化建设工作。建设总体目标如下:
1. 加强信息资源整合,搭建全市统一的政府网站信息资源库,有效管理全市政府网站信息资源。
2. 建立信息支撑体系,提供网站信息采集技术,丰富网站信息供给手段。能够通过集约化平台集中实现采集、发布信息和数据,实现主站与子站、子站与子站、子站与栏目和市级部门子站与县级部门专栏等之间的互联互通、信息复用,为信息公开提供平台支撑,充分发挥政府网站在政务公开中第一平台的作用。
3. 加强网站智能化建设,提供智能搜索、智能问答、智能推荐和无障碍访问等功能。可根据用户需求调整搜索排序、聚合相关服务等,实现“搜索即服务”。主动为社会公众提供智能、实用、便捷、精准、高效的网站服务,提升政府网站的公共服务能力和水平。
4. 建立健全网站内容保障监管体系,加强网站的运维、监管手段,提供切实有效的网站运维、监管能力,及时发现网站存在的问题。保证网站运行安全、稳定,服务内容全面、准确。
5. 提供统一、完善的网站互动交流功能,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。
6. 注重政务微博、微信等互联网新技术的应用,加强对移动终端应用功能的支持,丰富公众访问渠道,有效提高用户体验。
7.能够通过“深度链接”、各类接口整合等方式,实现全市统一的办事服务入口和数据开放入口;与有效与四川省政府信息公开目录管理系统、四川省一体化政务服务平台、德阳市政务信息资源共享平台等进行整合和对接,最终实现平台互联互通、信息资源共享。
8.围绕2018年国家和四川省政府网站绩效评估指标体系,对网站建设进行升级优化,提升德阳市政府门户网站排名,力争进入省内前10名;加强网站建设的方向性引导、有效激励服务改进措施,保障网站持续发展。
三、总体技术要求
(一)软件产品技术要求
1.本次项目的投标商必须采用先进且成熟的技术和产品,主要产品应具有云平台部署成功案例。
2.软件产品应具有网站集群化平台建设能力。
3.系统需支持大量用户访问和海量数据的存储、检索和管理,平台功能部署灵活统一。
4.产品具有安全、可优化、可扩展性能,易于二次开发,应免费提供接口。
5.系统应采用J2EE或其他符合行业发展方向的先进技术架构;
6.系统应用结构体系的表示层、业务层、数据层、访问层应分开,支持分布式部署,支持无限站点扩展;
7.系统应支持Oracle、MySQL、Microsoft SQL Server等主流数据库系统和主要国产化数据库系统;
8.网站系统兼容性强,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
9.系统支持双机热备部署模式。
(二)运行性能指标
1. 在网络稳定的环境下,系统后台单一操作的响应时间小于3秒;网站页面访问响应时间小于1秒。
2. 网站满足并发访问用户数不低于10000的访问请求。
3. 支持初始数据量不少于100万记录数,支持表空间自动扩充。
4. 系统能够实现满足网站面向服务的目标,最终实现服务化、构件化、松耦合的SOA体系架构。
5. 系统提供7×24小时的连续运行,平均系统年故障时间≤2个小时,平均故障修复时间≤30分钟。
6. 网页代码和标记设计尽可能简化,以节约带宽。
7. 网站要提供不间断服务,支持信息多个站点同时发布功能,单个站点故障或更新维护等不能影响其它站点的正常使用。
(三)安全性能要求
1. 系统应支持分布式部署,系统应支持静态页面发布。
2. 系统应建立基于角色和工作分工的权限控制机制,重要信息需具备有效的加密方式进行传递;系统应提供数据自动非本机转储备份和故障恢复等应急响应功能,具备完善的日志记录、审计和数据备份功能。
3. 具备良好的数据库安全策略。系统安全设计符合《计算机信息系统安全保护等级划分准则》(GB17859-1999)第三级(安全标记保护级)要求。
四、建设内容及功能性需求
此次项目招标主要目的是规划、搭建好德阳市政府网站集约化平台,并完成“中国·德阳”网的改版和40个市级政府部门网站(含德阳经开区网站、德阳高新区网站)的集约化建设,但不包括德阳市6县(市、区)政府门户网站集约化建设内容。德阳市政府网站集约化平台将部署在德阳市政务云上。具体建设内容如下:
(一)统一用户管理系统
将德阳市使用站群系统的所有用户统一管理起来,实现用户的属性管理,并将用户与组织机构相关联。
用户管理,提供对用户的增、删、改,可禁用和启用用户帐号,设置用户拥有的功能权限;可自定义用户组织架构;用户组管理,提供对用户组的增、删、改,设置用户组拥有的功能权限。
(二)信息资源库系统
以整合德阳市所有政府网站资源实现共享为目标,建设集约化网站信息资源库,实现对信息资源的统一分类、统一展现、统一监管及各模块之间的无缝调用,有效解决平台建设资源共享的问题。
1. 要求针对信息资源库建设提出相应的解决方案和产品,满足结构化和非结构化数据的数据库建设。
2. 要求系统提供标准管理体系,即涵盖已经发布的国家标准、企业标准、行业标准和地方标准,也可以管理系统自定义的数据字典。
3. 要求系统具有资源库管理,数据元管理,数据集管理,表单管理等数据库基础应用组件。
4. 要求系统提供分类管理能力,分类管理包括数据元分类管理,数据分类管理。
5. 要求系统提供资源管理能力,系统提供基本的数据录入功能,也可以使用数据交换平台,通过WebService或ETL工具进行数据交换。
6. 要求系统提供共享管理能力,包括:自定义分组管理,共享维护,共享授权。共享授权实现数据分级管理,可以对用户授权,也可以对分组授权。
7. 要求系统提供系统管理能力,包括用户管理,角色管理,授权管理,日志管理。
(三)集约化网站监管平台
以“统一标准体系、统一技术平台、统一安全防护、统一运维监管,集中管理信息数据,集中提供内容服务”为目标,结合网站属地化管理体系,建设德阳市政府网站集约化管理平台,实现站点管理、规范性检查、网站普查指标自检、网站访问监控、网站维护监控、网站运行监控等功能,满足网站集约化统一管理要求。具体功能如下:
1.站点监管
(1)提供站群系统内各子站基本信息管理功能,包括管理的站点名称、站点域名、站点描述信息、主办单位及联系人信息、网站备案信息等。
(2)按照《政府网站发展指引》要求提供各项网站规范性的监测功能,包括名称规范、域名规范、备案信息规范、模板规范、标签规范、栏目规范等一致性检查、冗余检查、属地化监测等。
2.网站普查指标监测
根据网站普查要求,提供网站指标监测功能,包括网站可用性监测、存在错误页面分析、页面关联分析、空白栏目监测、栏目更新频率监测、网站外链监测、敏感词及错别字扫描等。
3.网站访问监测
根据网站实际运行情况,可数字化或图表化展现网站运行监控的各项访问指标,可对指定时间段的访问情况进行统计、分析,并能生成统计分析报告(表)进行打印或导出。监测功能及内容如下:
(1)搜索引擎监控:包括访问人次、站内搜索次数、搜索结果点击次数、搜索结果点击率、搜索引擎排行、网站检索词排行等。
(2)网站访问监控:包括访问渠道、浏览量、访客数、平均停留时间、日访问变化趋势图等;
(3)浏览页数性能监控:包括系统连接时间、响应时间、下载时间以及无法访问次数等;
(4)智能报警策略:包括故障的持续时间、问题严重性分级、分类报警,报警通知方式支持邮件、短信等。
4.网站维护监测
(1)针对网站内容管理进行数据分析,包括网站栏目(栏目访问量、栏目信息量、栏目参与部门数和栏目参与人员数等)、部门信息(部门信息发布量、部门业务办理量和部门业务办结率等)和公共诉求(诉求目的、诉求内容分类、处理单位、满意度等)等数据的统计分析功能。
(2)提供系统站内通知功能,可对系统内各用户发送消息,解决系统管理人员日常工作沟通及信息共享。
5.网站运行检测
(1)支持对服务器硬件层进行监控,包括服务器的工作状态、处理器、内存、进程等。
(2)提供灵活、全面、便捷的监控方式,监管页面秒级刷新,运行高效、安全可靠。
6.系统日志管理
提供系统日志的管理界面,能详细记录系统操作日志,并形成日志信息或日志文件,可对日志文件进行导出。
(四)网站群管理平台
以站点管理为重点,支持集中式建设部署和分布式管理维护。
支持对历史信息的调入、调出,提供对信息的全流程跟踪管理。
支持与其它平台的无缝对接。系统接口可开放,支持网站扩展功能模块的安装调试,具有高集成、可扩展、易管理等特性。
采用XML、WebService等标准,提供组件化的统一数据接口,有效实现信息的采集、聚合。
1.站群管理系统
(1)要求实现页面展现与信息分离,删除或修改网页模板时不会对信息造成影响。
(2)站群管理系统支持站群下所有子站点的创建、修改、暂停、删除及服务器资源配置。
(3)系统提供多级授权分层管理机制,每个子站点都提供独立的站点管理功能,站点管理人员能够对子站点进行角色权限管理、资源管理、用户权限管理及站点统计等操作,保证用户在统一的平台下独立管理自己的子站点。
(4)站群系统内各站点之间可以共享数据源,保证各站点信息的一致性。
(5)系统支持密码强度管理、CA绑定等安全策略。
2.站点管理系统
(1)网站信息的发布具有静态信息发布和动态信息发布相结合的发布模式,用户可根据实际需要选择发布方式,以同时满足网站访问速度、并发访问量及网站交互功能的多重需求。
(2)系统支持对多种信息格式的发布,包括音频、视频等多媒体格式。
(3)系统支持增量发布与完全发布,支持定时发布和立即发布,可根据需要自定义发布方式。
(4)系统提供统一用户验证功能,通过账号、密码、验证码相结合的方式登陆到系统管理界面。
(5)内容维护人员只能对自己权限范围内的内容进行管理,无权看到并操作其他用户管理的内容。
(6)系统详细记录所有用户的系统操作,以便于查询和管理。
(7)系统提供权限组功能,具有相同权限的用户可划分为同一权限组。权限的分配可以详细到每一个栏目。
(8)提供系统登陆账号长时间无操作的自动注销功能,可自行设置注销时间。
(9)系统可根据自定义备份策略(如异地备份、定时备份等)进行站点数据备份,能对备份文件进行删除、下载、恢复管理。
3.内容管理系统
(1)具有网站内容采集、在线编辑、审核发布、敏感词过滤、错别字检测等功能,提供可视化编辑器,实现“所见即所得”的信息录入、编辑效果。
(2)支持文档录入、发布、预览、修改、删除等操作,拥有丰富的文档引用、复制、链接、移动、同步等操作功能。
(3)内容编辑器具有多图片上传、word和pdf等文档导入、一键排版、格式清理、去除空行、首行缩进等常用功能;
(4)各子站点具有独立、完善的信息采集、编发功能,可根据用户权限进行跨栏目、跨站点信息推送与共享。
(5)支持信息发布过程中的多级审核管理,能够针对不同站点、不同栏目设置不同审核流程;
(6)支持前台页面样式由模板进行控制,模板提供代码级修改,模板管理支持标签语法,模板可嵌套模板,也可嵌套标签;
(7)网站栏目能够自由移动,可定制栏目信息发布类型,可按权限获取不同栏目、不同站点(如内容管理系统、信息公开系统)的信息;
(8)信息录入具备文章、组图、链接、视频四种类型,能够对普通文本、图
片信息和音视频等多种流媒体信息进行发布和管理,满足信息多样化的需求;
(9)支持站点发布、分级栏目发布、信息单独发布等操作,并可以指定文档发布后在页面显示的顺序;
(10)支持静态发布、动态发布和动态静态相结合的发布方式。
(五)政府信息公开管理系统
根据部门业务和网站功能特点进行科学分析、认真梳理,合理规划频道和栏目,与四川省政府信息公开目录管理系统进行数据对接,有效实现德阳市政府信息公开数据在网站上的聚类、共享、展示。
(1)该系统必须完全符合《政府信息公开目录系统实施指引(试行)》(国办秘函[2009]6号)文件中的各项要求。
(2)要求系统提供灵活的元数据管理,以能适应不同类型的信息记录需要,元数据必需符合国家相关文件的要求,并具备元数据扩展功能;提供对多种类型的元数据字段支持。定义数据层、功能层、使用层规范,同时配以编码规则管理,支持批量修改,保持良好的扩展性;
(3)要求系统提供灵活的分类管理,可自由地将采集到的信息进行多渠道分类,包括主题分类、机构分类、体裁分类及服务对象分类。同时支持分类的自由扩展。
(4)要求系统提供灵活的目录管理功能,用户可根据公众的需要定义目录的展现内容,通过定义目录节点的生成规则,从而来获取相应的数据,形成最终的人性化目录;系统支持目录推荐功能,即上级政府建立完成的目录,可以作为“模板”推荐给下级单位。
(5)要求系统能够自定义索引号编码规则,依照信息公开标准对信息进行自动编码,生成信息索引号。当编码规则发生修改时,也可制定新规则,并批量修改信息索引号。
(6)要求系统提供良好的信息管理功能,从采集、标引、审核、发布到归档,完整记录信息生命周期活动。
(7)系统提供列表、简要、细览等展现形式,显示核心元数据,包括索引号、名称、内容概述、生成日期、文号等。
(8)系统应满足信息录入和审核权限的逐级分配,强化信息源头管理,保障信息发布安全。
(9)系统具有依申请公开功能,可对依申请公开信息进行接收、受理、审核、发布,并提供统计分析等功能,访问用户可实时查询依申请公开处理状态。
(10)要求系统提供综合的绩效评估模式,包括信息公开工作量评估、依申
请公开办结率和办结质量评估。
(六)互动交流系统
系统严格遵循SOA模块化设计思想,按照“高内聚,低耦合”原则,提供全面完善的网站互动交流功能,包括领导信箱、民意征集、在线调查、咨询投诉、网上信访、在线访谈等,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。具体功能要求如下:
1.在线访谈系统
(1)支持图文和视频同步的在线访谈,要求具有文字直播、图片直播、音频直播及视频直播四种功能形式;
(2)要求提供良好的人机对话界面,网友通过文字形式可实时提问,管理人员采集
和审核问题,主持人转达和引导提问,嘉宾对问题实时解答;
(3)管理员可查看在线用户情况,可以通过IP或用户名来禁止用户行为,可对用户发言内容设置过滤模式。
(4)主持人、嘉宾与网友的发言区要划分明确;
(5)系统必须具有访谈预告功能,访谈预告可采用文字、图片或视频方式展示访谈背景和相关资料。
(6)访谈过程中要确保文字、图片、音频、视频的流畅;
(7)对于历史访谈,可按照日期进行归档,形成历史访谈目录,网友可调阅历史访谈。
(8)对于已经完成的访谈,管理员可继续对访谈内容进行修改和编辑。
2.领导信箱系统
(1)系统具有工作流管理功能,可自定义信件办理流程,实现从受理、转办、承办、退回、办结的全流程管理。
(2)系统具有信件办理状态实时查询功能,来信人可根据信件编码、姓名、联系电话等对信件办理状态进行查询,信箱管理人员可通过关键字、信件编码、时间、部门、信件状态等条件进行查询。
(3)前台提供“信件选登”、“信件查询”、“我要写信”等功能,写信内容需收录
姓名、昵称、身份证号码、联系电话、电子邮件、信件标题、信件内容,可上传附件材料等,具有详实的展现形式,可对敏感词进行自动屏蔽。
(4)后台提供信件的回复、发布、选登等状态的查看及信件办理状态的统计功能,提供信件的“公开/不公开”选项功能。
3.意见征集系统
(1)针对社会公众关注的热点问题或者政策制定和工作成果开展民意征集活动,民意征集的各个主题要求布局清晰、合理,方便阅览;
(2)网友可根据征集主题的内容和背景资料发表自己的建议和观点,可以查看征集结果;
(3)系统后台可实时查看所有社会公众提交的意见和建议;
(4)意见征集结束后,前台只保留征集主题、内容、结果,网友不能再进行意见和建议的提交;
(5)能对网友发表的文字信息进行安全性检查。
4.网上调查系统
(1)管理员可根据不同的调查内容新建、修改、删除调查问卷。对于每个调查问卷可以对标题、摘要、内容、选项、调查项组成结构等进行管理,可灵活设计投票问卷风格;
(2)同一调查主题,可设置多个调查项;调查项应包括单选项调查、多选项调查、附加选项(填空)等调查类型;
(3)同一IP地址在设定时间内只允许提交一次投票,杜绝恶意投票行为发生;
(4)投票结果可通过表格、柱状图、饼图等形式进行展现。
(七)数据采集系统
(1)数据采集系统借助先进的信息抓取、信息分类和信息流转技术,实现对指定网站信息(包括但不限于中央政府网站、省政府网站、重要新闻网站和平台内外所需政府信息资源)的更新监测和有效采集。
(2)系统按照不同需要,可定点、定时监测和采集所需信息,并下载信息的图片、视频及附件等相关文件,将采集信息进行准确分类、整理、筛选,通过内容推送功能自动推送到指定栏目。
(3)管理员可在后台设置抓取的范围、关键字、抓取时间等参数,系统根据设置好的抓取策略进行信息自动抓取。
(4)用户可对采集到的信息按照日期、来源、标题进行检索、浏览;可以对信息内容与图片分类保存,支持信息分类的自定义。
(5)系统支持将网页中的信息内容按标题、作者、栏目、内容等进行提取;自动过滤网页中的无用信息、广告图片等,自动过滤重复的信息。
(6)对采集的信息可进行二次编辑、审核,可向网站群内各个子站栏目进行发布。
(八)无障碍浏览系统
(1)面向听力、视力等有障碍的特殊人群提供缩放字体、缩放页面、辅助光标、文本化网页和语音个性化调整等辅助浏览功能。
(2)具有全程自动语音提示、全程语音导航交互、光标语音指读与连读、文
字放大阅读专用屏、网页图文放大缩小、高对比阅读配色器、阅读辅助光标等功能。
(3)系统需界面友好、易操作,无需安装插件,支持各种主流浏览器。
(九)智能检索系统
(1)提供专业的政府网站检索功能,对政府网站检索进行分类引导,按照政策法规、办事事项、政府文件、新闻咨询等类别对用户检索内容进行归类整理,清晰引导用户进行查阅。
(2)数据检索范围应包括站群内各业务部门、各县(市、区)网站站点,可对不同类型数据源的数据进行检索。
(3)满足即搜即用原则,支持图片、视频格式信息的检索。
(4)支持关键字搜索、日期搜索。要求提供个性化检索结果功能,如检索结果分类导航展现、检索结果按不同维度(可以按系统,站点,栏目,区县,文档类型,时间单位,相似度等)过滤展示,检索结果可进行二次搜索。
(5)具有搜索关键词自动补全能力,动态分析公众搜索关键词,按照关键词的内在逻辑关系进行自动匹配,给出搜索提示,纠正用户输入错误。
(6)具有热词自动排序和显示功能,可自动统计搜索关键词的搜索频度,将某一时间段内搜索量较高的关键词作为搜索热词,并根据热度动态自动调整排序。
(7)支持拼音搜索功能,采用词语智能拼音匹配模式,并结合关键词提醒联想功能,实现拼音和中文友好联系的搜索功能。
(8)系统支持管理员定义屏蔽词和停用词的搜索,当用户输入收录
的词汇时,系统不展示搜索结果信息。
(9)支持多个关键词搜索和整句搜索。
(10)系统使用基于文档语义的技术实现同一站点内搜索结果信息的自动排重,即“相同”的文档在索引过程中仅被索引一次,解决大量相同文档的搜索问题,提高索引效率,帮助用户快速找到搜索结果。
(11)对含有图片的信息,其搜索结果列表应显示其缩略图;
(12)系统具有检索结果优先显示置顶功能。
(十)智能推荐系统
(1)根据网站用户访问行为,结合网站数据分析,找到网站访问热点,自动聚合相关信息(即相关文件、政策、咨询类信息),实现网站信息智能推荐。
(2)可根据关键词、热词等条件分析信息之间的直接联系或间接关系,自动分析、梳理、聚类展示。
(3)可自动进行专题信息汇聚,通过数据采集技术,获取相关信息进行集中
管理和存储,根据用户访问习惯,进行数据的重组、拼装,聚合,形成专题栏目;也可根据各专题的关注度,对推荐专题及相应的页面表现位置进行展示顺序的自动调整,供公众访问。
(十一)智能问答系统
(1)能够深度挖掘网站群信息内容,建立和完善智能应答知识库,可根据用户自定义规则,通过信息聚合技术,按照信息采集、聚合、挖掘和检索流程,实现跨部门、跨行业的信息整合与资源共享。
(2)能够自动将咨询问题保存入库,可自定义站点检索到相关咨询问题,可实时预处理用户的输入信息,根据输入内容与后台检索引擎交互,自动纠错,实时提示相关信息,引导类似问题进行解答。
(3)可利用信息资源库及应答知识库中的信息,即时自动回答用户提出的问题,向用户展示相关度较高的信息。
(4)能够充分使用站群内所有站点的信息资源,咨询问题答复内容可由平台下多个站点信息数据组成关联页面提供给用户。
(5)能够实现多样化展现方式,可以预分类政务资源,将多个网站中的同类栏目合并为一个分类,为用户按分类展现更全面精准的搜索结果。
(6)要求具备自学习功能,能够自动丰富知识库,对于无法解决的问题可自动转人工解答。
(十二)移动门户系统
(1)要求采用HTML5网站页面应自适应技术,能够实现不同移动终端(例如苹果、安卓系统) 访问移动门户时自适应展示,能够在各种访问终端下保持完整良好的页面布局和内容可读性。
(2)要求移动端与PC端使用同一域名进行访问,系统自动识别访问终端并自适应页面展示效果。
(3)要求移动门户所展示信息不再二次录入,统一由站点内容管理系统提供,以保证数据来源的统一性。
(4)要求提供最新新闻、政务公开、互动交流、解读回应、民意调查、舆论引导、政务服务、政府办公等信息内容的展示。
(5)要求支持可定制栏目访问。
五、其他需求说明
1.网站兼容性要求
要求网站页面具有很好的兼容性,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
2.UI/UE设计
(1)界面设计需要突出地方特色
(2)文字,图形色彩统一,搭配合理,界面清楚整洁,层次结构清楚。
(3)统一首页和其他各级页面的排版风格。
(4)页面富有时代气息和美感,色彩搭配稳重、合理、大气。
(5)多媒体、动画页面要求丰富而生动。
3.子站设计要求
(1)满足各子站个性化页面设计需求,根据各部门网站管理人员要求进行设计与实施。
(2)本次页面设计主要从以下几个方面进行规划:页面风格、页面人性化和易用性、页面内容、页面结构等,围绕信息公开、办事服务、互动交流等功能定位,设计门户网站页面框架,清晰、合理、科学展现网站内容,避免累赘和页面冗余。
4.历史数据迁移要求
(1)要求提出详尽的网站数据迁移方案。
(2)要求将实施集约化的网站的全部数据,收录
各站点栏目信息、新闻信息、公开信息、互动信息、用户信息、用户对应权限、图片、附件、多媒体文件等数据平稳迁移至德阳市政府网站集约化平台,确保不丢失任何有效数据,处理好新网站栏目信息与历史数据的对应关系。
(3)要求保证集约化网站切换的平滑过渡,做好数据的同步更新。
5.硬件及部署要求
投标人必须详细列出项目的硬件需求,即政务云平台虚拟机数量及资源参数,以及系统的部署方案。
六、项目实施、培训
(一)项目竣工验收要求
按中华人民共和国现行项目建设规范和合同规定的验收评定标准等要求进行验收。
根据施工进度情况,按照标志性工作成果划分,分期进行检查、验收。
2.实施要求
投标人应具体说明实施本项目拟采用方案,确保至少两人驻场实施,团队
组织方式和保障力量,中标单位实施过程中出现资源、速度、质量协调控制不力、采购方有权更换责任人。
3.测试要求
投标供应商在实施过程中必须制定整体的测试方案,保证各子系统联接正确,数据传送正常。测试方案要明确测试关键点,分单元测试、边缘测试、整体测试等。测试方法应包括模块测试、回归测试、压力测试、性能测试、功能测试、数据测试、安全测试、系统测试等。测试内容必须包括功能要求、可靠性、安全性、可扩充性、可维护性、平台移植性、整体性能、与其他平台接口等,系统试运行期不低于三个月。
4.验收要求
投标供应商应负责在项目用户验收前将系统的全部相关的系统软件,各阶段开发文档,平台及其他应用系统交互接口功能的源代码和数据表结构,以及有关产品的系统说明书、安装手册、维护手册、技术文件、资料及安装、测试、验收报告等文档汇集成册交付项目单位。只有文档齐全后方可组织验收。对整个项目的验收包括检查整个系统是否实现了招标人所要求的功能,是否与投标供应商提出的解决方案中既定目标功能完全一致。
投标供应商必须根据系统总体设计方案提出验收细则和验收文档清单(收录
需求调研、系统分析、软件设计、软件开发、系统测试、实施上线、运行维护等阶段),招标人将根据验收方案对系统每个部分逐一进行项目验收。
5.文档要求
投标供应商提供的技术文件应该真实、全面、完整、详细,应以中文书写。投标供应商提供的技术文件应是能满足系统运行所需的安装调试、操作使用及维护管理等的详细技术资料。
投标供应商应负责在项目最终验收时将系统从合同签定之日起所有关于本项目的文档资料(包括初步验收文档的版本更新和试运行期产生的文档)交付采购人。
招标人认为必要的其他文档。
(二)培训承诺
供应商技术培训及相关系统的基础培训,内容包括软件安装调试及初始化、使用等的基本操作培训。供应商须制定出详细完整的培训方案,包括培训的具体内容、培训方式(现场培训或集中培训)、人数、教师、日程安排、资料等。应能使采购人相关人员独立操作、维护、管理,确保系统能正常安全运行。
供应商应提供的详细培训方案必须包括:(1)集群管理员操作培训;(2)各
部门管理员、应用软件操作员等的基本操作培训。
实际培训时间和地点按中标人与采购人商定的为准。
七、售后服务技术需求
售后服务包括但不限于下列服务:
1.网站页面优化服务
(1)网站信息维护培训指导。包括网站信息的增、删、查、改等操作的指导和问题解答;添加图片及附件操作指导;网站静态页面生成等操作指导。
(2)网站页面的图片、文字排版和调整。包括网页图片的制作、更换、布局调整,文字的内容、格式、链接等的修改。
(3)保证网站页面显示正常。解决文字或图片内容撑出、内容不显示或显示不正确、页面文字出现乱码、页面出现错误报告、页面在有的浏览器上显示不正确、页面没有找到、网页不能访问等问题。
2. 网站内容管理平台及选件维护服务
(1)对国家及省政府最新要求的响应
及时响应国家及省政府对政府门户网站、集约化建设及互联网+政务服务相关内容的建设要求,对门户网站前台服务内容进行调整。
(2)模版维护服务
每月一次。包括:定期对现有网站巡检,对现有的模版存在的不足进行调优,如排版不合适、格式不统一、色调不一致、内容块错位、字体大小不一致、文字没对齐等情况,但不涉及到页面新的风格。对现有的模版调整,包括添加删除专题链接、页面局部细节样式调整,错字,错链,图标替换等,提交《网站模版优化记录》。
(3)常规检查维护
每月一次。包括:各服务器运行状况、存储空间状况、软件运行状况、备份系统状况等。并提出现有问题和解决方法,并提交《网站常规检查维护运行状况报告》。
(4)专题维护
根据用户需求提供专题制作协助服务。
(5)产品版本升级
不定期提供。主要帮助客户不断完善产品的功能和系统稳定性。每次升级要对升级的版本、工作做好日志记录,并提交《版本升级记录表》。
3、技术运维服务
(1)备份服务
对门户网站系统涉及到的内容进行备份,包括数据库每天备份、网站应用程
序备份、网站所有补丁备份、项目涉及到的文档进行备份等。提交《系统备份检查表》,内容包括备份联系人、联系电话、时间、路径、内容等。
(2)错误日志分析
对网站涉及到的所有日志(包括中间件等产品)记录要进行定期查看,找出错误内容。提交《日志错误分析表》。
4、服务质量要求
(1)质量保证期限及费用
系统验收合格、双方签署验收书之日起,为本次建设内容中的子站提供至少1年维保服务。在系统维护期内,开发的软件应提供免费升级服务。维保服务到期后,应承诺对系统的升级仅收取成本费。
(2)售后服务方案
中标人需要提供详细的售后服务方案,包括服务人员、措施、应急预案及相关流程等内容。在安装、调试及系统免费维护期内,必须提供系统故障的应急处理方案。承诺所投产品系统不存在“后门”问题。
(3)服务响应要求
中标人承诺提供现场服务人员,且能够提供7*24小时响应服务,一般问题30分钟之内解决,重大问题4小时内解决。
说明:
1、欢迎供应商提供服务保障等于或高于该基本要求的服务。
2、本章的要求不能作为资格性条件要求评标,如存在资格性条件要求,应当认定招标文件编制存在重大缺陷,评标委员会应当停止评标。 查看全部
解决方案:labview100个实例之简单采集(2)
目录
提示:文章写完后,目录可以
前言
之前做过一个很简单的程序,但总觉得不能体现labview真正的特点,所以打算做一个系列,让一些初学者容易理解这些。首先是模块化和功能封装的概念。
1.例子
这是一个完整的主程序框图,可以清楚的看到分为两大区域——“参数”设置区和“主界面”。主界面收录
四个区域,分别是修改频率较高的参数区、控制区(启停)、状态区和显示区。用于采集一段时间内的声音和电流信号。

运行效果为:
设置采集条件和数据存储路径,通过按钮控制采集的开始,程序按照指定的采样率采集一段时间的信号并保存时域数据(原创
数据,方便后期数据处理)。如果可能,你可以尝试运行一下来测试一下效果。
模块化与功能封装.zip-MCU文档资源-CSDN文库
2. 模块化与功能封装 1. 模块化
Labview的一大特点是程序往往以模块化的方式构建,也就是常说的子VI。
2.功能封装

如图所示,此时我们说这个程序使用了三个子VI,分别封装了采集、回放、存储三个功能。
在制作子VI时,需要明确需要封装的函数,输入输出的数据类型。在保证通用性的前提下,主程序框图应该是最简洁的。
总结
本例主要是简单说明Labview中子VI的功能以及函数封装的方便性。当我们创建一个子VI并赋予它特定的功能时,我们可以很方便地在项目的任何地方调用它,而不需要再次编辑重复的代码。
特别注意的是,当一个子VI被我们封装后,理论上我们可以直接在本程序中调用。但往往在一个大型项目中,一些子VI因为其功能而被频繁使用,我们需要考虑是否要重复调用它们。重复调用是指我们在某个时间多次调用同一个子VI,程序会等待并逐次执行每次调用,导致程序运行时间发生变化甚至数据冲突(因为一般一个子VI计算机只分配一块内存空间 同时调用时,我们不知道谁先调用并输出结果)。
我们可以在VI的属性——“执行”栏中将VI设置为可重入VI。这样,程序运行时,当在多个地方同时调用这个VI时,会创建不同的工作区,多个调用者的数据会分别存储,不会发生冲突和干扰。
★ 范例中提到的结构、文件、信号处理和信号分析的范例版本及后续计划为17版本,如需降级请及时联系我们。
解决方案:采购内容及技术要求
一、采购要求
一、项目建设背景
政府网站是现代政府在信息化条件下政府密切联系人民群众的重要桥梁,是网络时代政府履行职责的重要平台,是各级政府机关提供信息公开、回应关切、办事服务、互动交流的重要载体。近年来,党中央、国务院、四川省政府高度重视政府网站建设和管理工作,先后下发了多项关于加强政府网站建设的管理规定。从2015年4月起,国务院开展了全国政府网站普查工作,对政府网站的建设起到了前所未有的推动作用。
2017年5月,《国务院办公厅关于印发政府网站发展指引的通知》(国办发〔2017〕47号)发布,对政府网站集约化建设提出了详细的建设要求。德阳市政府网站集约化建设项目将以此为依据,并根据《四川省人民政府办公厅关于加强政府网站信息内容建设的实施意见》(川办发〔2015〕53号)和《德阳市人民政府办公室关于进一步做好“互联网+政务服务”有关工作的通知》(德办函〔2016〕99号)以及政府网站绩效考核的要求,以问题和需求为导向,以为民服务为根本宗旨,顺应公众的期盼,按照利企便民的原则,树立“以信息公开为基础、公共服务为核心”的理念,积极推进政府网站集约化平台建设、应用新技术拓展服务渠道,以增强网站用户体验、提高办事服务、实现信息共享,为公众提供优质、便捷、高效服务。
二、项目建设目标
根据国家和四川省政府网站绩效考核指标及其他相关政策文件中对“互联网+”环境下政府网站的定位,借鉴国内外领先政府网站的先进经验和趋势特点,以“技术先进、功能完备、服务智能、安全稳定”为建设原则,着重新技术应用,基于大数据平台,采用移动互联网等技术手段,建设德阳智慧型、实用化、个性化、集约化网站群管理平台,最终实现德阳市政府门户网站、40个市级部门网站(含德阳经开区网站、德阳高新区网站)、6个县(市、区)政府门户网站的集约化建设工作。建设总体目标如下:
1. 加强信息资源整合,搭建全市统一的政府网站信息资源库,有效管理全市政府网站信息资源。
2. 建立信息支撑体系,提供网站信息采集技术,丰富网站信息供给手段。能够通过集约化平台集中实现采集、发布信息和数据,实现主站与子站、子站与子站、子站与栏目和市级部门子站与县级部门专栏等之间的互联互通、信息复用,为信息公开提供平台支撑,充分发挥政府网站在政务公开中第一平台的作用。
3. 加强网站智能化建设,提供智能搜索、智能问答、智能推荐和无障碍访问等功能。可根据用户需求调整搜索排序、聚合相关服务等,实现“搜索即服务”。主动为社会公众提供智能、实用、便捷、精准、高效的网站服务,提升政府网站的公共服务能力和水平。
4. 建立健全网站内容保障监管体系,加强网站的运维、监管手段,提供切实有效的网站运维、监管能力,及时发现网站存在的问题。保证网站运行安全、稳定,服务内容全面、准确。
5. 提供统一、完善的网站互动交流功能,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。
6. 注重政务微博、微信等互联网新技术的应用,加强对移动终端应用功能的支持,丰富公众访问渠道,有效提高用户体验。
7.能够通过“深度链接”、各类接口整合等方式,实现全市统一的办事服务入口和数据开放入口;与有效与四川省政府信息公开目录管理系统、四川省一体化政务服务平台、德阳市政务信息资源共享平台等进行整合和对接,最终实现平台互联互通、信息资源共享。
8.围绕2018年国家和四川省政府网站绩效评估指标体系,对网站建设进行升级优化,提升德阳市政府门户网站排名,力争进入省内前10名;加强网站建设的方向性引导、有效激励服务改进措施,保障网站持续发展。
三、总体技术要求
(一)软件产品技术要求
1.本次项目的投标商必须采用先进且成熟的技术和产品,主要产品应具有云平台部署成功案例。
2.软件产品应具有网站集群化平台建设能力。
3.系统需支持大量用户访问和海量数据的存储、检索和管理,平台功能部署灵活统一。
4.产品具有安全、可优化、可扩展性能,易于二次开发,应免费提供接口。
5.系统应采用J2EE或其他符合行业发展方向的先进技术架构;
6.系统应用结构体系的表示层、业务层、数据层、访问层应分开,支持分布式部署,支持无限站点扩展;
7.系统应支持Oracle、MySQL、Microsoft SQL Server等主流数据库系统和主要国产化数据库系统;
8.网站系统兼容性强,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
9.系统支持双机热备部署模式。
(二)运行性能指标
1. 在网络稳定的环境下,系统后台单一操作的响应时间小于3秒;网站页面访问响应时间小于1秒。
2. 网站满足并发访问用户数不低于10000的访问请求。
3. 支持初始数据量不少于100万记录数,支持表空间自动扩充。
4. 系统能够实现满足网站面向服务的目标,最终实现服务化、构件化、松耦合的SOA体系架构。
5. 系统提供7×24小时的连续运行,平均系统年故障时间≤2个小时,平均故障修复时间≤30分钟。
6. 网页代码和标记设计尽可能简化,以节约带宽。
7. 网站要提供不间断服务,支持信息多个站点同时发布功能,单个站点故障或更新维护等不能影响其它站点的正常使用。
(三)安全性能要求
1. 系统应支持分布式部署,系统应支持静态页面发布。
2. 系统应建立基于角色和工作分工的权限控制机制,重要信息需具备有效的加密方式进行传递;系统应提供数据自动非本机转储备份和故障恢复等应急响应功能,具备完善的日志记录、审计和数据备份功能。
3. 具备良好的数据库安全策略。系统安全设计符合《计算机信息系统安全保护等级划分准则》(GB17859-1999)第三级(安全标记保护级)要求。
四、建设内容及功能性需求
此次项目招标主要目的是规划、搭建好德阳市政府网站集约化平台,并完成“中国·德阳”网的改版和40个市级政府部门网站(含德阳经开区网站、德阳高新区网站)的集约化建设,但不包括德阳市6县(市、区)政府门户网站集约化建设内容。德阳市政府网站集约化平台将部署在德阳市政务云上。具体建设内容如下:
(一)统一用户管理系统
将德阳市使用站群系统的所有用户统一管理起来,实现用户的属性管理,并将用户与组织机构相关联。
用户管理,提供对用户的增、删、改,可禁用和启用用户帐号,设置用户拥有的功能权限;可自定义用户组织架构;用户组管理,提供对用户组的增、删、改,设置用户组拥有的功能权限。
(二)信息资源库系统
以整合德阳市所有政府网站资源实现共享为目标,建设集约化网站信息资源库,实现对信息资源的统一分类、统一展现、统一监管及各模块之间的无缝调用,有效解决平台建设资源共享的问题。
1. 要求针对信息资源库建设提出相应的解决方案和产品,满足结构化和非结构化数据的数据库建设。
2. 要求系统提供标准管理体系,即涵盖已经发布的国家标准、企业标准、行业标准和地方标准,也可以管理系统自定义的数据字典。
3. 要求系统具有资源库管理,数据元管理,数据集管理,表单管理等数据库基础应用组件。
4. 要求系统提供分类管理能力,分类管理包括数据元分类管理,数据分类管理。
5. 要求系统提供资源管理能力,系统提供基本的数据录入功能,也可以使用数据交换平台,通过WebService或ETL工具进行数据交换。
6. 要求系统提供共享管理能力,包括:自定义分组管理,共享维护,共享授权。共享授权实现数据分级管理,可以对用户授权,也可以对分组授权。
7. 要求系统提供系统管理能力,包括用户管理,角色管理,授权管理,日志管理。
(三)集约化网站监管平台
以“统一标准体系、统一技术平台、统一安全防护、统一运维监管,集中管理信息数据,集中提供内容服务”为目标,结合网站属地化管理体系,建设德阳市政府网站集约化管理平台,实现站点管理、规范性检查、网站普查指标自检、网站访问监控、网站维护监控、网站运行监控等功能,满足网站集约化统一管理要求。具体功能如下:
1.站点监管
(1)提供站群系统内各子站基本信息管理功能,包括管理的站点名称、站点域名、站点描述信息、主办单位及联系人信息、网站备案信息等。
(2)按照《政府网站发展指引》要求提供各项网站规范性的监测功能,包括名称规范、域名规范、备案信息规范、模板规范、标签规范、栏目规范等一致性检查、冗余检查、属地化监测等。
2.网站普查指标监测
根据网站普查要求,提供网站指标监测功能,包括网站可用性监测、存在错误页面分析、页面关联分析、空白栏目监测、栏目更新频率监测、网站外链监测、敏感词及错别字扫描等。
3.网站访问监测
根据网站实际运行情况,可数字化或图表化展现网站运行监控的各项访问指标,可对指定时间段的访问情况进行统计、分析,并能生成统计分析报告(表)进行打印或导出。监测功能及内容如下:
(1)搜索引擎监控:包括访问人次、站内搜索次数、搜索结果点击次数、搜索结果点击率、搜索引擎排行、网站检索词排行等。
(2)网站访问监控:包括访问渠道、浏览量、访客数、平均停留时间、日访问变化趋势图等;
(3)浏览页数性能监控:包括系统连接时间、响应时间、下载时间以及无法访问次数等;
(4)智能报警策略:包括故障的持续时间、问题严重性分级、分类报警,报警通知方式支持邮件、短信等。
4.网站维护监测
(1)针对网站内容管理进行数据分析,包括网站栏目(栏目访问量、栏目信息量、栏目参与部门数和栏目参与人员数等)、部门信息(部门信息发布量、部门业务办理量和部门业务办结率等)和公共诉求(诉求目的、诉求内容分类、处理单位、满意度等)等数据的统计分析功能。
(2)提供系统站内通知功能,可对系统内各用户发送消息,解决系统管理人员日常工作沟通及信息共享。
5.网站运行检测
(1)支持对服务器硬件层进行监控,包括服务器的工作状态、处理器、内存、进程等。
(2)提供灵活、全面、便捷的监控方式,监管页面秒级刷新,运行高效、安全可靠。
6.系统日志管理
提供系统日志的管理界面,能详细记录系统操作日志,并形成日志信息或日志文件,可对日志文件进行导出。
(四)网站群管理平台
以站点管理为重点,支持集中式建设部署和分布式管理维护。
支持对历史信息的调入、调出,提供对信息的全流程跟踪管理。
支持与其它平台的无缝对接。系统接口可开放,支持网站扩展功能模块的安装调试,具有高集成、可扩展、易管理等特性。
采用XML、WebService等标准,提供组件化的统一数据接口,有效实现信息的采集、聚合。
1.站群管理系统
(1)要求实现页面展现与信息分离,删除或修改网页模板时不会对信息造成影响。
(2)站群管理系统支持站群下所有子站点的创建、修改、暂停、删除及服务器资源配置。
(3)系统提供多级授权分层管理机制,每个子站点都提供独立的站点管理功能,站点管理人员能够对子站点进行角色权限管理、资源管理、用户权限管理及站点统计等操作,保证用户在统一的平台下独立管理自己的子站点。
(4)站群系统内各站点之间可以共享数据源,保证各站点信息的一致性。
(5)系统支持密码强度管理、CA绑定等安全策略。
2.站点管理系统
(1)网站信息的发布具有静态信息发布和动态信息发布相结合的发布模式,用户可根据实际需要选择发布方式,以同时满足网站访问速度、并发访问量及网站交互功能的多重需求。
(2)系统支持对多种信息格式的发布,包括音频、视频等多媒体格式。
(3)系统支持增量发布与完全发布,支持定时发布和立即发布,可根据需要自定义发布方式。

(4)系统提供统一用户验证功能,通过账号、密码、验证码相结合的方式登陆到系统管理界面。
(5)内容维护人员只能对自己权限范围内的内容进行管理,无权看到并操作其他用户管理的内容。
(6)系统详细记录所有用户的系统操作,以便于查询和管理。
(7)系统提供权限组功能,具有相同权限的用户可划分为同一权限组。权限的分配可以详细到每一个栏目。
(8)提供系统登陆账号长时间无操作的自动注销功能,可自行设置注销时间。
(9)系统可根据自定义备份策略(如异地备份、定时备份等)进行站点数据备份,能对备份文件进行删除、下载、恢复管理。
3.内容管理系统
(1)具有网站内容采集、在线编辑、审核发布、敏感词过滤、错别字检测等功能,提供可视化编辑器,实现“所见即所得”的信息录入、编辑效果。
(2)支持文档录入、发布、预览、修改、删除等操作,拥有丰富的文档引用、复制、链接、移动、同步等操作功能。
(3)内容编辑器具有多图片上传、word和pdf等文档导入、一键排版、格式清理、去除空行、首行缩进等常用功能;
(4)各子站点具有独立、完善的信息采集、编发功能,可根据用户权限进行跨栏目、跨站点信息推送与共享。
(5)支持信息发布过程中的多级审核管理,能够针对不同站点、不同栏目设置不同审核流程;
(6)支持前台页面样式由模板进行控制,模板提供代码级修改,模板管理支持标签语法,模板可嵌套模板,也可嵌套标签;
(7)网站栏目能够自由移动,可定制栏目信息发布类型,可按权限获取不同栏目、不同站点(如内容管理系统、信息公开系统)的信息;
(8)信息录入具备文章、组图、链接、视频四种类型,能够对普通文本、图
片信息和音视频等多种流媒体信息进行发布和管理,满足信息多样化的需求;
(9)支持站点发布、分级栏目发布、信息单独发布等操作,并可以指定文档发布后在页面显示的顺序;
(10)支持静态发布、动态发布和动态静态相结合的发布方式。
(五)政府信息公开管理系统
根据部门业务和网站功能特点进行科学分析、认真梳理,合理规划频道和栏目,与四川省政府信息公开目录管理系统进行数据对接,有效实现德阳市政府信息公开数据在网站上的聚类、共享、展示。
(1)该系统必须完全符合《政府信息公开目录系统实施指引(试行)》(国办秘函[2009]6号)文件中的各项要求。
(2)要求系统提供灵活的元数据管理,以能适应不同类型的信息记录需要,元数据必需符合国家相关文件的要求,并具备元数据扩展功能;提供对多种类型的元数据字段支持。定义数据层、功能层、使用层规范,同时配以编码规则管理,支持批量修改,保持良好的扩展性;
(3)要求系统提供灵活的分类管理,可自由地将采集到的信息进行多渠道分类,包括主题分类、机构分类、体裁分类及服务对象分类。同时支持分类的自由扩展。
(4)要求系统提供灵活的目录管理功能,用户可根据公众的需要定义目录的展现内容,通过定义目录节点的生成规则,从而来获取相应的数据,形成最终的人性化目录;系统支持目录推荐功能,即上级政府建立完成的目录,可以作为“模板”推荐给下级单位。
(5)要求系统能够自定义索引号编码规则,依照信息公开标准对信息进行自动编码,生成信息索引号。当编码规则发生修改时,也可制定新规则,并批量修改信息索引号。
(6)要求系统提供良好的信息管理功能,从采集、标引、审核、发布到归档,完整记录信息生命周期活动。
(7)系统提供列表、简要、细览等展现形式,显示核心元数据,包括索引号、名称、内容概述、生成日期、文号等。
(8)系统应满足信息录入和审核权限的逐级分配,强化信息源头管理,保障信息发布安全。
(9)系统具有依申请公开功能,可对依申请公开信息进行接收、受理、审核、发布,并提供统计分析等功能,访问用户可实时查询依申请公开处理状态。
(10)要求系统提供综合的绩效评估模式,包括信息公开工作量评估、依申
请公开办结率和办结质量评估。
(六)互动交流系统
系统严格遵循SOA模块化设计思想,按照“高内聚,低耦合”原则,提供全面完善的网站互动交流功能,包括领导信箱、民意征集、在线调查、咨询投诉、网上信访、在线访谈等,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。具体功能要求如下:
1.在线访谈系统
(1)支持图文和视频同步的在线访谈,要求具有文字直播、图片直播、音频直播及视频直播四种功能形式;
(2)要求提供良好的人机对话界面,网友通过文字形式可实时提问,管理人员采集
和审核问题,主持人转达和引导提问,嘉宾对问题实时解答;
(3)管理员可查看在线用户情况,可以通过IP或用户名来禁止用户行为,可对用户发言内容设置过滤模式。
(4)主持人、嘉宾与网友的发言区要划分明确;
(5)系统必须具有访谈预告功能,访谈预告可采用文字、图片或视频方式展示访谈背景和相关资料。
(6)访谈过程中要确保文字、图片、音频、视频的流畅;
(7)对于历史访谈,可按照日期进行归档,形成历史访谈目录,网友可调阅历史访谈。
(8)对于已经完成的访谈,管理员可继续对访谈内容进行修改和编辑。
2.领导信箱系统
(1)系统具有工作流管理功能,可自定义信件办理流程,实现从受理、转办、承办、退回、办结的全流程管理。
(2)系统具有信件办理状态实时查询功能,来信人可根据信件编码、姓名、联系电话等对信件办理状态进行查询,信箱管理人员可通过关键字、信件编码、时间、部门、信件状态等条件进行查询。
(3)前台提供“信件选登”、“信件查询”、“我要写信”等功能,写信内容需收录
姓名、昵称、身份证号码、联系电话、电子邮件、信件标题、信件内容,可上传附件材料等,具有详实的展现形式,可对敏感词进行自动屏蔽。
(4)后台提供信件的回复、发布、选登等状态的查看及信件办理状态的统计功能,提供信件的“公开/不公开”选项功能。
3.意见征集系统
(1)针对社会公众关注的热点问题或者政策制定和工作成果开展民意征集活动,民意征集的各个主题要求布局清晰、合理,方便阅览;
(2)网友可根据征集主题的内容和背景资料发表自己的建议和观点,可以查看征集结果;
(3)系统后台可实时查看所有社会公众提交的意见和建议;
(4)意见征集结束后,前台只保留征集主题、内容、结果,网友不能再进行意见和建议的提交;
(5)能对网友发表的文字信息进行安全性检查。
4.网上调查系统
(1)管理员可根据不同的调查内容新建、修改、删除调查问卷。对于每个调查问卷可以对标题、摘要、内容、选项、调查项组成结构等进行管理,可灵活设计投票问卷风格;
(2)同一调查主题,可设置多个调查项;调查项应包括单选项调查、多选项调查、附加选项(填空)等调查类型;
(3)同一IP地址在设定时间内只允许提交一次投票,杜绝恶意投票行为发生;
(4)投票结果可通过表格、柱状图、饼图等形式进行展现。
(七)数据采集系统
(1)数据采集系统借助先进的信息抓取、信息分类和信息流转技术,实现对指定网站信息(包括但不限于中央政府网站、省政府网站、重要新闻网站和平台内外所需政府信息资源)的更新监测和有效采集。
(2)系统按照不同需要,可定点、定时监测和采集所需信息,并下载信息的图片、视频及附件等相关文件,将采集信息进行准确分类、整理、筛选,通过内容推送功能自动推送到指定栏目。
(3)管理员可在后台设置抓取的范围、关键字、抓取时间等参数,系统根据设置好的抓取策略进行信息自动抓取。
(4)用户可对采集到的信息按照日期、来源、标题进行检索、浏览;可以对信息内容与图片分类保存,支持信息分类的自定义。
(5)系统支持将网页中的信息内容按标题、作者、栏目、内容等进行提取;自动过滤网页中的无用信息、广告图片等,自动过滤重复的信息。
(6)对采集的信息可进行二次编辑、审核,可向网站群内各个子站栏目进行发布。
(八)无障碍浏览系统
(1)面向听力、视力等有障碍的特殊人群提供缩放字体、缩放页面、辅助光标、文本化网页和语音个性化调整等辅助浏览功能。
(2)具有全程自动语音提示、全程语音导航交互、光标语音指读与连读、文
字放大阅读专用屏、网页图文放大缩小、高对比阅读配色器、阅读辅助光标等功能。
(3)系统需界面友好、易操作,无需安装插件,支持各种主流浏览器。
(九)智能检索系统
(1)提供专业的政府网站检索功能,对政府网站检索进行分类引导,按照政策法规、办事事项、政府文件、新闻咨询等类别对用户检索内容进行归类整理,清晰引导用户进行查阅。
(2)数据检索范围应包括站群内各业务部门、各县(市、区)网站站点,可对不同类型数据源的数据进行检索。
(3)满足即搜即用原则,支持图片、视频格式信息的检索。
(4)支持关键字搜索、日期搜索。要求提供个性化检索结果功能,如检索结果分类导航展现、检索结果按不同维度(可以按系统,站点,栏目,区县,文档类型,时间单位,相似度等)过滤展示,检索结果可进行二次搜索。
(5)具有搜索关键词自动补全能力,动态分析公众搜索关键词,按照关键词的内在逻辑关系进行自动匹配,给出搜索提示,纠正用户输入错误。
(6)具有热词自动排序和显示功能,可自动统计搜索关键词的搜索频度,将某一时间段内搜索量较高的关键词作为搜索热词,并根据热度动态自动调整排序。
(7)支持拼音搜索功能,采用词语智能拼音匹配模式,并结合关键词提醒联想功能,实现拼音和中文友好联系的搜索功能。
(8)系统支持管理员定义屏蔽词和停用词的搜索,当用户输入收录
的词汇时,系统不展示搜索结果信息。
(9)支持多个关键词搜索和整句搜索。
(10)系统使用基于文档语义的技术实现同一站点内搜索结果信息的自动排重,即“相同”的文档在索引过程中仅被索引一次,解决大量相同文档的搜索问题,提高索引效率,帮助用户快速找到搜索结果。
(11)对含有图片的信息,其搜索结果列表应显示其缩略图;
(12)系统具有检索结果优先显示置顶功能。
(十)智能推荐系统
(1)根据网站用户访问行为,结合网站数据分析,找到网站访问热点,自动聚合相关信息(即相关文件、政策、咨询类信息),实现网站信息智能推荐。
(2)可根据关键词、热词等条件分析信息之间的直接联系或间接关系,自动分析、梳理、聚类展示。
(3)可自动进行专题信息汇聚,通过数据采集技术,获取相关信息进行集中
管理和存储,根据用户访问习惯,进行数据的重组、拼装,聚合,形成专题栏目;也可根据各专题的关注度,对推荐专题及相应的页面表现位置进行展示顺序的自动调整,供公众访问。

(十一)智能问答系统
(1)能够深度挖掘网站群信息内容,建立和完善智能应答知识库,可根据用户自定义规则,通过信息聚合技术,按照信息采集、聚合、挖掘和检索流程,实现跨部门、跨行业的信息整合与资源共享。
(2)能够自动将咨询问题保存入库,可自定义站点检索到相关咨询问题,可实时预处理用户的输入信息,根据输入内容与后台检索引擎交互,自动纠错,实时提示相关信息,引导类似问题进行解答。
(3)可利用信息资源库及应答知识库中的信息,即时自动回答用户提出的问题,向用户展示相关度较高的信息。
(4)能够充分使用站群内所有站点的信息资源,咨询问题答复内容可由平台下多个站点信息数据组成关联页面提供给用户。
(5)能够实现多样化展现方式,可以预分类政务资源,将多个网站中的同类栏目合并为一个分类,为用户按分类展现更全面精准的搜索结果。
(6)要求具备自学习功能,能够自动丰富知识库,对于无法解决的问题可自动转人工解答。
(十二)移动门户系统
(1)要求采用HTML5网站页面应自适应技术,能够实现不同移动终端(例如苹果、安卓系统) 访问移动门户时自适应展示,能够在各种访问终端下保持完整良好的页面布局和内容可读性。
(2)要求移动端与PC端使用同一域名进行访问,系统自动识别访问终端并自适应页面展示效果。
(3)要求移动门户所展示信息不再二次录入,统一由站点内容管理系统提供,以保证数据来源的统一性。
(4)要求提供最新新闻、政务公开、互动交流、解读回应、民意调查、舆论引导、政务服务、政府办公等信息内容的展示。
(5)要求支持可定制栏目访问。
五、其他需求说明
1.网站兼容性要求
要求网站页面具有很好的兼容性,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
2.UI/UE设计
(1)界面设计需要突出地方特色
(2)文字,图形色彩统一,搭配合理,界面清楚整洁,层次结构清楚。
(3)统一首页和其他各级页面的排版风格。
(4)页面富有时代气息和美感,色彩搭配稳重、合理、大气。
(5)多媒体、动画页面要求丰富而生动。
3.子站设计要求
(1)满足各子站个性化页面设计需求,根据各部门网站管理人员要求进行设计与实施。
(2)本次页面设计主要从以下几个方面进行规划:页面风格、页面人性化和易用性、页面内容、页面结构等,围绕信息公开、办事服务、互动交流等功能定位,设计门户网站页面框架,清晰、合理、科学展现网站内容,避免累赘和页面冗余。
4.历史数据迁移要求
(1)要求提出详尽的网站数据迁移方案。
(2)要求将实施集约化的网站的全部数据,收录
各站点栏目信息、新闻信息、公开信息、互动信息、用户信息、用户对应权限、图片、附件、多媒体文件等数据平稳迁移至德阳市政府网站集约化平台,确保不丢失任何有效数据,处理好新网站栏目信息与历史数据的对应关系。
(3)要求保证集约化网站切换的平滑过渡,做好数据的同步更新。
5.硬件及部署要求
投标人必须详细列出项目的硬件需求,即政务云平台虚拟机数量及资源参数,以及系统的部署方案。
六、项目实施、培训
(一)项目竣工验收要求
按中华人民共和国现行项目建设规范和合同规定的验收评定标准等要求进行验收。
根据施工进度情况,按照标志性工作成果划分,分期进行检查、验收。
2.实施要求
投标人应具体说明实施本项目拟采用方案,确保至少两人驻场实施,团队
组织方式和保障力量,中标单位实施过程中出现资源、速度、质量协调控制不力、采购方有权更换责任人。
3.测试要求
投标供应商在实施过程中必须制定整体的测试方案,保证各子系统联接正确,数据传送正常。测试方案要明确测试关键点,分单元测试、边缘测试、整体测试等。测试方法应包括模块测试、回归测试、压力测试、性能测试、功能测试、数据测试、安全测试、系统测试等。测试内容必须包括功能要求、可靠性、安全性、可扩充性、可维护性、平台移植性、整体性能、与其他平台接口等,系统试运行期不低于三个月。
4.验收要求
投标供应商应负责在项目用户验收前将系统的全部相关的系统软件,各阶段开发文档,平台及其他应用系统交互接口功能的源代码和数据表结构,以及有关产品的系统说明书、安装手册、维护手册、技术文件、资料及安装、测试、验收报告等文档汇集成册交付项目单位。只有文档齐全后方可组织验收。对整个项目的验收包括检查整个系统是否实现了招标人所要求的功能,是否与投标供应商提出的解决方案中既定目标功能完全一致。
投标供应商必须根据系统总体设计方案提出验收细则和验收文档清单(收录
需求调研、系统分析、软件设计、软件开发、系统测试、实施上线、运行维护等阶段),招标人将根据验收方案对系统每个部分逐一进行项目验收。
5.文档要求
投标供应商提供的技术文件应该真实、全面、完整、详细,应以中文书写。投标供应商提供的技术文件应是能满足系统运行所需的安装调试、操作使用及维护管理等的详细技术资料。
投标供应商应负责在项目最终验收时将系统从合同签定之日起所有关于本项目的文档资料(包括初步验收文档的版本更新和试运行期产生的文档)交付采购人。
招标人认为必要的其他文档。
(二)培训承诺
供应商技术培训及相关系统的基础培训,内容包括软件安装调试及初始化、使用等的基本操作培训。供应商须制定出详细完整的培训方案,包括培训的具体内容、培训方式(现场培训或集中培训)、人数、教师、日程安排、资料等。应能使采购人相关人员独立操作、维护、管理,确保系统能正常安全运行。
供应商应提供的详细培训方案必须包括:(1)集群管理员操作培训;(2)各
部门管理员、应用软件操作员等的基本操作培训。
实际培训时间和地点按中标人与采购人商定的为准。
七、售后服务技术需求
售后服务包括但不限于下列服务:
1.网站页面优化服务
(1)网站信息维护培训指导。包括网站信息的增、删、查、改等操作的指导和问题解答;添加图片及附件操作指导;网站静态页面生成等操作指导。
(2)网站页面的图片、文字排版和调整。包括网页图片的制作、更换、布局调整,文字的内容、格式、链接等的修改。
(3)保证网站页面显示正常。解决文字或图片内容撑出、内容不显示或显示不正确、页面文字出现乱码、页面出现错误报告、页面在有的浏览器上显示不正确、页面没有找到、网页不能访问等问题。
2. 网站内容管理平台及选件维护服务
(1)对国家及省政府最新要求的响应
及时响应国家及省政府对政府门户网站、集约化建设及互联网+政务服务相关内容的建设要求,对门户网站前台服务内容进行调整。
(2)模版维护服务
每月一次。包括:定期对现有网站巡检,对现有的模版存在的不足进行调优,如排版不合适、格式不统一、色调不一致、内容块错位、字体大小不一致、文字没对齐等情况,但不涉及到页面新的风格。对现有的模版调整,包括添加删除专题链接、页面局部细节样式调整,错字,错链,图标替换等,提交《网站模版优化记录》。
(3)常规检查维护
每月一次。包括:各服务器运行状况、存储空间状况、软件运行状况、备份系统状况等。并提出现有问题和解决方法,并提交《网站常规检查维护运行状况报告》。
(4)专题维护
根据用户需求提供专题制作协助服务。
(5)产品版本升级
不定期提供。主要帮助客户不断完善产品的功能和系统稳定性。每次升级要对升级的版本、工作做好日志记录,并提交《版本升级记录表》。
3、技术运维服务
(1)备份服务
对门户网站系统涉及到的内容进行备份,包括数据库每天备份、网站应用程
序备份、网站所有补丁备份、项目涉及到的文档进行备份等。提交《系统备份检查表》,内容包括备份联系人、联系电话、时间、路径、内容等。
(2)错误日志分析
对网站涉及到的所有日志(包括中间件等产品)记录要进行定期查看,找出错误内容。提交《日志错误分析表》。
4、服务质量要求
(1)质量保证期限及费用
系统验收合格、双方签署验收书之日起,为本次建设内容中的子站提供至少1年维保服务。在系统维护期内,开发的软件应提供免费升级服务。维保服务到期后,应承诺对系统的升级仅收取成本费。
(2)售后服务方案
中标人需要提供详细的售后服务方案,包括服务人员、措施、应急预案及相关流程等内容。在安装、调试及系统免费维护期内,必须提供系统故障的应急处理方案。承诺所投产品系统不存在“后门”问题。
(3)服务响应要求
中标人承诺提供现场服务人员,且能够提供7*24小时响应服务,一般问题30分钟之内解决,重大问题4小时内解决。
说明:
1、欢迎供应商提供服务保障等于或高于该基本要求的服务。
2、本章的要求不能作为资格性条件要求评标,如存在资格性条件要求,应当认定招标文件编制存在重大缺陷,评标委员会应当停止评标。
干货教程:【Python】抖音采集话题/音乐/用户作品和喜欢+调用Aria2下载+fire
采集交流 • 优采云 发表了文章 • 0 个评论 • 247 次浏览 • 2022-11-22 16:26
抖音集合开源仓库
介绍
Python 获取数据 + Vue 写入接口 + Aria2 下载
根据抖音的各种链接或ID,通过网页界面采集视频作品并下载到本地计算机。
支持用户主页链接或sec_uid/主题挑战和音乐配乐链接或ID。
支持下载喜欢的列表(需要喜欢的列表可见)。
使用0x00安装依赖项
在程序目录中打开命令行,然后输入
pip install -r requirements.txt
0x01 使用界面
双击打开启动.bat,或在程序目录中打开命令行,输入
python ui.py
0x02 直接修改 douyin.py 中的相关参数
完全不懂 Python 的朋友使用命令行或操作界面。
0x03 使用 exec.py 直接从命令行运行以查看命令列表,或使用 -h 参数查看帮助
python exec.py
python exec.py -h
python exec.py download -h
python exec.py download_batch -h
使用函数名称调用程序
--type 指定下载类型,默认值:--type=user
--limit 指定采集数量,默认值:--limit=0(不限制)
例如,采集
用户的所有作品:
python exec.py download https://v.douyin.com/xxxx/
python exec.py download 用户的secuid
例如,采集
用户喜欢的前 10 部作品:
python exec.py download MS4wLjABAAAAl7TJWjJJrnu11IlllB6Mi5V9VbAsQo1N987guPjctc8 --type=like --limit=10
python exec.py download 用户的secuid
例如,采集
音乐配乐的前 10 首作品:
python exec.py download https://v.douyin.com/xxxx/ --type=music --limit=10
python exec.py download 音乐ID --type=music --limit=10
TODO知识点:抖音相关Aria2相关Python相关命令行模块、火相关UI模块、pywebview相关抖音集合部分源码
# -*- encoding: utf-8 -*-
'''
@File : douyin.py
@Time : 2021年03月12日 18:16:57 星期五
@Author : erma0
@Version : 1.0
@Link : https://erma0.cn
@Desc : 抖音用户作品采集
'''
import json
import os
import time
from urllib.parse import parse_qs, urlparse
import requests
from download import Download
class Douyin(object):
"""
抖音用户类
采集作品列表
"""
def __init__(self, param: str, limit: int = 0):
"""
初始化用户信息
参数自动判断:ID/URL
"""
self.limit = limit
self.http = requests.Session()
self.url = ''
self.type = 'unknow'
self.download_path = '暂未定义目录'
# ↑ 预定义属性,避免调用时未定义 ↑
self.param = param.strip()
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq' # sign可以固定
self.__get_type() # 判断当前任务类型:链接/ID
self.aria2 = Download() # 初始化Aria2下载服务,先不指定目录了,在设置文件名的时候再加入目录
self.has_more = True
self.finish = False
# 字典格式方便入库用id做key/取值/修改对应数据,但是表格都接收数组
self.videosL = [] #列表格式
# self.videos = {} #字典格式
self.gids = {} # gid和作品序号映射
def __get_type(self):
"""
判断当前任务类型
链接/ID
"""
if '://' in self.param: # 链接
self.__url2redirect()
else: # ID
self.id = self.param
def __url2redirect(self):
"""
取302跳转地址
短连接转长链接
"""
headers = { # 以前作品需要解析去水印,要用到移动端UA,现在不用了
'User-Agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/89.0.4389.82'
}
try:
r = self.http.head(self.param, headers=headers, allow_redirects=False)
self.url = r.headers['Location']
except:
self.url = self.param
def __url2id(self):
try:
self.id = urlparse(self.url).path.split('/')[3]
except:
self.id = ''
def __url2uid(self):
try:
<p>
query = urlparse(self.url).query
self.id = parse_qs(query)['sec_uid'][0]
except:
self.id = ''
def get_sign(self):
"""
网页sign算法,现在不需要了,直接固定
"""
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq'
return self.sign
def get_user_info(self):
"""
取用户信息
查询结果在 self.user_info
"""
if self.url:
self.__url2uid()
url = 'https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid=' + self.id
try:
res = self.http.get(url).json()
info = res.get('user_info', dict())
except:
info = dict()
self.user_info = info
# 下载路径
username = '{}_{}_{}'.format(self.user_info.get('short_id', '0'),
self.user_info.get('nickname', '无昵称'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_challenge_info(self):
"""
取话题挑战信息
查询结果在 self.challenge_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/challenge/info/?ch_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('ch_info', dict())
except:
info = dict()
self.challenge_info = info
# 话题挑战下载路径
username = '{}_{}_{}'.format(self.challenge_info.get('cid', '0'),
self.challenge_info.get('cha_name', '无标题'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_music_info(self):
"""
取音乐原声信息
查询结果在 self.music_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/music/info/?music_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('music_info', dict())
except:
info = dict()
self.music_info = info
# 音乐原声下载路径
username = '{}_{}_{}'.format(self.music_info.get('mid', '0'), self.music_info.get('title', '无标题'),
self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def crawling_users_post(self):
"""
采集用户作品
"""
self.type = 'post'
self.__crawling_user()
def crawling_users_like(self):
"""
采集用户喜欢
"""
self.type = 'like'
self.__crawling_user()
def crawling_challenge(self):
"""
采集话题挑战
"""
self.type = 'challenge'
self.get_challenge_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... QFzfg
url = 'https://www.iesdouyin.com/web/api/v2/challenge/aweme/'
cursor = '0'
while self.has_more:
params = {
"ch_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('话题挑战采集出错')
print('话题挑战采集完成')
def crawling_music(self):
"""
采集音乐原声
"""
self.type = 'music'
self.get_music_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... OVC5j
url = 'https://www.iesdouyin.com/web/api/v2/music/list/aweme/'
cursor = '0'
while self.has_more:
params = {
"music_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('音乐原声采集出错')
print('音乐原声采集完成')
def __crawling_user(self):
"""
采集用户作品/喜欢
"""
self.get_user_info() # 取当前用户信息,昵称用做下载目录
max_cursor = 0
# https://www.iesdouyin.com/web/ ... tk%3D
# https://www.iesdouyin.com/web/ ... tk%3D
url = 'https://www.iesdouyin.com/web/api/v2/aweme/{}/'.format(self.type)
while self.has_more:
params = {
"sec_uid": self.id,
"count": "21",
"max_cursor": max_cursor,
"aid": "1128",
"_signature": self.sign,
"dytk": ""
}
try:
res = self.http.get(url, params=params).json()
max_cursor = res['max_cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('作品采集出错')
print('作品采集完成')
def __append_videos(self, res):
"""
数据入库
"""
if res.get('aweme_list'):
for item in res['aweme_list']:
info = item['statistics']
info.pop('forward_count')
info.pop('play_count')
info['desc'] = Download.title2path(item['desc']) # 需提前处理非法字符串
info['uri'] = item['video']['play_addr']['uri']
info['play_addr'] = item['video']['play_addr']['url_list'][0]
info['dynamic_cover'] = item['video']['dynamic_cover']['url_list'][0]
info['status'] = 0 # 下载进度状态;等待下载:0,下载中:0.xx;下载完成:1
# 列表格式
self.videosL.append(info)
# 字典格式
# self.videos[info['aweme_id']] = info
# 此处可以直接添加下载任务,不过考虑到下载占用网速,影响采集过程,所以采集完再下载
if self.limit:
more = len(self.videos) - self.limit
if more >= 0:
# 如果给出了限制采集数目,超出的删除后直接返回
self.has_more = False
# 列表格式
self.videosL = self.videosL[:self.limit]
# 字典格式
# for i in range(more):
# self.videos.popitem()
# return
else: # 还有作品的情况下没返回数据则进入这里
print('未采集完成,但返回作品列表为空')
def download_all(self):
"""
作品抓取完成后,统一添加下载任务
可选择在外部注册回调函数,监听下载任务状态
"""
for id, video in enumerate(self.videosL):
# for id, video in self.videos.items():
gid = self.aria2.download(url=video['play_addr'],
filename='{}/{}_{}.mp4'.format(self.download_path, video['aweme_id'],
video['desc'])
# ,options={'gid': id} # 指定gid
)
self.gids[gid] = id # 因为传入gid必须16位,所以就不指定gid了,另存一个字典映射
print('下载任务投递完成')</p>
技巧:拼多多大神是怎么复制抖音爆款上传到自己店铺的?这个工具无需授权
随着抖音小店的火爆,不少拼多多商家开始在抖音上寻找爆款商品,急需一款抖音宝到拼多多小店收款的工具。
今天要跟大家分享的是一款支持斗尚拼的工具。不仅可以采集复制宝物上架,还可以采集宝物进行分析优化。下面我主要介绍大家用的比较多的3个工具:
①宝贝复制:一键复制抖音小店宝贝上传至拼多多,支持批量采集
,可快速完成发货!
工具支持多次开启,无需授权,不绑定电脑。店铺团版支持5-200家店铺!
②图片处理器:抖音店铺宝贝图片一键采集
工具限时免费,快来试用吧~
本工具可以一键采集下载淘喜、拼多多、京东、豆店宝的主图、sku图、详情页、750详情图、主图视频、搜索列表展示图等,还可以自动拼接详情图片。
宝贝优化过程中,卖家可以采集竞品宝贝图片进行分析,并一键导出数据,方便美工学习和模仿。
③宝贝详情(评论/sku/买家秀/问大家)分析器:一键采集
抖音店铺宝贝评论/sku/买家秀/问大家
工具限时免费,快来试用吧~
一键采集
淘喜、拼多多、京东、豆店等各大平台评论、sku占比分析、下载买家秀等,并支持一键拆分评论根、根占比分析、挖掘产品卖点。重点采集
问大家,分析买家痛点。
工具免费分享,有需要的卖家可以免费试用!
下面,小编就为大家详细讲解一下拼多多宝贝复制工具的使用方法:
1.采集
宝贝
数据来源包括淘宝/天猫、1688、抖音小店、拼多多批发等平台。也就是说,卖家可以在淘宝、1688、抖音小店、批发商上采集
宝贝并上传到自己的店铺。
工具限时免费,快来试用吧~
淘宝平台采集宝贝数据,需要登录普通买家账号。如果采集
太多,可以在多个帐户之间切换。1688和淘宝账号一样。
无需登录即可采集
拼多多批发宝贝数据。如果您采集
了拼多多宝贝的数据,可以通过手机号和token登录。
多多宝的采集
方式可以通过关键词和分类采集
,也可以全店采集
、其他平台采集
、复制或批量导入。
2.上传配置
宝贝收好后,进入配置页面:
工具限时免费,快来试用吧~
还没有收到工具的卖家可以免费试用,还有限时会员权限!
一、价格
拼多多上的商品价格包括单价、单价、折扣价、最低SKU价等,采集
淘宝宝贝一般默认为折扣价,折扣价显示如下图:
如果优惠价格是临时活动,没有优惠后,源链接价格会上涨。
拼多多默认单价,可以通过加百分比、加减固定金额、指定价格等方式设置。
工具限时免费,快来试用吧~
2. 图片
主图可以默认不处理,也可以选择以下几张作为主图。采集到的淘宝宝贝只有5张主图,工具可以自动补全10张主图。
细节图也可以不处理,也可以去掉指定位置的地图,保留编号,也可以插入自定义细节图,自定义细节加水印。
对于采集到的淘宝宝贝,高度超过1500的详细图片可以自动压缩分割,压缩可以减少图片空间的占用。
注意:处理图片时,一定要勾选【使用图片空间上传图片】!如果你复制视频,你需要有上传视频的权限!
3.标题
标题设置包括标题清词(启用本地自定义过滤)、标题过滤词、标题替换(宝贝ID=新标题)等。标题可以通过添加前缀/后缀或直接替换来处理。
可以设置新标题只保留采集
宝贝标题前的字符数。特殊分类支持长标题校验【上传宝贝标题支持10个字符】。
标题重组可以分裂根,随机打乱和重组。
4.类别
因为商品类目是跨平台的,只是部分商品的类目分类会有所不同。需要手动指定四级类别(每个类别级别都必须选择),但大多数情况下默认匹配上一个类别。
5.单品
SKU规格配置,不同平台有不同的SKU属性,可以过滤/替换符号和违禁词,自动分割SKU名称和备注,商家也可以自定义SKU。
注意:如果没有sku,默认添加一个sku,最大数量限制为24个!
6.属性
商品类型可根据实际情况选择,如普通商品、虚拟商品、进口商品、积分卡或海外抄送个人邮寄等。
设置品牌(可以选择不使用该品牌或更换其他品牌),设置产品编码,是否支持假一赔十,7天无理由,坏了赔,是否秒-手/虚拟产品,您还可以自定义属性。
7. 运输
商家可以设置物流重量、物流类型、发货时间。
还没有收到工具的卖家,点击↓即可免费试用!
3.上传
点击保存设置后,会跳转至上传页面,如下图:
工具限时免费,快来试用吧~
卖家可以通过浏览器操作将宝贝信息上传至列表,保存至草稿箱,或直接上架。如果上传失败,则不会保存到草稿箱。
此外,该页面还可以清空上传列表,删除勾选的宝贝,去除上传成功导出失败的链接,选择运费模板,一键勾选跳过重复上传的宝贝。
繁琐的操作也变得简单方便。通过工具装货,不仅可以解放双手,还可以减少失误,大大提高工作效率。
4.宝贝管理
对于店铺宝贝,卖家可以在宝贝列表中选择时间范围内的店铺、类目、商品id数据,批量下架、修改价格和库存等,一键删除/清空宝贝。
工具限时免费,快来试用吧~
可设置清洁宝贝的创建时间、访问人数、采集
人数、销量等,并可一键导出数据,查看修改失败记录。
注:右键列表可以查看上一个宝贝的链接。
五、服务保障
这款宝贝复制工具不仅功能稳定,而且还有完善的服务体系。多名技术人员24/7在线,随时处理用户问题。
无论是工具安装问题,还是日常操作问题,卖家总能找到工作人员实时沟通。
同时,工具技术团队会定期采集
用户需求,进行有针对性的开发和研发,并保持工具功能版本不断更新,满足大家对商品的需求。
如果您需要工具,可以免费试用!
以上是宝贝复制工具的概况。功能稳定,服务保障完善。商户可以轻松完成装货操作,大大提高工作效率。 查看全部
干货教程:【Python】抖音采集话题/音乐/用户作品和喜欢+调用Aria2下载+fire
抖音集合开源仓库
介绍
Python 获取数据 + Vue 写入接口 + Aria2 下载
根据抖音的各种链接或ID,通过网页界面采集视频作品并下载到本地计算机。
支持用户主页链接或sec_uid/主题挑战和音乐配乐链接或ID。
支持下载喜欢的列表(需要喜欢的列表可见)。
使用0x00安装依赖项
在程序目录中打开命令行,然后输入
pip install -r requirements.txt
0x01 使用界面
双击打开启动.bat,或在程序目录中打开命令行,输入
python ui.py
0x02 直接修改 douyin.py 中的相关参数
完全不懂 Python 的朋友使用命令行或操作界面。
0x03 使用 exec.py 直接从命令行运行以查看命令列表,或使用 -h 参数查看帮助
python exec.py
python exec.py -h
python exec.py download -h
python exec.py download_batch -h
使用函数名称调用程序
--type 指定下载类型,默认值:--type=user
--limit 指定采集数量,默认值:--limit=0(不限制)
例如,采集
用户的所有作品:
python exec.py download https://v.douyin.com/xxxx/
python exec.py download 用户的secuid
例如,采集
用户喜欢的前 10 部作品:
python exec.py download MS4wLjABAAAAl7TJWjJJrnu11IlllB6Mi5V9VbAsQo1N987guPjctc8 --type=like --limit=10
python exec.py download 用户的secuid
例如,采集
音乐配乐的前 10 首作品:
python exec.py download https://v.douyin.com/xxxx/ --type=music --limit=10
python exec.py download 音乐ID --type=music --limit=10
TODO知识点:抖音相关Aria2相关Python相关命令行模块、火相关UI模块、pywebview相关抖音集合部分源码
# -*- encoding: utf-8 -*-
'''
@File : douyin.py
@Time : 2021年03月12日 18:16:57 星期五
@Author : erma0
@Version : 1.0
@Link : https://erma0.cn
@Desc : 抖音用户作品采集
'''
import json
import os
import time
from urllib.parse import parse_qs, urlparse
import requests
from download import Download
class Douyin(object):
"""
抖音用户类
采集作品列表
"""
def __init__(self, param: str, limit: int = 0):
"""
初始化用户信息
参数自动判断:ID/URL
"""
self.limit = limit
self.http = requests.Session()
self.url = ''
self.type = 'unknow'
self.download_path = '暂未定义目录'
# ↑ 预定义属性,避免调用时未定义 ↑
self.param = param.strip()
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq' # sign可以固定
self.__get_type() # 判断当前任务类型:链接/ID
self.aria2 = Download() # 初始化Aria2下载服务,先不指定目录了,在设置文件名的时候再加入目录
self.has_more = True
self.finish = False
# 字典格式方便入库用id做key/取值/修改对应数据,但是表格都接收数组
self.videosL = [] #列表格式
# self.videos = {} #字典格式
self.gids = {} # gid和作品序号映射
def __get_type(self):
"""
判断当前任务类型
链接/ID
"""
if '://' in self.param: # 链接
self.__url2redirect()
else: # ID
self.id = self.param
def __url2redirect(self):
"""
取302跳转地址
短连接转长链接
"""
headers = { # 以前作品需要解析去水印,要用到移动端UA,现在不用了
'User-Agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/89.0.4389.82'
}
try:
r = self.http.head(self.param, headers=headers, allow_redirects=False)
self.url = r.headers['Location']
except:
self.url = self.param
def __url2id(self):
try:
self.id = urlparse(self.url).path.split('/')[3]
except:
self.id = ''
def __url2uid(self):
try:
<p>

query = urlparse(self.url).query
self.id = parse_qs(query)['sec_uid'][0]
except:
self.id = ''
def get_sign(self):
"""
网页sign算法,现在不需要了,直接固定
"""
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq'
return self.sign
def get_user_info(self):
"""
取用户信息
查询结果在 self.user_info
"""
if self.url:
self.__url2uid()
url = 'https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid=' + self.id
try:
res = self.http.get(url).json()
info = res.get('user_info', dict())
except:
info = dict()
self.user_info = info
# 下载路径
username = '{}_{}_{}'.format(self.user_info.get('short_id', '0'),
self.user_info.get('nickname', '无昵称'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_challenge_info(self):
"""
取话题挑战信息
查询结果在 self.challenge_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/challenge/info/?ch_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('ch_info', dict())
except:
info = dict()
self.challenge_info = info
# 话题挑战下载路径
username = '{}_{}_{}'.format(self.challenge_info.get('cid', '0'),
self.challenge_info.get('cha_name', '无标题'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_music_info(self):
"""
取音乐原声信息
查询结果在 self.music_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/music/info/?music_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('music_info', dict())
except:
info = dict()
self.music_info = info
# 音乐原声下载路径
username = '{}_{}_{}'.format(self.music_info.get('mid', '0'), self.music_info.get('title', '无标题'),
self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def crawling_users_post(self):
"""
采集用户作品
"""
self.type = 'post'
self.__crawling_user()
def crawling_users_like(self):
"""
采集用户喜欢
"""
self.type = 'like'
self.__crawling_user()
def crawling_challenge(self):
"""
采集话题挑战
"""
self.type = 'challenge'
self.get_challenge_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... QFzfg
url = 'https://www.iesdouyin.com/web/api/v2/challenge/aweme/'
cursor = '0'
while self.has_more:
params = {
"ch_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('话题挑战采集出错')

print('话题挑战采集完成')
def crawling_music(self):
"""
采集音乐原声
"""
self.type = 'music'
self.get_music_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... OVC5j
url = 'https://www.iesdouyin.com/web/api/v2/music/list/aweme/'
cursor = '0'
while self.has_more:
params = {
"music_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('音乐原声采集出错')
print('音乐原声采集完成')
def __crawling_user(self):
"""
采集用户作品/喜欢
"""
self.get_user_info() # 取当前用户信息,昵称用做下载目录
max_cursor = 0
# https://www.iesdouyin.com/web/ ... tk%3D
# https://www.iesdouyin.com/web/ ... tk%3D
url = 'https://www.iesdouyin.com/web/api/v2/aweme/{}/'.format(self.type)
while self.has_more:
params = {
"sec_uid": self.id,
"count": "21",
"max_cursor": max_cursor,
"aid": "1128",
"_signature": self.sign,
"dytk": ""
}
try:
res = self.http.get(url, params=params).json()
max_cursor = res['max_cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('作品采集出错')
print('作品采集完成')
def __append_videos(self, res):
"""
数据入库
"""
if res.get('aweme_list'):
for item in res['aweme_list']:
info = item['statistics']
info.pop('forward_count')
info.pop('play_count')
info['desc'] = Download.title2path(item['desc']) # 需提前处理非法字符串
info['uri'] = item['video']['play_addr']['uri']
info['play_addr'] = item['video']['play_addr']['url_list'][0]
info['dynamic_cover'] = item['video']['dynamic_cover']['url_list'][0]
info['status'] = 0 # 下载进度状态;等待下载:0,下载中:0.xx;下载完成:1
# 列表格式
self.videosL.append(info)
# 字典格式
# self.videos[info['aweme_id']] = info
# 此处可以直接添加下载任务,不过考虑到下载占用网速,影响采集过程,所以采集完再下载
if self.limit:
more = len(self.videos) - self.limit
if more >= 0:
# 如果给出了限制采集数目,超出的删除后直接返回
self.has_more = False
# 列表格式
self.videosL = self.videosL[:self.limit]
# 字典格式
# for i in range(more):
# self.videos.popitem()
# return
else: # 还有作品的情况下没返回数据则进入这里
print('未采集完成,但返回作品列表为空')
def download_all(self):
"""
作品抓取完成后,统一添加下载任务
可选择在外部注册回调函数,监听下载任务状态
"""
for id, video in enumerate(self.videosL):
# for id, video in self.videos.items():
gid = self.aria2.download(url=video['play_addr'],
filename='{}/{}_{}.mp4'.format(self.download_path, video['aweme_id'],
video['desc'])
# ,options={'gid': id} # 指定gid
)
self.gids[gid] = id # 因为传入gid必须16位,所以就不指定gid了,另存一个字典映射
print('下载任务投递完成')</p>
技巧:拼多多大神是怎么复制抖音爆款上传到自己店铺的?这个工具无需授权
随着抖音小店的火爆,不少拼多多商家开始在抖音上寻找爆款商品,急需一款抖音宝到拼多多小店收款的工具。
今天要跟大家分享的是一款支持斗尚拼的工具。不仅可以采集复制宝物上架,还可以采集宝物进行分析优化。下面我主要介绍大家用的比较多的3个工具:
①宝贝复制:一键复制抖音小店宝贝上传至拼多多,支持批量采集
,可快速完成发货!
工具支持多次开启,无需授权,不绑定电脑。店铺团版支持5-200家店铺!
②图片处理器:抖音店铺宝贝图片一键采集
工具限时免费,快来试用吧~
本工具可以一键采集下载淘喜、拼多多、京东、豆店宝的主图、sku图、详情页、750详情图、主图视频、搜索列表展示图等,还可以自动拼接详情图片。
宝贝优化过程中,卖家可以采集竞品宝贝图片进行分析,并一键导出数据,方便美工学习和模仿。
③宝贝详情(评论/sku/买家秀/问大家)分析器:一键采集
抖音店铺宝贝评论/sku/买家秀/问大家
工具限时免费,快来试用吧~
一键采集
淘喜、拼多多、京东、豆店等各大平台评论、sku占比分析、下载买家秀等,并支持一键拆分评论根、根占比分析、挖掘产品卖点。重点采集
问大家,分析买家痛点。
工具免费分享,有需要的卖家可以免费试用!
下面,小编就为大家详细讲解一下拼多多宝贝复制工具的使用方法:
1.采集
宝贝
数据来源包括淘宝/天猫、1688、抖音小店、拼多多批发等平台。也就是说,卖家可以在淘宝、1688、抖音小店、批发商上采集
宝贝并上传到自己的店铺。
工具限时免费,快来试用吧~
淘宝平台采集宝贝数据,需要登录普通买家账号。如果采集
太多,可以在多个帐户之间切换。1688和淘宝账号一样。
无需登录即可采集
拼多多批发宝贝数据。如果您采集
了拼多多宝贝的数据,可以通过手机号和token登录。
多多宝的采集
方式可以通过关键词和分类采集
,也可以全店采集
、其他平台采集
、复制或批量导入。
2.上传配置
宝贝收好后,进入配置页面:

工具限时免费,快来试用吧~
还没有收到工具的卖家可以免费试用,还有限时会员权限!
一、价格
拼多多上的商品价格包括单价、单价、折扣价、最低SKU价等,采集
淘宝宝贝一般默认为折扣价,折扣价显示如下图:
如果优惠价格是临时活动,没有优惠后,源链接价格会上涨。
拼多多默认单价,可以通过加百分比、加减固定金额、指定价格等方式设置。
工具限时免费,快来试用吧~
2. 图片
主图可以默认不处理,也可以选择以下几张作为主图。采集到的淘宝宝贝只有5张主图,工具可以自动补全10张主图。
细节图也可以不处理,也可以去掉指定位置的地图,保留编号,也可以插入自定义细节图,自定义细节加水印。
对于采集到的淘宝宝贝,高度超过1500的详细图片可以自动压缩分割,压缩可以减少图片空间的占用。
注意:处理图片时,一定要勾选【使用图片空间上传图片】!如果你复制视频,你需要有上传视频的权限!
3.标题
标题设置包括标题清词(启用本地自定义过滤)、标题过滤词、标题替换(宝贝ID=新标题)等。标题可以通过添加前缀/后缀或直接替换来处理。
可以设置新标题只保留采集
宝贝标题前的字符数。特殊分类支持长标题校验【上传宝贝标题支持10个字符】。
标题重组可以分裂根,随机打乱和重组。
4.类别
因为商品类目是跨平台的,只是部分商品的类目分类会有所不同。需要手动指定四级类别(每个类别级别都必须选择),但大多数情况下默认匹配上一个类别。
5.单品
SKU规格配置,不同平台有不同的SKU属性,可以过滤/替换符号和违禁词,自动分割SKU名称和备注,商家也可以自定义SKU。
注意:如果没有sku,默认添加一个sku,最大数量限制为24个!
6.属性

商品类型可根据实际情况选择,如普通商品、虚拟商品、进口商品、积分卡或海外抄送个人邮寄等。
设置品牌(可以选择不使用该品牌或更换其他品牌),设置产品编码,是否支持假一赔十,7天无理由,坏了赔,是否秒-手/虚拟产品,您还可以自定义属性。
7. 运输
商家可以设置物流重量、物流类型、发货时间。
还没有收到工具的卖家,点击↓即可免费试用!
3.上传
点击保存设置后,会跳转至上传页面,如下图:
工具限时免费,快来试用吧~
卖家可以通过浏览器操作将宝贝信息上传至列表,保存至草稿箱,或直接上架。如果上传失败,则不会保存到草稿箱。
此外,该页面还可以清空上传列表,删除勾选的宝贝,去除上传成功导出失败的链接,选择运费模板,一键勾选跳过重复上传的宝贝。
繁琐的操作也变得简单方便。通过工具装货,不仅可以解放双手,还可以减少失误,大大提高工作效率。
4.宝贝管理
对于店铺宝贝,卖家可以在宝贝列表中选择时间范围内的店铺、类目、商品id数据,批量下架、修改价格和库存等,一键删除/清空宝贝。
工具限时免费,快来试用吧~
可设置清洁宝贝的创建时间、访问人数、采集
人数、销量等,并可一键导出数据,查看修改失败记录。
注:右键列表可以查看上一个宝贝的链接。
五、服务保障
这款宝贝复制工具不仅功能稳定,而且还有完善的服务体系。多名技术人员24/7在线,随时处理用户问题。
无论是工具安装问题,还是日常操作问题,卖家总能找到工作人员实时沟通。
同时,工具技术团队会定期采集
用户需求,进行有针对性的开发和研发,并保持工具功能版本不断更新,满足大家对商品的需求。
如果您需要工具,可以免费试用!
以上是宝贝复制工具的概况。功能稳定,服务保障完善。商户可以轻松完成装货操作,大大提高工作效率。
解决方案:服务器监控——Cacti(全新版)
采集交流 • 优采云 发表了文章 • 0 个评论 • 130 次浏览 • 2022-11-22 09:19
MariaDB-client MariaDB-server
MariaDB-devel
PHP \//安装 LAMP 架构 PHP-SNMP
php-ldap
php-pdo
php-mysql
php-devel
PHP-梨
PHP 通用
PHP-GD
php-mbstring
php-xml
php-process
Net-SNMP
net-snmp-utils
net-snmp-libs
net-snmp-agent-libs
net-snmp-devel
RRDTOOL
rrdtool-php
rrdtool-perl
RRDTOOL-devel
GCC OpenSSL-DEVEL
DOS2UNIX
自动会议
自动制作
Binutils libtool
CPP 后缀
glibc-headers
内核标头
格利布-德维尔GD
GD-DEVEL
帮助2人
新冠酸酯
wget 补丁// 以上都是配置仙人掌所需的插件[root@aa ~]# vi /etc/httpd/conf/httpd.confServerName [root@aa ~]# vi /etc/httpd/
conf.d/php.confLoadModule php5_module modules/libphp5.so[root@aa ~]# vi /etc/php.inisafe_mode = off // Add date.timezone = PRC //Find modification [root@aa ~]# systemctl stop firewalld.service[root@aa ~]# setenforce 0[root@aa ~]# systemctl start httpd.service[root@aa ~]# systemctl start mariadb.service
成功启动 [root@aa ~]#
mysql_secure_installation // 按照提示初步设置 Mariadb,设置密码,删除匿名用户,打开根远程登录,刷新权限下方灯测试,先测试 PHP 健康状态 [root@aa ~]# vi /var/www/html/index.php // 加入测试页面 Win10 访问
PHP 工作正常,以下测试数据库连接 [root@aa ~]# mysql -uroot –p//登录数据库进行测试帐户仙人掌授权 MariaDB [(none)]> 创建数据库 仙人掌字符集 utf8 整理utf8_bin;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'%' 由 'admin123' 标识;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'localhost' 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/index.php // 替换 Windows 10 访问的测试页面
数据库连接没有问题
---------可以开始安装 cacti--------------[root@aa ~]# tar xf cacti-1。26. .tar.gz[root@aa ~]# MV 仙人掌-1。1。26 /var/www/html/cacti[root@aa ~]# mysql -ucacti -p cacti < /var/www/html/cacti/cacti。sql输入 password:// 密码 admin123 将仙人掌的数据库导入 [root@aa ~]# mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -urootmysql -pEnter password:// 密码是abc123,1。1。cacti 版本 26 需要导入时间数据库 [root@aa ~]# mysql -uroot –p//授予 cacti 用户对时间数据库 MariaDB [(none)] 的权限>授予 mysql 上的选择。time_zone_name “cacti”@“localhost” 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/cacti/include/config。
php$database_username = 'cacti'; $database_password = 'admin123';//要修改这两个项目,数据库不在本地计算机上,需要修改 $rdatabase 对应的条目并删除注释 [root@aa ~]# vi /etc/snmp/snmpd。 confcom2sec notConfigUser localhost public // 更改为环回地址 41access notConfigGroup “”anynoauth exact all none none// 将系统视图更改为所有 62view 全部收录
。180 // 删除 # 符号 85[root@aa ~]# systemctl restart snmpd。service[root@aa ~]# systemctl enable snmpd。service[root@aa ~]# useradd -r -M cacti[root@aa ~]# chown -R cacti。cacti /var/www/html/cacti/rra/[root@aa ~]# chown -R cacti。
cacti /var/www/html/cacti/log/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/resource/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/cache[root@aa ~]# chown -R apache。Apache /var/www/html/cacti/scripts
-----------安装仙人掌脊椎
为了优化数据轮询速度-----新版本的 Cacti 可以在没有 PHP 脚本的情况下采集
数据,并且集成了一个新的插件 spine 用于采集
数据[root@aa ~]# rpm -ivh help2man-1.41.1-3.el7.noarch.rpm//install spine dependencies[root@aa ~]# ln -s /usr/ lib64/libmysqlclient.so.18.0.0 /usr/lib64/libmysqlclient.so[root@aa ~]# tar xf cacti-spine-1.1.26.tar.gz[root@aa ~]# CD 仙人掌-脊柱-1.1.26[root@aa 仙人掌脊椎-1.1.26]# ./ 配置[root@aa 仙人掌脊-1.1.26]# 制作 &&制作 install[root@aa ~]# cp /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf[root@aa ~]# vi /usr/local/spine/ etc/spine.conf// 修改相关参数DB_HostlocalhostDB_DatabasecactiDB_UsercactiDB_Passadmin123DB_Port3306
RDB_HostlocalhostRDB_DatabasecactiRDB_UsercactiRDB_Passadmin123RDB_Port3306配置后,win10可以访问192.168.80.181/cacti/进行安装
发现没有安装mbstring和snmp,数据库参数设置有问题,我们来优化一下
安装两个软件包[root@aa ~]# rpm -ivh php-mbstring-5.4.16-42.el7.x86_64.rpm[root@aa ~]#
rpm -ivh php-snmp-5.4.16-42.el7.x86_64.rpm 转到数据库设置 [root@aa ~]# vi /etc/f.d/fcharacter_set_ 服务器 = utf8mb4collation_server = utf8mb4_unicode_cicharacter_set_client = utf8mb4max_connections = 100max_heap_table_size = 256Mmax_allowed_packet = 16777216join_buffer_size = 64Mtmp_table_size = 64Minnodb_file_per_table = ONinnodb_buffer_pool_size = 1024Minnodb_doublewrite = OFFinnodb_lock_wait_timeout = 50innodb_flush_log_at_timeout = 3innodb_read_io_线程 = 32innodb_write_io_threads = 16[root@aa ~]# 服务 MariaDB 重启[root@aa ~]# 服务 httpd 重启,然后访问网页安装
软件包已安装
数据库配置没有问题,然后直接下一步
根据要求选择安装后,初始用户名admin密码admin,输入后需要更改密码,密码有一定的复杂度,必须超过8位数字(必须收录
大写小写字符)。
登录成功----------------以下仙人掌监控设置------------------控制台 -> 设置 -> 路径 -> 在 Spine 配置文件路径 /usr/local/spine/bin/spine 中填写 spine 二进制文件
位置文本框 在文件路径文本框中填写配置文件路径 /usr/local/spine/etc/spine.conf,然后单击保存。
控制台 ->设置 -> 轮询器
-> 在轮询器类型下拉框中选择脊柱,然后单击保存。注意:如果使用 spine,则以下两个轮换时间和计划任务间隔应设置为每分钟
添加设备和图形后,需要重建采集
器缓存。控制台>系统实用程序>重建轮询器缓存
点击进入以下屏幕,无需设置
仙人掌的基本配置之后,
你需要在服务器上添加一个定时任务来采集
数据(PHP 中定时任务的间隔是 5 分钟,而我们使用 Spine 模式时,定时任务的间隔是 1 分钟)[root@aa cacti]# crontab –e*/1 * * * * /usr/bin/php /var/www/html/cacti/poller.php >> /tmp/ cacti_rrdtool.log我们去仙人掌检查管理 设备(设备)检查 Linux 状态为 UP, 注意不要着急 脊椎方式刚开始大约需要2-5分钟,有快有慢
您可以在下面创建一个图表来分析所选设备
选择GO
然后直接选择图形查看仙人掌加工后的图片
解决方案:降本增效利器?Share Creators智能数字资产管理系统真香!
降本增效似乎是一个持续而永恒的话题。尤其是今年,尤为重要~
疫情不知不觉已经伴随我们三年了。在各行各业都受到疫情冲击较大的背景下,降本增效对于很多企业来说不再是锦上添花,而可能是唯一的出路。
随着市场的缩小和竞争的加剧,在更加“体量”的行业环境下,如何通过提升自身效率来有效降低成本,是每个团队都面临的问题。
什么是降低成本?如何提高效率?
要回答这个问题,我先来看看各个团队每天都在经历什么:
您是否经常淹没在充满不同版本和各种文件的文件夹中?苦苦寻找,还是找不到最新的文件分享?当你终于找到自己需要的资源时,往往需要通过不同的通讯软件与内部同事和外部伙伴公开分享。
简单计算一下,制作一个游戏角色需要2个月左右,目前国内平均制作价格为1000元/天,一个丢失的文件损失约4万元。你现在的公司能保证每个文件的流程文件和最终文件都能妥善备份,并且随时可以找到吗?
设计行业往往伴随着大量的数字资产,文件种类繁多,种类繁多。一个CG 3D文件动辄几十甚至上百GB,每个文件都需要下载到本地才能查看。在多办公室远程办公场景下,一个简单的文件重命名可能需要几个小时才能下载到本地才能完成。
Dropbox、Google Drive、云盘等外部工具上传下载需要大量的等待时间。对方上传的文件在一段时间后下载链接失效,文件被删除。这些都是很常见的问题。更糟糕的是,如果文件没有及时妥善备份,往往会给企业带来巨大的经济损失,而实际案例更是数不胜数……
这些看似常规的数字资产的搜索、共享、传输和备份,往往浪费了太多的时间,消耗了太多的精力。
长此以往,何谈降本增效?
是时候做出一些改变了。
欲善其事,必先利其器
效率的提升离不开先进工具的帮助。
根据普华永道的一项调查,一款优秀的数字资产管理软件可以帮助被调查团队在一年内节省一个月的制作时间,效率得到大幅提升。Share Creators智能数字资产管理系统就是这样一款软件。
Share Creators智能数字资产管理系统
无论是企业、团队还是个人,无论团队是远程工作还是协同工作,我们都希望Share Creators强大、智能的数字资源管理系统能够有效提高您和您团队的工作效率。
先看一下demo:
申请免费试用:
简单理解,我们的产品就是“企业级谷歌”,可以高效的帮您备份、搜索、复用、版本控制之前所有的历史资源和文档:
1、AI智能搜索快速找到所需资源
Share Creators拥有业界领先的AI识别功能,可智能解析资源文件,让您轻松找到所有文件。即使我们忘记给文件命名,也能被AI识别,随时找到对应的资源。
同时,强大的人工智能标签结合自定义个人标签库+团队标签池功能,可大幅提升搜索精准度。
你觉得这就结束了吗?Share Creators还提供了多种搜索方式,用户可以通过颜色、名称、标签、文件类型、文件大小、横竖排版、上传时间等属性进行搜索。这些强大的搜索不仅限于图像、PSD、视频文件等内部文件,还包括 URL、Google Drive 等其他系统中的文件。
2.支持上百种资源格式在线高速预览和即时反馈
Share Creators全面支持100多种资源格式,快速在线实时预览。目前支持的格式包括:2D图片、3D FBX/OBJ、2D-SPINE动画、视频、音频、PPT、word等。将支持Maya和3dmax在线观看),轻松实现高速秒级在线预览。
同时,您还可以进行查看回复、实时分享等多项操作。评论回复时,只需停在3D模型或视频的某一帧进行标注反馈,非常方便。
3. 便捷易用的分享交流:外包商管理的利器
数字资产的共享是日常工作中使用频率最高的功能之一。您可以直接从Share Creators界面选择单个文件或共享整个文件夹内容,整个过程简单方便。
Share Creators新增访客模式,充分满足外部合作伙伴的接入需求,与外包商合作的进度管理和审核变得更加得心应手。不再翻聊天记录,回到原来的更新,却发现文件已经过期,无法下载。
同时,当您对外共享数字资产时,可以为共享内容设置只读和可编辑两种共享权限,在满足不同需求的同时,最大程度保护共享内容的安全。
在日常交流方面,Share Creators支持整合常用的交流工具。飞书、钉钉、企业微信、Slack等通讯工具都可以通过API方式集成到Share Creators中。这样一来,整个公司的组织人员就可以轻松导入。人员离职,只能在通讯工具中删除,资产访问权限自动关闭,无需管理双方用户列表。
4、从生产工具到游戏引擎,上下游全流程接入
Share Creators可以实现Photoshop、After Effect等上游制作工具的对接,Unity、Unreal等游戏引擎的对接,以及SVN、Perforce码控等下游制作工具的对接(逐步上线,部分软件对接已有得到支持)。
Share Creators即将开放更多API接口,实现设计和游戏行业常用软件的深度融合,让整个制作过程更加方便快捷。
5.一键轻松采集
资源
Share Creators强大的一键资源采集
功能,可以轻松帮助设计师解决资源采集
问题。
点击批量采集
,在网页查看需要采集
的图片,轻松完成一键采集
。选中的图片会自动保存在Share Creators个人文件夹中,供您日后使用。
Share Creators还有强大的页面截图和屏幕录制功能。您可以选择对页面特定区域、页面可见区域或整个页面进行一键截图。
6、本地资源实时备份
Share Creators可以将本地资源实时同步到服务器,同时支持权限管理,最大程度降低资产不合理丢失的风险;实时同步的文件也可以让团队成员轻松实现远程或移动办公。
在Globee2022信息技术世界大奖的评选中,Share Creators智能数字资产管理系统成功斩获三项大奖,其中,在年度数字资产管理软件评选中,以极高的含金量成功摘得金奖。
目前,全球许多游戏开发商和工作室都在使用Share Creators来提高他们的数字资产管理效率。无数事例表明,Share Creators智能数字资产管理系统已经成为帮助他们降本增效的利器。
针对不同规模的团队,Share Creators 提供了基于用户数量的座位版本;针对大型企业,Share Creators提供了不限制用户数量的企业版。
这就是你苦苦寻找的提升工作效率的神器吗?快来免费体验Share Creators智能数字资产管理系统吧!
申请免费试用:
或者随时联系 查看全部
解决方案:服务器监控——Cacti(全新版)
MariaDB-client MariaDB-server
MariaDB-devel
PHP \//安装 LAMP 架构 PHP-SNMP
php-ldap
php-pdo
php-mysql
php-devel
PHP-梨
PHP 通用
PHP-GD
php-mbstring
php-xml
php-process
Net-SNMP
net-snmp-utils
net-snmp-libs
net-snmp-agent-libs
net-snmp-devel
RRDTOOL
rrdtool-php
rrdtool-perl
RRDTOOL-devel
GCC OpenSSL-DEVEL
DOS2UNIX
自动会议
自动制作
Binutils libtool

CPP 后缀
glibc-headers
内核标头
格利布-德维尔GD
GD-DEVEL
帮助2人
新冠酸酯
wget 补丁// 以上都是配置仙人掌所需的插件[root@aa ~]# vi /etc/httpd/conf/httpd.confServerName [root@aa ~]# vi /etc/httpd/
conf.d/php.confLoadModule php5_module modules/libphp5.so[root@aa ~]# vi /etc/php.inisafe_mode = off // Add date.timezone = PRC //Find modification [root@aa ~]# systemctl stop firewalld.service[root@aa ~]# setenforce 0[root@aa ~]# systemctl start httpd.service[root@aa ~]# systemctl start mariadb.service
成功启动 [root@aa ~]#
mysql_secure_installation // 按照提示初步设置 Mariadb,设置密码,删除匿名用户,打开根远程登录,刷新权限下方灯测试,先测试 PHP 健康状态 [root@aa ~]# vi /var/www/html/index.php // 加入测试页面 Win10 访问
PHP 工作正常,以下测试数据库连接 [root@aa ~]# mysql -uroot –p//登录数据库进行测试帐户仙人掌授权 MariaDB [(none)]> 创建数据库 仙人掌字符集 utf8 整理utf8_bin;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'%' 由 'admin123' 标识;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'localhost' 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/index.php // 替换 Windows 10 访问的测试页面
数据库连接没有问题
---------可以开始安装 cacti--------------[root@aa ~]# tar xf cacti-1。26. .tar.gz[root@aa ~]# MV 仙人掌-1。1。26 /var/www/html/cacti[root@aa ~]# mysql -ucacti -p cacti < /var/www/html/cacti/cacti。sql输入 password:// 密码 admin123 将仙人掌的数据库导入 [root@aa ~]# mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -urootmysql -pEnter password:// 密码是abc123,1。1。cacti 版本 26 需要导入时间数据库 [root@aa ~]# mysql -uroot –p//授予 cacti 用户对时间数据库 MariaDB [(none)] 的权限>授予 mysql 上的选择。time_zone_name “cacti”@“localhost” 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/cacti/include/config。
php$database_username = 'cacti'; $database_password = 'admin123';//要修改这两个项目,数据库不在本地计算机上,需要修改 $rdatabase 对应的条目并删除注释 [root@aa ~]# vi /etc/snmp/snmpd。 confcom2sec notConfigUser localhost public // 更改为环回地址 41access notConfigGroup “”anynoauth exact all none none// 将系统视图更改为所有 62view 全部收录
。180 // 删除 # 符号 85[root@aa ~]# systemctl restart snmpd。service[root@aa ~]# systemctl enable snmpd。service[root@aa ~]# useradd -r -M cacti[root@aa ~]# chown -R cacti。cacti /var/www/html/cacti/rra/[root@aa ~]# chown -R cacti。
cacti /var/www/html/cacti/log/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/resource/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/cache[root@aa ~]# chown -R apache。Apache /var/www/html/cacti/scripts
-----------安装仙人掌脊椎
为了优化数据轮询速度-----新版本的 Cacti 可以在没有 PHP 脚本的情况下采集
数据,并且集成了一个新的插件 spine 用于采集
数据[root@aa ~]# rpm -ivh help2man-1.41.1-3.el7.noarch.rpm//install spine dependencies[root@aa ~]# ln -s /usr/ lib64/libmysqlclient.so.18.0.0 /usr/lib64/libmysqlclient.so[root@aa ~]# tar xf cacti-spine-1.1.26.tar.gz[root@aa ~]# CD 仙人掌-脊柱-1.1.26[root@aa 仙人掌脊椎-1.1.26]# ./ 配置[root@aa 仙人掌脊-1.1.26]# 制作 &&制作 install[root@aa ~]# cp /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf[root@aa ~]# vi /usr/local/spine/ etc/spine.conf// 修改相关参数DB_HostlocalhostDB_DatabasecactiDB_UsercactiDB_Passadmin123DB_Port3306
RDB_HostlocalhostRDB_DatabasecactiRDB_UsercactiRDB_Passadmin123RDB_Port3306配置后,win10可以访问192.168.80.181/cacti/进行安装
发现没有安装mbstring和snmp,数据库参数设置有问题,我们来优化一下

安装两个软件包[root@aa ~]# rpm -ivh php-mbstring-5.4.16-42.el7.x86_64.rpm[root@aa ~]#
rpm -ivh php-snmp-5.4.16-42.el7.x86_64.rpm 转到数据库设置 [root@aa ~]# vi /etc/f.d/fcharacter_set_ 服务器 = utf8mb4collation_server = utf8mb4_unicode_cicharacter_set_client = utf8mb4max_connections = 100max_heap_table_size = 256Mmax_allowed_packet = 16777216join_buffer_size = 64Mtmp_table_size = 64Minnodb_file_per_table = ONinnodb_buffer_pool_size = 1024Minnodb_doublewrite = OFFinnodb_lock_wait_timeout = 50innodb_flush_log_at_timeout = 3innodb_read_io_线程 = 32innodb_write_io_threads = 16[root@aa ~]# 服务 MariaDB 重启[root@aa ~]# 服务 httpd 重启,然后访问网页安装
软件包已安装
数据库配置没有问题,然后直接下一步
根据要求选择安装后,初始用户名admin密码admin,输入后需要更改密码,密码有一定的复杂度,必须超过8位数字(必须收录
大写小写字符)。
登录成功----------------以下仙人掌监控设置------------------控制台 -> 设置 -> 路径 -> 在 Spine 配置文件路径 /usr/local/spine/bin/spine 中填写 spine 二进制文件
位置文本框 在文件路径文本框中填写配置文件路径 /usr/local/spine/etc/spine.conf,然后单击保存。
控制台 ->设置 -> 轮询器
-> 在轮询器类型下拉框中选择脊柱,然后单击保存。注意:如果使用 spine,则以下两个轮换时间和计划任务间隔应设置为每分钟
添加设备和图形后,需要重建采集
器缓存。控制台>系统实用程序>重建轮询器缓存
点击进入以下屏幕,无需设置
仙人掌的基本配置之后,
你需要在服务器上添加一个定时任务来采集
数据(PHP 中定时任务的间隔是 5 分钟,而我们使用 Spine 模式时,定时任务的间隔是 1 分钟)[root@aa cacti]# crontab –e*/1 * * * * /usr/bin/php /var/www/html/cacti/poller.php >> /tmp/ cacti_rrdtool.log我们去仙人掌检查管理 设备(设备)检查 Linux 状态为 UP, 注意不要着急 脊椎方式刚开始大约需要2-5分钟,有快有慢
您可以在下面创建一个图表来分析所选设备
选择GO
然后直接选择图形查看仙人掌加工后的图片
解决方案:降本增效利器?Share Creators智能数字资产管理系统真香!
降本增效似乎是一个持续而永恒的话题。尤其是今年,尤为重要~
疫情不知不觉已经伴随我们三年了。在各行各业都受到疫情冲击较大的背景下,降本增效对于很多企业来说不再是锦上添花,而可能是唯一的出路。
随着市场的缩小和竞争的加剧,在更加“体量”的行业环境下,如何通过提升自身效率来有效降低成本,是每个团队都面临的问题。
什么是降低成本?如何提高效率?
要回答这个问题,我先来看看各个团队每天都在经历什么:
您是否经常淹没在充满不同版本和各种文件的文件夹中?苦苦寻找,还是找不到最新的文件分享?当你终于找到自己需要的资源时,往往需要通过不同的通讯软件与内部同事和外部伙伴公开分享。
简单计算一下,制作一个游戏角色需要2个月左右,目前国内平均制作价格为1000元/天,一个丢失的文件损失约4万元。你现在的公司能保证每个文件的流程文件和最终文件都能妥善备份,并且随时可以找到吗?
设计行业往往伴随着大量的数字资产,文件种类繁多,种类繁多。一个CG 3D文件动辄几十甚至上百GB,每个文件都需要下载到本地才能查看。在多办公室远程办公场景下,一个简单的文件重命名可能需要几个小时才能下载到本地才能完成。
Dropbox、Google Drive、云盘等外部工具上传下载需要大量的等待时间。对方上传的文件在一段时间后下载链接失效,文件被删除。这些都是很常见的问题。更糟糕的是,如果文件没有及时妥善备份,往往会给企业带来巨大的经济损失,而实际案例更是数不胜数……
这些看似常规的数字资产的搜索、共享、传输和备份,往往浪费了太多的时间,消耗了太多的精力。
长此以往,何谈降本增效?
是时候做出一些改变了。
欲善其事,必先利其器
效率的提升离不开先进工具的帮助。
根据普华永道的一项调查,一款优秀的数字资产管理软件可以帮助被调查团队在一年内节省一个月的制作时间,效率得到大幅提升。Share Creators智能数字资产管理系统就是这样一款软件。
Share Creators智能数字资产管理系统
无论是企业、团队还是个人,无论团队是远程工作还是协同工作,我们都希望Share Creators强大、智能的数字资源管理系统能够有效提高您和您团队的工作效率。

先看一下demo:
申请免费试用:
简单理解,我们的产品就是“企业级谷歌”,可以高效的帮您备份、搜索、复用、版本控制之前所有的历史资源和文档:
1、AI智能搜索快速找到所需资源
Share Creators拥有业界领先的AI识别功能,可智能解析资源文件,让您轻松找到所有文件。即使我们忘记给文件命名,也能被AI识别,随时找到对应的资源。
同时,强大的人工智能标签结合自定义个人标签库+团队标签池功能,可大幅提升搜索精准度。
你觉得这就结束了吗?Share Creators还提供了多种搜索方式,用户可以通过颜色、名称、标签、文件类型、文件大小、横竖排版、上传时间等属性进行搜索。这些强大的搜索不仅限于图像、PSD、视频文件等内部文件,还包括 URL、Google Drive 等其他系统中的文件。
2.支持上百种资源格式在线高速预览和即时反馈
Share Creators全面支持100多种资源格式,快速在线实时预览。目前支持的格式包括:2D图片、3D FBX/OBJ、2D-SPINE动画、视频、音频、PPT、word等。将支持Maya和3dmax在线观看),轻松实现高速秒级在线预览。
同时,您还可以进行查看回复、实时分享等多项操作。评论回复时,只需停在3D模型或视频的某一帧进行标注反馈,非常方便。
3. 便捷易用的分享交流:外包商管理的利器
数字资产的共享是日常工作中使用频率最高的功能之一。您可以直接从Share Creators界面选择单个文件或共享整个文件夹内容,整个过程简单方便。
Share Creators新增访客模式,充分满足外部合作伙伴的接入需求,与外包商合作的进度管理和审核变得更加得心应手。不再翻聊天记录,回到原来的更新,却发现文件已经过期,无法下载。
同时,当您对外共享数字资产时,可以为共享内容设置只读和可编辑两种共享权限,在满足不同需求的同时,最大程度保护共享内容的安全。
在日常交流方面,Share Creators支持整合常用的交流工具。飞书、钉钉、企业微信、Slack等通讯工具都可以通过API方式集成到Share Creators中。这样一来,整个公司的组织人员就可以轻松导入。人员离职,只能在通讯工具中删除,资产访问权限自动关闭,无需管理双方用户列表。

4、从生产工具到游戏引擎,上下游全流程接入
Share Creators可以实现Photoshop、After Effect等上游制作工具的对接,Unity、Unreal等游戏引擎的对接,以及SVN、Perforce码控等下游制作工具的对接(逐步上线,部分软件对接已有得到支持)。
Share Creators即将开放更多API接口,实现设计和游戏行业常用软件的深度融合,让整个制作过程更加方便快捷。
5.一键轻松采集
资源
Share Creators强大的一键资源采集
功能,可以轻松帮助设计师解决资源采集
问题。
点击批量采集
,在网页查看需要采集
的图片,轻松完成一键采集
。选中的图片会自动保存在Share Creators个人文件夹中,供您日后使用。
Share Creators还有强大的页面截图和屏幕录制功能。您可以选择对页面特定区域、页面可见区域或整个页面进行一键截图。
6、本地资源实时备份
Share Creators可以将本地资源实时同步到服务器,同时支持权限管理,最大程度降低资产不合理丢失的风险;实时同步的文件也可以让团队成员轻松实现远程或移动办公。
在Globee2022信息技术世界大奖的评选中,Share Creators智能数字资产管理系统成功斩获三项大奖,其中,在年度数字资产管理软件评选中,以极高的含金量成功摘得金奖。
目前,全球许多游戏开发商和工作室都在使用Share Creators来提高他们的数字资产管理效率。无数事例表明,Share Creators智能数字资产管理系统已经成为帮助他们降本增效的利器。
针对不同规模的团队,Share Creators 提供了基于用户数量的座位版本;针对大型企业,Share Creators提供了不限制用户数量的企业版。
这就是你苦苦寻找的提升工作效率的神器吗?快来免费体验Share Creators智能数字资产管理系统吧!
申请免费试用:
或者随时联系
解决方案:如何使用 SkyWalking 给 Dubbo 服务做链路追踪?
采集交流 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-11-22 09:18
Skywalking监控截图:
Apache Skywalking(孵化器)简介
Apache Skywalking (Incubator) 专为微服务架构和云原生架构系统设计,支持分布式链路跟踪APM系统。Apache Skywalking(孵化器)通过加载探针采集
应用调用链接信息,对采集
到的调用链接信息进行分析,生成应用间关系、服务间关系和服务指标。Apache Skywalking (Incubating) 目前支持多种语言,包括 Java、.Net Core、Node.js 和 Go 语言。
目前Skywalking已经支持从6个可视化维度分析分布式系统的运行情况。
Dubbo与Apache Skywalking(孵化器)编写Dubbo示例程序
Dubbo示例程序已经上传到Github仓库。方便大家下载使用。
API工程
服务接口:
package org.apache.skywalking.demo.interfaces;<br /><br />public interface HelloService {<br /> String sayHello(String name);<br />}<br />
Dubbo服务提供项目
package org.apache.skywalking.demo.provider;<br /><br />@Service(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> protocol = "${dubbo.protocol.id}",<br /> registry = "${dubbo.registry.id}", timeout = 60000)<br />public class HelloServiceImpl implements HelloService {<br /><br /> public String sayHello(String name) {<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));<br /> return "Hello, " + name;<br /> }<br /><br />}<br />
消费者工程
package org.apache.skywalking.demo.consumer;<br /><br />@RestController<br />public class ConsumerController {<br /><br /> private static int COUNT = 0;<br /><br /> @Reference(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> url = "dubbo://localhost:20880", timeout = 60000)<br /> private HelloService helloService;<br /><br /> @GetMapping("/sayHello/{name}")<br /> public String sayHello(@PathVariable(name = "name") String name) {<br /> if ((COUNT++) % 3 == 0){<br /> throw new RuntimeException();<br /> }<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));<br /> return helloService.sayHello(name);<br /> }<br />}<br />
部署 Apache Skywalking(孵化器)
Apache Skywalking(孵化器)提供两种部署模式:单节点模式和集群模式。以下是单节点模式部署步骤。有关集群模式部署的详细信息,请参阅文档。
依赖第三方组件
JDK8+
弹性搜索 5.x
部署步骤
下载 Apache Skywalking 采集
器
部署弹性搜索
解压缩并启动 Skywalking Collector。运行 bin/startup.sh 命令启动 Skywalking Collector
启动示例程序
在启动示例程序之前,先执行编译打包命令:
./mvnw clean package<br />
启动服务提供者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-provider -Dskywalking.collector.servers=localhost:10800 dubbo-provider/target/dubbo-provider.jar<br />
启动服务消费者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-consumer -Dskywalking.collector.servers=localhost:10800 dubbo-consumer/target/dubbo-consumer.jar <br />
获得消费者提供的服务
curl http://localhost:8080/sayHello/test<br />
Skywalking监控截图:首页
/admin-guide/images/skywalking-dashboard.png 拓扑图
/admin-guide/images/skywalking-topology.png 应用视图
/admin-guide/images/skywalking-application.png
JVM信息
/admin-guide/images/skywalking-application_instance.png 服务视图
服务消费者:
/admin-guide/images/skywalking-service-consumer.png
服务提供者:
/admin-guide/images/skywalking-service-provider.png 跟踪视图
/admin-guide/images/skywalking-trace.png
跨度信息:
/admin-guide/images/skywalking-span-Info.png 报警视图
/admin-guide/images/skywalking-alarm.png
欢迎加入我的知识星球,一起探讨架构,交流源码。要加入,请按住下面的二维码:
知识星球上已更新源码,分析如下:
目前,《Dubbo源码解析》目录已在知识星球更新如下:
01.调试环境搭建
02.项目结构一览
03.配置配置
04.核心流程清单
05.扩展机制SPI
06.线程池
07.服务暴露Export
08. 服务参考 Refer
09.注册处
10.动态编译
11. 动态代理
12.服务调用Invoke
13.调用属性
14.过滤器
15.NIO 服务器
16.P2P服务器
解决方案:OZON平台产品审核不通过原因及产品上传常见错误
OZON官方有两种方式:单次上传和表单批量上传。上传后需要审核,目前是人工审核。很多卖家反映商品上传后“拒绝更新”,即商品审核不通过。是什么原因?
首先,确保您的产品或品牌可以在OZON上销售或不受限制。
二、首次上传填写商品信息前,一定要逐项查看填写的提示,并查看平台买家端的listing,可以有效避免出现明显错误。
三、卖家上传图片错误较多。上传前,他还查看了官方知识库中给出的详细上传图片要求。
以下是根据采集
到的买家反馈和实践经验总结的产品上传常见错误列表:
1.产品图片:图片底色偏暗或杂乱。上传的时候主图最好是无价的白底图(灰底图也可以),白色的东西可以深色,总之一定要干净整洁,尤其是主图,尺寸等信息不应该出现在图片中,只展示商品的全部内容,也应该整体展示,而不是只展示商品的一部分。对于服装,主要图片应显示在正面。
2. 多SKU:一个产品只能上传一个SKU。主副图颜色必须与SKU数量一致,同一商品不能出现多个SKU。请注意,这是一个严重的问题。
3.商品分类:上传商品时商品分类选择有问题,分类不确定。建议在买家网站上搜索并确认产品类别后再进行选择。
4、品牌问题:选择没有品牌的产品,但在产品栏目、图片或说明中显示品牌信息,或产品品牌信息不一致。
5.产品描述:描述太短,尺寸大小不对,收录
广告信息。
最后,如果产品已上传但未通过审核,将鼠标移到提醒编号上,系统通常会显示失败原因。 查看全部
解决方案:如何使用 SkyWalking 给 Dubbo 服务做链路追踪?
Skywalking监控截图:
Apache Skywalking(孵化器)简介
Apache Skywalking (Incubator) 专为微服务架构和云原生架构系统设计,支持分布式链路跟踪APM系统。Apache Skywalking(孵化器)通过加载探针采集
应用调用链接信息,对采集
到的调用链接信息进行分析,生成应用间关系、服务间关系和服务指标。Apache Skywalking (Incubating) 目前支持多种语言,包括 Java、.Net Core、Node.js 和 Go 语言。
目前Skywalking已经支持从6个可视化维度分析分布式系统的运行情况。
Dubbo与Apache Skywalking(孵化器)编写Dubbo示例程序
Dubbo示例程序已经上传到Github仓库。方便大家下载使用。
API工程
服务接口:
package org.apache.skywalking.demo.interfaces;<br /><br />public interface HelloService {<br /> String sayHello(String name);<br />}<br />
Dubbo服务提供项目
package org.apache.skywalking.demo.provider;<br /><br />@Service(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> protocol = "${dubbo.protocol.id}",<br /> registry = "${dubbo.registry.id}", timeout = 60000)<br />public class HelloServiceImpl implements HelloService {<br /><br /> public String sayHello(String name) {<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));<br /> return "Hello, " + name;<br /> }<br /><br />}<br />
消费者工程
package org.apache.skywalking.demo.consumer;<br /><br />@RestController<br />public class ConsumerController {<br /><br /> private static int COUNT = 0;<br /><br /> @Reference(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> url = "dubbo://localhost:20880", timeout = 60000)<br /> private HelloService helloService;<br /><br /> @GetMapping("/sayHello/{name}")<br /> public String sayHello(@PathVariable(name = "name") String name) {<br /> if ((COUNT++) % 3 == 0){<br /> throw new RuntimeException();<br /> }<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));<br /> return helloService.sayHello(name);<br /> }<br />}<br />
部署 Apache Skywalking(孵化器)
Apache Skywalking(孵化器)提供两种部署模式:单节点模式和集群模式。以下是单节点模式部署步骤。有关集群模式部署的详细信息,请参阅文档。
依赖第三方组件
JDK8+
弹性搜索 5.x
部署步骤
下载 Apache Skywalking 采集
器
部署弹性搜索
解压缩并启动 Skywalking Collector。运行 bin/startup.sh 命令启动 Skywalking Collector
启动示例程序
在启动示例程序之前,先执行编译打包命令:

./mvnw clean package<br />
启动服务提供者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-provider -Dskywalking.collector.servers=localhost:10800 dubbo-provider/target/dubbo-provider.jar<br />
启动服务消费者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-consumer -Dskywalking.collector.servers=localhost:10800 dubbo-consumer/target/dubbo-consumer.jar <br />
获得消费者提供的服务
curl http://localhost:8080/sayHello/test<br />
Skywalking监控截图:首页
/admin-guide/images/skywalking-dashboard.png 拓扑图
/admin-guide/images/skywalking-topology.png 应用视图
/admin-guide/images/skywalking-application.png
JVM信息
/admin-guide/images/skywalking-application_instance.png 服务视图
服务消费者:
/admin-guide/images/skywalking-service-consumer.png
服务提供者:
/admin-guide/images/skywalking-service-provider.png 跟踪视图
/admin-guide/images/skywalking-trace.png

跨度信息:
/admin-guide/images/skywalking-span-Info.png 报警视图
/admin-guide/images/skywalking-alarm.png
欢迎加入我的知识星球,一起探讨架构,交流源码。要加入,请按住下面的二维码:
知识星球上已更新源码,分析如下:
目前,《Dubbo源码解析》目录已在知识星球更新如下:
01.调试环境搭建
02.项目结构一览
03.配置配置
04.核心流程清单
05.扩展机制SPI
06.线程池
07.服务暴露Export
08. 服务参考 Refer
09.注册处
10.动态编译
11. 动态代理
12.服务调用Invoke
13.调用属性
14.过滤器
15.NIO 服务器
16.P2P服务器
解决方案:OZON平台产品审核不通过原因及产品上传常见错误
OZON官方有两种方式:单次上传和表单批量上传。上传后需要审核,目前是人工审核。很多卖家反映商品上传后“拒绝更新”,即商品审核不通过。是什么原因?
首先,确保您的产品或品牌可以在OZON上销售或不受限制。
二、首次上传填写商品信息前,一定要逐项查看填写的提示,并查看平台买家端的listing,可以有效避免出现明显错误。

三、卖家上传图片错误较多。上传前,他还查看了官方知识库中给出的详细上传图片要求。
以下是根据采集
到的买家反馈和实践经验总结的产品上传常见错误列表:
1.产品图片:图片底色偏暗或杂乱。上传的时候主图最好是无价的白底图(灰底图也可以),白色的东西可以深色,总之一定要干净整洁,尤其是主图,尺寸等信息不应该出现在图片中,只展示商品的全部内容,也应该整体展示,而不是只展示商品的一部分。对于服装,主要图片应显示在正面。
2. 多SKU:一个产品只能上传一个SKU。主副图颜色必须与SKU数量一致,同一商品不能出现多个SKU。请注意,这是一个严重的问题。

3.商品分类:上传商品时商品分类选择有问题,分类不确定。建议在买家网站上搜索并确认产品类别后再进行选择。
4、品牌问题:选择没有品牌的产品,但在产品栏目、图片或说明中显示品牌信息,或产品品牌信息不一致。
5.产品描述:描述太短,尺寸大小不对,收录
广告信息。
最后,如果产品已上传但未通过审核,将鼠标移到提醒编号上,系统通常会显示失败原因。
分享文章:织梦CMS实现复制文章自动加出处信息(织梦文章调用标签)
采集交流 • 优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2022-11-21 02:29
如果你发现自己辛辛苦苦创作的很多文章被别人复制或采集
,没有留下一个链接,你会不会非常生气和郁闷?好在我们还有一些基本的保护措施可以减少损失,那就是使用javascript来实现对文章原作者的基本版权保护。复制或采集
时,会自动添加文章出处。其实这个功能的实现代码很简单,只需要在内容页模板(article_*.htm)的区域添加代码即可:
document.body.oncopy = function (){
<p>
setTimeout(function (){
var text = clipboardData.getData("text");
if (text){
texttext = text + "rn本文转载于{dede:global.cfg_webname/}:{dede:global.cfg_basehost/}-原文链接:"+location.href;
clipboardData.setData("text", text);
}
},100)
}
</p>
嗯,赶快试试吧!
技巧:什么工具可以输入关键词自动生成文章?
一、文章采集工具来源
文章采集、聚合、二次收录、权重站维护程序
普通的文章采集、批量采集和发布已经不能满足搜索引擎的需求。懂基本百度相似度算法simhash算法的人应该都做过文章相似度检测。经过我的实际测试,大部分伪原创文章搜索引擎都可以识别文章,真正优质的文章不仅要原创,还要有完整的语义,能够完全帮助用户解决问题。比如像一个短视频平台,如果一个视频从头到尾都是废话,没有回答开头提出的问题,那你是不是要评论喷作者废话,跑题了;所以文章实用,第一时间解决用户心中的疑惑,这是一篇好文章,
今天我们就来看看自媒体文章采集工具:
现在比较实用的媒体文章采集工具有易写文章采集工具,可以批量采集媒体文章,可以选择不同的媒体平台,还可以选择内容发布时间,输入你要搜索的内容即可 关键词,可以获得很多相关的内容素材,可以选择下载,视频采集方法同理。
什么是自媒体文章采集工具?
自媒体文章采集工具,顾名思义,就是一款可以采集自媒体文章的工具。
本工具可以采集
海量文章和图片,为你的创作带来灵感,操作简单方便。
对于素材需求高的工作室和公司,使用这个工具会节省很多时间。
2、趣快拍AI搜索聚合文章及问答采集工具
通过整合百度(百度知乎)、搜狗(搜狗问答)、360(360问答)、新浪(新浪爱客)、今日头条(悟空问答)、知乎(知乎问答、知乎话题)以及自媒体平台今日头条,搜狐、百家号利用自动语义检测算法、相似度检测算法、段落拆分与组合,将不同文章中语义最接近的段落进行整合,生成聚合优质文章。第一,可以满足百度的相似度算法;原创优质文章段落,三是可以自定义内容模板,增加内容模板的原创性,这是普通采集工具无法企及的。
问答聚合文章
网站日常秒收三、文章收录工具聚合程序介绍
支持Google SEO文章生成100多种语言的外贸软文,支持开源CMS自动发布。(目前支持zblog、WordPress、织梦cms、帝国cms、迅锐cms、小旋风蜘蛛池等自动收发布自动上传),支持文章定时定量发布,支持html与纯文本相互转换。通过IF-TDF算法、simHash、NLP、段落分词、完备的语义检测算法,匹配优质内容,多搜索引擎内容聚合,提高内容原创性和可读性;同时可以自定义内容模板,实现内容模板页面的多样性原创。
AI搜索提取文章合集
------------------by文子seo-button: 61910465----------------
[配置]
;搜索引擎(单篇文章模板只能设置这个)
searchengine=知乎、今日头条、新浪、百度、搜狗、360
;采集页数(默认采集第一页,多页会影响文章生成速度)
页=1
;文本长度(采集内容不得低于此文本长度)
字符长度=20
;标题样式(关键词和联想词不可移动)
titletype=关键词 联想词
;同一篇文章允许被调用的次数
时间 = 3
;是否删除原图
delimg=否
;平台名称,
;z-blog 自动发布:z-blog;
;帝国自动发布:diguo
;织梦自动发布:dede;
;wordpress 自动发布:wordpress;
;小旋风式文章; 小轩风;
;迅锐CMS自动发布:xunrui;
;留空会把生成的文章保存到shengcheng文件夹
平台=z-博客
;生成的文章数
publish_num=1000
;发布间隔秒
发布时间=300
;定时更新,每天固定时间运行程序(如果不定时,留空即可)
固定时间=
;是否打开全文翻译成英文,翻译是yes,不翻译是no
翻译=否
;自动检测要翻译的语言,默认auto
sl=自动
tl=en
;html是否转为文本格式,转为yes,不转为no
html_text=否 查看全部
分享文章:织梦CMS实现复制文章自动加出处信息(织梦文章调用标签)
如果你发现自己辛辛苦苦创作的很多文章被别人复制或采集
,没有留下一个链接,你会不会非常生气和郁闷?好在我们还有一些基本的保护措施可以减少损失,那就是使用javascript来实现对文章原作者的基本版权保护。复制或采集
时,会自动添加文章出处。其实这个功能的实现代码很简单,只需要在内容页模板(article_*.htm)的区域添加代码即可:
document.body.oncopy = function (){
<p>

setTimeout(function (){
var text = clipboardData.getData("text");
if (text){
texttext = text + "rn本文转载于{dede:global.cfg_webname/}:{dede:global.cfg_basehost/}-原文链接:"+location.href;
clipboardData.setData("text", text);

}
},100)
}
</p>
嗯,赶快试试吧!
技巧:什么工具可以输入关键词自动生成文章?
一、文章采集工具来源
文章采集、聚合、二次收录、权重站维护程序
普通的文章采集、批量采集和发布已经不能满足搜索引擎的需求。懂基本百度相似度算法simhash算法的人应该都做过文章相似度检测。经过我的实际测试,大部分伪原创文章搜索引擎都可以识别文章,真正优质的文章不仅要原创,还要有完整的语义,能够完全帮助用户解决问题。比如像一个短视频平台,如果一个视频从头到尾都是废话,没有回答开头提出的问题,那你是不是要评论喷作者废话,跑题了;所以文章实用,第一时间解决用户心中的疑惑,这是一篇好文章,
今天我们就来看看自媒体文章采集工具:
现在比较实用的媒体文章采集工具有易写文章采集工具,可以批量采集媒体文章,可以选择不同的媒体平台,还可以选择内容发布时间,输入你要搜索的内容即可 关键词,可以获得很多相关的内容素材,可以选择下载,视频采集方法同理。
什么是自媒体文章采集工具?
自媒体文章采集工具,顾名思义,就是一款可以采集自媒体文章的工具。
本工具可以采集
海量文章和图片,为你的创作带来灵感,操作简单方便。
对于素材需求高的工作室和公司,使用这个工具会节省很多时间。
2、趣快拍AI搜索聚合文章及问答采集工具
通过整合百度(百度知乎)、搜狗(搜狗问答)、360(360问答)、新浪(新浪爱客)、今日头条(悟空问答)、知乎(知乎问答、知乎话题)以及自媒体平台今日头条,搜狐、百家号利用自动语义检测算法、相似度检测算法、段落拆分与组合,将不同文章中语义最接近的段落进行整合,生成聚合优质文章。第一,可以满足百度的相似度算法;原创优质文章段落,三是可以自定义内容模板,增加内容模板的原创性,这是普通采集工具无法企及的。
问答聚合文章
网站日常秒收三、文章收录工具聚合程序介绍
支持Google SEO文章生成100多种语言的外贸软文,支持开源CMS自动发布。(目前支持zblog、WordPress、织梦cms、帝国cms、迅锐cms、小旋风蜘蛛池等自动收发布自动上传),支持文章定时定量发布,支持html与纯文本相互转换。通过IF-TDF算法、simHash、NLP、段落分词、完备的语义检测算法,匹配优质内容,多搜索引擎内容聚合,提高内容原创性和可读性;同时可以自定义内容模板,实现内容模板页面的多样性原创。

AI搜索提取文章合集
------------------by文子seo-button: 61910465----------------
[配置]
;搜索引擎(单篇文章模板只能设置这个)
searchengine=知乎、今日头条、新浪、百度、搜狗、360
;采集页数(默认采集第一页,多页会影响文章生成速度)
页=1
;文本长度(采集内容不得低于此文本长度)
字符长度=20
;标题样式(关键词和联想词不可移动)
titletype=关键词 联想词
;同一篇文章允许被调用的次数
时间 = 3
;是否删除原图
delimg=否
;平台名称,
;z-blog 自动发布:z-blog;
;帝国自动发布:diguo
;织梦自动发布:dede;

;wordpress 自动发布:wordpress;
;小旋风式文章; 小轩风;
;迅锐CMS自动发布:xunrui;
;留空会把生成的文章保存到shengcheng文件夹
平台=z-博客
;生成的文章数
publish_num=1000
;发布间隔秒
发布时间=300
;定时更新,每天固定时间运行程序(如果不定时,留空即可)
固定时间=
;是否打开全文翻译成英文,翻译是yes,不翻译是no
翻译=否
;自动检测要翻译的语言,默认auto
sl=自动
tl=en
;html是否转为文本格式,转为yes,不转为no
html_text=否
解决方案:CN113726526A_人脸数据采集、验证的方法、设备及系统在审
采集交流 • 优采云 发表了文章 • 0 个评论 • 115 次浏览 • 2022-11-20 08:17
人脸数据采集、验证的方法、设备及系统
技术领域
本申请涉及信息技术领域,尤其涉及一种人脸数据采集、验证的方法、设备及系统。
背景技术
随着信息技术的发展,越来越多的场景中会使用到人脸识别技术。在使用人脸识别技术时,首先需要采集人脸数据,然后将采集到的人脸数据发送给处理设备中进行人脸识别。该上述过程中存在着人脸数据重放攻击风险,即攻击者使用此前交易中截获的人脸数据,或者在其他渠道获取的用户人脸数据,在人脸识别的通讯报文中进行替换,从而伪冒用户达到欺骗识别设备的目的。目前的解决方案一般是通过对报文完整性的保护来进行防范,如使用报文签名或者计算报文MAC(Media Access Control,介质访问控制)地址的方式,但是此种并不能从采集源头上防止重放攻击,仍然存在一定的安全风险。
发明内容
本申请的一个目的是提供一种人脸数据采集、验证的方案,用以解决现有方案中无法从采集源头上防止了重放攻击的问题。
本申请实施例提供了一种人脸数据采集方法,所述方法包括:
采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
本申请实施例还提供了一种人脸数据验证方法,所述方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
所述人脸识别服务器对收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种人脸数据采集和验证的方法,该方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
采集设备获取所述随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集的采集设备,所述采集设备包括:
数据接收装置,用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;
视频采集模块,用于采集人脸样本;
人脸输出模块,用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,其中,所述人脸识别服务器包括:
数据收发模块,用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
数据处理模块,用于生成所述随机数,对收录
设备公钥的数字证书进行证书验证,在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集和验证的系统,该系统包括:
采集设备,用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
人脸识别服务器,用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种计算设备,该设备包括用于存储计算机程序指令的存储器和用于执行计算机程序指令的处理器,其中,当该计算机程序指令被该处理器执行时,触发所述设备执行所述的方法。
此外,本申请实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现所述的方法。
本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
附图说明
通过阅读参照以下附图所作的对非限制性实施例所作的详细描述,本申请的其它特征、目的和优点将会变得更明显:
图1为本申请实施例中采集设备在实现人脸数据采集方法时的处理流程图;
图2为本申请实施例中可信人脸数据的一种数据构成示意图;
图3为本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程图;
图4为采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程图;
图5为本申请实施例提供的一种人脸数据采集和验证的方法的处理流程图;
图6为本申请实施例提供的另一种人脸数据采集和验证的方法的处理流程图;
图7为本申请实施例提供的一种计算设备的结构示意图;
附图中相同或相似的附图标记代表相同或相似的部件。
具体实施方式
下面结合附图对本申请作进一步详细描述。
在本申请一个典型的配置中,终端、服务网络的设备均包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体,可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的装置或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。
本申请实施例提供了一种人脸数据采集及验证方法,由采集设备实现人脸数据的采集,并由人脸识别服务器实现人脸数据的验证,该方案在采集设备上就对人脸样本添加了用于校验的内容,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
在实际场景中,所述采集设备可以是具有视频采集及信息处理功能的电子设备,例如收录
摄像头以及数据处理芯片的设备。其中,所述摄像头可以是能够采集彩色图像的普通摄像头,或者也可以是能够采集深度信息、红外信息等额外信息的摄像头。所述人脸识别服务器在实现时可以包括但不限于单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现,可以用于实现设置闹钟时的部分处理功能。在此,云由基于云计算(Cloud Computing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
图1示出了本申请实施例中采集设备在实现人脸数据采集方法时的处理流程,包括以下处理步骤:
步骤S101,采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本。所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
步骤S102,采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。其中,所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
步骤S103,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
图3示出了本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程,包括以下处理步骤:
步骤S301,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
步骤S302,人脸识别服务器获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得。
步骤S303,人脸识别服务器对收录
设备公钥的数字证书进行证书验证。其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
步骤S304,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
步骤S305,在通过签名验证后,所述人脸识别服务器对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数进行验证,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。由此,人脸识别服务器在生成对应于本次人脸数据采集的随机数,并将其提供给采集设备时,可以接收本地业务终端发送的随机数获取请求,而后根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
图4示出了采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程,具体流程包括准备阶段和使用阶段。其中,准备阶段的流程如下:
P1)为采集设备配置设备ID(即设备标识)和设备可信密钥对,其中设备ID是与每台采集设备一一对应的,设备可信密钥对可以是每台采集设备一套,也可以是一批次采集设备共享一套。在使用阶段之前,将设备ID和其对应的设备可信密钥对中的设备公钥上传到可信管理服务器上。
P2)采集设备在出厂时,在每一台采集设备写入其对应的设备ID,用来唯一标识该采集设备;另外,需要在采集设备中写入设备可信密钥对的设备私钥以及对应的设备公钥证书。
P3)人脸识别服务器从可信管理服务器获取到其用以签发设备公钥证书的私钥所对应的公钥。
使用阶段的流程如下:
S1)用户在本地业务终端上发起业务请求,例如实际场景中可以是人脸认证、人脸识别等与需要基于人脸数据实现的业务请求,本地业务终端从人脸识别服务器请求一个随机数;
S2)本地业务终端调用采集设备对用户进行人脸采集,并将随机数发送给采集设备;
S3)采集设备对用户人脸的原创
样本进行采集后,经过质量判断和活体检测后,作为人脸样本与设备标识、传入的随机数等信息一起使用设备私钥进行签名,获得人脸数据签名,然后与收录
设备公钥的数字证书一起形成可信人脸数据后,返回给本地业务终端。
S4)本地业务终端将获得的可信人脸数据块送至人脸识别服务器进行处理。
S5)人脸识别服务器对可信人脸数据进行验证,具体方法为:先使用可信管理服务器公钥验证可信人脸数据中附带的数字证书的合法性。如果验证通过,则使用该数字证书中的设备公钥,验证可信人脸数据中的人脸数据签名的合法性。如果验证通过,则验证可信人脸数据中的随机数与人脸识别服务器生成并保存的随机数是否一致。如果一致,则认为验证通过,可以使用该可信人脸数据中的人脸样本进行后续业务处理,例如进行人脸注册或者人脸识别等;
S6)人脸识别服务器返回处理结果给本地业务终端,例如人脸注册或者人脸识别的结果是否成功。
基于前述人脸数据的采集方案和验证方案,本申请实施例还提供了一种人脸数据采集和验证的方法,该方法所涉及的人脸识别服务器和采集设备的交互过程如下图5所示,包括如下步骤:
步骤S501,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
步骤S502,采集设备获取所述随机数,并采集人脸样本;
步骤S503,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S504,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S505,所述人脸识别服务器获取由采集设备生成的可信人脸数据;
步骤S506,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S507,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S508,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的一些实施例中,实现人脸数据采集和验证的方法时,还可以包括本地业务终端,所述本地业务终端与人脸识别服务器、采集设备之间的交互过程如下图6所示,包括如下步骤:
步骤S601,本地业务终端获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令;
步骤S602,本地业务终端向所述人脸识别服务器发送随机数获取请求;
步骤S603,人脸识别服务器根据所述随机数获取请求生成对应于本次人脸数据采集的随机数;
步骤S604,人脸识别服务器向所述本地业务终端返回所述随机数;
步骤S605,本地业务终端向所述采集设备发送采集调用指令和所述随机数;
步骤S606,采集设备获取所述随机数,并根据采集调用指令采集人脸样本;
步骤S607,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S608,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S609,所述人脸识别服务器获取由采集设备生成的可信人脸数据。采集设备在生成可信人脸数据之后,可以先将其发送给本地业务终端,再由本地业务终端将可信人脸数据发送至人脸识别服务器。
步骤S610,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S611,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S612,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
基于同一发明构思,本申请实施例中还提供了用于人脸数据采集的采集设备、用于人脸数据验证的人脸识别服务器以及用于实现人脸数据采集和验证的系统,所述采集设备、人脸识别服务器和系统对应的方法是前述实施例中相应方法,并且其解决问题的原理与该方法相似。
本申请实施例提供的一种用于人脸数据采集的采集设备的结构可以至少包括数据接收装置、视频采集模块和人脸输出模块。其中,所述数据接收装置用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;所述视频采集模块用于采集人脸样本;所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
由此,本申请的一些实施例中,所述视频采集模块可以包括采集单元和检测评估单元,所述采集单元用于采集人脸的原创
样本,而所述检测评估单元用于对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在获得待签名数据和人脸数据签名之后,人脸输出模块可以根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。由此,本申请的一些实施例中,所述采集设备还可以包括数据接收模块,该数据接收模块用于在获取人脸的原创
样本之前,获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,该人脸识别服务器可以包括数据收发模块和数据处理模块。其中,数据收发模块用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得人脸数据签名。
所述数据处理模块用于生成所述随机数,以及根据可信人脸数据进行各种验证,包括用于对收录
设备公钥的数字证书进行证书验证、使用所述数字证书中的设备公钥对人脸数据签名进行签名验证以及对校验数据进行校验数据验证。
其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
在通过证书验证后,所述人脸识别服务器的数据处理模块使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
在通过签名验证后,所述人脸识别服务器的数据处理模块对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,所述数据收发模块还用于接收本地业务终端发送的随机数获取请求,并向所述本地业务终端返回随机数,以使所述本地业务终端将所述随机数提供给采集设备;所述数据处理模块还用于根据所述随机数获取请求生成随机数。即用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。
此外,本申请的一些实施例还提供了一种用于人脸数据采集和验证的系统,系统至少包括采集设备和人脸识别服务器。
采集设备用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
人脸识别服务器则用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请的另一实施例中,所述该系统还可以包括本地业务终端。所述本地业务终端用于获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令,并向所述人脸识别服务器发送随机数获取请求;获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;以及向所述采集设备发送采集调用指令和所述随机数。
所述采集装置在采集人脸样本时,可以根据所述采集调用指令采集人脸样本;而所述人脸识别服务器在提供随机数时,可以根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
综上所述,本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
另外,本申请的一部分可被应用为计算机程序产品,例如计算机程序指令,当其被计算机执行时,通过该计算机的操作,可以调用或提供根据本申请的方法和/或技术方案。而调用本申请的方法的程序指令,可能被存储在固定的或可移动的记录介质中,和/或通过广播或其他信号承载媒体中的数据流而被传输,和/或被存储在根据程序指令运行的计算机设备的工作存储器中。在此,根据本申请的一些实施例包括一个如图7所示的计算设备,该设备包括存储有计算机可读指令的一个或多个存储器710和用于执行计算机可读指令的处理器720,其中,当该计算机可读指令被该处理器执行时,使得所述设备执行基于前述本申请的多个实施例的方法和/或技术方案。
此外,本申请的一些实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现前述本申请的多个实施例的方法和/或技术方案。
需要注意的是,本申请可在软件和/或软件与硬件的组合体中被实施,例如,可采用专用集成电路(ASIC)、通用目的计算机或任何其他类似硬件设备来实现。在一些实施例中,本申请的软件程序可以通过处理器执行以实现上文步骤或功能。同样地,本申请的软件程序(包括相关的数据结构)可以被存储到计算机可读记录介质中,例如,RAM存储器,磁或光驱动器或软磁盘及类似设备。另外,本申请的一些步骤或功能可采用硬件来实现,例如,作为与处理器配合从而执行各个步骤或功能的电路。
对于本领域技术人员而言,显然本申请不限于上述示范性实施例的细节,而且在不背离本申请的精神或基本特征的情况下,能够以其他的具体形式实现本申请。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本申请的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本申请内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。装置权利要求中陈述的多个单元或装置也可以由一个单元或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
整套解决方案:优采云
采集器之PBOOTCMS入库
网上已经有优采云
采集
器的使用方法。
我正在使用从云端下载的 优采云
PBOOTCMS 规则。但是在使用的时候发现在存储选择中只能存储新闻中心、新闻动态和公司动态三个类别。
今天我们就来说说如何修改存储列。顺带从头到尾说说优采云
的使用方法。
大哥step:下载插件。
首先我们在后台云平台上搜索PBOOT找到这个插件,然后下载。
看一下,这里可以看到一个APP的logo:PbootDemoSkycaiji
这个方法就是下载官方插件的方法。或者,您可以自己发布一个插件。
自己发布还是官方下载都无所谓。如果不是很熟悉,直接使用官方插件即可。
第 2 步:让我们创建一个新任务。
你可以随意填写。
然后点击:采集器设置
根据需要填写这些内容。
然后设置其他三个,比较简单。在此不再赘述。
第 3 步:让我们点击发布设置。
按选择,然后选择绑定。
这时候会报错。由于PBOOCMS不是系统已知的CMS,所以需要添加:@pboot
下面的插件会显示我们自己创建安装的插件。选择您使用的那个。如果我选择从云平台下载的pboot示例。
根据需要填写相关选项。
这时我们会发现,在分类栏目中,我们只能看到三个栏目:新闻中心、公司新闻、行业新闻。
这也是我们今天要讲的重点。
正如我们刚才所说,这是要记住的事情。这实际上是发布时调用的 PHP 文件。具体路径为: 在你的优采云
采集
网站的根目录下,找到这个文件夹:
\\plugin\\release\\cms
可以看到,有两个与刚才APP名称同名的PHP文件。你使用哪个插件对应修改哪个PHP文件。
我用的是官方的PbootDemoSkycaiji,我们打开这个PHP文件。
在醉酒的底部我们看到
public function param_option_category(){
<p>
$catsDb=$this->db()->table('__CONTENT_SORT__')->where("contenttpl='news.html'")->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}</p>
它指定了一个news.html,如果你改成:case.html,你会在优采云
的后台看到publication classification变成了一个case栏。因此,如果我们要显示所有的列,我们可以这样修改。
public function param_option_category(){
$catsDb=$this->db()->table('__CONTENT_SORT__')->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}
然后回到发布后台,就可以看到了。列出所有列。然后正常采集
和释放。 查看全部
解决方案:CN113726526A_人脸数据采集、验证的方法、设备及系统在审
人脸数据采集、验证的方法、设备及系统
技术领域
本申请涉及信息技术领域,尤其涉及一种人脸数据采集、验证的方法、设备及系统。
背景技术
随着信息技术的发展,越来越多的场景中会使用到人脸识别技术。在使用人脸识别技术时,首先需要采集人脸数据,然后将采集到的人脸数据发送给处理设备中进行人脸识别。该上述过程中存在着人脸数据重放攻击风险,即攻击者使用此前交易中截获的人脸数据,或者在其他渠道获取的用户人脸数据,在人脸识别的通讯报文中进行替换,从而伪冒用户达到欺骗识别设备的目的。目前的解决方案一般是通过对报文完整性的保护来进行防范,如使用报文签名或者计算报文MAC(Media Access Control,介质访问控制)地址的方式,但是此种并不能从采集源头上防止重放攻击,仍然存在一定的安全风险。
发明内容
本申请的一个目的是提供一种人脸数据采集、验证的方案,用以解决现有方案中无法从采集源头上防止了重放攻击的问题。
本申请实施例提供了一种人脸数据采集方法,所述方法包括:
采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
本申请实施例还提供了一种人脸数据验证方法,所述方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
所述人脸识别服务器对收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种人脸数据采集和验证的方法,该方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
采集设备获取所述随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集的采集设备,所述采集设备包括:
数据接收装置,用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;
视频采集模块,用于采集人脸样本;
人脸输出模块,用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,其中,所述人脸识别服务器包括:
数据收发模块,用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
数据处理模块,用于生成所述随机数,对收录
设备公钥的数字证书进行证书验证,在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集和验证的系统,该系统包括:
采集设备,用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
人脸识别服务器,用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种计算设备,该设备包括用于存储计算机程序指令的存储器和用于执行计算机程序指令的处理器,其中,当该计算机程序指令被该处理器执行时,触发所述设备执行所述的方法。
此外,本申请实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现所述的方法。
本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
附图说明
通过阅读参照以下附图所作的对非限制性实施例所作的详细描述,本申请的其它特征、目的和优点将会变得更明显:
图1为本申请实施例中采集设备在实现人脸数据采集方法时的处理流程图;
图2为本申请实施例中可信人脸数据的一种数据构成示意图;
图3为本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程图;
图4为采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程图;
图5为本申请实施例提供的一种人脸数据采集和验证的方法的处理流程图;
图6为本申请实施例提供的另一种人脸数据采集和验证的方法的处理流程图;

图7为本申请实施例提供的一种计算设备的结构示意图;
附图中相同或相似的附图标记代表相同或相似的部件。
具体实施方式
下面结合附图对本申请作进一步详细描述。
在本申请一个典型的配置中,终端、服务网络的设备均包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体,可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的装置或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。
本申请实施例提供了一种人脸数据采集及验证方法,由采集设备实现人脸数据的采集,并由人脸识别服务器实现人脸数据的验证,该方案在采集设备上就对人脸样本添加了用于校验的内容,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
在实际场景中,所述采集设备可以是具有视频采集及信息处理功能的电子设备,例如收录
摄像头以及数据处理芯片的设备。其中,所述摄像头可以是能够采集彩色图像的普通摄像头,或者也可以是能够采集深度信息、红外信息等额外信息的摄像头。所述人脸识别服务器在实现时可以包括但不限于单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现,可以用于实现设置闹钟时的部分处理功能。在此,云由基于云计算(Cloud Computing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
图1示出了本申请实施例中采集设备在实现人脸数据采集方法时的处理流程,包括以下处理步骤:
步骤S101,采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本。所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
步骤S102,采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。其中,所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
步骤S103,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
图3示出了本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程,包括以下处理步骤:
步骤S301,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
步骤S302,人脸识别服务器获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得。
步骤S303,人脸识别服务器对收录
设备公钥的数字证书进行证书验证。其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
步骤S304,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
步骤S305,在通过签名验证后,所述人脸识别服务器对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数进行验证,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。由此,人脸识别服务器在生成对应于本次人脸数据采集的随机数,并将其提供给采集设备时,可以接收本地业务终端发送的随机数获取请求,而后根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
图4示出了采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程,具体流程包括准备阶段和使用阶段。其中,准备阶段的流程如下:
P1)为采集设备配置设备ID(即设备标识)和设备可信密钥对,其中设备ID是与每台采集设备一一对应的,设备可信密钥对可以是每台采集设备一套,也可以是一批次采集设备共享一套。在使用阶段之前,将设备ID和其对应的设备可信密钥对中的设备公钥上传到可信管理服务器上。
P2)采集设备在出厂时,在每一台采集设备写入其对应的设备ID,用来唯一标识该采集设备;另外,需要在采集设备中写入设备可信密钥对的设备私钥以及对应的设备公钥证书。
P3)人脸识别服务器从可信管理服务器获取到其用以签发设备公钥证书的私钥所对应的公钥。
使用阶段的流程如下:
S1)用户在本地业务终端上发起业务请求,例如实际场景中可以是人脸认证、人脸识别等与需要基于人脸数据实现的业务请求,本地业务终端从人脸识别服务器请求一个随机数;
S2)本地业务终端调用采集设备对用户进行人脸采集,并将随机数发送给采集设备;
S3)采集设备对用户人脸的原创
样本进行采集后,经过质量判断和活体检测后,作为人脸样本与设备标识、传入的随机数等信息一起使用设备私钥进行签名,获得人脸数据签名,然后与收录
设备公钥的数字证书一起形成可信人脸数据后,返回给本地业务终端。
S4)本地业务终端将获得的可信人脸数据块送至人脸识别服务器进行处理。
S5)人脸识别服务器对可信人脸数据进行验证,具体方法为:先使用可信管理服务器公钥验证可信人脸数据中附带的数字证书的合法性。如果验证通过,则使用该数字证书中的设备公钥,验证可信人脸数据中的人脸数据签名的合法性。如果验证通过,则验证可信人脸数据中的随机数与人脸识别服务器生成并保存的随机数是否一致。如果一致,则认为验证通过,可以使用该可信人脸数据中的人脸样本进行后续业务处理,例如进行人脸注册或者人脸识别等;
S6)人脸识别服务器返回处理结果给本地业务终端,例如人脸注册或者人脸识别的结果是否成功。
基于前述人脸数据的采集方案和验证方案,本申请实施例还提供了一种人脸数据采集和验证的方法,该方法所涉及的人脸识别服务器和采集设备的交互过程如下图5所示,包括如下步骤:
步骤S501,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
步骤S502,采集设备获取所述随机数,并采集人脸样本;
步骤S503,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S504,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S505,所述人脸识别服务器获取由采集设备生成的可信人脸数据;

步骤S506,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S507,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S508,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的一些实施例中,实现人脸数据采集和验证的方法时,还可以包括本地业务终端,所述本地业务终端与人脸识别服务器、采集设备之间的交互过程如下图6所示,包括如下步骤:
步骤S601,本地业务终端获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令;
步骤S602,本地业务终端向所述人脸识别服务器发送随机数获取请求;
步骤S603,人脸识别服务器根据所述随机数获取请求生成对应于本次人脸数据采集的随机数;
步骤S604,人脸识别服务器向所述本地业务终端返回所述随机数;
步骤S605,本地业务终端向所述采集设备发送采集调用指令和所述随机数;
步骤S606,采集设备获取所述随机数,并根据采集调用指令采集人脸样本;
步骤S607,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S608,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S609,所述人脸识别服务器获取由采集设备生成的可信人脸数据。采集设备在生成可信人脸数据之后,可以先将其发送给本地业务终端,再由本地业务终端将可信人脸数据发送至人脸识别服务器。
步骤S610,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S611,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S612,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
基于同一发明构思,本申请实施例中还提供了用于人脸数据采集的采集设备、用于人脸数据验证的人脸识别服务器以及用于实现人脸数据采集和验证的系统,所述采集设备、人脸识别服务器和系统对应的方法是前述实施例中相应方法,并且其解决问题的原理与该方法相似。
本申请实施例提供的一种用于人脸数据采集的采集设备的结构可以至少包括数据接收装置、视频采集模块和人脸输出模块。其中,所述数据接收装置用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;所述视频采集模块用于采集人脸样本;所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
由此,本申请的一些实施例中,所述视频采集模块可以包括采集单元和检测评估单元,所述采集单元用于采集人脸的原创
样本,而所述检测评估单元用于对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在获得待签名数据和人脸数据签名之后,人脸输出模块可以根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。由此,本申请的一些实施例中,所述采集设备还可以包括数据接收模块,该数据接收模块用于在获取人脸的原创
样本之前,获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,该人脸识别服务器可以包括数据收发模块和数据处理模块。其中,数据收发模块用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得人脸数据签名。
所述数据处理模块用于生成所述随机数,以及根据可信人脸数据进行各种验证,包括用于对收录
设备公钥的数字证书进行证书验证、使用所述数字证书中的设备公钥对人脸数据签名进行签名验证以及对校验数据进行校验数据验证。
其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
在通过证书验证后,所述人脸识别服务器的数据处理模块使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
在通过签名验证后,所述人脸识别服务器的数据处理模块对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,所述数据收发模块还用于接收本地业务终端发送的随机数获取请求,并向所述本地业务终端返回随机数,以使所述本地业务终端将所述随机数提供给采集设备;所述数据处理模块还用于根据所述随机数获取请求生成随机数。即用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。
此外,本申请的一些实施例还提供了一种用于人脸数据采集和验证的系统,系统至少包括采集设备和人脸识别服务器。
采集设备用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
人脸识别服务器则用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请的另一实施例中,所述该系统还可以包括本地业务终端。所述本地业务终端用于获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令,并向所述人脸识别服务器发送随机数获取请求;获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;以及向所述采集设备发送采集调用指令和所述随机数。
所述采集装置在采集人脸样本时,可以根据所述采集调用指令采集人脸样本;而所述人脸识别服务器在提供随机数时,可以根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
综上所述,本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
另外,本申请的一部分可被应用为计算机程序产品,例如计算机程序指令,当其被计算机执行时,通过该计算机的操作,可以调用或提供根据本申请的方法和/或技术方案。而调用本申请的方法的程序指令,可能被存储在固定的或可移动的记录介质中,和/或通过广播或其他信号承载媒体中的数据流而被传输,和/或被存储在根据程序指令运行的计算机设备的工作存储器中。在此,根据本申请的一些实施例包括一个如图7所示的计算设备,该设备包括存储有计算机可读指令的一个或多个存储器710和用于执行计算机可读指令的处理器720,其中,当该计算机可读指令被该处理器执行时,使得所述设备执行基于前述本申请的多个实施例的方法和/或技术方案。
此外,本申请的一些实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现前述本申请的多个实施例的方法和/或技术方案。
需要注意的是,本申请可在软件和/或软件与硬件的组合体中被实施,例如,可采用专用集成电路(ASIC)、通用目的计算机或任何其他类似硬件设备来实现。在一些实施例中,本申请的软件程序可以通过处理器执行以实现上文步骤或功能。同样地,本申请的软件程序(包括相关的数据结构)可以被存储到计算机可读记录介质中,例如,RAM存储器,磁或光驱动器或软磁盘及类似设备。另外,本申请的一些步骤或功能可采用硬件来实现,例如,作为与处理器配合从而执行各个步骤或功能的电路。
对于本领域技术人员而言,显然本申请不限于上述示范性实施例的细节,而且在不背离本申请的精神或基本特征的情况下,能够以其他的具体形式实现本申请。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本申请的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本申请内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。装置权利要求中陈述的多个单元或装置也可以由一个单元或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
整套解决方案:优采云
采集器之PBOOTCMS入库
网上已经有优采云
采集
器的使用方法。
我正在使用从云端下载的 优采云
PBOOTCMS 规则。但是在使用的时候发现在存储选择中只能存储新闻中心、新闻动态和公司动态三个类别。
今天我们就来说说如何修改存储列。顺带从头到尾说说优采云
的使用方法。
大哥step:下载插件。
首先我们在后台云平台上搜索PBOOT找到这个插件,然后下载。
看一下,这里可以看到一个APP的logo:PbootDemoSkycaiji
这个方法就是下载官方插件的方法。或者,您可以自己发布一个插件。
自己发布还是官方下载都无所谓。如果不是很熟悉,直接使用官方插件即可。
第 2 步:让我们创建一个新任务。
你可以随意填写。
然后点击:采集器设置
根据需要填写这些内容。
然后设置其他三个,比较简单。在此不再赘述。

第 3 步:让我们点击发布设置。
按选择,然后选择绑定。
这时候会报错。由于PBOOCMS不是系统已知的CMS,所以需要添加:@pboot
下面的插件会显示我们自己创建安装的插件。选择您使用的那个。如果我选择从云平台下载的pboot示例。
根据需要填写相关选项。
这时我们会发现,在分类栏目中,我们只能看到三个栏目:新闻中心、公司新闻、行业新闻。
这也是我们今天要讲的重点。
正如我们刚才所说,这是要记住的事情。这实际上是发布时调用的 PHP 文件。具体路径为: 在你的优采云
采集
网站的根目录下,找到这个文件夹:
\\plugin\\release\\cms
可以看到,有两个与刚才APP名称同名的PHP文件。你使用哪个插件对应修改哪个PHP文件。
我用的是官方的PbootDemoSkycaiji,我们打开这个PHP文件。
在醉酒的底部我们看到
public function param_option_category(){
<p>

$catsDb=$this->db()->table('__CONTENT_SORT__')->where("contenttpl='news.html'")->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}</p>
它指定了一个news.html,如果你改成:case.html,你会在优采云
的后台看到publication classification变成了一个case栏。因此,如果我们要显示所有的列,我们可以这样修改。
public function param_option_category(){
$catsDb=$this->db()->table('__CONTENT_SORT__')->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}
然后回到发布后台,就可以看到了。列出所有列。然后正常采集
和释放。
解决方案:Windows平台实现Unity下窗体|摄像头|屏幕采集并推送至RTMP服务器
采集交流 • 优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-11-19 07:31
技术背景
随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业的虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。
基于此,许多开发者苦于 Unity 环境中缺乏低延迟的推拉流解决方案。几年前,我们在Unity环境下推出了一款跨平台的低延迟RTMP|RTSP直播播放器,解决了很多问题。延迟关键的使用场景。
随着时间的推移,越来越多的开发者联系我们,希望我们能够在Unity环境下推出RTMP推送模块,从Unity中获取实时数据,实现延迟更低、效率更高的数据传输和推送。基于此,我们发布了Unity环境下的RTMP推送模块。
本文以Windows平台为例。数据来源为Unity窗口、摄像头或整屏、编码传输模块、或调用大牛直播SDK(官方)的原生接口。简单的界面是一个预览:
技术实现 1. 基本初始化
private bool InitSDK()
{
if (!is_pusher_sdk_init_)
{
// 设置日志路径(请确保目录存在)
String log_path = "D:\\pulisherlog";
NTSmartLog.NT_SL_SetPath(log_path);
UInt32 isInited = NTSmartPublisherSDK.NT_PB_Init(0, IntPtr.Zero);
if (isInited != 0)
{
Debug.Log("调用NT_PB_Init失败..");
return false;
}
is_pusher_sdk_init_ = true;
}
return true;
}
2.调用Open()接口获取推送实例
public bool OpenPublisherHandle(uint video_option, uint audio_option)
{
if (publisher_handle_ != IntPtr.Zero)
{
return true;
}
publisher_handle_count_ = 0;
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_Open(out publisher_handle_,
video_option, audio_option, 0, IntPtr.Zero))
{
return false;
}
if (publisher_handle_ != IntPtr.Zero)
{
pb_event_call_back_ = new NT_PB_SDKEventCallBack(PbEventCallBack);
NTSmartPublisherSDK.NT_PB_SetEventCallBack(publisher_handle_, IntPtr.Zero, pb_event_call_back_);
return true;
}
else
{
return false;
}
}
3.初始化参数配置
这里需要注意的是,如果要采集unity窗口,需要设置图层模式,先填充一层RGBA黑色背景,再添加一层用于叠加外部数据。
private void SetCommonOptionToPublisherSDK()
{
if (!IsPublisherHandleAvailable())
{
Debug.Log("SetCommonOptionToPublisherSDK, publisher handle with null..");
return;
}
NTSmartPublisherSDK.NT_PB_ClearLayersConfig(publisher_handle_, 0,
0, IntPtr.Zero);
if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_LAYER)
{
// 第0层填充RGBA矩形, 目的是保证帧率, 颜色就填充全黑
int red = 0;
int green = 0;
int blue = 0;
int alpha = 255;
NT_PB_RGBARectangleLayerConfig rgba_layer_c0 = new NT_PB_RGBARectangleLayerConfig();
rgba_layer_c0.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE;
rgba_layer_c0.base_.index_ = 0;
rgba_layer_c0.base_.enable_ = 1;
rgba_layer_c0.base_.region_.x_ = 0;
rgba_layer_c0.base_.region_.y_ = 0;
rgba_layer_c0.base_.region_.width_ = video_width_;
rgba_layer_c0.base_.region_.height_ = video_height_;
rgba_layer_c0.base_.offset_ = Marshal.OffsetOf(rgba_layer_c0.GetType(), "base_").ToInt32();
rgba_layer_c0.base_.cb_size_ = (uint)Marshal.SizeOf(rgba_layer_c0);
rgba_layer_c0.red_ = System.BitConverter.GetBytes(red)[0];
rgba_layer_c0.green_ = System.BitConverter.GetBytes(green)[0];
rgba_layer_c0.blue_ = System.BitConverter.GetBytes(blue)[0];
rgba_layer_c0.alpha_ = System.BitConverter.GetBytes(alpha)[0];
IntPtr rgba_conf = Marshal.AllocHGlobal(Marshal.SizeOf(rgba_layer_c0));
Marshal.StructureToPtr(rgba_layer_c0, rgba_conf, true);
UInt32 rgba_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
rgba_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE,
0, IntPtr.Zero);
Marshal.FreeHGlobal(rgba_conf);
NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();
external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 1;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;
external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);
IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));
Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);
UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,
0, IntPtr.Zero);
Marshal.FreeHGlobal(external_layer_conf);
}
<p>
else if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_CAMERA)
{
CameraInfo camera = cameras_[cur_sel_camera_index_];
NT_PB_VideoCaptureCapability cap = camera.capabilities_[cur_sel_camera_resolutions_index_];
SetVideoCaptureDeviceBaseParameter(camera.id_.ToString(), (UInt32)cap.width_, (UInt32)cap.height_);
}
SetFrameRate((UInt32)CalBitRate(edit_key_frame_, video_width_, video_height_));
Int32 type = 0; //软编码
Int32 encoder_id = 1;
UInt32 codec_id = (UInt32)NTCommonMediaDefine.NT_MEDIA_CODEC_ID.NT_MEDIA_CODEC_ID_H264;
Int32 param1 = 0;
SetVideoEncoder(type, encoder_id, codec_id, param1);
SetVideoQualityV2(CalVideoQuality(video_width_, video_height_, is_h264_encoder));
SetVideoMaxBitRate((CalMaxKBitRate(edit_key_frame_, video_width_, video_height_, false)));
SetVideoKeyFrameInterval((edit_key_frame_));
if (is_h264_encoder)
{
SetVideoEncoderProfile(1);
}
SetVideoEncoderSpeed(CalVideoEncoderSpeed(video_width_, video_height_, is_h264_encoder));
// 音频相关设置
SetAuidoInputDeviceId(0);
SetPublisherAudioCodecType(1);
SetPublisherMute(is_mute);
SetEchoCancellation(0, 0);
SetNoiseSuppression(0);
SetAGC(0);
SetVAD(0);
SetInputAudioVolume(Convert.ToSingle(edit_audio_input_volume_));
}
</p>
4.数据采集
摄像头和屏幕数据采集依然调用原生SDK接口,本文不再赘述。如果需要采集Unity形式的数据,可以参考如下代码:
if ( texture_ == null || video_width_ != Screen.width || video_height_ != Screen.height)
{
Debug.Log("OnPostRender screen changed++ scr_width: " + Screen.width + " scr_height: " + Screen.height);
if (screen_image_ != IntPtr.Zero)
{
Marshal.FreeHGlobal(screen_image_);
screen_image_ = IntPtr.Zero;
}
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
video_width_ = Screen.width;
video_height_ = Screen.height;
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.BGRA32, false);
screen_image_ = Marshal.AllocHGlobal(video_width_ * 4 * video_height_);
Debug.Log("OnPostRender screen changed--");
return;
}
texture_.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);
texture_.Apply();
从纹理中,通过调用 GetRawTextureData() 获取原创数据。
5、数据对接
获取原创数据后,通过调用系统封装的OnPostRGBAData()接口将数据传递给SDK层。
6.本地数据预览
public bool StartPreview()
{
if(CheckPublisherHandleAvailable() == false)
return false;
video_preview_image_callback_ = new NT_PB_SDKVideoPreviewImageCallBack(SDKVideoPreviewImageCallBack);
NTSmartPublisherSDK.NT_PB_SetVideoPreviewImageCallBack(publisher_handle_, (int)NTSmartPublisherDefine.NT_PB_E_IMAGE_FORMAT.NT_PB_E_IMAGE_FORMAT_RGB32, IntPtr.Zero, video_preview_image_callback_);
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPreview(publisher_handle_, 0, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
return false;
}
publisher_handle_count_++;
is_previewing_ = true;
return true;
}
public void StopPreview()
{
if (is_previewing_ == false) return;
is_previewing_ = false;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPreview(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
设置好预览后,处理预览的数据回调
//预览数据回调
public void SDKVideoPreviewImageCallBack(IntPtr handle, IntPtr user_data, IntPtr image)
{
NT_PB_Image pb_image = (NT_PB_Image)Marshal.PtrToStructure(image, typeof(NT_PB_Image));
NT_VideoFrame pVideoFrame = new NT_VideoFrame();
pVideoFrame.width_ = pb_image.width_;
pVideoFrame.height_ = pb_image.height_;
<p>
pVideoFrame.stride_ = pb_image.stride_[0];
Int32 argb_size = pb_image.stride_[0] * pb_image.height_;
pVideoFrame.plane_data_ = new byte[argb_size];
if (argb_size > 0)
{
Marshal.Copy(pb_image.plane_[0],pVideoFrame.plane_data_,0, argb_size);
}
{
cur_image_ = pVideoFrame;
}
}
</p>
7.相关事件回调处理
private void PbEventCallBack(IntPtr handle, IntPtr user_data,
UInt32 event_id,
Int64 param1,
Int64 param2,
UInt64 param3,
UInt64 param4,
[MarshalAs(UnmanagedType.LPStr)] String param5,
[MarshalAs(UnmanagedType.LPStr)] String param6,
IntPtr param7)
{
String event_log = "";
switch (event_id)
{
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTING:
event_log = "连接中";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTION_FAILED:
event_log = "连接失败";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTED:
event_log = "已连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_DISCONNECTED:
event_log = "断开连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
default:
break;
}
if(OnLogEventMsg != null) OnLogEventMsg.Invoke(event_id, event_log);
}
8.开始推送,停止推送
public bool StartPublisher(String url)
{
if (CheckPublisherHandleAvailable() == false) return false;
if (publisher_handle_ == IntPtr.Zero)
{
return false;
}
if (!String.IsNullOrEmpty(url))
{
NTSmartPublisherSDK.NT_PB_SetURL(publisher_handle_, url, IntPtr.Zero);
}
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPublisher(publisher_handle_, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
return false;
}
publisher_handle_count_++;
is_publishing_ = true;
return true;
}
public void StopPublisher()
{
if (is_publishing_ == false) return;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPublisher(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
}
9.关闭实例
public void Close()
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
总结
经测试,在Unity环境下,通过高效数据采集,编码推送,配合SmartPlayer播放,整体延迟可以控制在毫秒级,适合大部分Unity对延迟和稳定性的要求环境恶劣的场景。
解决方案:利用ROS采集VLP-16激光雷达数据
启动VLP-16激光雷达,想用ROS采集雷达数据,按照现有的教程总有一些小问题,现在分享自己成功采集的数据,希望对那些刚进坑的人有所帮助。
我使用 Ubuntu 16.04+ 动力学系统
1. 安装驱动程序
sudo apt-get install ros-kinetic-velodyne
2. 配置网络以连接到激光雷达(无需关闭无线):
修改 IPv4:在有线网络中
更改为手动
IP 地址为 192.168.1.77,
子网掩码为 255.255.255.0,网关为 192.168.1.1。然后连接激光雷达,
打开浏览器输入192.168.1.201,查看激光雷达配置文件。
每次连接雷达时,输入以下两个命令:
sudo ifconfig enp2s0 192.168.1.123
sudo 路由添加 192.168.1.201 enp2s0
3. 创建 ROS 项目:
MKDIR -P catkin_velodyne/SRC
光盘catkin_velodyne/SRC
git 克隆
光盘..
Rosdep install --from-path src --ignore-src --rosdistro kinetic -y
catkin_make
Source devel/setup.bash
4.将Velodyne XML文件转换为ROS节点的YAML文件,VLP-16.xml据说在免费的USB闪存盘中,反正没找到
我从互联网上下载了一个。请记住将下面的地址更改为您的 VLP-16 .xml文件的地址。
rosrun velodyne_pointcloud gen_calibration.py ~/VLP-16.xml (更改为你自己保存的目录)。
5. 加载:
roslaunch velodyne_pointcloud VLP16_points.launch calibration:=~/VLP-16.yaml (更改为你自己保存的目录)。
6、点云图实时展示:
Rosrun Rviz Rviz -F velodyne
然后按主题添加
rviz 添加 PointCloud2,并在主题中输入 /velodyne_points,这样得到的 3D 点云图就可以实时展示。
7. 记录数据:
我看到的教程是用 rosbagrecord-oout/velodyne_points 命令获取 /velodyne_points 主题的数据,但是当我去分析保存的数据时,发现里面的雷达数据被处理了,反正我根本无法解读。我想获取雷达原创UDP报文中的信息来生成距离和强度图像,所以我保存了/velodyne_packets这个主题的数据,保存的数据是收录UDP的正文,每76个UDP数据包(每周扫描360度)都有一个时间戳,然后根据手册就可以从数据中获取距离和强度信息。
罗斯巴格记录 -O 文件名 /velodyne_packets 查看全部
解决方案:Windows平台实现Unity下窗体|摄像头|屏幕采集并推送至RTMP服务器
技术背景
随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业的虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。
基于此,许多开发者苦于 Unity 环境中缺乏低延迟的推拉流解决方案。几年前,我们在Unity环境下推出了一款跨平台的低延迟RTMP|RTSP直播播放器,解决了很多问题。延迟关键的使用场景。
随着时间的推移,越来越多的开发者联系我们,希望我们能够在Unity环境下推出RTMP推送模块,从Unity中获取实时数据,实现延迟更低、效率更高的数据传输和推送。基于此,我们发布了Unity环境下的RTMP推送模块。
本文以Windows平台为例。数据来源为Unity窗口、摄像头或整屏、编码传输模块、或调用大牛直播SDK(官方)的原生接口。简单的界面是一个预览:
技术实现 1. 基本初始化
private bool InitSDK()
{
if (!is_pusher_sdk_init_)
{
// 设置日志路径(请确保目录存在)
String log_path = "D:\\pulisherlog";
NTSmartLog.NT_SL_SetPath(log_path);
UInt32 isInited = NTSmartPublisherSDK.NT_PB_Init(0, IntPtr.Zero);
if (isInited != 0)
{
Debug.Log("调用NT_PB_Init失败..");
return false;
}
is_pusher_sdk_init_ = true;
}
return true;
}
2.调用Open()接口获取推送实例
public bool OpenPublisherHandle(uint video_option, uint audio_option)
{
if (publisher_handle_ != IntPtr.Zero)
{
return true;
}
publisher_handle_count_ = 0;
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_Open(out publisher_handle_,
video_option, audio_option, 0, IntPtr.Zero))
{
return false;
}
if (publisher_handle_ != IntPtr.Zero)
{
pb_event_call_back_ = new NT_PB_SDKEventCallBack(PbEventCallBack);
NTSmartPublisherSDK.NT_PB_SetEventCallBack(publisher_handle_, IntPtr.Zero, pb_event_call_back_);
return true;
}
else
{
return false;
}
}
3.初始化参数配置
这里需要注意的是,如果要采集unity窗口,需要设置图层模式,先填充一层RGBA黑色背景,再添加一层用于叠加外部数据。
private void SetCommonOptionToPublisherSDK()
{
if (!IsPublisherHandleAvailable())
{
Debug.Log("SetCommonOptionToPublisherSDK, publisher handle with null..");
return;
}
NTSmartPublisherSDK.NT_PB_ClearLayersConfig(publisher_handle_, 0,
0, IntPtr.Zero);
if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_LAYER)
{
// 第0层填充RGBA矩形, 目的是保证帧率, 颜色就填充全黑
int red = 0;
int green = 0;
int blue = 0;
int alpha = 255;
NT_PB_RGBARectangleLayerConfig rgba_layer_c0 = new NT_PB_RGBARectangleLayerConfig();
rgba_layer_c0.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE;
rgba_layer_c0.base_.index_ = 0;
rgba_layer_c0.base_.enable_ = 1;
rgba_layer_c0.base_.region_.x_ = 0;
rgba_layer_c0.base_.region_.y_ = 0;
rgba_layer_c0.base_.region_.width_ = video_width_;
rgba_layer_c0.base_.region_.height_ = video_height_;
rgba_layer_c0.base_.offset_ = Marshal.OffsetOf(rgba_layer_c0.GetType(), "base_").ToInt32();
rgba_layer_c0.base_.cb_size_ = (uint)Marshal.SizeOf(rgba_layer_c0);
rgba_layer_c0.red_ = System.BitConverter.GetBytes(red)[0];
rgba_layer_c0.green_ = System.BitConverter.GetBytes(green)[0];
rgba_layer_c0.blue_ = System.BitConverter.GetBytes(blue)[0];
rgba_layer_c0.alpha_ = System.BitConverter.GetBytes(alpha)[0];
IntPtr rgba_conf = Marshal.AllocHGlobal(Marshal.SizeOf(rgba_layer_c0));
Marshal.StructureToPtr(rgba_layer_c0, rgba_conf, true);
UInt32 rgba_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
rgba_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE,
0, IntPtr.Zero);
Marshal.FreeHGlobal(rgba_conf);
NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();
external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 1;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;
external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);
IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));
Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);
UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,
0, IntPtr.Zero);
Marshal.FreeHGlobal(external_layer_conf);
}
<p>

else if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_CAMERA)
{
CameraInfo camera = cameras_[cur_sel_camera_index_];
NT_PB_VideoCaptureCapability cap = camera.capabilities_[cur_sel_camera_resolutions_index_];
SetVideoCaptureDeviceBaseParameter(camera.id_.ToString(), (UInt32)cap.width_, (UInt32)cap.height_);
}
SetFrameRate((UInt32)CalBitRate(edit_key_frame_, video_width_, video_height_));
Int32 type = 0; //软编码
Int32 encoder_id = 1;
UInt32 codec_id = (UInt32)NTCommonMediaDefine.NT_MEDIA_CODEC_ID.NT_MEDIA_CODEC_ID_H264;
Int32 param1 = 0;
SetVideoEncoder(type, encoder_id, codec_id, param1);
SetVideoQualityV2(CalVideoQuality(video_width_, video_height_, is_h264_encoder));
SetVideoMaxBitRate((CalMaxKBitRate(edit_key_frame_, video_width_, video_height_, false)));
SetVideoKeyFrameInterval((edit_key_frame_));
if (is_h264_encoder)
{
SetVideoEncoderProfile(1);
}
SetVideoEncoderSpeed(CalVideoEncoderSpeed(video_width_, video_height_, is_h264_encoder));
// 音频相关设置
SetAuidoInputDeviceId(0);
SetPublisherAudioCodecType(1);
SetPublisherMute(is_mute);
SetEchoCancellation(0, 0);
SetNoiseSuppression(0);
SetAGC(0);
SetVAD(0);
SetInputAudioVolume(Convert.ToSingle(edit_audio_input_volume_));
}
</p>
4.数据采集
摄像头和屏幕数据采集依然调用原生SDK接口,本文不再赘述。如果需要采集Unity形式的数据,可以参考如下代码:
if ( texture_ == null || video_width_ != Screen.width || video_height_ != Screen.height)
{
Debug.Log("OnPostRender screen changed++ scr_width: " + Screen.width + " scr_height: " + Screen.height);
if (screen_image_ != IntPtr.Zero)
{
Marshal.FreeHGlobal(screen_image_);
screen_image_ = IntPtr.Zero;
}
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
video_width_ = Screen.width;
video_height_ = Screen.height;
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.BGRA32, false);
screen_image_ = Marshal.AllocHGlobal(video_width_ * 4 * video_height_);
Debug.Log("OnPostRender screen changed--");
return;
}
texture_.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);
texture_.Apply();
从纹理中,通过调用 GetRawTextureData() 获取原创数据。
5、数据对接
获取原创数据后,通过调用系统封装的OnPostRGBAData()接口将数据传递给SDK层。
6.本地数据预览
public bool StartPreview()
{
if(CheckPublisherHandleAvailable() == false)
return false;
video_preview_image_callback_ = new NT_PB_SDKVideoPreviewImageCallBack(SDKVideoPreviewImageCallBack);
NTSmartPublisherSDK.NT_PB_SetVideoPreviewImageCallBack(publisher_handle_, (int)NTSmartPublisherDefine.NT_PB_E_IMAGE_FORMAT.NT_PB_E_IMAGE_FORMAT_RGB32, IntPtr.Zero, video_preview_image_callback_);
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPreview(publisher_handle_, 0, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
return false;
}
publisher_handle_count_++;
is_previewing_ = true;
return true;
}
public void StopPreview()
{
if (is_previewing_ == false) return;
is_previewing_ = false;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPreview(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
设置好预览后,处理预览的数据回调
//预览数据回调
public void SDKVideoPreviewImageCallBack(IntPtr handle, IntPtr user_data, IntPtr image)
{
NT_PB_Image pb_image = (NT_PB_Image)Marshal.PtrToStructure(image, typeof(NT_PB_Image));
NT_VideoFrame pVideoFrame = new NT_VideoFrame();
pVideoFrame.width_ = pb_image.width_;
pVideoFrame.height_ = pb_image.height_;
<p>

pVideoFrame.stride_ = pb_image.stride_[0];
Int32 argb_size = pb_image.stride_[0] * pb_image.height_;
pVideoFrame.plane_data_ = new byte[argb_size];
if (argb_size > 0)
{
Marshal.Copy(pb_image.plane_[0],pVideoFrame.plane_data_,0, argb_size);
}
{
cur_image_ = pVideoFrame;
}
}
</p>
7.相关事件回调处理
private void PbEventCallBack(IntPtr handle, IntPtr user_data,
UInt32 event_id,
Int64 param1,
Int64 param2,
UInt64 param3,
UInt64 param4,
[MarshalAs(UnmanagedType.LPStr)] String param5,
[MarshalAs(UnmanagedType.LPStr)] String param6,
IntPtr param7)
{
String event_log = "";
switch (event_id)
{
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTING:
event_log = "连接中";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTION_FAILED:
event_log = "连接失败";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTED:
event_log = "已连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_DISCONNECTED:
event_log = "断开连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
default:
break;
}
if(OnLogEventMsg != null) OnLogEventMsg.Invoke(event_id, event_log);
}
8.开始推送,停止推送
public bool StartPublisher(String url)
{
if (CheckPublisherHandleAvailable() == false) return false;
if (publisher_handle_ == IntPtr.Zero)
{
return false;
}
if (!String.IsNullOrEmpty(url))
{
NTSmartPublisherSDK.NT_PB_SetURL(publisher_handle_, url, IntPtr.Zero);
}
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPublisher(publisher_handle_, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
return false;
}
publisher_handle_count_++;
is_publishing_ = true;
return true;
}
public void StopPublisher()
{
if (is_publishing_ == false) return;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPublisher(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
}
9.关闭实例
public void Close()
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
总结
经测试,在Unity环境下,通过高效数据采集,编码推送,配合SmartPlayer播放,整体延迟可以控制在毫秒级,适合大部分Unity对延迟和稳定性的要求环境恶劣的场景。
解决方案:利用ROS采集VLP-16激光雷达数据
启动VLP-16激光雷达,想用ROS采集雷达数据,按照现有的教程总有一些小问题,现在分享自己成功采集的数据,希望对那些刚进坑的人有所帮助。
我使用 Ubuntu 16.04+ 动力学系统
1. 安装驱动程序
sudo apt-get install ros-kinetic-velodyne
2. 配置网络以连接到激光雷达(无需关闭无线):
修改 IPv4:在有线网络中
更改为手动
IP 地址为 192.168.1.77,
子网掩码为 255.255.255.0,网关为 192.168.1.1。然后连接激光雷达,
打开浏览器输入192.168.1.201,查看激光雷达配置文件。
每次连接雷达时,输入以下两个命令:

sudo ifconfig enp2s0 192.168.1.123
sudo 路由添加 192.168.1.201 enp2s0
3. 创建 ROS 项目:
MKDIR -P catkin_velodyne/SRC
光盘catkin_velodyne/SRC
git 克隆
光盘..
Rosdep install --from-path src --ignore-src --rosdistro kinetic -y
catkin_make
Source devel/setup.bash
4.将Velodyne XML文件转换为ROS节点的YAML文件,VLP-16.xml据说在免费的USB闪存盘中,反正没找到

我从互联网上下载了一个。请记住将下面的地址更改为您的 VLP-16 .xml文件的地址。
rosrun velodyne_pointcloud gen_calibration.py ~/VLP-16.xml (更改为你自己保存的目录)。
5. 加载:
roslaunch velodyne_pointcloud VLP16_points.launch calibration:=~/VLP-16.yaml (更改为你自己保存的目录)。
6、点云图实时展示:
Rosrun Rviz Rviz -F velodyne
然后按主题添加
rviz 添加 PointCloud2,并在主题中输入 /velodyne_points,这样得到的 3D 点云图就可以实时展示。
7. 记录数据:
我看到的教程是用 rosbagrecord-oout/velodyne_points 命令获取 /velodyne_points 主题的数据,但是当我去分析保存的数据时,发现里面的雷达数据被处理了,反正我根本无法解读。我想获取雷达原创UDP报文中的信息来生成距离和强度图像,所以我保存了/velodyne_packets这个主题的数据,保存的数据是收录UDP的正文,每76个UDP数据包(每周扫描360度)都有一个时间戳,然后根据手册就可以从数据中获取距离和强度信息。
罗斯巴格记录 -O 文件名 /velodyne_packets
最新版:jquery基础快速教程和“jquery之本”框架教程(免费版)
采集交流 • 优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2022-11-18 10:28
文章采集调用ie,然后经过前端转换输出html加js让用户点击页面,点击后执行相应的动作,js代码通过后端返回页面并获取交互数据,进行展示,整个过程不涉及到网页的加载,即flash,难度稍微低些,另外,在实现这个前端功能的时候,可以用jquery框架,总的来说还是要具备一定的前端功底以及网络编程的基础,如果是小白也没有关系,现在也有免费开源的jquery框架,直接通过mvc的模式进行开发。
开发效率还是挺高的,最新版本的一些工具提供了大量的mvc模式开发示例视频教程,供大家学习交流。首页:jquery基础快速教程和“jquery之本”框架教程(免费版)“jquery之本”框架教程(付费版)下载:链接密码:n50b具体参见:jquery教程_jquery框架教程精讲_android开发_视频教程_免费教程大全当然在学习过程中,有不懂的问题可以关注我的公众号回复:jquery,获取相应的教程视频以及后端js开发教程!。
写几个页面,就熟练了,
已经给jquery提交了,他们回答的还挺详细的。 查看全部
最新版:jquery基础快速教程和“jquery之本”框架教程(免费版)
文章采集调用ie,然后经过前端转换输出html加js让用户点击页面,点击后执行相应的动作,js代码通过后端返回页面并获取交互数据,进行展示,整个过程不涉及到网页的加载,即flash,难度稍微低些,另外,在实现这个前端功能的时候,可以用jquery框架,总的来说还是要具备一定的前端功底以及网络编程的基础,如果是小白也没有关系,现在也有免费开源的jquery框架,直接通过mvc的模式进行开发。

开发效率还是挺高的,最新版本的一些工具提供了大量的mvc模式开发示例视频教程,供大家学习交流。首页:jquery基础快速教程和“jquery之本”框架教程(免费版)“jquery之本”框架教程(付费版)下载:链接密码:n50b具体参见:jquery教程_jquery框架教程精讲_android开发_视频教程_免费教程大全当然在学习过程中,有不懂的问题可以关注我的公众号回复:jquery,获取相应的教程视频以及后端js开发教程!。

写几个页面,就熟练了,
已经给jquery提交了,他们回答的还挺详细的。
教程:dedecms织梦TAG标签调用代码
采集交流 • 优采云 发表了文章 • 0 个评论 • 134 次浏览 • 2022-11-17 02:51
标签标签
是一种自己定义的关键词,比分类更准确、更具体,可以概括文章主要内容,合理使用TAG标签,可以让你发表的文章更容易检索。
很多网站首页、列表页和文章页都用超链接调用TAG关键词,有利于蜘蛛搜索和抓取,也有利于用户点击,那么如何在织梦dedecms系统的网站上实现此功能呢?对此,做网站吧,整理出以下方法供大家使用:
1、TaT ?B 6g 标签 o V % 的语法解释
基本语法:
{dede:tag row='30' sort='new' getall='0′}
c B 8 r///a/dedejq/[field:link/]'>[field:tag /]
{/dede:tag}
参数说明:
row=K z 9 W k \ B * x '30' 呼叫号码为 30
sort='new' 排序 月, 兰特, 周
getall='0' 获取当前内容页面 TAG 标记的类型 0,以及获取所有 TAG 标记的类型 1。
基础模板字段:链接、标记
2. 最新的标签标签称为
{dede:tag row='30' sort='new'}[字段:突出显示/]
([字段:结果/])
{/dede:tag}
3.调用本月热门标签标签
{dede:tag row='30' sort='month'}I d s d stp:///a/dedejq/[field:link/]'>[field:
tagname/]([field:result/])
{/dede:tag}
4. 随机标签调用
{deu } ^de:tag row='60' sort='rand'}
$ J | m W 5 F /a/dedejq/[field:link/]'>[field:highlight/]([field:result/])
{/dede:tag}
5. 采集热 [# W 0 V N L n – 门标签,转换后刷新
模板代码:
{dede:tag row='10' sort='month' }
, E y u mom/a/dedejq/[field:link/]'>[field:tagname/] &o : T # hlt;/a>
{/dede:tag}
^ e 8 {t language=“JavaScript”>
偏移量){
tag_a.className=“tag”+(rnd-offsc y 2 4et);
}
}
}/
/–>
CSS代码:
.tag1 { color:h Z j j m G i + X#339900; font-weight:bold; }
.tag2 { color:#e65730; }
.tag3 { color:#00b9da; }
.tag4 { color:#FG 2 4 C +E3981; 7 5 ) T [ Jfont-weighW Z P 7 } G &t:bold; font-size:14px; }
6. 在页面文章调用标签标签
{J w % = S y p 8 gdede:tag table='dede_search_keywords' sort='keyword' row='2′ ifd O b y F=“}
\ L \dedejq/[field:link/]' target=_i 7 * # _blank>[field:tag /]
{/dede:tag}
或
{dede:fie# n : 2 [ r XLD name='Keywords' runphp='yes' }
if(!empty(@me)){
$kws = 爆炸(' ',@me);
@me = “”;
foreach($kws as $k){
@me .= “O / x 4 # '/tag.php?/$k/'>$k ”;
}
@me= str_repla' $ F 0 }ce('+', ' ',trim(@me));
}
{/dede:field}
7. 列表页调用 TAG 标签的两个 b # k F w D 方法
dedecms列表中的默认值无法调用 tag\q v C; _ X 标签。Do 网站 G * { r p i, 7 n 为您提供以下不同版本的标签标签调用 T D G A p A are you 方法:
(1)、de, w \decms 5.7 调用方法
首先,找到 include\helpers\archive.helper.php 文件(注:有些朋友会有疑问,首页和频道,列表应该添加不同的调用,但我开始用列表页面测试,成功;添加 m \ b v q r 首页后,测试也进入了 D Y G R U Y T + D 功能显示,所以我没有继续深入研究,另外,这个文件的内容发生了变化,在后台文件是无法更改的,提示 _&0 7 是注入 sql,所以要在 ftp 中找到这个文件来更改 0。)
在底部添加:
函数; f G GetTags_list($aid)
{
全球$dsql;
$tags = “;
$query = “从'ma_taglisi v \ at'中选择标签,其中aid='$aid'”;
~ w T $dsql->Execute('tag',$query);
0 I 5 + 2 y a s whil' j % s ~ we($row = $dsql->GetArray('tag'))
{
$tags .= ($tags==“ ?“9 R.Q e #<^ ) \ n 6;a hreb E H f Q uf='“.urlencode($row['tag']).”' &gl f _t;Y ] R 5 L t # = G“.$row['tag'].”“ : ','.”O % V x b ^ .i P /tags.php?/“.urlencode($row['tag']).”' >“.$row['tag'].”“);
}
返回 $tau P % @ rgs;
}
那么Q I S + v b H k,加上:,这里列表需要调用标签标签
[字段:id 函数=GetTags_list(@me)/]
以完成。
(2)、dedecms 5K T y W + C g j.6 版本 G \ G Y # |G本的调用方法
方法一:
只需在模板需要的地方添加以下代码:
[字段:ID runphp=yes]
$tsql = new DedeSql(false);
$tags = “B F e –;
$tsql->SetQuery(“选择 i.tag 从 dede_taglist t 左连接 dede_tagindex i on i.id=t.tid 其中 t.an / ;E Zid='@me'“);
$tsql-e ) ;>ExG V q @ecute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “”.$row['tag'].“ &k u blt;/a>”;
}
@me=$tags;
[/字段:id]
注意:此步骤无法在 dede 5.7 中实现。
方法2:
打开 dedecms根目录 T k Y ~include/common.func.php,在底部的 “!k ?A b O?>“在以下代码之前:
让我们做网站:列表页调用标签的方法
函数列表标签($aid)
{
$tsql = new DedeSql(false);
$tags = “;{ ( n : u X ' , m
$tsql->SetQuery(“Select i.tag FrM .o 9 Oom dt 7 ;2 j ] ^ede_taglist t left join dede_tagindex i on i.id=t.tid where t.aid='$aid'“);
$tsql->执行('t');
whi– x W s e – ale($row = $tsql->GetArray('t',MYSQL_ASSOC)){7 C \ j
$tags .= “D ( & 6lencode($row['tag']).” /'>“.$rowj 0 Y ? x v z o J['tag'].”";
}% W ?z F |_ = i
雷图]U Y骨灰盒$tags;
}
{@ ? n i 2 0 , 5 4dede:field.id runphp=yes}
$tsql = new DedeSql(false);
$tags = “;
$tsql->SetQuery(“Select i.tag From ded\ } q |e_taglist t left join dede_tak f 4gindex i on i.id=t.tid where t.aid='@me'”);
$' 1 ~tsql->Execute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “e D Hhp?/”.urlencode($row['tag']).“' >”.$row['tag'].“”;
}
@me=$# A F ytags;
{/dede:field.id}
添加代码 6 j't*$x 后,可以使用列表页:
{m s s C $dede:field.id function=“listtag(@me)”/}
以调用标签标签。
方法三:
inc_functions.php 添加 :
函数列表标记($aid){
$tsql = new DedeSql(p ' w x 8 Q 3 s tfalse);
$tags = “;
$tsql->SetQuery(“Select i.tagname From xkzzz_tag_list t left join xkzzz_tu 4 t \ 0 { x gag_index i on i.id=t.tid where t.aid='$aid'”);
$tsql->执行('t');
while($row = $tsql->Getj [ x &Array('t'{ N f M K v S,MYSQL_AO r _ 0 |SSOC)){
$tags .= “s 1 j { ~ + !/tag.php?/”.urlencodeE # 6 [ z H 0 V Y($row['tagname']).“' >”.$rowu F G y A ,['tagname'].“”;
}
+ _ c j c 6 d 返回$tags;
}
然后添加 :,其中列表页位于
[字段:ID 函数=“列表标记(@me)”/]
可以调出来,但是这个方法也需要更改程序文件,看不懂代码的朋友,慎用吧!
8. 首页调用该方法文章 Tg j LAG 标签
如果您网站使用 dedecms v5.7 可以使用以下标签:
径直
[field:id function=GetTags(@me)/]
可以调出,但不能调出g Y # k x s T O \没有连接,为了添加标签标签的链接,还需要做到以下几点:
首先,注 4 + z { # 。E % 删除 130 行收录/帮助程序/存档.helper.php 文件
$tags .= ($tags==“ ? $row['标签'] : ','.$row['标签']);
用以下?!C 语句替换,当然是 J { |R 您还可以添加自己的样式:
$tags .= “_ % k a !php?/”.urlencode($row['tag']).“ /'>”.$row['tag'].”";
添加 # z ; ! p t ] o 下一代 { 0 H R i 代码:
if ( ! function_exists(7 h * Y 0 r Q'GetTagk')){
函数 GetTagk($aid)
{@ / ! ; * K { i
全球$dsql;
$tagk = “;
$query = “选择标签,从'ma_taglist'中辅助,其中aid='$aid'”;
$dsql->Execute('tagD v ^ n b',$query);
while($row = $dsql->GetArray('tag'))
{
$tagk .= ($t\ Z * & \ } 3agk==“n 1 i ? $row['tag'] : ','.$row['tag']);
}
返回 $ta 2 V )O { mgk;
}
}
然后,打开 dede/a( h m^ Jrticle_edit.php 找到:
$tags = Gf I j DetTags($aid);
添加以下内容:
$t( H e ~ M T 8 | *agk = GetTagk($o Q D Jaid);
打开 dede/tempj x z t F n h mlets/article_edit.htm 再次调用标签标签
学习笔记:学python,怎么能不学习scrapy呢
本文分享自华为云社区《学python怎么能不学scrapy?本博客带你学起来-云社区-华为云》,作者:橡皮擦。
在正式写爬虫案例之前,我们先系统地了解一下scrapy。
scrapy安装和简单操作
使用命令pip install scrapy进行安装。安装成功后,需要采集几个网址,方便后续学习使用。
安装完成后,直接在控制台输入scrapy,出现如下命令即表示安装成功。
> scrapy
Scrapy 2.5.0 - no active project
Usage:
scrapy [options] [args]
Available commands:
上图是scrapy内置命令列表,标准格式的scrapy,可以通过scrapy -h查看指定命令的帮助手册。
scrapy中有两种命令,一种是全局的,一种是项目中的。后者需要进入scrapy目录才能运行。
这些命令一开始不需要完全记住,随时可以查看。还有几个比较常用的,例如:
**scrpy 启动项目**
该命令首先根据项目名称创建一个文件夹,然后在该文件夹下创建一个scrpy项目。这一步是所有后续代码的起点。
> scrapy startproject my_scrapy
> New Scrapy project 'my_scrapy', using template directory 'e:\pythonproject\venv\lib\site-packages\scrapy\templates\project', created in: # 一个新的 scrapy 项目被创建了,使用的模板是 XXX,创建的位置是 XXX
E:\pythonProject\滚雪球学Python第4轮\my_scrapy
You can start your first spider with: # 开启你的第一个爬虫程序
cd my_scrapy # 进入文件夹
scrapy genspider example example.com # 使用项目命令创建爬虫文件
以上内容添加了一些评论,可以对照学习。默认生成的文件位于 python 运行时目录中。如果要修改项目目录,请使用如下格式化命令:
scrapy startproject myproject [project_dir]
例如
scrapy startproject myproject d:/d1
命令基于模板创建的项目结构如下,其中红色下划线为项目目录,绿色下划线为scrapy项目。如果要运行项目命令,首先要进入项目目录下红色下划线的my_scrapy文件夹。控制项目。
下面生成爬虫文件
使用命令scrapy genspider [-t template]生成爬虫文件。该方法是快捷操作,也可以手动创建。创建的爬虫文件会出现在当前目录或项目文件夹下的spiders文件夹中,name为爬虫名称,domain用于爬虫文件中allowed_domains和start_urls数据,[-t template]表示可以选择生成文件模板。
要查看所有模板,请使用以下命令,默认模板是 basic。
> scrapy genspider -l
basic
crawl
csvfeed
xmlfeed
创建第一个scrapy爬虫文件,测试命令如下:
>scrapy genspider pm imspm.com
Created spider 'pm' using template 'basic' in module:
my_project.spiders.pm
这时在spiders文件夹中,出现了pm.py文件,文件内容如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['imspm.com']
start_urls = ['http://imspm.com/']
def parse(self, response):
pass
测试 scrapy 爬虫运行
使用命令scrapy crawl,spider是上面生成的爬虫文件名,如果出现如下内容,说明爬虫加载正确。
>scrapy crawl pm
2021-10-02 21:34:34 [scrapy.utils.log] INFO: Scrapy 2.5.0 started (bot: my_project)
[...]
scrapy的基本应用
scrapy 的工作流程非常简单:
采集首页源码;分析首页源码,获取下一页链接;请求下一页的源代码;解析源码,获取下一页的源码;[…] 过程中,提取到目标数据后,保存。
下面给大家展示一个scrapy的完整案例应用,作为爬虫120案例scrapy部分的第一个例子。
> scrapy startproject my_project 爬虫
> cd 爬虫
<p>
> scrapy genspider pm imspm.com</p>
得到项目结构如下:
对上图中部分文件的简要说明。
使用scrapy crawl pm运行爬虫后,所有的输出和描述如下:
上面代码的请求次数是7次,因为pm.py文件中默认没有添加www。如果添加此内容,则请求数变为 4。
当前pm.py文件代码如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['www.imspm.com']
start_urls = ['http://www.imspm.com/']
def parse(self, response):
print(response.text)
其中的parse是指请求start_urls中的地址,得到response后的回调函数,通过参数response的.text属性直接输出网页源码。
获取到源码后,需要对源码进行解析存储
在存储之前,需要手动定义一个数据结构,在items.py文件中实现,修改代码中的类名,MyProjectItem → ArticleItem。
import scrapy
class ArticleItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
author = scrapy.Field() # 作者
修改pm.py文件中的parse函数,增加网页解析相关操作。这个操作类似于pyquery的知识点,直接观察代码就可以掌握。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for item in list_item:
title = item.css('.title::text').extract_first() # 直接获取文本
url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
author = item.css('.author::text').extract_first() # 直接获取文本
print(title, url, author)
response.css 方法返回一个选择器列表,可以对其进行迭代,然后对其中的对象调用 css 方法。
在pm.py中导入items.py中的ArticleItem类,然后按照如下代码修改:
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
<p>
item['author'] = author
yield item</p>
这时候scrapy爬虫运行时,会出现如下提示信息。
至此一个单页爬虫就完成了
接下来再次修改parse函数,解析完第一页后,再解析第二页的数据。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first() # 获取下一页链接
# print(next)
# 再次生成一个请求
yield scrapy.Request(url=next, callback=self.parse)
上面代码中,变量next代表下一页的地址,通过response.css函数获取链接。请重点学习css选择器。
产量下降。request(url=next, callback=self.parse)表示重新创建一个请求,请求的回调函数是parse自身,代码运行效果如下。
如果要保存运行结果,只需运行以下命令即可。
scrapy crawl pm -o pm.json
如果要将每条数据存储为单独的一行,请使用以下命令 scrapy crawl pm -o pm.jl 。
生成的文件还支持csv、xml、marchal、pickle,大家可以自己试试。
让我们使用数据管道
打开pipelines.py文件,修改类名MyProjectPipeline→TitlePipeline,然后编译如下代码:
class TitlePipeline:
def process_item(self, item, spider): # 移除标题中的空格
if item["title"]:
item["title"] = item["title"].strip()
return item
else:
return DropItem("异常数据")
此代码用于去除标题中的左右空格。
写入后需要在settings.py文件中开启ITEM_PIPELINES配置。
ITEM_PIPELINES = {
'my_project.pipelines.TitlePipeline': 300,
}
300是PIPELINES操作的优先顺序,可以根据需要修改。再次运行爬虫代码,你会发现标题的左右空格已经被去掉了。
至此,一个scrapy的基础爬虫就写好了。
戳下方关注,第一时间了解华为云的新鲜技术~
华为云博客_大数据博客_人工智能博客_云计算博客_开发者中心-华为云 查看全部
教程:dedecms织梦TAG标签调用代码
标签标签
是一种自己定义的关键词,比分类更准确、更具体,可以概括文章主要内容,合理使用TAG标签,可以让你发表的文章更容易检索。
很多网站首页、列表页和文章页都用超链接调用TAG关键词,有利于蜘蛛搜索和抓取,也有利于用户点击,那么如何在织梦dedecms系统的网站上实现此功能呢?对此,做网站吧,整理出以下方法供大家使用:
1、TaT ?B 6g 标签 o V % 的语法解释
基本语法:
{dede:tag row='30' sort='new' getall='0′}
c B 8 r///a/dedejq/[field:link/]'>[field:tag /]
{/dede:tag}
参数说明:
row=K z 9 W k \ B * x '30' 呼叫号码为 30
sort='new' 排序 月, 兰特, 周
getall='0' 获取当前内容页面 TAG 标记的类型 0,以及获取所有 TAG 标记的类型 1。
基础模板字段:链接、标记
2. 最新的标签标签称为
{dede:tag row='30' sort='new'}[字段:突出显示/]
([字段:结果/])
{/dede:tag}
3.调用本月热门标签标签
{dede:tag row='30' sort='month'}I d s d stp:///a/dedejq/[field:link/]'>[field:
tagname/]([field:result/])
{/dede:tag}
4. 随机标签调用
{deu } ^de:tag row='60' sort='rand'}
$ J | m W 5 F /a/dedejq/[field:link/]'>[field:highlight/]([field:result/])
{/dede:tag}
5. 采集热 [# W 0 V N L n – 门标签,转换后刷新
模板代码:
{dede:tag row='10' sort='month' }
, E y u mom/a/dedejq/[field:link/]'>[field:tagname/] &o : T # hlt;/a>
{/dede:tag}
^ e 8 {t language=“JavaScript”>
偏移量){
tag_a.className=“tag”+(rnd-offsc y 2 4et);
}
}
}/
/–>
CSS代码:
.tag1 { color:h Z j j m G i + X#339900; font-weight:bold; }
.tag2 { color:#e65730; }
.tag3 { color:#00b9da; }
.tag4 { color:#FG 2 4 C +E3981; 7 5 ) T [ Jfont-weighW Z P 7 } G &t:bold; font-size:14px; }
6. 在页面文章调用标签标签
{J w % = S y p 8 gdede:tag table='dede_search_keywords' sort='keyword' row='2′ ifd O b y F=“}
\ L \dedejq/[field:link/]' target=_i 7 * # _blank>[field:tag /]
{/dede:tag}
或
{dede:fie# n : 2 [ r XLD name='Keywords' runphp='yes' }
if(!empty(@me)){
$kws = 爆炸(' ',@me);
@me = “”;
foreach($kws as $k){
@me .= “O / x 4 # '/tag.php?/$k/'>$k ”;
}

@me= str_repla' $ F 0 }ce('+', ' ',trim(@me));
}
{/dede:field}
7. 列表页调用 TAG 标签的两个 b # k F w D 方法
dedecms列表中的默认值无法调用 tag\q v C; _ X 标签。Do 网站 G * { r p i, 7 n 为您提供以下不同版本的标签标签调用 T D G A p A are you 方法:
(1)、de, w \decms 5.7 调用方法
首先,找到 include\helpers\archive.helper.php 文件(注:有些朋友会有疑问,首页和频道,列表应该添加不同的调用,但我开始用列表页面测试,成功;添加 m \ b v q r 首页后,测试也进入了 D Y G R U Y T + D 功能显示,所以我没有继续深入研究,另外,这个文件的内容发生了变化,在后台文件是无法更改的,提示 _&0 7 是注入 sql,所以要在 ftp 中找到这个文件来更改 0。)
在底部添加:
函数; f G GetTags_list($aid)
{
全球$dsql;
$tags = “;
$query = “从'ma_taglisi v \ at'中选择标签,其中aid='$aid'”;
~ w T $dsql->Execute('tag',$query);
0 I 5 + 2 y a s whil' j % s ~ we($row = $dsql->GetArray('tag'))
{
$tags .= ($tags==“ ?“9 R.Q e #<^ ) \ n 6;a hreb E H f Q uf='“.urlencode($row['tag']).”' &gl f _t;Y ] R 5 L t # = G“.$row['tag'].”“ : ','.”O % V x b ^ .i P /tags.php?/“.urlencode($row['tag']).”' >“.$row['tag'].”“);
}
返回 $tau P % @ rgs;
}
那么Q I S + v b H k,加上:,这里列表需要调用标签标签
[字段:id 函数=GetTags_list(@me)/]
以完成。
(2)、dedecms 5K T y W + C g j.6 版本 G \ G Y # |G本的调用方法
方法一:
只需在模板需要的地方添加以下代码:
[字段:ID runphp=yes]
$tsql = new DedeSql(false);
$tags = “B F e –;
$tsql->SetQuery(“选择 i.tag 从 dede_taglist t 左连接 dede_tagindex i on i.id=t.tid 其中 t.an / ;E Zid='@me'“);
$tsql-e ) ;>ExG V q @ecute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “”.$row['tag'].“ &k u blt;/a>”;
}
@me=$tags;
[/字段:id]
注意:此步骤无法在 dede 5.7 中实现。
方法2:
打开 dedecms根目录 T k Y ~include/common.func.php,在底部的 “!k ?A b O?>“在以下代码之前:
让我们做网站:列表页调用标签的方法
函数列表标签($aid)
{
$tsql = new DedeSql(false);
$tags = “;{ ( n : u X ' , m
$tsql->SetQuery(“Select i.tag FrM .o 9 Oom dt 7 ;2 j ] ^ede_taglist t left join dede_tagindex i on i.id=t.tid where t.aid='$aid'“);
$tsql->执行('t');
whi– x W s e – ale($row = $tsql->GetArray('t',MYSQL_ASSOC)){7 C \ j
$tags .= “D ( & 6lencode($row['tag']).” /'>“.$rowj 0 Y ? x v z o J['tag'].”";
}% W ?z F |_ = i
雷图]U Y骨灰盒$tags;
}
{@ ? n i 2 0 , 5 4dede:field.id runphp=yes}
$tsql = new DedeSql(false);
$tags = “;

$tsql->SetQuery(“Select i.tag From ded\ } q |e_taglist t left join dede_tak f 4gindex i on i.id=t.tid where t.aid='@me'”);
$' 1 ~tsql->Execute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “e D Hhp?/”.urlencode($row['tag']).“' >”.$row['tag'].“”;
}
@me=$# A F ytags;
{/dede:field.id}
添加代码 6 j't*$x 后,可以使用列表页:
{m s s C $dede:field.id function=“listtag(@me)”/}
以调用标签标签。
方法三:
inc_functions.php 添加 :
函数列表标记($aid){
$tsql = new DedeSql(p ' w x 8 Q 3 s tfalse);
$tags = “;
$tsql->SetQuery(“Select i.tagname From xkzzz_tag_list t left join xkzzz_tu 4 t \ 0 { x gag_index i on i.id=t.tid where t.aid='$aid'”);
$tsql->执行('t');
while($row = $tsql->Getj [ x &Array('t'{ N f M K v S,MYSQL_AO r _ 0 |SSOC)){
$tags .= “s 1 j { ~ + !/tag.php?/”.urlencodeE # 6 [ z H 0 V Y($row['tagname']).“' >”.$rowu F G y A ,['tagname'].“”;
}
+ _ c j c 6 d 返回$tags;
}
然后添加 :,其中列表页位于
[字段:ID 函数=“列表标记(@me)”/]
可以调出来,但是这个方法也需要更改程序文件,看不懂代码的朋友,慎用吧!
8. 首页调用该方法文章 Tg j LAG 标签
如果您网站使用 dedecms v5.7 可以使用以下标签:
径直
[field:id function=GetTags(@me)/]
可以调出,但不能调出g Y # k x s T O \没有连接,为了添加标签标签的链接,还需要做到以下几点:
首先,注 4 + z { # 。E % 删除 130 行收录/帮助程序/存档.helper.php 文件
$tags .= ($tags==“ ? $row['标签'] : ','.$row['标签']);
用以下?!C 语句替换,当然是 J { |R 您还可以添加自己的样式:
$tags .= “_ % k a !php?/”.urlencode($row['tag']).“ /'>”.$row['tag'].”";
添加 # z ; ! p t ] o 下一代 { 0 H R i 代码:
if ( ! function_exists(7 h * Y 0 r Q'GetTagk')){
函数 GetTagk($aid)
{@ / ! ; * K { i
全球$dsql;
$tagk = “;
$query = “选择标签,从'ma_taglist'中辅助,其中aid='$aid'”;
$dsql->Execute('tagD v ^ n b',$query);
while($row = $dsql->GetArray('tag'))
{
$tagk .= ($t\ Z * & \ } 3agk==“n 1 i ? $row['tag'] : ','.$row['tag']);
}
返回 $ta 2 V )O { mgk;
}
}
然后,打开 dede/a( h m^ Jrticle_edit.php 找到:
$tags = Gf I j DetTags($aid);
添加以下内容:
$t( H e ~ M T 8 | *agk = GetTagk($o Q D Jaid);
打开 dede/tempj x z t F n h mlets/article_edit.htm 再次调用标签标签
学习笔记:学python,怎么能不学习scrapy呢
本文分享自华为云社区《学python怎么能不学scrapy?本博客带你学起来-云社区-华为云》,作者:橡皮擦。
在正式写爬虫案例之前,我们先系统地了解一下scrapy。
scrapy安装和简单操作
使用命令pip install scrapy进行安装。安装成功后,需要采集几个网址,方便后续学习使用。
安装完成后,直接在控制台输入scrapy,出现如下命令即表示安装成功。
> scrapy
Scrapy 2.5.0 - no active project
Usage:
scrapy [options] [args]
Available commands:
上图是scrapy内置命令列表,标准格式的scrapy,可以通过scrapy -h查看指定命令的帮助手册。
scrapy中有两种命令,一种是全局的,一种是项目中的。后者需要进入scrapy目录才能运行。
这些命令一开始不需要完全记住,随时可以查看。还有几个比较常用的,例如:
**scrpy 启动项目**
该命令首先根据项目名称创建一个文件夹,然后在该文件夹下创建一个scrpy项目。这一步是所有后续代码的起点。
> scrapy startproject my_scrapy
> New Scrapy project 'my_scrapy', using template directory 'e:\pythonproject\venv\lib\site-packages\scrapy\templates\project', created in: # 一个新的 scrapy 项目被创建了,使用的模板是 XXX,创建的位置是 XXX
E:\pythonProject\滚雪球学Python第4轮\my_scrapy
You can start your first spider with: # 开启你的第一个爬虫程序
cd my_scrapy # 进入文件夹
scrapy genspider example example.com # 使用项目命令创建爬虫文件
以上内容添加了一些评论,可以对照学习。默认生成的文件位于 python 运行时目录中。如果要修改项目目录,请使用如下格式化命令:
scrapy startproject myproject [project_dir]
例如
scrapy startproject myproject d:/d1
命令基于模板创建的项目结构如下,其中红色下划线为项目目录,绿色下划线为scrapy项目。如果要运行项目命令,首先要进入项目目录下红色下划线的my_scrapy文件夹。控制项目。
下面生成爬虫文件
使用命令scrapy genspider [-t template]生成爬虫文件。该方法是快捷操作,也可以手动创建。创建的爬虫文件会出现在当前目录或项目文件夹下的spiders文件夹中,name为爬虫名称,domain用于爬虫文件中allowed_domains和start_urls数据,[-t template]表示可以选择生成文件模板。
要查看所有模板,请使用以下命令,默认模板是 basic。
> scrapy genspider -l
basic
crawl
csvfeed
xmlfeed
创建第一个scrapy爬虫文件,测试命令如下:
>scrapy genspider pm imspm.com
Created spider 'pm' using template 'basic' in module:
my_project.spiders.pm
这时在spiders文件夹中,出现了pm.py文件,文件内容如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['imspm.com']
start_urls = ['http://imspm.com/']
def parse(self, response):
pass
测试 scrapy 爬虫运行
使用命令scrapy crawl,spider是上面生成的爬虫文件名,如果出现如下内容,说明爬虫加载正确。
>scrapy crawl pm
2021-10-02 21:34:34 [scrapy.utils.log] INFO: Scrapy 2.5.0 started (bot: my_project)
[...]
scrapy的基本应用
scrapy 的工作流程非常简单:
采集首页源码;分析首页源码,获取下一页链接;请求下一页的源代码;解析源码,获取下一页的源码;[…] 过程中,提取到目标数据后,保存。
下面给大家展示一个scrapy的完整案例应用,作为爬虫120案例scrapy部分的第一个例子。
> scrapy startproject my_project 爬虫
> cd 爬虫
<p>

> scrapy genspider pm imspm.com</p>
得到项目结构如下:
对上图中部分文件的简要说明。
使用scrapy crawl pm运行爬虫后,所有的输出和描述如下:
上面代码的请求次数是7次,因为pm.py文件中默认没有添加www。如果添加此内容,则请求数变为 4。
当前pm.py文件代码如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['www.imspm.com']
start_urls = ['http://www.imspm.com/']
def parse(self, response):
print(response.text)
其中的parse是指请求start_urls中的地址,得到response后的回调函数,通过参数response的.text属性直接输出网页源码。
获取到源码后,需要对源码进行解析存储
在存储之前,需要手动定义一个数据结构,在items.py文件中实现,修改代码中的类名,MyProjectItem → ArticleItem。
import scrapy
class ArticleItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
author = scrapy.Field() # 作者
修改pm.py文件中的parse函数,增加网页解析相关操作。这个操作类似于pyquery的知识点,直接观察代码就可以掌握。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for item in list_item:
title = item.css('.title::text').extract_first() # 直接获取文本
url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
author = item.css('.author::text').extract_first() # 直接获取文本
print(title, url, author)
response.css 方法返回一个选择器列表,可以对其进行迭代,然后对其中的对象调用 css 方法。
在pm.py中导入items.py中的ArticleItem类,然后按照如下代码修改:
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
<p>

item['author'] = author
yield item</p>
这时候scrapy爬虫运行时,会出现如下提示信息。
至此一个单页爬虫就完成了
接下来再次修改parse函数,解析完第一页后,再解析第二页的数据。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first() # 获取下一页链接
# print(next)
# 再次生成一个请求
yield scrapy.Request(url=next, callback=self.parse)
上面代码中,变量next代表下一页的地址,通过response.css函数获取链接。请重点学习css选择器。
产量下降。request(url=next, callback=self.parse)表示重新创建一个请求,请求的回调函数是parse自身,代码运行效果如下。
如果要保存运行结果,只需运行以下命令即可。
scrapy crawl pm -o pm.json
如果要将每条数据存储为单独的一行,请使用以下命令 scrapy crawl pm -o pm.jl 。
生成的文件还支持csv、xml、marchal、pickle,大家可以自己试试。
让我们使用数据管道
打开pipelines.py文件,修改类名MyProjectPipeline→TitlePipeline,然后编译如下代码:
class TitlePipeline:
def process_item(self, item, spider): # 移除标题中的空格
if item["title"]:
item["title"] = item["title"].strip()
return item
else:
return DropItem("异常数据")
此代码用于去除标题中的左右空格。
写入后需要在settings.py文件中开启ITEM_PIPELINES配置。
ITEM_PIPELINES = {
'my_project.pipelines.TitlePipeline': 300,
}
300是PIPELINES操作的优先顺序,可以根据需要修改。再次运行爬虫代码,你会发现标题的左右空格已经被去掉了。
至此,一个scrapy的基础爬虫就写好了。
戳下方关注,第一时间了解华为云的新鲜技术~
华为云博客_大数据博客_人工智能博客_云计算博客_开发者中心-华为云
解决方案:VS2022基于C语言的动态链接库创建与调用
采集交流 • 优采云 发表了文章 • 0 个评论 • 325 次浏览 • 2022-11-17 00:21
//extern "C",告诉编译器它所修饰的代码按c语言方式编译
//"__declspec(dllexport)",告诉编译器和链接器此函数需要从DLL导出
extern "C" _declspec(dllexport) int Sour_Initialize(char* rsrcname);
//函数原型所依赖的lib文件
#pragma comment(lib, "test.lib")
5.关闭一些错误警告
对于 Visual Studio 库中的许多函数、成员函数、函数模板和全局变量,此错误已弃用。一些函数/变量(例如 POSIX 和 Microsoft 特定函数)已被弃用,因为它们现在使用不同的首选名称。一些 C 运行时库函数已被弃用,因为它们不安全,现在有更安全的变体。其他函数/变量已弃用,因为它们已过时。弃用消息通常包括已弃用函数或全局变量的建议替换。
我这里试试没有错,在函数声明的头文件中加入如下代码,直接关闭提示
#pragma warning(disable : 4996)
<p>
</p>
6.编译
生成的库需要在32位环境下编译,这里选择x86
如果成功,在项目文件夹中寻找DEBUG文件夹,会生成需要的DLL文件和LIB文件
三、调用动态链接库 1、创建项目
选择控制台应用程序
2.复制dll文件和lib文件
将刚刚创建的dll文件和lib文件复制到本项目的文件夹中
3. 添加.dll、.lib、.h文件
将声明函数原型的.dll文件、.lib文件和.h文件添加到项目中
4.修改.h文件
在.h文件中添加以下代码
#pragma once
//函数原型所依赖的lib库
#pragma comment(lib, "test.lib")
//刚刚生成的lib库
#pragma comment(lib, "TestDLL.lib")
将函数声明前的“extern "C" _declspec(dllexport)" 更改为 "extern "C" _declspec(dllimport)"
extern "C" _declspec(dllimport) int Sour_Initialize(char* rsrcname);
5.main函数编写调用逻辑
在你写的函数的main函数中调用就可以了。
核心方法:内容和标记SEO分析工具
您的 网站 页面排名因素来自 网站 内容和标记。因此,优化内容并尽量减少标记中的错误非常重要。
1.SEO浏览器
SEO 浏览器是最古老的免费 SEO 工具之一,但它仍然非常有用。该工具是 100% 免费的,它提供两种模式:简单模式和高级模式。简单模式像基于文本的 Web 浏览器(例如,lynx)一样显示给定的 URL。高级模式提供基于文本的 URL 视图,它还包括总结 URL 内容的有用信息(例如页面标题、元标记、页面大小、字数、IP 地址等)。
2. 复制景观
Copyscape 是一种使用免费增值模式的在线重复内容检测工具。您只需输入页面的 URL,该工具就会返回重复该 URL 内容的页面列表。对于免费帐户,该工具仅显示前十名结果,并且该工具每月仅允许来自任何给定站点的一定数量的请求(此限制与通过 IP 提交请求无关)。
3.W3C 标记验证服务
W3C 标记验证服务 标记验证服务是一个免费的在线工具,用于检查与给定 URI 关联的 Web 文档的标记有效性。您只需输入一个 URI,该工具就会检查它的正确性(基于其文档类型的语法)。最后,该工具会显示在验证过程中发现的错误和警告的逐项列表(具有相应的行号和列号)。
历史上的今天: 查看全部
解决方案:VS2022基于C语言的动态链接库创建与调用
//extern "C",告诉编译器它所修饰的代码按c语言方式编译
//"__declspec(dllexport)",告诉编译器和链接器此函数需要从DLL导出
extern "C" _declspec(dllexport) int Sour_Initialize(char* rsrcname);
//函数原型所依赖的lib文件
#pragma comment(lib, "test.lib")
5.关闭一些错误警告
对于 Visual Studio 库中的许多函数、成员函数、函数模板和全局变量,此错误已弃用。一些函数/变量(例如 POSIX 和 Microsoft 特定函数)已被弃用,因为它们现在使用不同的首选名称。一些 C 运行时库函数已被弃用,因为它们不安全,现在有更安全的变体。其他函数/变量已弃用,因为它们已过时。弃用消息通常包括已弃用函数或全局变量的建议替换。
我这里试试没有错,在函数声明的头文件中加入如下代码,直接关闭提示
#pragma warning(disable : 4996)
<p>

</p>
6.编译
生成的库需要在32位环境下编译,这里选择x86
如果成功,在项目文件夹中寻找DEBUG文件夹,会生成需要的DLL文件和LIB文件
三、调用动态链接库 1、创建项目
选择控制台应用程序
2.复制dll文件和lib文件
将刚刚创建的dll文件和lib文件复制到本项目的文件夹中
3. 添加.dll、.lib、.h文件
将声明函数原型的.dll文件、.lib文件和.h文件添加到项目中
4.修改.h文件

在.h文件中添加以下代码
#pragma once
//函数原型所依赖的lib库
#pragma comment(lib, "test.lib")
//刚刚生成的lib库
#pragma comment(lib, "TestDLL.lib")
将函数声明前的“extern "C" _declspec(dllexport)" 更改为 "extern "C" _declspec(dllimport)"
extern "C" _declspec(dllimport) int Sour_Initialize(char* rsrcname);
5.main函数编写调用逻辑
在你写的函数的main函数中调用就可以了。
核心方法:内容和标记SEO分析工具
您的 网站 页面排名因素来自 网站 内容和标记。因此,优化内容并尽量减少标记中的错误非常重要。
1.SEO浏览器

SEO 浏览器是最古老的免费 SEO 工具之一,但它仍然非常有用。该工具是 100% 免费的,它提供两种模式:简单模式和高级模式。简单模式像基于文本的 Web 浏览器(例如,lynx)一样显示给定的 URL。高级模式提供基于文本的 URL 视图,它还包括总结 URL 内容的有用信息(例如页面标题、元标记、页面大小、字数、IP 地址等)。
2. 复制景观
Copyscape 是一种使用免费增值模式的在线重复内容检测工具。您只需输入页面的 URL,该工具就会返回重复该 URL 内容的页面列表。对于免费帐户,该工具仅显示前十名结果,并且该工具每月仅允许来自任何给定站点的一定数量的请求(此限制与通过 IP 提交请求无关)。

3.W3C 标记验证服务
W3C 标记验证服务 标记验证服务是一个免费的在线工具,用于检查与给定 URI 关联的 Web 文档的标记有效性。您只需输入一个 URI,该工具就会检查它的正确性(基于其文档类型的语法)。最后,该工具会显示在验证过程中发现的错误和警告的逐项列表(具有相应的行号和列号)。
历史上的今天:
技巧:“手把手”的性能优化文章来了!
采集交流 • 优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2022-11-16 12:37
通过setFactory,我们不仅可以控制View的生成,甚至可以将一个View变成另一个View。比如文章中,我们把TextView变成了Button。
后续的换皮和一些黑白的方案都是以此为基础。
这意味着我们现在可以:
在运行时,接管某个View的生成,也就是我们可以去掉单个View标签的反射逻辑。
相似代码:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}
<br />
但是一般网上的项目都很大,可能会有各种自定义的View,类似上面的if else,怎么写呢?
先采集,再手写?
如何采集项目中使用的所有View?
假设我们采集了,如果是手写,项目一般都是增量的,那新加的View呢?
我们可以看到我们面临两个问题:
如何采集项目中xml中使用的View;
如何保证编写的View生成代码兼容项目的正常迭代;
3 确定方案
目标已经在这里确定了。
在xml->View的过程中,去掉反射相关的逻辑
下面说一下如何解决我们面临的两个问题:
1、如何采集项目中xml中使用的View;
采集所有xml中用到的View,有一个简单的思路,我们可以解析项目中所有的layout.xml文件,但是项目中的layout.xml文件有各个module,有些依赖的aars需要解压太难.
仔细想想,在我们apk的生成过程中,资源应该是需要合并的,是否是解析某个Task合并后的产物。
确实,具体的实现会在后面说到。
我们来看第二个问题:
2、如何保证编写的View生成代码兼容项目的正常迭代;
我们已经能够采集所有使用过的视图列表,因此为此:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}<br />
逻辑规则,简单,编译时生成一个代码类,完成相关的转换代码生成。这里我选择apt。
有了xml->View转换逻辑的代码类,只需要在运行时使用LayoutFactory注入即可。
3.找到安全的注入逻辑
大家都知道我们View生成相关的逻辑在LayoutInflater下面的代码中:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,<br /> boolean ignoreThemeAttr) {<br /> // ...<br /> View view;<br /> if (mFactory2 != null) {<br /> view = mFactory2.onCreateView(parent, name, context, attrs);<br /> } else if (mFactory != null) {<br /> view = mFactory.onCreateView(name, context, attrs);<br /> } else {<br /> view = null;<br /> }<br /><br /> if (view == null && mPrivateFactory != null) {<br /> view = mPrivateFactory.onCreateView(parent, name, context, attrs);<br /> }<br /><br /> if (view == null) {<br /> final Object lastContext = mConstructorArgs[0];<br /> mConstructorArgs[0] = context;<br /> try {<br /> if (-1 == name.indexOf('.')) {<br /> view = onCreateView(parent, name, attrs);<br /> } else {<br /> view = createView(name, null, attrs);<br /> }<br /> } finally {<br /> mConstructorArgs[0] = lastContext;<br /> }<br /> }<br /><br /> return view;<br /><br />}<br />
<br />
View通过mFactory2、mFactory和mPrivateFactory。建不完,后面等待的就是反思。
前两个工厂和支持包一般用于扩展功能,比如TextView->AppCompatTextView。
我们考虑使用 mPrivateFactory。使用mPrivateFactory的好处是,在当前版本中,mPrivateFactory是Activity,所以我们只需要重写Activity的onCreateView即可:
这样一来,完全不需要hooks,也不会干扰appcompat相关的生成逻辑,可谓是零风险。
4 开始实施
1.获取项目中使用的控件名称列表
我新建了一个工程,在布局文件中写了一些自定义控件,分别叫MyMainView1、MyMainView、MyMainView3、MyMainView4,布局文件就不贴了。
正如我们之前所说,我们需要在构建apk的过程中找到一个合适的注入点来完成这个任务。
那么在apk构建过程中,什么时候会合并资源呢?
我们把构建过程中的所有任务打印出来,输入命令:
./gradlew app:assembleDebug --console=plain<br />
<br />
输出:
>Task :app:preBuild UP-TO-DATE<br />> Task :app:preDebugBuild UP-TO-DATE<br />> Task :app:checkDebugManifest UP-TO-DATE<br />> Task :app:generateDebugBuildConfig UP-TO-DATE<br />> Task :app:javaPreCompileDebug UP-TO-DATE<br />> Task :app:mainApkListPersistenceDebug UP-TO-DATE<br />> Task :app:generateDebugResValues UP-TO-DATE<br />> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE<br />> Task :app:mergeDebugShaders UP-TO-DATE<br />> Task :app:compileDebugShaders UP-TO-DATE<br />> Task :app:generateDebugAssets UP-TO-DATE<br />> Task :app:compileDebugAidl NO-SOURCE<br />> Task :app:compileDebugRenderscript NO-SOURCE<br />> Task :app:generateDebugResources UP-TO-DATE<br />> Task :app:mergeDebugResources UP-TO-DATE<br />> Task :app:processDebugManifest UP-TO-DATE<br />> Task :app:processDebugResources UP-TO-DATE<br />> Task :app:compileDebugJavaWithJavac UP-TO-DATE<br />> Task :app:compileDebugSources UP-TO-DATE<br />> Task :app:mergeDebugAssets UP-TO-DATE<br />> Task :app:processDebugJavaRes NO-SOURCE<br />> Task :app:mergeDebugJavaResource UP-TO-DATE<br />> Task :app:transformClassesWithDexBuilderForDebug UP-TO-DATE<br />> Task :app:checkDebugDuplicateClasses UP-TO-DATE<br />> Task :app:validateSigningDebug UP-TO-DATE<br />> Task :app:mergeExtDexDebug UP-TO-DATE<br />> Task :app:mergeDexDebug UP-TO-DATE<br />> Task :app:signingConfigWriterDebug UP-TO-DATE<br />> Task :app:mergeDebugJniLibFolders UP-TO-DATE<br />> Task :app:mergeDebugNativeLibs UP-TO-DATE<br />> Task :app:stripDebugDebugSymbols UP-TO-DATE<br />> Task :app:packageDebug UP-TO-DATE<br />> Task :app:assembleDebug UP-TO-DATE<br />
<br />
哪一个最像?一看就有一个Task叫:mergeDebugResources,就是这样。
对应build目录,还有一个mergeDebugResources目录:
注意里面有一个merger.xml,里面收录了整个项目所有资源的合并内容。
我们打开看看:
关注里面type=layout的相关标签。
<br />
<br />
可以看到收录我们布局文件的路径,那么我们只需要解析这个merger.xml,然后在里面找到所有type=layout的标签,然后解析出布局文件的实际路径,然后解析出相应的layout xml来获取控件的名称。
对了,这个任务需要注入到mergeDebugResources中执行。
如何注入任务?
很简单:
project.afterEvaluate {<br /> def mergeDebugResourcesTask = project.tasks.findByName("mergeDebugResources")<br /> if (mergeDebugResourcesTask != null) {<br /> def resParseDebugTask = project.tasks.create("ResParseDebugTask", ResParseTask.class)<br /> resParseDebugTask.isDebug = true<br /> mergeDebugResourcesTask.finalizedBy(resParseDebugTask);<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
我们首先找到mergeDebugResources任务,然后注入一个ResParseTask任务。
然后在ResParseTask中完成文件解析:
<br />
class ResParseTask extends DefaultTask {<br /> File viewNameListFile<br /> boolean isDebug<br /> HashSet viewSet = new HashSet()<br /> // 自己根据输出几个添加<br /> List ignoreViewNameList = Arrays.asList("include", "fragment", "merge", "view","DateTimeView")<br /><br /> @TaskAction<br /> void doTask() {<br /><br /> File distDir = new File(project.buildDir, "tmp_custom_views")<br /> if (!distDir.exists()) {<br /> distDir.mkdirs()<br /> }<br /> viewNameListFile = new File(distDir, "custom_view_final.txt")<br /> if (viewNameListFile.exists()) {<br /> viewNameListFile.delete()<br /> }<br /> viewNameListFile.createNewFile()<br /> viewSet.clear()<br /> viewSet.addAll(ignoreViewNameList)<br /><br /> try {<br /> File resMergeFile = new File(project.buildDir, "/intermediates/incremental/merge" + (isDebug ? "Debug" : "Release") + "Resources/merger.xml")<br /><br /> println("resMergeFile:${resMergeFile.getAbsolutePath()} === ${resMergeFile.exists()}")<br /><br /> if (!resMergeFile.exists()) {<br /> return<br /> }<br /><br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(resMergeFile)<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /><br /> } catch (Throwable e) {<br /> e.printStackTrace()<br /> }<br /><br /> }<br /><br /> void parseNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> if (node.name() == "file" && node.attributes.get("type") == "layout") {<br /> String layoutPath = node.attributes.get("path")<br /> try {<br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(layoutPath)<br /><br /> String viewName = result.name();<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /> } catch (Throwable e) {<br /> e.printStackTrace();<br /> }<br /><br /> } else {<br /> node.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /> }<br /><br /> void parseLayoutNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> String viewName = node.name()<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (node.childNodes().size() <br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
代码很简单,主要就是解析merge.xml,找到所有的布局文件,然后解析xml,最后输出到build目录。
我们都把代码写在位于项目根目录的view_opt.gradle中,应用在app的build.gradle中:
<br />
apply from: rootProject.file('view_opt.gradle')<br />
<br />
然后我们再次运行assembleDebug,输出:
注意上面我们还有一个ignoreViewNameList对象,我们过滤了一些特殊的标签,比如:“include”、“fragment”、“merge”、“view”,你可以根据输出结果自行添加。
输出是:
可以看到是去重View的名字。
在这里提一下,很多同学看到写gradle脚本都会感到害怕。其实很简单。你可以只写Java。如果不熟悉语法,可以用Java写。没有什么特别的。
在这一点上,我们有所有使用的视图的名称。
2.apt生成代理类
有了所有用到的View的名字,然后我们用apt生成一个代理类和代理方法。
要使用 apt,我们需要创建 3 个新模块:
ViewOptAnnotation:存储注解;
ViewOptProcessor:放注解处理器相关代码;
ViewOptApi:放相关API。
关于Apt的基础知识就不说了。这块知识太复杂了。你可以自己查一下。后面我会把demo上传到github,大家自己看看。
直接看我们的核心Processor类:
<p>@AutoService(Processor.class)<br />public class ViewCreatorProcessor extends AbstractProcessor {<br /><br /> private Messager mMessager;<br /><br /><br /> @Override<br /> public synchronized void init(ProcessingEnvironment processingEnvironment) {<br /> super.init(processingEnvironment);<br /> mMessager = processingEnv.getMessager();<br /> }<br /><br /> @Override<br /> public boolean process(Set 查看全部
技巧:“手把手”的性能优化文章来了!
通过setFactory,我们不仅可以控制View的生成,甚至可以将一个View变成另一个View。比如文章中,我们把TextView变成了Button。
后续的换皮和一些黑白的方案都是以此为基础。
这意味着我们现在可以:
在运行时,接管某个View的生成,也就是我们可以去掉单个View标签的反射逻辑。
相似代码:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}
<br />
但是一般网上的项目都很大,可能会有各种自定义的View,类似上面的if else,怎么写呢?
先采集,再手写?
如何采集项目中使用的所有View?
假设我们采集了,如果是手写,项目一般都是增量的,那新加的View呢?
我们可以看到我们面临两个问题:
如何采集项目中xml中使用的View;
如何保证编写的View生成代码兼容项目的正常迭代;
3 确定方案
目标已经在这里确定了。
在xml->View的过程中,去掉反射相关的逻辑
下面说一下如何解决我们面临的两个问题:
1、如何采集项目中xml中使用的View;
采集所有xml中用到的View,有一个简单的思路,我们可以解析项目中所有的layout.xml文件,但是项目中的layout.xml文件有各个module,有些依赖的aars需要解压太难.
仔细想想,在我们apk的生成过程中,资源应该是需要合并的,是否是解析某个Task合并后的产物。
确实,具体的实现会在后面说到。
我们来看第二个问题:
2、如何保证编写的View生成代码兼容项目的正常迭代;
我们已经能够采集所有使用过的视图列表,因此为此:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}<br />
逻辑规则,简单,编译时生成一个代码类,完成相关的转换代码生成。这里我选择apt。
有了xml->View转换逻辑的代码类,只需要在运行时使用LayoutFactory注入即可。
3.找到安全的注入逻辑
大家都知道我们View生成相关的逻辑在LayoutInflater下面的代码中:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,<br /> boolean ignoreThemeAttr) {<br /> // ...<br /> View view;<br /> if (mFactory2 != null) {<br /> view = mFactory2.onCreateView(parent, name, context, attrs);<br /> } else if (mFactory != null) {<br /> view = mFactory.onCreateView(name, context, attrs);<br /> } else {<br /> view = null;<br /> }<br /><br /> if (view == null && mPrivateFactory != null) {<br /> view = mPrivateFactory.onCreateView(parent, name, context, attrs);<br /> }<br /><br /> if (view == null) {<br /> final Object lastContext = mConstructorArgs[0];<br /> mConstructorArgs[0] = context;<br /> try {<br /> if (-1 == name.indexOf('.')) {<br /> view = onCreateView(parent, name, attrs);<br /> } else {<br /> view = createView(name, null, attrs);<br /> }<br /> } finally {<br /> mConstructorArgs[0] = lastContext;<br /> }<br /> }<br /><br /> return view;<br /><br />}<br />
<br />
View通过mFactory2、mFactory和mPrivateFactory。建不完,后面等待的就是反思。
前两个工厂和支持包一般用于扩展功能,比如TextView->AppCompatTextView。
我们考虑使用 mPrivateFactory。使用mPrivateFactory的好处是,在当前版本中,mPrivateFactory是Activity,所以我们只需要重写Activity的onCreateView即可:
这样一来,完全不需要hooks,也不会干扰appcompat相关的生成逻辑,可谓是零风险。
4 开始实施
1.获取项目中使用的控件名称列表
我新建了一个工程,在布局文件中写了一些自定义控件,分别叫MyMainView1、MyMainView、MyMainView3、MyMainView4,布局文件就不贴了。
正如我们之前所说,我们需要在构建apk的过程中找到一个合适的注入点来完成这个任务。
那么在apk构建过程中,什么时候会合并资源呢?
我们把构建过程中的所有任务打印出来,输入命令:
./gradlew app:assembleDebug --console=plain<br />
<br />
输出:
>Task :app:preBuild UP-TO-DATE<br />> Task :app:preDebugBuild UP-TO-DATE<br />> Task :app:checkDebugManifest UP-TO-DATE<br />> Task :app:generateDebugBuildConfig UP-TO-DATE<br />> Task :app:javaPreCompileDebug UP-TO-DATE<br />> Task :app:mainApkListPersistenceDebug UP-TO-DATE<br />> Task :app:generateDebugResValues UP-TO-DATE<br />> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE<br />> Task :app:mergeDebugShaders UP-TO-DATE<br />> Task :app:compileDebugShaders UP-TO-DATE<br />> Task :app:generateDebugAssets UP-TO-DATE<br />> Task :app:compileDebugAidl NO-SOURCE<br />> Task :app:compileDebugRenderscript NO-SOURCE<br />> Task :app:generateDebugResources UP-TO-DATE<br />> Task :app:mergeDebugResources UP-TO-DATE<br />> Task :app:processDebugManifest UP-TO-DATE<br />> Task :app:processDebugResources UP-TO-DATE<br />> Task :app:compileDebugJavaWithJavac UP-TO-DATE<br />> Task :app:compileDebugSources UP-TO-DATE<br />> Task :app:mergeDebugAssets UP-TO-DATE<br />> Task :app:processDebugJavaRes NO-SOURCE<br />> Task :app:mergeDebugJavaResource UP-TO-DATE<br />> Task :app:transformClassesWithDexBuilderForDebug UP-TO-DATE<br />> Task :app:checkDebugDuplicateClasses UP-TO-DATE<br />> Task :app:validateSigningDebug UP-TO-DATE<br />> Task :app:mergeExtDexDebug UP-TO-DATE<br />> Task :app:mergeDexDebug UP-TO-DATE<br />> Task :app:signingConfigWriterDebug UP-TO-DATE<br />> Task :app:mergeDebugJniLibFolders UP-TO-DATE<br />> Task :app:mergeDebugNativeLibs UP-TO-DATE<br />> Task :app:stripDebugDebugSymbols UP-TO-DATE<br />> Task :app:packageDebug UP-TO-DATE<br />> Task :app:assembleDebug UP-TO-DATE<br />
<br />
哪一个最像?一看就有一个Task叫:mergeDebugResources,就是这样。
对应build目录,还有一个mergeDebugResources目录:
注意里面有一个merger.xml,里面收录了整个项目所有资源的合并内容。
我们打开看看:
关注里面type=layout的相关标签。
<br />
<br />
可以看到收录我们布局文件的路径,那么我们只需要解析这个merger.xml,然后在里面找到所有type=layout的标签,然后解析出布局文件的实际路径,然后解析出相应的layout xml来获取控件的名称。
对了,这个任务需要注入到mergeDebugResources中执行。
如何注入任务?
很简单:
project.afterEvaluate {<br /> def mergeDebugResourcesTask = project.tasks.findByName("mergeDebugResources")<br /> if (mergeDebugResourcesTask != null) {<br /> def resParseDebugTask = project.tasks.create("ResParseDebugTask", ResParseTask.class)<br /> resParseDebugTask.isDebug = true<br /> mergeDebugResourcesTask.finalizedBy(resParseDebugTask);<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
我们首先找到mergeDebugResources任务,然后注入一个ResParseTask任务。
然后在ResParseTask中完成文件解析:
<br />
class ResParseTask extends DefaultTask {<br /> File viewNameListFile<br /> boolean isDebug<br /> HashSet viewSet = new HashSet()<br /> // 自己根据输出几个添加<br /> List ignoreViewNameList = Arrays.asList("include", "fragment", "merge", "view","DateTimeView")<br /><br /> @TaskAction<br /> void doTask() {<br /><br /> File distDir = new File(project.buildDir, "tmp_custom_views")<br /> if (!distDir.exists()) {<br /> distDir.mkdirs()<br /> }<br /> viewNameListFile = new File(distDir, "custom_view_final.txt")<br /> if (viewNameListFile.exists()) {<br /> viewNameListFile.delete()<br /> }<br /> viewNameListFile.createNewFile()<br /> viewSet.clear()<br /> viewSet.addAll(ignoreViewNameList)<br /><br /> try {<br /> File resMergeFile = new File(project.buildDir, "/intermediates/incremental/merge" + (isDebug ? "Debug" : "Release") + "Resources/merger.xml")<br /><br /> println("resMergeFile:${resMergeFile.getAbsolutePath()} === ${resMergeFile.exists()}")<br /><br /> if (!resMergeFile.exists()) {<br /> return<br /> }<br /><br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(resMergeFile)<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /><br /> } catch (Throwable e) {<br /> e.printStackTrace()<br /> }<br /><br /> }<br /><br /> void parseNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> if (node.name() == "file" && node.attributes.get("type") == "layout") {<br /> String layoutPath = node.attributes.get("path")<br /> try {<br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(layoutPath)<br /><br /> String viewName = result.name();<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /> } catch (Throwable e) {<br /> e.printStackTrace();<br /> }<br /><br /> } else {<br /> node.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /> }<br /><br /> void parseLayoutNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> String viewName = node.name()<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (node.childNodes().size() <br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
代码很简单,主要就是解析merge.xml,找到所有的布局文件,然后解析xml,最后输出到build目录。
我们都把代码写在位于项目根目录的view_opt.gradle中,应用在app的build.gradle中:
<br />
apply from: rootProject.file('view_opt.gradle')<br />
<br />
然后我们再次运行assembleDebug,输出:

注意上面我们还有一个ignoreViewNameList对象,我们过滤了一些特殊的标签,比如:“include”、“fragment”、“merge”、“view”,你可以根据输出结果自行添加。
输出是:
可以看到是去重View的名字。
在这里提一下,很多同学看到写gradle脚本都会感到害怕。其实很简单。你可以只写Java。如果不熟悉语法,可以用Java写。没有什么特别的。
在这一点上,我们有所有使用的视图的名称。
2.apt生成代理类
有了所有用到的View的名字,然后我们用apt生成一个代理类和代理方法。
要使用 apt,我们需要创建 3 个新模块:
ViewOptAnnotation:存储注解;
ViewOptProcessor:放注解处理器相关代码;
ViewOptApi:放相关API。
关于Apt的基础知识就不说了。这块知识太复杂了。你可以自己查一下。后面我会把demo上传到github,大家自己看看。
直接看我们的核心Processor类:
<p>@AutoService(Processor.class)<br />public class ViewCreatorProcessor extends AbstractProcessor {<br /><br /> private Messager mMessager;<br /><br /><br /> @Override<br /> public synchronized void init(ProcessingEnvironment processingEnvironment) {<br /> super.init(processingEnvironment);<br /> mMessager = processingEnv.getMessager();<br /> }<br /><br /> @Override<br /> public boolean process(Set
推荐文章:想写一篇高引用的综述文章?你需要这样做!
采集交流 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-11-16 12:28
这是社科学术圈推送的第2307篇文章文章
打开topic-experiment-publishing,每一步都需要阅读文献,但是这几个步骤的文献并不全面。从解决一个问题的开始到解决一个问题的结束,所有的具体文献都涉及到。要想全面把握整个题目的走向,写综述是非常有必要的。而且,经过长时间的相关研究,写一篇评论文章有以下好处:
在很大程度上可以提高把握整个学科方向的能力。通过详细、全面的文献检索和阅读,可以全面掌握和了解本课题的发展脉络、研究进展和最新成果。
其次,是对自己作品的总结和升华。经过多年的相关研究,我心中一定有很多的思考和疑问。这时候,大量的阅读就是对自己固有知识的一个归纳升华的过程。写完应该有顿悟的感觉。
再次,对以后的实验研究具有重要的指导作用。写好review之后,通过对整个项目方向的了解,知道哪些问题已经解决,哪些地方还存在问题,哪些问题是热点问题,哪些是难点骨头,是制约项目发展的关键. 这样,就可以有针对性地设计以后的实验。
在小的方面,评论也是一个文章。现在国内的评价都是看个人成绩,总结也是一种发表文章的方式。另一方面,你可以提高你在同龄人中的地位。一般来说,评论 文章 比研究 文章 有更多的引用,从而提高了它们在同行中的知名度。
《文献检索准备工作》
在开始写评论之前,一个重要的准备工作就是文献检索。审查文章 需要全面,并且必须综合审查中审查的问题。因此,有必要进行详尽的文献检索。
这里说的全面,并不是说下载阅读几十年的所有文章。这将是太多的工作。这是一。第二,早期的文章可能已经总结过了。因此,只需寻找一些综述 文章。这里的综合指的是更多的关键词搜索和更多的数据库搜索。先说关键词,每个作者对关键词的偏好不同,在新兴领域没有统一术语的时候,多改几个关键词是很有必要的。除了数据库,由于各个数据库收录的期刊并不全面,所以重要的搜索工具在这里必不可少。
获取相关文献还有两个技巧。一个是我读过的文章中引用的文献。这个很容易理解,文末的参考资料就是这样。另外就是看哪个文章引用了你读过的文章,也是相关文献。例如,谷歌学术有一个引用计数,你可以通过点击查看哪些文章引用了这篇文章文章。
通过以上几种方法,才能找到所有相关文献。
“大量阅读以备不时之需”
找到所有的文献之后,下一步就是开始阅读了。
首先,没必要全部看完,时间太长,工作量太大。但是,应该通读最近两年的文章。两年是对一个相对热门的领域进行全面概述 文章 的合理时间点。近两年的文章要通读重点,这也是复习的重点。不通读就知道解决了什么问题,如何解决是不够的;没看完就写点评有点不负责任。
两年前的文章完全没必要看,因为你可以从这两年的文章里的序言里看对这些文章的评论,就可以了也看了评论文章获取相关信息。这些文章可以重点阅读摘要,也有针对某个问题的针对性阅读。
“如何阅读文件”
阅读数百份文件并非易事。如果你只是浏览它们,你只能留下一个大概的印象。一段时间后或者随着阅读文档的增多,这种模糊的印象也会消失。知识点的记忆是写作和创作的基础。我不记得如何组织语言。就算查了,也不知道从几百份文件,几千页里查到哪里去。
我的导师教我要辩证地看书,边想边记,不能在书上乱写。对我来说,“好记性不如烂笔头”更适合我,也适合我的德国同事。他们将文件打印在A4纸上,并用荧光笔标出重要的句子。看完后,抄写在A5纸上,作为选集书到原稿上。摘录的才是真正对你有用的知识点。大多数其他 文章 都是伏笔,或者已经在你的记忆中。“划重点+读书笔记”可以有效帮助记忆。
虽然一开始这样看很慢,但是随着文档写了十多二十篇,积累多了,后面的摘录就会越来越少。还有,你的阅读速度越来越快。
《文件管理》
下载数百个文档后,文档流水线就成了问题。对于文献管理,Endnote就是这样一个专业,它可以有效地组织庞大的文献,并为您提供全面的信息,如作者、期刊、年份、标题、卷页码和摘要。有些期刊在投稿的时候需要DOI,Endnote也可以。Endnote在文章的编排中起着巨大的作用,是写评论、写论文、写书的必备工具。
虽然电子版很方便,但我还是更喜欢看纸质版。我喜欢把文件打印出来,统一编号(和Endnote一致,Endnote中的Label可以加编号),打孔,放在活页夹里。
“文章 的架构”
文学阅读是一个从“说得过去”、“说得过去”、“大是大非”到“无事生非”的过程。
我刚开始读书。由于本人知识有限,之前文章提出的方法和结果对我来说都是全新的,我的知识储备不足以判断观点。因此,当你刚开始阅读时,你会完全接受文章中的所有内容,很难提出有问题的观点,你阅读的任何内容都是“有理有据”的。看了十八篇文章,明白了更多的方法和观点,有些可能会有不同的看法。这是因为疑惑会跳出来,我会挑剔我读到的论据,但我不能仅仅依靠一两篇文章文章就断定一种方法完全优于另一种方法。每种方法都有其优缺点,从而达到“似是而非”的境界。只有看到足够多的文章才能做出完整的评价,得到的对比结果也有足够的论据。这时,已经达到了“大是大非”的境界。
一篇评论文章,一部分是综合别人的作品,一部分是讨论自己的观点。大是大非只是全面的一步,还应该更进一步。通过对“大是大非”的把握,要能够发现新问题、新优势或劣势,提出改进方法,对今后的工作和发展前景提出建议和设想。更有什者,跳出对原实验细枝末节的讨论,从更高的层次,从原理、方法和系统上进行评价。这当然是非常困难的。所以,大部分的总结文章都是总结而不总结,以至于读者看完后对过去有所了解,但对未来还是茫然无措。当然,
如果看完之后能做到“大是大非”的经济,就可以开始写作了。写作时,首先要搭建一个框架,对要概括的内容进行分类、细分。分得越细越好,至少三级,三级标题下可能还有四五级标题。这样做有以下好处:
@frame 要审查并缩小范围的问题。不要让你的写作“随心所欲”,偏离了方向,失去了重心。也容易分清主次,而不是抓眉毛胡子。这不是在写一本书,没有太多的空间来全面讨论,所以限制你的评论范围。
@写作压力小。一想到写文章文章,就想到“至少写5000字,看100篇文档”,瞬间压力倍增,不知从何下手。细分之后,你需要考虑的就是讨论某个方法的某个参数,只需要一小段文字。它非常容易,可以立即完成,没有太大的压力。
@有顺序地。所有要讨论的问题都列在那里,就像一个TO-DO LIST,完成一项划掉一项,一项一项,有条不紊,进度非常直观。
《写作的小细节》
文章细分成小节后,就可以开始完成每个小节了。下面介绍几个非常有效的小技巧。
@注意写作的连贯性:最好一口气写完,写A的时候不要想着B。这里有两个意思。写A题时,找到B题有用的材料;另一个意思是你在写A题的时候发现了B题的错误、遗漏或者其他问题。这时候不要停下来,直接用便利贴做笔记(我习惯用ONENOTE做笔记采集材料)。做完笔记,继续写A题,直到写完。我们回过头来梳理B题。
@二手文献:为了证明一个结论,可能需要引用文章主题之外的文献,或者需要从文献中引用的文献中寻找证据,这称为二手文献。文献中被他人引用的数据一定要核对,避免错引文献、错引数据。
@图片处理:一个是图片的版权问题,这个不用担心。当你投稿给期刊时,期刊的编辑会处理;二是画质。从其他文档中提取图片时,不要使用截图,因为图片的分辨率不够。PDF文件要用PHOTOSHOP打开,裁剪出需要的图片,然后保存为TIFF/JPEG格式。PPT中绘制的图片,不要使用PPT的“图片另存为”功能,分辨率太弱。应该说是把PPT保存成PDF,然后用PHOTOSHOP处理。
@references 的修改。前期写作时,必须用ENDNOTE对插入WORD的文档进行索引。如果文章已经形成,则ENDNOTE已经导出了参考文献,其他作者修改后,需要增删参考文献。添加或删除文档将更改其他文档的索引号。这时候很容易出错。我用的是下面的方法:在每个要更改的文档的索引中加上“*”;在“*”后添加新的参考索引号;使用搜索功能确认每一个需要改的文档都用“*”连接(应该出现两次,比如添加引用121、122应该有两个,121*122、122*123,即121变成 122,122 变成 123);删除“*”和之前的索引号。
@英语句子,短句胜于长句。被人理解才是最重要的。简短的句子很容易理解。太多的定语从句会让人头晕目眩。
“文章 的亮点”
一篇文章文章必须要有一些“干货”,才能被更多人引用。所以在你写之前,看看你下载的 文章 的引用。哪个 文章 获得了最多的引用?为什么?
从我个人引用文章的习惯来看,下面的文章会被引用:
@第一篇文章:该领域的开创性工作,不引用是不合理的;
@milestone文章:文章达到最高、最高、最大、最快等,或者突出的进步,应该注明;
@正在讨论核心问题。
另外,我也喜欢引用结论性的句子,比如某项技术的优点……;以及量化的句子,比如70%的文章目前都采用了某种方法。
如果你能在你的评论中提供这些内容,那肯定会增加其他引用的数量。前三个干货是研究型文章的东西,后两个就不简单了。第一个需要你自己总结,第二个需要大量的统计。
分享文章:文章伪原创检查(在线文章伪原创)
本文阅读提示:在线文章伪原创,文章伪原创软件移动版,文章采集伪原创
文章伪原创检查工具在线 zoding(文章伪原创),4 个经典 SEO 伪原创|谷歌搜索引擎:pR劫持,5个常规工件
网站共同点和伪原创是SEO伪项目,1支持多个平台的SEO伪原创
SEO伪原创检测工具伪原创,1并支持多个平台的SEO伪原创
SEO伪原创检测工具在线伪原创,2并支持多种快速替换的SEO伪原创
搜索引擎优化
伪原创检测工具伪原创,3并支持多种快速替换的SEO伪原创
SEO伪原创检测工具在线伪原创,1支持图文组合的快速伪原创
SEO伪原创检测工具伪原创,1并支持多种快速替换的SEO伪原创
SEO伪原创检测工具,1支持图文组合的多版本伪原创
SEO伪原创检测工具,2支持重大修改
SEO伪原创,3大伪原创成本测试
SEO伪原创文章工具,1个搜索引擎与文章库集成
SEO 伪原创文章工具,1 个集成关键词
SEO伪原创文章工具,1个集成关键词,搜索量关键词
SEO伪原创文章工具,2密度的组织关键词
SEO伪原创文章工具,3.优化网站内部链
SEO伪原创文章工具,1网站结构优化
SEO伪原创文章工具,1网站结构优化:平面结构。辅助导航。痕迹导航。子导航。野外站。特殊优化2.内容页面优化:(优化最新文章。推荐文章。热门文章 3页面加载速度(秒) 4.页面代码压缩和简化
SEO伪原创文章工具,2个面包屑来指导页面。 301重定向第五代。图像标签 6.网站 TDK写作 7.关键词密度控制8.在单词标签周围使用关键字 9.粗体关键字等 10.合理使用NO11。分页代码优化SEO 伪原创文章工具
、3SEO 伪原创文章工具站点地图设置
SEO 伪原创文章工具,1 网站结构优化 2.网站地图优化提交。主动推送。自动推送)。
SEO伪原创文章工具,4个优化的关键词布局
SEO伪原创文章工具,1选择和识别核心关键词。长尾关键词延伸。关键词工具词挖掘研究。竞争对手网站关键词分享研究成果
搜索引擎优化伪原创文章工具,
相关文章 查看全部
推荐文章:想写一篇高引用的综述文章?你需要这样做!
这是社科学术圈推送的第2307篇文章文章
打开topic-experiment-publishing,每一步都需要阅读文献,但是这几个步骤的文献并不全面。从解决一个问题的开始到解决一个问题的结束,所有的具体文献都涉及到。要想全面把握整个题目的走向,写综述是非常有必要的。而且,经过长时间的相关研究,写一篇评论文章有以下好处:
在很大程度上可以提高把握整个学科方向的能力。通过详细、全面的文献检索和阅读,可以全面掌握和了解本课题的发展脉络、研究进展和最新成果。
其次,是对自己作品的总结和升华。经过多年的相关研究,我心中一定有很多的思考和疑问。这时候,大量的阅读就是对自己固有知识的一个归纳升华的过程。写完应该有顿悟的感觉。
再次,对以后的实验研究具有重要的指导作用。写好review之后,通过对整个项目方向的了解,知道哪些问题已经解决,哪些地方还存在问题,哪些问题是热点问题,哪些是难点骨头,是制约项目发展的关键. 这样,就可以有针对性地设计以后的实验。
在小的方面,评论也是一个文章。现在国内的评价都是看个人成绩,总结也是一种发表文章的方式。另一方面,你可以提高你在同龄人中的地位。一般来说,评论 文章 比研究 文章 有更多的引用,从而提高了它们在同行中的知名度。
《文献检索准备工作》
在开始写评论之前,一个重要的准备工作就是文献检索。审查文章 需要全面,并且必须综合审查中审查的问题。因此,有必要进行详尽的文献检索。
这里说的全面,并不是说下载阅读几十年的所有文章。这将是太多的工作。这是一。第二,早期的文章可能已经总结过了。因此,只需寻找一些综述 文章。这里的综合指的是更多的关键词搜索和更多的数据库搜索。先说关键词,每个作者对关键词的偏好不同,在新兴领域没有统一术语的时候,多改几个关键词是很有必要的。除了数据库,由于各个数据库收录的期刊并不全面,所以重要的搜索工具在这里必不可少。
获取相关文献还有两个技巧。一个是我读过的文章中引用的文献。这个很容易理解,文末的参考资料就是这样。另外就是看哪个文章引用了你读过的文章,也是相关文献。例如,谷歌学术有一个引用计数,你可以通过点击查看哪些文章引用了这篇文章文章。
通过以上几种方法,才能找到所有相关文献。
“大量阅读以备不时之需”
找到所有的文献之后,下一步就是开始阅读了。
首先,没必要全部看完,时间太长,工作量太大。但是,应该通读最近两年的文章。两年是对一个相对热门的领域进行全面概述 文章 的合理时间点。近两年的文章要通读重点,这也是复习的重点。不通读就知道解决了什么问题,如何解决是不够的;没看完就写点评有点不负责任。

两年前的文章完全没必要看,因为你可以从这两年的文章里的序言里看对这些文章的评论,就可以了也看了评论文章获取相关信息。这些文章可以重点阅读摘要,也有针对某个问题的针对性阅读。
“如何阅读文件”
阅读数百份文件并非易事。如果你只是浏览它们,你只能留下一个大概的印象。一段时间后或者随着阅读文档的增多,这种模糊的印象也会消失。知识点的记忆是写作和创作的基础。我不记得如何组织语言。就算查了,也不知道从几百份文件,几千页里查到哪里去。
我的导师教我要辩证地看书,边想边记,不能在书上乱写。对我来说,“好记性不如烂笔头”更适合我,也适合我的德国同事。他们将文件打印在A4纸上,并用荧光笔标出重要的句子。看完后,抄写在A5纸上,作为选集书到原稿上。摘录的才是真正对你有用的知识点。大多数其他 文章 都是伏笔,或者已经在你的记忆中。“划重点+读书笔记”可以有效帮助记忆。
虽然一开始这样看很慢,但是随着文档写了十多二十篇,积累多了,后面的摘录就会越来越少。还有,你的阅读速度越来越快。
《文件管理》
下载数百个文档后,文档流水线就成了问题。对于文献管理,Endnote就是这样一个专业,它可以有效地组织庞大的文献,并为您提供全面的信息,如作者、期刊、年份、标题、卷页码和摘要。有些期刊在投稿的时候需要DOI,Endnote也可以。Endnote在文章的编排中起着巨大的作用,是写评论、写论文、写书的必备工具。
虽然电子版很方便,但我还是更喜欢看纸质版。我喜欢把文件打印出来,统一编号(和Endnote一致,Endnote中的Label可以加编号),打孔,放在活页夹里。
“文章 的架构”
文学阅读是一个从“说得过去”、“说得过去”、“大是大非”到“无事生非”的过程。
我刚开始读书。由于本人知识有限,之前文章提出的方法和结果对我来说都是全新的,我的知识储备不足以判断观点。因此,当你刚开始阅读时,你会完全接受文章中的所有内容,很难提出有问题的观点,你阅读的任何内容都是“有理有据”的。看了十八篇文章,明白了更多的方法和观点,有些可能会有不同的看法。这是因为疑惑会跳出来,我会挑剔我读到的论据,但我不能仅仅依靠一两篇文章文章就断定一种方法完全优于另一种方法。每种方法都有其优缺点,从而达到“似是而非”的境界。只有看到足够多的文章才能做出完整的评价,得到的对比结果也有足够的论据。这时,已经达到了“大是大非”的境界。
一篇评论文章,一部分是综合别人的作品,一部分是讨论自己的观点。大是大非只是全面的一步,还应该更进一步。通过对“大是大非”的把握,要能够发现新问题、新优势或劣势,提出改进方法,对今后的工作和发展前景提出建议和设想。更有什者,跳出对原实验细枝末节的讨论,从更高的层次,从原理、方法和系统上进行评价。这当然是非常困难的。所以,大部分的总结文章都是总结而不总结,以至于读者看完后对过去有所了解,但对未来还是茫然无措。当然,
如果看完之后能做到“大是大非”的经济,就可以开始写作了。写作时,首先要搭建一个框架,对要概括的内容进行分类、细分。分得越细越好,至少三级,三级标题下可能还有四五级标题。这样做有以下好处:
@frame 要审查并缩小范围的问题。不要让你的写作“随心所欲”,偏离了方向,失去了重心。也容易分清主次,而不是抓眉毛胡子。这不是在写一本书,没有太多的空间来全面讨论,所以限制你的评论范围。
@写作压力小。一想到写文章文章,就想到“至少写5000字,看100篇文档”,瞬间压力倍增,不知从何下手。细分之后,你需要考虑的就是讨论某个方法的某个参数,只需要一小段文字。它非常容易,可以立即完成,没有太大的压力。
@有顺序地。所有要讨论的问题都列在那里,就像一个TO-DO LIST,完成一项划掉一项,一项一项,有条不紊,进度非常直观。

《写作的小细节》
文章细分成小节后,就可以开始完成每个小节了。下面介绍几个非常有效的小技巧。
@注意写作的连贯性:最好一口气写完,写A的时候不要想着B。这里有两个意思。写A题时,找到B题有用的材料;另一个意思是你在写A题的时候发现了B题的错误、遗漏或者其他问题。这时候不要停下来,直接用便利贴做笔记(我习惯用ONENOTE做笔记采集材料)。做完笔记,继续写A题,直到写完。我们回过头来梳理B题。
@二手文献:为了证明一个结论,可能需要引用文章主题之外的文献,或者需要从文献中引用的文献中寻找证据,这称为二手文献。文献中被他人引用的数据一定要核对,避免错引文献、错引数据。
@图片处理:一个是图片的版权问题,这个不用担心。当你投稿给期刊时,期刊的编辑会处理;二是画质。从其他文档中提取图片时,不要使用截图,因为图片的分辨率不够。PDF文件要用PHOTOSHOP打开,裁剪出需要的图片,然后保存为TIFF/JPEG格式。PPT中绘制的图片,不要使用PPT的“图片另存为”功能,分辨率太弱。应该说是把PPT保存成PDF,然后用PHOTOSHOP处理。
@references 的修改。前期写作时,必须用ENDNOTE对插入WORD的文档进行索引。如果文章已经形成,则ENDNOTE已经导出了参考文献,其他作者修改后,需要增删参考文献。添加或删除文档将更改其他文档的索引号。这时候很容易出错。我用的是下面的方法:在每个要更改的文档的索引中加上“*”;在“*”后添加新的参考索引号;使用搜索功能确认每一个需要改的文档都用“*”连接(应该出现两次,比如添加引用121、122应该有两个,121*122、122*123,即121变成 122,122 变成 123);删除“*”和之前的索引号。
@英语句子,短句胜于长句。被人理解才是最重要的。简短的句子很容易理解。太多的定语从句会让人头晕目眩。
“文章 的亮点”
一篇文章文章必须要有一些“干货”,才能被更多人引用。所以在你写之前,看看你下载的 文章 的引用。哪个 文章 获得了最多的引用?为什么?
从我个人引用文章的习惯来看,下面的文章会被引用:
@第一篇文章:该领域的开创性工作,不引用是不合理的;
@milestone文章:文章达到最高、最高、最大、最快等,或者突出的进步,应该注明;
@正在讨论核心问题。
另外,我也喜欢引用结论性的句子,比如某项技术的优点……;以及量化的句子,比如70%的文章目前都采用了某种方法。
如果你能在你的评论中提供这些内容,那肯定会增加其他引用的数量。前三个干货是研究型文章的东西,后两个就不简单了。第一个需要你自己总结,第二个需要大量的统计。
分享文章:文章伪原创检查(在线文章伪原创)
本文阅读提示:在线文章伪原创,文章伪原创软件移动版,文章采集伪原创
文章伪原创检查工具在线 zoding(文章伪原创),4 个经典 SEO 伪原创|谷歌搜索引擎:pR劫持,5个常规工件
网站共同点和伪原创是SEO伪项目,1支持多个平台的SEO伪原创
SEO伪原创检测工具伪原创,1并支持多个平台的SEO伪原创
SEO伪原创检测工具在线伪原创,2并支持多种快速替换的SEO伪原创
搜索引擎优化
伪原创检测工具伪原创,3并支持多种快速替换的SEO伪原创
SEO伪原创检测工具在线伪原创,1支持图文组合的快速伪原创

SEO伪原创检测工具伪原创,1并支持多种快速替换的SEO伪原创
SEO伪原创检测工具,1支持图文组合的多版本伪原创
SEO伪原创检测工具,2支持重大修改
SEO伪原创,3大伪原创成本测试
SEO伪原创文章工具,1个搜索引擎与文章库集成
SEO 伪原创文章工具,1 个集成关键词
SEO伪原创文章工具,1个集成关键词,搜索量关键词
SEO伪原创文章工具,2密度的组织关键词
SEO伪原创文章工具,3.优化网站内部链

SEO伪原创文章工具,1网站结构优化
SEO伪原创文章工具,1网站结构优化:平面结构。辅助导航。痕迹导航。子导航。野外站。特殊优化2.内容页面优化:(优化最新文章。推荐文章。热门文章 3页面加载速度(秒) 4.页面代码压缩和简化
SEO伪原创文章工具,2个面包屑来指导页面。 301重定向第五代。图像标签 6.网站 TDK写作 7.关键词密度控制8.在单词标签周围使用关键字 9.粗体关键字等 10.合理使用NO11。分页代码优化SEO 伪原创文章工具
、3SEO 伪原创文章工具站点地图设置
SEO 伪原创文章工具,1 网站结构优化 2.网站地图优化提交。主动推送。自动推送)。
SEO伪原创文章工具,4个优化的关键词布局
SEO伪原创文章工具,1选择和识别核心关键词。长尾关键词延伸。关键词工具词挖掘研究。竞争对手网站关键词分享研究成果
搜索引擎优化伪原创文章工具,
相关文章
解读:【精选小说】文章采集调用bing程序的作用呢?
采集交流 • 优采云 发表了文章 • 0 个评论 • 124 次浏览 • 2022-11-28 15:32
文章采集调用bing爬虫程序的方法,直接用爬虫就能采集大量数据,但是bing爬虫对我们来说又有什么作用呢?bing云采集网站抓取的页面标题,地址和数据应该是一个独立的页面吗?应该独立在某个页面上吗?要达到什么效果?可以调用吗?公众号查询【精选小说】文章采集使用sublime安装pythonsublime有windows版,需要一个安装visualstudiocode的编辑器。
使用pythonsublime怎么采集bing云采集结果地址对应的云采集地址可以调用吗?可以调用的方法就是chrome云采集selenium+pyseleniumwindows版chrome采集用pyselenium之前需要编写一段脚本,用它运行脚本,然后在bing页面上随机输入地址,是没有数据的。pythonsublime插件,需要编写代码如果开发团队有开发的python的项目,为了尽快在pythonsublime的工作环境中测试脚本,可以将脚本写成c和c++,ruby等语言编写。
这个项目叫做pythonwebdriver的selenium,用于windows,linux和mac桌面环境下开发爬虫程序。可以自行百度查看chromecss开发社区。可以导入下载的js文件,此外还需要安装下载助手。在项目目录下,会发现出现一个chrome/webdriver.swig。解压。看一下源码:脚本在解压后目录中应该有一个.py。
内置的爬虫程序。下载:百度云下载帮助文件,用next找到要下载的文件,然后copy。一般我这边下载是128m这个大小。右键点击以管理员身份运行,选择copymetadata到,复制源码粘贴到运行中,测试。运行成功之后,就生成了一个文件,具体如下:运行成功之后,查看项目目录下生成的文件,没看到.py,而看到的是这样的:现在我们先在另一台电脑上安装bing,在安装bing之前,需要添加环境变量。
添加到visualstudiocode的extensions的plugins文件夹中。path中加入;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%。 查看全部
解读:【精选小说】文章采集调用bing程序的作用呢?
文章采集调用bing爬虫程序的方法,直接用爬虫就能采集大量数据,但是bing爬虫对我们来说又有什么作用呢?bing云采集网站抓取的页面标题,地址和数据应该是一个独立的页面吗?应该独立在某个页面上吗?要达到什么效果?可以调用吗?公众号查询【精选小说】文章采集使用sublime安装pythonsublime有windows版,需要一个安装visualstudiocode的编辑器。

使用pythonsublime怎么采集bing云采集结果地址对应的云采集地址可以调用吗?可以调用的方法就是chrome云采集selenium+pyseleniumwindows版chrome采集用pyselenium之前需要编写一段脚本,用它运行脚本,然后在bing页面上随机输入地址,是没有数据的。pythonsublime插件,需要编写代码如果开发团队有开发的python的项目,为了尽快在pythonsublime的工作环境中测试脚本,可以将脚本写成c和c++,ruby等语言编写。
这个项目叫做pythonwebdriver的selenium,用于windows,linux和mac桌面环境下开发爬虫程序。可以自行百度查看chromecss开发社区。可以导入下载的js文件,此外还需要安装下载助手。在项目目录下,会发现出现一个chrome/webdriver.swig。解压。看一下源码:脚本在解压后目录中应该有一个.py。

内置的爬虫程序。下载:百度云下载帮助文件,用next找到要下载的文件,然后copy。一般我这边下载是128m这个大小。右键点击以管理员身份运行,选择copymetadata到,复制源码粘贴到运行中,测试。运行成功之后,就生成了一个文件,具体如下:运行成功之后,查看项目目录下生成的文件,没看到.py,而看到的是这样的:现在我们先在另一台电脑上安装bing,在安装bing之前,需要添加环境变量。
添加到visualstudiocode的extensions的plugins文件夹中。path中加入;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%;%path%%。
解决方案:web开发中如何快速开发标准?
采集交流 • 优采云 发表了文章 • 0 个评论 • 134 次浏览 • 2022-11-28 12:25
文章采集调用百度收录-提取请求参数getheaderbyormer提取关键字直接编译下getheaderbyormer成java脚本,生成jar然后调用即可先直接在http请求的getheaderbyformer用-g打开获取到的参数xml然后使用java反射最终构造出java类作为参数提交到web页面中开发还是maven比较方便可以管理版本和依赖项,发布到服务器,更方便代码更稳定。
楼上建议maven的非常对,但是我觉得你还需要了解一个东西,就是spring整个的生态圈,如果使用的netty,那么我觉得你可以参考maven来实现,他不是唯一的做事情的方式,但是做web开发,用maven肯定不是最佳方式,没有看到过用jpa的,毕竟web开发的难度还是比较大的。我个人觉得spring使用用,相比jpa而言做开发难度就降低不少。
如果要更快速的话我建议使用ejb标准,现在ejb泛滥,效率极其低,企业环境下不常用,也很难改。企业环境是一个复杂度很高的问题,往往涉及到架构本身的设计,系统的性能优化,业务复杂度,单体环境对网络和硬件的要求,权限划分,数据库同步等问题。而spring让这些复杂的内容成为可能,但是真正想要快速开发,还是推荐maven,要不然又是spring的一堆坑。
对于如何快速,我可以给出一个看起来比较容易实现的方法:1.批量抓取百度首页(每页),提取出高频的关键字组合;2.对关键字进行md5+hash加密,用于加密之后的参数;3.然后提取出低频词或者模糊搜索关键字,放入正则;4.放入所需的参数中即可,譬如用户。 查看全部
解决方案:web开发中如何快速开发标准?
文章采集调用百度收录-提取请求参数getheaderbyormer提取关键字直接编译下getheaderbyormer成java脚本,生成jar然后调用即可先直接在http请求的getheaderbyformer用-g打开获取到的参数xml然后使用java反射最终构造出java类作为参数提交到web页面中开发还是maven比较方便可以管理版本和依赖项,发布到服务器,更方便代码更稳定。

楼上建议maven的非常对,但是我觉得你还需要了解一个东西,就是spring整个的生态圈,如果使用的netty,那么我觉得你可以参考maven来实现,他不是唯一的做事情的方式,但是做web开发,用maven肯定不是最佳方式,没有看到过用jpa的,毕竟web开发的难度还是比较大的。我个人觉得spring使用用,相比jpa而言做开发难度就降低不少。

如果要更快速的话我建议使用ejb标准,现在ejb泛滥,效率极其低,企业环境下不常用,也很难改。企业环境是一个复杂度很高的问题,往往涉及到架构本身的设计,系统的性能优化,业务复杂度,单体环境对网络和硬件的要求,权限划分,数据库同步等问题。而spring让这些复杂的内容成为可能,但是真正想要快速开发,还是推荐maven,要不然又是spring的一堆坑。
对于如何快速,我可以给出一个看起来比较容易实现的方法:1.批量抓取百度首页(每页),提取出高频的关键字组合;2.对关键字进行md5+hash加密,用于加密之后的参数;3.然后提取出低频词或者模糊搜索关键字,放入正则;4.放入所需的参数中即可,譬如用户。
解决方案:最简单的方法,优采云 采集后直接导入到wordpress的数据库
采集交流 • 优采云 发表了文章 • 0 个评论 • 118 次浏览 • 2022-11-28 12:24
采集后直接导入到wordpress的数据库
很多人用wordpress做网站,用优采云
采集
,但不会发布。这里有一个简单的方法,可以瞬间将采集
到的内容直接发布到wordpress
优点:简单、快速、一目了然。
缺点:发布文章的分类标签需要手动编辑。
更适合纯文本,或者像尴尬百科这样的笑话网站
不谈采集
,只谈出版,
这里是最简单的演示,只发布内容和标题,要发布其他内容,照着做即可。
首先找到默认模板:
然后将模板更改为这样的东西,
这段代码是怎么来的?了解数据库的人一看就会知道。如果你不懂数据库,叫你哥是一种简单的方式。空间带的mysql数据库有运行界面phpmyadmin,一般空间都有。打开找到wp-post表,插入一条数据:这条数据,只填content和title
, 其他留空
然后点击执行,你会看到这样一段代码:
插入 `DatabaseName`.`wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status` , `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count `) VALUES (NULL, '0', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '内容 xxxxxxx', '标题 XXXXXXXX', '', '发布', '打开', '打开', '', '', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', ' ', '0', '', '0', '发布', '', '0');
替换:数据库名称 -> 你的数据库名称
汇总:Python如何采集关键词数据
对于SEO来说,关键词的排名对网站优化起着决定性的作用。关键词排名、流量来源、同行网站数据都可以通过SEO查询。常见的爱站站长工具、站长工具和5118都是不错的网站。
当然现在5118更全面,应用更广泛!
在数据和功能上,5118很强大!
可以的话就付钱!
5118的抗爬还是很不错的!
需要登录领取,发现5118更新了一次!
比如登录账号需要经过滑块验证码的反爬限制,关键词索引等数据以图片加密的形式展示。这人渣破解不了,就怕了。.
不过有些数据还是可以参考的!所以,让 python 起来!
打听一下设计网站,关键词设计迷信现状
抓取网址:
如果您不是付费会员,您只能查看前100页的数据!
很多数据都是反爬限制,有点可惜!
虽然5118会员登录有滑块验证码,但是cookies登录还是非常好用的!
我们手动添加 cookie 以登录以采集
所需数据。
几个关键点:
1.添加协议头
headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': ua,
'X-Requested-With': 'XMLHttpRequest',
}
自行添加ua和cooikes!
当然这是一个完整的协议头,有些可以删掉,大家可以自己试试!
2. zip函数的使用及格式化数据处理
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
3.排名波动的处理
通过源码查询可以知道,绿色表示排名上升,红色表示排名下降。这里有一个判断就搞定了!
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
4. 关键词 将数据写入csv
写了一个案例,发现了两个参考案例
import csv
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#参考一
def write_csv(self):
path = "aa.csv"
with open(path, 'a+') as f:
csv_write = csv.writer(f)
data_row = ["1", "2"]
<p>
csv_write.writerow(data_row)
# 参考二
def wcsv(self):
csvfile = open('csvtest.csv', 'w')
writer = csv.writer(csvfile)
writer.writerow(['keywords'])
data = [
('1', 'http://www.xiaoheiseo.com/', '小黑'),
('2', 'http://www.baidu.com/', '百度'),
('3', 'http://www.jd.com/', '京东')
]
writer.writerows(data)
csvfile.close()
</p>
5、查询网站相关关键词数据,写入excel表格
使用第三方库, xlsxwriter
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
由于页码也是js生成的,所以没有找到,所以自己输入页码!
输入查询网站的URL格式为:抓取后数据存储文件使用主域名!
附上完整代码:
#5118网站关键词数据获取
import requests
from lxml import etree
from urllib.parse import unquote
import xlsxwriter
import time
import csv
class C5118(object):
def __init__(self,url,nums):
self.keyword_datas=[]
self.data_lists=[]
self.index_links_hrefs=[]
self.headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': UA,
'X-Requested-With': 'XMLHttpRequest',
}
self.post_url=url
self.file_name=url.split('.')[1]
self.pagenums=nums
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
<p>
#获取数据
def get_data(self,pagenum):
url="https://www.5118.com/seo/baidupc"
params={
'isPager': 'true',
'viewtype': '2',
'days': '90',
'url': self.post_url,
'orderField': 'Rank',
'orderDirection': 'asc',
'pageIndex': pagenum, #页码
'catalogName': '',
}
response=requests.post(url,params=params,headers=self.headers)
time.sleep(1)
print(response.status_code)
doc=etree.HTML(response.content.decode('utf-8'))
keywords= doc.xpath('//tr[@class="list-row"]/td[1]/a/text()') #关键词
print(keywords)
self.keyword_datas.extend(keywords)
ranks = doc.xpath('//tr[@class="list-row"]/td[2]/a') #排名
titles = doc.xpath('//tr[@class="list-row"]/td[5]/a/text()') #网页标题
links=doc.xpath('//tr[@class="list-row"]/td[5]/a/@href') #网页链接
index_links=doc.xpath('//tr[@class="list-row"]/td[7]/a/@href') #长尾词数量链接
self.index_links_hrefs.extend(index_links)
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
self.data_lists.append(data)
time.sleep(4)
return self.data_lists
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
def main(self):
for i in range(1,self.pagenums+1):
print(f'>>> 正在采集第{i}页关键词数据...')
self.get_data(i)
print("数据采集完成!")
self.write_keywords()
self.write_to_xlsx()
if __name__=="__main__":
url = "www.shejipi.com"
nums=100
spider=C5118(url,nums)
spider.main()
</p> 查看全部
解决方案:最简单的方法,优采云
采集后直接导入到wordpress的数据库
很多人用wordpress做网站,用优采云
采集
,但不会发布。这里有一个简单的方法,可以瞬间将采集
到的内容直接发布到wordpress
优点:简单、快速、一目了然。
缺点:发布文章的分类标签需要手动编辑。
更适合纯文本,或者像尴尬百科这样的笑话网站
不谈采集
,只谈出版,

这里是最简单的演示,只发布内容和标题,要发布其他内容,照着做即可。
首先找到默认模板:
然后将模板更改为这样的东西,

这段代码是怎么来的?了解数据库的人一看就会知道。如果你不懂数据库,叫你哥是一种简单的方式。空间带的mysql数据库有运行界面phpmyadmin,一般空间都有。打开找到wp-post表,插入一条数据:这条数据,只填content和title
, 其他留空
然后点击执行,你会看到这样一段代码:
插入 `DatabaseName`.`wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status` , `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count `) VALUES (NULL, '0', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '内容 xxxxxxx', '标题 XXXXXXXX', '', '发布', '打开', '打开', '', '', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', ' ', '0', '', '0', '发布', '', '0');
替换:数据库名称 -> 你的数据库名称
汇总:Python如何采集关键词数据
对于SEO来说,关键词的排名对网站优化起着决定性的作用。关键词排名、流量来源、同行网站数据都可以通过SEO查询。常见的爱站站长工具、站长工具和5118都是不错的网站。
当然现在5118更全面,应用更广泛!
在数据和功能上,5118很强大!
可以的话就付钱!
5118的抗爬还是很不错的!
需要登录领取,发现5118更新了一次!
比如登录账号需要经过滑块验证码的反爬限制,关键词索引等数据以图片加密的形式展示。这人渣破解不了,就怕了。.
不过有些数据还是可以参考的!所以,让 python 起来!
打听一下设计网站,关键词设计迷信现状
抓取网址:
如果您不是付费会员,您只能查看前100页的数据!
很多数据都是反爬限制,有点可惜!
虽然5118会员登录有滑块验证码,但是cookies登录还是非常好用的!
我们手动添加 cookie 以登录以采集
所需数据。
几个关键点:
1.添加协议头
headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': ua,
'X-Requested-With': 'XMLHttpRequest',
}
自行添加ua和cooikes!
当然这是一个完整的协议头,有些可以删掉,大家可以自己试试!
2. zip函数的使用及格式化数据处理
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
3.排名波动的处理
通过源码查询可以知道,绿色表示排名上升,红色表示排名下降。这里有一个判断就搞定了!
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
4. 关键词 将数据写入csv
写了一个案例,发现了两个参考案例
import csv
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#参考一
def write_csv(self):
path = "aa.csv"
with open(path, 'a+') as f:
csv_write = csv.writer(f)
data_row = ["1", "2"]
<p>

csv_write.writerow(data_row)
# 参考二
def wcsv(self):
csvfile = open('csvtest.csv', 'w')
writer = csv.writer(csvfile)
writer.writerow(['keywords'])
data = [
('1', 'http://www.xiaoheiseo.com/', '小黑'),
('2', 'http://www.baidu.com/', '百度'),
('3', 'http://www.jd.com/', '京东')
]
writer.writerows(data)
csvfile.close()
</p>
5、查询网站相关关键词数据,写入excel表格
使用第三方库, xlsxwriter
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
由于页码也是js生成的,所以没有找到,所以自己输入页码!
输入查询网站的URL格式为:抓取后数据存储文件使用主域名!
附上完整代码:
#5118网站关键词数据获取
import requests
from lxml import etree
from urllib.parse import unquote
import xlsxwriter
import time
import csv
class C5118(object):
def __init__(self,url,nums):
self.keyword_datas=[]
self.data_lists=[]
self.index_links_hrefs=[]
self.headers={
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Length': '0',
'Cookie': Cookies,
'Host': 'www.5118.com',
'Origin': 'https://www.5118.com',
'Referer': 'https://www.5118.com/',
'User-Agent': UA,
'X-Requested-With': 'XMLHttpRequest',
}
self.post_url=url
self.file_name=url.split('.')[1]
self.pagenums=nums
#判断排名是否提升
def get_change(self,rank):
rank=etree.tostring(rank).decode('utf-8')
if "red" in str(rank):
change="下降"
elif "green" in str(rank):
change = "提升"
else:
change = "不变"
return change
<p>

#获取数据
def get_data(self,pagenum):
url="https://www.5118.com/seo/baidupc"
params={
'isPager': 'true',
'viewtype': '2',
'days': '90',
'url': self.post_url,
'orderField': 'Rank',
'orderDirection': 'asc',
'pageIndex': pagenum, #页码
'catalogName': '',
}
response=requests.post(url,params=params,headers=self.headers)
time.sleep(1)
print(response.status_code)
doc=etree.HTML(response.content.decode('utf-8'))
keywords= doc.xpath('//tr[@class="list-row"]/td[1]/a/text()') #关键词
print(keywords)
self.keyword_datas.extend(keywords)
ranks = doc.xpath('//tr[@class="list-row"]/td[2]/a') #排名
titles = doc.xpath('//tr[@class="list-row"]/td[5]/a/text()') #网页标题
links=doc.xpath('//tr[@class="list-row"]/td[5]/a/@href') #网页链接
index_links=doc.xpath('//tr[@class="list-row"]/td[7]/a/@href') #长尾词数量链接
self.index_links_hrefs.extend(index_links)
for keyword,rank,title,link,index_link in zip(keywords,ranks,titles,links,index_links):
data=[
keyword,
rank.xpath('string(.)').strip().replace(' ','').replace('\r\n','-'),
self.get_change(rank),
title,
unquote(link.split('target=')[-1]),
'https:{}'.format(index_link),
]
print(data)
self.data_lists.append(data)
time.sleep(4)
return self.data_lists
#关键词数据写入csv
def write_keywords(self):
path='{}_keywords.csv'.format(self.file_name)
csvfile = open(path, 'a+')
for keyword in self.keyword_datas:
csvfile.write('%s\n' % keyword)
print("5118关键词搜索数据写入csv成功!")
#数据写入excle表格
def write_to_xlsx(self):
workbook = xlsxwriter.Workbook('{}_search_results.xlsx'.format(self.file_name)) # 创建一个Excel文件
worksheet = workbook.add_worksheet(self.file_name)
title = ['关键词', '排名', '排名波动', '网页标题', '网页链接', '长尾词链接'] # 表格title
worksheet.write_row('A1', title)
for index, data in enumerate(self.data_lists):
num0 = str(index + 2)
row = 'A' + num0
worksheet.write_row(row, data)
workbook.close()
print("5118搜索数据写入excel成功!")
def main(self):
for i in range(1,self.pagenums+1):
print(f'>>> 正在采集第{i}页关键词数据...')
self.get_data(i)
print("数据采集完成!")
self.write_keywords()
self.write_to_xlsx()
if __name__=="__main__":
url = "www.shejipi.com"
nums=100
spider=C5118(url,nums)
spider.main()
</p>
解决方案:基于K8S部署filebeat及logstash并输出到java程序中
采集交流 • 优采云 发表了文章 • 0 个评论 • 112 次浏览 • 2022-11-27 23:46
从 K8S 集群采集
容器日志并集中存储。
溶液:
1、守护进程集
运行文件节拍
作为守护进程,Filebeat 会在 JAVA 程序中采集
通过 logstash 发送的日志,然后由 JAVA 程序对其进行处理并集中存储。
2、边车
每个 POD 都增加了一个额外的 Filebeat 容器,Filebeat 读取相应的日志,并通过日志共享将其发送到 JAVA 程序。
这两种方法可以共存而不会发生冲突。DaemonSet 方法采集容器的标准输出,如果有特殊要求,可以通过 sidecar 方法自定义采集日志。
下面介绍了用于采集
容器日志的 daemonSet 方法的内容:
首先粘贴 K8S 部署的 yaml 文件:
# 创建账户
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager
namespace: kube-system
---
# 创建角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager-role
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- nodes
- namespaces
- events
- pods
verbs:
- get
- list
- watch
---
# 账户与角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: itsm-node-manager-role-binding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: itsm-node-manager-role
subjects:
- kind: ServiceAccount
name: itsm-node-manager
namespace: kube-system
---
# 创建logstash配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: logstash-config
namespace: kube-system
data:
logstash.yml: 'config.reload.automatic: true'
pipeline.conf: |-
input {
beats {
port => 5044
codec => json
}
}
filter {
}
output {
http {
http_method => "post"
format => "json"
# 此处配置程序的url路径,java代码会在下面贴出来。如果调用的是集群内部的程序,可以采用和filebeat一样的域名方式
url => "http://192.168.0.195:8080/cont ... ot%3B
content_type => "application/json"
}
}
---
# 创建logstash
apiVersion: apps/v1
kind: Deployment
metadata:
name: logstash
namespace: kube-system
labels:
server: logstash-7.10.1
spec:
selector:
matchLabels:
<p>
k8s-app: logstash
template:
metadata:
creationTimestamp: null
labels:
k8s-app: logstash
name: logstash
spec:
containers:
- image: elastic/logstash:7.10.1
imagePullPolicy: IfNotPresent
name: logstash
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /usr/share/logstash/config/logstash.yml
name: logstash-config
readOnly: true
subPath: logstash.yml
- mountPath: /usr/share/logstash/pipeline/logstash.conf
name: logstash-config
readOnly: true
subPath: pipeline.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: dockerpull
volumes:
- configMap:
defaultMode: 420
name: logstash-config
name: logstash-config
---
# 创建logstash service
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: logstash
name: logstash
namespace: kube-system
spec:
type: ClusterIP
selector:
k8s-app: logstash
ports:
- port: 5044
protocol: TCP
targetPort: 5044
---
# 创建filebeat配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: filebeat-config
namespace: kube-system
data:
filebeat.yml: |-
filebeat.autodiscover:
providers:
- type: kubernetes
host: ${NODE_NAME}
hints.enabled: true
hints.default_config:
type: container
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
processors:
- add_cloud_metadata:
- add_host_metadata:
output.logstash:
hosts: ["logstash.kube-system.svc.cluster.local:5044"] # kubectl -n logs get svc
enabled: true
---
# 创建filebeat守护进程
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
labels:
server: filebeat-7.10.1
spec:
selector:
matchLabels:
name: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
creationTimestamp: null
labels:
name: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: elastic/filebeat:7.10.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
- mountPath: /var/log
name: varlog
readOnly: true
restartPolicy: Always
serviceAccount: itsm-node-manager
serviceAccountName: itsm-node-manager
volumes:
- configMap:
defaultMode: 384
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- hostPath:
path: /var/log
type: ""
name: varlog
- hostPath:
path: /opt/filebeat/data
type: DirectoryOrCreate
name: data
</p>
这是将多个部署信息放在一个 YAML 文件中,用“---”分隔。
以下是 JAVA 代码片段:
@Api(tags = "服务日志控制类")
@Slf4j
@RestController
@RequestMapping("/containerLog")
public class ContainerLogController {
@Autowired
private ContainerLogService containerLogService;
@ApiOperation(value = "容器日志写入接口",produces = "application/json", response = String.class)
@PostMapping("insert")
public Result insert(HttpServletRequest httpServletRequest){
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try {
br = httpServletRequest.getReader();
String str;
while ((str=br.readLine())!=null){
sb.append(str);
}
containerLogService.insert(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return Result.newSuccess();
}
}
此时,您可以获取 logstash 发送的日志信息,并且容器日志均为 JSON 格式。
您可以在三个位置扩展以满足您的需求:
1. 文件节拍采集
规则
2. 日志存储过滤规则
3. 程序处理逻辑
最佳实践:pytest文档83 - 把收集的 yaml 文件转 Item 用例并运行
前言
上一篇文章通过用例采集
挂钩pytest_collect_file采集
YAML 文件,但只采集
用例,无法执行。
接下来,详细解释如何将 yaml 文件的内容转换为要执行的 Item 用例。
pytest_collect_file 采集
钩子
准备 YAML 文件内容 test_login.yml
name: login case1<br />request:<br /> url: http://127.0.0.1:8000/api/v1/login/<br /> method: POST<br /> headers:<br /> Content-Type: application/json<br /> json:<br /> username: test<br /> password: 123456
首先将集合钩子写 conftest.py
def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return pytest.File.from_parent(parent, path=file_path)
如果采集
到 yaml 文件中,则返回 pytest。File.from_parent(父级,路径=file_path),运行时将报告错误
============================================ ERRORS ============================================<br />_____________________________ ERROR collecting case/test_login.yml _____________________________<br />venv\lib\site-packages\_pytest\runner.py:339: in from_call<br /> result: Optional[TResult] = func()<br />venv\lib\site-packages\_pytest\runner.py:370: in <br /> call = CallInfo.from_call(lambda: list(collector.collect()), "collect")<br />venv\lib\site-packages\_pytest\nodes.py:536: in collect<br /> raise NotImplementedError("abstract")<br />E NotImplementedError: abstract<br />=================================== short test summary info ====================================<br />ERROR case/test_login.yml - NotImplementedError: abstract<br />!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!
该错误在 nodes.py 文件的 collect() 方法中报告,因此请在 nodes.py 中找到采集
器
class Collector(Node):<br /> """Collector instances create children through collect() and thus<br /> iteratively build a tree."""<br /><br /> class CollectError(Exception):<br /> """An error during collection, contains a custom message."""<br /><br /> def collect(self) -> Iterable[Union["Item", "Collector"]]:<br /> """Return a list of children (items and collectors) for this<br /> collection node."""<br /> raise NotImplementedError("abstract")
由于 collect() 方法
为空,它直接引发异常 NotImplementError(“abstract”),因此我们需要覆盖 collect() 方法
YamlFile 重写 collect()。
对应于 YamlFile 类,继承 ytest。文件,它覆盖 collect() 方法
class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield pytest.Item.from_parent(self, name=raw.get('name'), values=raw)
再次运行 pytest
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />item = <br /><br /> def pytest_runtest_call(item: Item) -> None:<br /> _update_current_test_var(item, "call")<br /> try:<br /> del sys.last_type<br /> del sys.last_value<br /> del sys.last_traceback<br /> except AttributeError:<br /> pass<br /> try:<br />> item.runtest()<br /><br />venv\lib\site-packages\_pytest\runner.py:167:<br />_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />self = <br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br />> raise NotImplementedError("runtest must be implemented by Item subclass")<br />E NotImplementedError: runtest must be implemented by Item subclass<br /><br />venv\lib\site-packages\_pytest\nodes.py:733: NotImplementedError
这次发生的错误在 runner.py 文件中报告,并且通过执行 runtest() 方法 NotImplementError(“runtest 必须由 Item 子类实现”)引发的异常
)。
看到这里,就意味着用例 Item 已经生成,并且在执行时,没有定义执行 yaml 文件的方法,因此报告了一个错误
所以我在 nodes.py 中找到了 Item(Node) 类
class Item(Node):<br /> """A basic test invocation item.<br /><br /> Note that for a single function there might be multiple test invocation items.<br /> """<br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br /> raise NotImplementedError("runtest must be implemented by Item subclass")
接下来,您需要重写 Item 中的运行测试以执行用例
重写项目的运行测试
您最终看到执行yaml文件的简短版本的界面用例 conftest.py 如下
import pytest<br />import requests<br />import yaml<br />from pathlib import Path<br /><br />def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return YamlFile.from_parent(parent, path=file_path)<br /><br />class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield YamlTest.from_parent(self, name=raw.get('name'), values=raw)<br /><br />class YamlTest(pytest.Item):<br /> def __init__(self, name, parent, values):<br /> super(YamlTest, self).__init__(name, parent)<br /> self.name = name<br /> self.values = values<br /> self.s = requests.session()<br /><br /> def runtest(self) -> None:<br /> """运行用例"""<br /> request_data = self.values["request"]<br /> response = self.s.request(**request_data)<br /> print("\n", response.text)
输入pytest,您可以看到yaml文件作为用例执行 查看全部
解决方案:基于K8S部署filebeat及logstash并输出到java程序中
从 K8S 集群采集
容器日志并集中存储。
溶液:
1、守护进程集
运行文件节拍
作为守护进程,Filebeat 会在 JAVA 程序中采集
通过 logstash 发送的日志,然后由 JAVA 程序对其进行处理并集中存储。
2、边车
每个 POD 都增加了一个额外的 Filebeat 容器,Filebeat 读取相应的日志,并通过日志共享将其发送到 JAVA 程序。
这两种方法可以共存而不会发生冲突。DaemonSet 方法采集容器的标准输出,如果有特殊要求,可以通过 sidecar 方法自定义采集日志。
下面介绍了用于采集
容器日志的 daemonSet 方法的内容:
首先粘贴 K8S 部署的 yaml 文件:
# 创建账户
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager
namespace: kube-system
---
# 创建角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: itsm-node-manager
name: itsm-node-manager-role
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- nodes
- namespaces
- events
- pods
verbs:
- get
- list
- watch
---
# 账户与角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: itsm-node-manager-role-binding
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: itsm-node-manager-role
subjects:
- kind: ServiceAccount
name: itsm-node-manager
namespace: kube-system
---
# 创建logstash配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: logstash-config
namespace: kube-system
data:
logstash.yml: 'config.reload.automatic: true'
pipeline.conf: |-
input {
beats {
port => 5044
codec => json
}
}
filter {
}
output {
http {
http_method => "post"
format => "json"
# 此处配置程序的url路径,java代码会在下面贴出来。如果调用的是集群内部的程序,可以采用和filebeat一样的域名方式
url => "http://192.168.0.195:8080/cont ... ot%3B
content_type => "application/json"
}
}
---
# 创建logstash
apiVersion: apps/v1
kind: Deployment
metadata:
name: logstash
namespace: kube-system
labels:
server: logstash-7.10.1
spec:
selector:
matchLabels:
<p>

k8s-app: logstash
template:
metadata:
creationTimestamp: null
labels:
k8s-app: logstash
name: logstash
spec:
containers:
- image: elastic/logstash:7.10.1
imagePullPolicy: IfNotPresent
name: logstash
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /usr/share/logstash/config/logstash.yml
name: logstash-config
readOnly: true
subPath: logstash.yml
- mountPath: /usr/share/logstash/pipeline/logstash.conf
name: logstash-config
readOnly: true
subPath: pipeline.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 120
imagePullSecrets:
- name: dockerpull
volumes:
- configMap:
defaultMode: 420
name: logstash-config
name: logstash-config
---
# 创建logstash service
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: logstash
name: logstash
namespace: kube-system
spec:
type: ClusterIP
selector:
k8s-app: logstash
ports:
- port: 5044
protocol: TCP
targetPort: 5044
---
# 创建filebeat配置文件
apiVersion: v1
kind: ConfigMap
metadata:
labels:
k8s-app: itsm-node-manager
name: filebeat-config
namespace: kube-system
data:
filebeat.yml: |-
filebeat.autodiscover:
providers:
- type: kubernetes
host: ${NODE_NAME}
hints.enabled: true
hints.default_config:
type: container
paths:
- /var/log/containers/*${data.kubernetes.container.id}.log
processors:
- add_cloud_metadata:
- add_host_metadata:
output.logstash:
hosts: ["logstash.kube-system.svc.cluster.local:5044"] # kubectl -n logs get svc
enabled: true
---
# 创建filebeat守护进程
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
labels:
server: filebeat-7.10.1
spec:
selector:
matchLabels:
name: filebeat
kubernetes.io/cluster-service: "true"
template:
metadata:
creationTimestamp: null

labels:
name: filebeat
kubernetes.io/cluster-service: "true"
spec:
containers:
- args:
- -c
- /etc/filebeat.yml
- -e
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
image: elastic/filebeat:7.10.1
imagePullPolicy: IfNotPresent
name: filebeat
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
securityContext:
procMount: Default
runAsUser: 0
volumeMounts:
- mountPath: /etc/filebeat.yml
name: config
readOnly: true
subPath: filebeat.yml
- mountPath: /usr/share/filebeat/data
name: data
- mountPath: /var/lib/docker/containers
name: varlibdockercontainers
readOnly: true
- mountPath: /var/log
name: varlog
readOnly: true
restartPolicy: Always
serviceAccount: itsm-node-manager
serviceAccountName: itsm-node-manager
volumes:
- configMap:
defaultMode: 384
name: filebeat-config
name: config
- hostPath:
path: /var/lib/docker/containers
type: ""
name: varlibdockercontainers
- hostPath:
path: /var/log
type: ""
name: varlog
- hostPath:
path: /opt/filebeat/data
type: DirectoryOrCreate
name: data
</p>
这是将多个部署信息放在一个 YAML 文件中,用“---”分隔。
以下是 JAVA 代码片段:
@Api(tags = "服务日志控制类")
@Slf4j
@RestController
@RequestMapping("/containerLog")
public class ContainerLogController {
@Autowired
private ContainerLogService containerLogService;
@ApiOperation(value = "容器日志写入接口",produces = "application/json", response = String.class)
@PostMapping("insert")
public Result insert(HttpServletRequest httpServletRequest){
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try {
br = httpServletRequest.getReader();
String str;
while ((str=br.readLine())!=null){
sb.append(str);
}
containerLogService.insert(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return Result.newSuccess();
}
}
此时,您可以获取 logstash 发送的日志信息,并且容器日志均为 JSON 格式。
您可以在三个位置扩展以满足您的需求:
1. 文件节拍采集
规则
2. 日志存储过滤规则
3. 程序处理逻辑
最佳实践:pytest文档83 - 把收集的 yaml 文件转 Item 用例并运行
前言
上一篇文章通过用例采集
挂钩pytest_collect_file采集
YAML 文件,但只采集
用例,无法执行。
接下来,详细解释如何将 yaml 文件的内容转换为要执行的 Item 用例。
pytest_collect_file 采集
钩子
准备 YAML 文件内容 test_login.yml
name: login case1<br />request:<br /> url: http://127.0.0.1:8000/api/v1/login/<br /> method: POST<br /> headers:<br /> Content-Type: application/json<br /> json:<br /> username: test<br /> password: 123456
首先将集合钩子写 conftest.py
def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return pytest.File.from_parent(parent, path=file_path)
如果采集
到 yaml 文件中,则返回 pytest。File.from_parent(父级,路径=file_path),运行时将报告错误
============================================ ERRORS ============================================<br />_____________________________ ERROR collecting case/test_login.yml _____________________________<br />venv\lib\site-packages\_pytest\runner.py:339: in from_call<br /> result: Optional[TResult] = func()<br />venv\lib\site-packages\_pytest\runner.py:370: in <br /> call = CallInfo.from_call(lambda: list(collector.collect()), "collect")<br />venv\lib\site-packages\_pytest\nodes.py:536: in collect<br /> raise NotImplementedError("abstract")<br />E NotImplementedError: abstract<br />=================================== short test summary info ====================================<br />ERROR case/test_login.yml - NotImplementedError: abstract<br />!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!

该错误在 nodes.py 文件的 collect() 方法中报告,因此请在 nodes.py 中找到采集
器
class Collector(Node):<br /> """Collector instances create children through collect() and thus<br /> iteratively build a tree."""<br /><br /> class CollectError(Exception):<br /> """An error during collection, contains a custom message."""<br /><br /> def collect(self) -> Iterable[Union["Item", "Collector"]]:<br /> """Return a list of children (items and collectors) for this<br /> collection node."""<br /> raise NotImplementedError("abstract")
由于 collect() 方法
为空,它直接引发异常 NotImplementError(“abstract”),因此我们需要覆盖 collect() 方法
YamlFile 重写 collect()。
对应于 YamlFile 类,继承 ytest。文件,它覆盖 collect() 方法
class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield pytest.Item.from_parent(self, name=raw.get('name'), values=raw)
再次运行 pytest
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />item = <br /><br /> def pytest_runtest_call(item: Item) -> None:<br /> _update_current_test_var(item, "call")<br /> try:<br /> del sys.last_type<br /> del sys.last_value<br /> del sys.last_traceback<br /> except AttributeError:<br /> pass<br /> try:<br />> item.runtest()<br /><br />venv\lib\site-packages\_pytest\runner.py:167:<br />_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _<br /><br />self = <br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br />> raise NotImplementedError("runtest must be implemented by Item subclass")<br />E NotImplementedError: runtest must be implemented by Item subclass<br /><br />venv\lib\site-packages\_pytest\nodes.py:733: NotImplementedError
这次发生的错误在 runner.py 文件中报告,并且通过执行 runtest() 方法 NotImplementError(“runtest 必须由 Item 子类实现”)引发的异常

)。
看到这里,就意味着用例 Item 已经生成,并且在执行时,没有定义执行 yaml 文件的方法,因此报告了一个错误
所以我在 nodes.py 中找到了 Item(Node) 类
class Item(Node):<br /> """A basic test invocation item.<br /><br /> Note that for a single function there might be multiple test invocation items.<br /> """<br /><br /> def runtest(self) -> None:<br /> """Run the test case for this item.<br /><br /> Must be implemented by subclasses.<br /><br /> .. seealso:: :ref:`non-python tests`<br /> """<br /> raise NotImplementedError("runtest must be implemented by Item subclass")
接下来,您需要重写 Item 中的运行测试以执行用例
重写项目的运行测试
您最终看到执行yaml文件的简短版本的界面用例 conftest.py 如下
import pytest<br />import requests<br />import yaml<br />from pathlib import Path<br /><br />def pytest_collect_file(file_path: Path, parent):<br /> # 获取文件.yml 文件,匹配规则<br /> if file_path.suffix == ".yml" and file_path.name.startswith("test"):<br /> return YamlFile.from_parent(parent, path=file_path)<br /><br />class YamlFile(pytest.File):<br /><br /> def collect(self):<br /> """返回读取内容的Iterable 可迭代对象"""<br /> raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))<br /> print(raw)<br /> # raw 是读取 yml 数据的内容<br /> yield YamlTest.from_parent(self, name=raw.get('name'), values=raw)<br /><br />class YamlTest(pytest.Item):<br /> def __init__(self, name, parent, values):<br /> super(YamlTest, self).__init__(name, parent)<br /> self.name = name<br /> self.values = values<br /> self.s = requests.session()<br /><br /> def runtest(self) -> None:<br /> """运行用例"""<br /> request_data = self.values["request"]<br /> response = self.s.request(**request_data)<br /> print("\n", response.text)
输入pytest,您可以看到yaml文件作为用例执行
分享文章:搜狐号文章图片解密还原 含调用例子
采集交流 • 优采云 发表了文章 • 0 个评论 • 128 次浏览 • 2022-11-27 19:58
任何参与该网站的人都应该采集
搜狐文章,但最近搜狐文章的图片已被加密。当你发送HTTP请求后想直接截取搜狐文章的正文,或者当你使用抓取软件时,发现搜狐文章的IMG图片路径是加密的???
仔细看看搜狐文章的文字 IMG 标签路径是加密的,但通过浏览器访问很正常,盲猜 JS 在起作用。
F12直接从裤裆,断点调整。一目了然,你可以看到它是AES加密,你知道加密方法。直接调用 CryptoJS 库进行解密!
CryptoJS 加密模块 AES ECB pkcs7 密钥是
js 调用示例:需要引用 CryptoJS 加密库
var key = CryptoJS.enc.Utf8.parse("www.sohu.com6666");
<p>
function AES_Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode</p>
干货教程:一分钟教你玩转手机回收小程序,源码+教程免费分享
在我们现在的生活中,最离不开的就是手机了。随着智能手机的不断普及,人们更换手机的频率也在不断加快,从而带动了二手手机回收市场的快速发展。在二手手机行业发展的今天,也诞生了很多手机回收小程序。今天我们就来介绍一下手机回收小程序的功能。
手机回收小程序功能介绍:
1.免费估价
用户可以在小程序中完成一系列系统问题,对手机进行智能估价,供用户参考和比较。
2.品类划分
除了手机,该平台还将涵盖笔记本、平板电脑、摄影器材等各类数码电子产品。种类型号齐全,满足更多用户的需求。
3.以旧换新
平台通过对旧机进行估价回收,让用户在平台购买新机时可以抵扣,让用户获得更大的优惠。
4.在线回收
通过在线估值测试后,实现快速恢复,让用户更快回款。
五、行业资讯
平台可以及时更新数字行业的动态和新闻,让用户更容易了解最新的数字资讯。
目前,二手手机行业的市场规模并不逊色于二手车、二手房。而相比之下,二手手机市场需求更为刚性,交易更为频繁。对于手机回收行业来说,小程序将拥有更广阔的市场空间。
今天分享的资源包括手机数码回收小程序源码+零基础新手教程。内容非常丰富,包括服务器和域名的配置、宝塔的安装、小程序的安装和启动等等,真正教你从零开始搭建。并正式推出了自己的小程序。
免费领取手机数码回收小程序源码流程:
1. 点赞+关注“解密小程序”
2.私信回复关键词:源码(可以免费领取)
如果资源失效,别着急,请联系小编补发!
感谢您的关注和支持。欢迎大家分享转发,让更多需要的朋友看到。未来我们也会努力分享更多优质的源码、教程等资料。希望大家继续关注!
《60分钟教你:从零开始搭建一个完整的小程序》
第一课:两种方式教你注册小程序账号
第二课:如何为小程序选择合适的服务器和域名?
第三课:十分钟教你快速搭建服务器环境
第四课:一键轻松搭建小程序第三方系统——微引擎
第五课:教你快速安装小程序应用
第六课:十分钟教你正式上线微信小程序 查看全部
分享文章:搜狐号文章图片解密还原 含调用例子
任何参与该网站的人都应该采集
搜狐文章,但最近搜狐文章的图片已被加密。当你发送HTTP请求后想直接截取搜狐文章的正文,或者当你使用抓取软件时,发现搜狐文章的IMG图片路径是加密的???
仔细看看搜狐文章的文字 IMG 标签路径是加密的,但通过浏览器访问很正常,盲猜 JS 在起作用。
F12直接从裤裆,断点调整。一目了然,你可以看到它是AES加密,你知道加密方法。直接调用 CryptoJS 库进行解密!

CryptoJS 加密模块 AES ECB pkcs7 密钥是
js 调用示例:需要引用 CryptoJS 加密库
var key = CryptoJS.enc.Utf8.parse("www.sohu.com6666");
<p>

function AES_Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
mode: CryptoJS.mode</p>
干货教程:一分钟教你玩转手机回收小程序,源码+教程免费分享
在我们现在的生活中,最离不开的就是手机了。随着智能手机的不断普及,人们更换手机的频率也在不断加快,从而带动了二手手机回收市场的快速发展。在二手手机行业发展的今天,也诞生了很多手机回收小程序。今天我们就来介绍一下手机回收小程序的功能。
手机回收小程序功能介绍:
1.免费估价
用户可以在小程序中完成一系列系统问题,对手机进行智能估价,供用户参考和比较。
2.品类划分
除了手机,该平台还将涵盖笔记本、平板电脑、摄影器材等各类数码电子产品。种类型号齐全,满足更多用户的需求。
3.以旧换新
平台通过对旧机进行估价回收,让用户在平台购买新机时可以抵扣,让用户获得更大的优惠。

4.在线回收
通过在线估值测试后,实现快速恢复,让用户更快回款。
五、行业资讯
平台可以及时更新数字行业的动态和新闻,让用户更容易了解最新的数字资讯。
目前,二手手机行业的市场规模并不逊色于二手车、二手房。而相比之下,二手手机市场需求更为刚性,交易更为频繁。对于手机回收行业来说,小程序将拥有更广阔的市场空间。
今天分享的资源包括手机数码回收小程序源码+零基础新手教程。内容非常丰富,包括服务器和域名的配置、宝塔的安装、小程序的安装和启动等等,真正教你从零开始搭建。并正式推出了自己的小程序。
免费领取手机数码回收小程序源码流程:
1. 点赞+关注“解密小程序”
2.私信回复关键词:源码(可以免费领取)

如果资源失效,别着急,请联系小编补发!
感谢您的关注和支持。欢迎大家分享转发,让更多需要的朋友看到。未来我们也会努力分享更多优质的源码、教程等资料。希望大家继续关注!
《60分钟教你:从零开始搭建一个完整的小程序》
第一课:两种方式教你注册小程序账号
第二课:如何为小程序选择合适的服务器和域名?
第三课:十分钟教你快速搭建服务器环境
第四课:一键轻松搭建小程序第三方系统——微引擎
第五课:教你快速安装小程序应用
第六课:十分钟教你正式上线微信小程序
测评:发布一个文章采集器大家试试,来者有分。
采集交流 • 优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-11-26 03:17
免费PHPCMS采集规则文章采集器采集百万数据
直接在本地电脑上运行该工具,(为什么要使用本地采集工具,因为在本地电脑上运行采集工具不会对服务器造成任何影响,最大限度地发挥服务器的性能,让网站打开速度更快,并且允许搜索引擎的抓取速度更快!使用SEO工具实现...
【站群必备】自动采集文章和伪原创文章后自动发布文章-一站式服务
很多人在做网站群的时候,往往要么请人帮忙写... 自动采集伪原创文章后自动发布文章的集成在线采集服务。简单易操作的面板,最快3分钟即可启动,可大幅提升。规模管理站群,每天可自动发布大量伪原创文章,并可选择...
50行代码教你打造公众号文章采集器
Alfred的女票是数据科学领域的新媒体运营官(没错,Alfred是程序员,Alfred有女票),每天阅读大量行业相关文章,把握行业动态,选择和生产相关...
【Wordpress】Wordpress插件自动采集
发布工具
安装好wordpress之后,就得开始发布文章了。由于之前的文章散落在各个平台上,要一篇一篇的复制,着实费时费力。所以,想要一劳永逸的解决这个问题,就必须要用到今天介绍的采集工具了。插件安装搜索:Fat Rat Coolect ...
免费PBootCMS采集支持聚合文章采集插件
Q:如何安装免费的PBOOT CMS采集插件?站长必备PBoot采集工具答:直接下载到本地电脑,双击直接运行!...答案:每天可采集百万条数据,支持单列采集发布,支持多列采集发布。Q:免费PBOOTCMS插件合集
技术文章:英文网站文章采集,英文文章采集批量翻译
英文网站文章采集
是我们常用的材料采集
方法,网站翻译我们可以通过页面浏览器自带的翻译进行,但是如何对我们采集
的文章进行本地批量翻译,您需要使用我们的批量翻译插件。
英文网站指定采集,
只需要进入我们的目标网站,简单的操作不需要切换IP即可进行,无论是英文、俄文、法文、日文、韩文等大小语种网站都可以进行视觉选择和采集操作,对于采集的文章,用自己的批量翻译,可以在发布到我们的网站或本地的条件下保留原创
语言标签和格式。
英文网站的推广也离不开SEO,除了素材的采集
,网站内容的日常及时更新,还需要进行相关的SEO优化。通过关键词挖掘,获取流行的实时下拉和长尾关键词及相关词,然后通过全网匹配采集来采集这些长尾词,得到高质量的爆款文章和热点文章。
当我们想要增加页面浏览量时,最好定位竞争较低的关键词——使它们更容易排名,我们将在 SERP 中看到更快的结果。可以帮助我们找到要定位的关键字。我们输入关键字,该工具将显示要定位的潜在关键字列表。
我们可以按关键字难度,国家,数量(每月访问者数量)等进行排序。如果我们使用此工具查找难度分数低的长尾关键字,我们将能够创建一个关键字列表来定位,我们可以自己使用或提供给我们的作家团队。
想象一下这样的场景:我们查看市场上的潜在网站,但我们想知道该网站是否有潜力在花钱之前快速(并且非常容易)改进。通常,我们必须做出估计并相信网站卖家对流量、收入、反向链接和关键字的说法;但是,使用英语网站抓取等工具可以让我们避免任何尴尬和代价高昂的错误。
我们可能会在软件中运行网站的域名,并接收数据和有价值信息的列表。例如,我们可以看到他们排名的关键字(更重要的是,他们没有排名)以及他们与竞争对手的匹配程度。
如果我们遇到未使用的关键字,但竞争对手确实如此,我们可以看到使用英语网站抓取工具创建内容并超越它们是多么容易。英文网站抓取工具为我们输入的任何搜索词提供详细数据,告诉我们与排名靠前的搜索词竞争是多么容易。
我们可能会遇到的另一种情况是找到一个在搜索结果中表现良好但没有良好内容或大量反向链接的网站。当这种情况发生时,这是一个好兆头,因为我们可以创建更好的内容,添加反向链接并获得更好的排名。
英文网站集合有一些价格计划,但即使是最便宜的计划也允许我们跟踪 100 个关键字。跟踪多个关键字意味着我们可以访问数据,并可以查看每个关键字的可视化屏幕和网站性能报告。我们可以在移动和桌面结果之间切换,并查看所有领先搜索引擎的日常活动。 查看全部
测评:发布一个文章采集器大家试试,来者有分。
免费PHPCMS采集规则文章采集器采集百万数据
直接在本地电脑上运行该工具,(为什么要使用本地采集工具,因为在本地电脑上运行采集工具不会对服务器造成任何影响,最大限度地发挥服务器的性能,让网站打开速度更快,并且允许搜索引擎的抓取速度更快!使用SEO工具实现...
【站群必备】自动采集文章和伪原创文章后自动发布文章-一站式服务

很多人在做网站群的时候,往往要么请人帮忙写... 自动采集伪原创文章后自动发布文章的集成在线采集服务。简单易操作的面板,最快3分钟即可启动,可大幅提升。规模管理站群,每天可自动发布大量伪原创文章,并可选择...
50行代码教你打造公众号文章采集器
Alfred的女票是数据科学领域的新媒体运营官(没错,Alfred是程序员,Alfred有女票),每天阅读大量行业相关文章,把握行业动态,选择和生产相关...
【Wordpress】Wordpress插件自动采集
发布工具

安装好wordpress之后,就得开始发布文章了。由于之前的文章散落在各个平台上,要一篇一篇的复制,着实费时费力。所以,想要一劳永逸的解决这个问题,就必须要用到今天介绍的采集工具了。插件安装搜索:Fat Rat Coolect ...
免费PBootCMS采集支持聚合文章采集插件
Q:如何安装免费的PBOOT CMS采集插件?站长必备PBoot采集工具答:直接下载到本地电脑,双击直接运行!...答案:每天可采集百万条数据,支持单列采集发布,支持多列采集发布。Q:免费PBOOTCMS插件合集
技术文章:英文网站文章采集,英文文章采集批量翻译
英文网站文章采集
是我们常用的材料采集
方法,网站翻译我们可以通过页面浏览器自带的翻译进行,但是如何对我们采集
的文章进行本地批量翻译,您需要使用我们的批量翻译插件。
英文网站指定采集,
只需要进入我们的目标网站,简单的操作不需要切换IP即可进行,无论是英文、俄文、法文、日文、韩文等大小语种网站都可以进行视觉选择和采集操作,对于采集的文章,用自己的批量翻译,可以在发布到我们的网站或本地的条件下保留原创
语言标签和格式。
英文网站的推广也离不开SEO,除了素材的采集
,网站内容的日常及时更新,还需要进行相关的SEO优化。通过关键词挖掘,获取流行的实时下拉和长尾关键词及相关词,然后通过全网匹配采集来采集这些长尾词,得到高质量的爆款文章和热点文章。

当我们想要增加页面浏览量时,最好定位竞争较低的关键词——使它们更容易排名,我们将在 SERP 中看到更快的结果。可以帮助我们找到要定位的关键字。我们输入关键字,该工具将显示要定位的潜在关键字列表。
我们可以按关键字难度,国家,数量(每月访问者数量)等进行排序。如果我们使用此工具查找难度分数低的长尾关键字,我们将能够创建一个关键字列表来定位,我们可以自己使用或提供给我们的作家团队。
想象一下这样的场景:我们查看市场上的潜在网站,但我们想知道该网站是否有潜力在花钱之前快速(并且非常容易)改进。通常,我们必须做出估计并相信网站卖家对流量、收入、反向链接和关键字的说法;但是,使用英语网站抓取等工具可以让我们避免任何尴尬和代价高昂的错误。

我们可能会在软件中运行网站的域名,并接收数据和有价值信息的列表。例如,我们可以看到他们排名的关键字(更重要的是,他们没有排名)以及他们与竞争对手的匹配程度。
如果我们遇到未使用的关键字,但竞争对手确实如此,我们可以看到使用英语网站抓取工具创建内容并超越它们是多么容易。英文网站抓取工具为我们输入的任何搜索词提供详细数据,告诉我们与排名靠前的搜索词竞争是多么容易。
我们可能会遇到的另一种情况是找到一个在搜索结果中表现良好但没有良好内容或大量反向链接的网站。当这种情况发生时,这是一个好兆头,因为我们可以创建更好的内容,添加反向链接并获得更好的排名。
英文网站集合有一些价格计划,但即使是最便宜的计划也允许我们跟踪 100 个关键字。跟踪多个关键字意味着我们可以访问数据,并可以查看每个关键字的可视化屏幕和网站性能报告。我们可以在移动和桌面结果之间切换,并查看所有领先搜索引擎的日常活动。
解决方案:微服务远程调用组件Feign的使用详解
采集交流 • 优采云 发表了文章 • 0 个评论 • 87 次浏览 • 2022-11-25 18:38
一、总结
我们知道目前最火、技术含量最高的技术就是SpringCloud微服务,那么今天一哥就带大家了解一下微服务的核心组件之一,Feign的基本使用及其工作机制。
二、Feign简介 一、概念
在学习如何使用Feign之前,我们先来了解一下什么是Feign。
Feign 是 Netflix 开发的声明式(目前由 Spring 维护)和模板化的 HTTP 客户端。Feign可以帮助我们更快速优雅的调用HTTP Api。
简单来说,Feign是一个远程服务调用的框架/工具,可以让开发者以更低耦合、更少代码、更快、更兼容的方式进行远程服务调用。
2.功能
了解了这些基本概念之后,接下来小编就带大家看看Feign组件是如何实现远程接口调用的。话不多说,我们直接上代码。
三、服务提供者 1、添加依赖
首先我们在父POM文件中添加核心依赖,如下:
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba-dependencies.version}
pom
import
然后在子POM文件中添加依赖如下:
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.配置文件
在 application.yml 文件中添加如下配置:
server:
port: 8090
spring:
application:
name: nacos-feign-example
cloud:
nacos:
discovery:
server-addr: 112.74.42.138:8848
3、创业班
项目的启动类代码如下:
@SpringBootApplication
public class NetflixFeignProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NetflixFeignProviderApplication.class, args);
}
}
4.控制层
我们可以写一个Controller控制器,定义web界面如下。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 模拟主键自增
*/
private AtomicInteger pk = new AtomicInteger();
<p>
@PostMappingpublic User save(@RequestBody User user) {
user.setUid(pk.incrementAndGet());
return user;
}
/**
* @param uid
* @return
*/@GetMapping("/{uid}")
public User user(@PathVariable("uid") int uid) {
return User.builder()
.uid(uid)
.username("admin")
.password("123456")
.build();
}
@GetMapping("/users")
public List users(@RequestHeader("token") String token) {
// 模拟从数据中获取数据
ArrayList users = new ArrayList();
for (int i = 1; i 查看全部
解决方案:微服务远程调用组件Feign的使用详解
一、总结
我们知道目前最火、技术含量最高的技术就是SpringCloud微服务,那么今天一哥就带大家了解一下微服务的核心组件之一,Feign的基本使用及其工作机制。
二、Feign简介 一、概念
在学习如何使用Feign之前,我们先来了解一下什么是Feign。
Feign 是 Netflix 开发的声明式(目前由 Spring 维护)和模板化的 HTTP 客户端。Feign可以帮助我们更快速优雅的调用HTTP Api。
简单来说,Feign是一个远程服务调用的框架/工具,可以让开发者以更低耦合、更少代码、更快、更兼容的方式进行远程服务调用。
2.功能
了解了这些基本概念之后,接下来小编就带大家看看Feign组件是如何实现远程接口调用的。话不多说,我们直接上代码。
三、服务提供者 1、添加依赖
首先我们在父POM文件中添加核心依赖,如下:
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba-dependencies.version}
pom
import
然后在子POM文件中添加依赖如下:
org.springframework.cloud
spring-cloud-starter-openfeign
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.配置文件
在 application.yml 文件中添加如下配置:
server:
port: 8090
spring:
application:
name: nacos-feign-example
cloud:
nacos:
discovery:
server-addr: 112.74.42.138:8848
3、创业班
项目的启动类代码如下:
@SpringBootApplication
public class NetflixFeignProviderApplication {
public static void main(String[] args) {
SpringApplication.run(NetflixFeignProviderApplication.class, args);
}
}
4.控制层
我们可以写一个Controller控制器,定义web界面如下。
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
/**
* 模拟主键自增
*/
private AtomicInteger pk = new AtomicInteger();
<p>

@PostMappingpublic User save(@RequestBody User user) {
user.setUid(pk.incrementAndGet());
return user;
}
/**
* @param uid
* @return
*/@GetMapping("/{uid}")
public User user(@PathVariable("uid") int uid) {
return User.builder()
.uid(uid)
.username("admin")
.password("123456")
.build();
}
@GetMapping("/users")
public List users(@RequestHeader("token") String token) {
// 模拟从数据中获取数据
ArrayList users = new ArrayList();
for (int i = 1; i
解决方案:支付宝小程序:人脸采集
采集交流 • 优采云 发表了文章 • 0 个评论 • 406 次浏览 • 2022-11-23 09:41
产品描述
人脸识别是公共服务场所提高业务效率和用户体验的新途径。人脸采集是指在获得用户充分授权认可、充分保护用户隐私的前提下,获取符合质量要求的活人。人脸图片用于后续比对、识别等操作,提升商户服务质量。核心功能包括:
用户界面
调用过程
应用场景
人脸应用广泛,可应用于以下场景:
场景
描述
拍摄证件照
小程序提供拍摄证件照的功能,光线角度好。
团餐
在校园点餐场景中,录入学生人脸,用于刷脸点餐。
不建议使用通过人脸采集小程序返回给开发者的真人照片与开发者自己的比对源图在安全性较差的比对算法下进行身份验证。如果开发者需要验证身份,请使用支付宝身份验证?或其他开放通道人脸认证产品。由于支付宝身份验证产品拥有完备的风控体系和更安全的后台活体检测算法,具有非常强的抗攻击和防误识别能力。
注意:
小程序“人脸认证”开放能力全面升级为“支付宝认证”,推荐开发者使用“支付宝认证”能力;已签约上线“人脸认证”的小程序可继续使用。
访问要求
注意:
计费方式
自由的
接入指南第一步:创建小程序
要在您的小程序中使用人脸抓拍功能,您需要先完成开发者注册并创建一个小程序。
第二步:添加功能
小程序创建完成后,开发者可以在“能力列表”部分点击“添加能力”,为创建的小程序添加能力,如下图;开发者勾选人脸采集能力后,点击右下角的确定完成添加。
第三步:承包能力
人脸采集功能需要签名才能生效。请点击功能列表右侧的“立即注册”。签约成功后,状态会置为“Active”,即可调用人脸采集接口。
第四步:集成并配置SDK
服务端SDK需要商家在自己的服务端系统中集成,用于后续服务端接口调用。
下载服务端SDK
为了方便开发者调用开放接口,我们提供开放平台服务端SDK,包括JAVA、PHP、NodeJS、Python、.NET五种语言,封装了签名&验证、HTTP接口请求等基础功能,请下载相应语言版本的SDK并导入到您的开发项目中。
接口调用配置
在调用 SDK 之前需要对其进行初始化。以JAVA代码为例:
AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
关键参数说明:
配置参数
示例值解释
如何获取/示例值
网址
支付宝网关(固定)
APPID
创建应用后生成APPID
获取查看创建应用程序
APP_PRIVATE_KEY
开发者私钥,由开发者自己生成
获取配置密钥
格式
参数返回格式,只支持json
json(固定)
字符集
编码集,支持GBK/UTF-8
开发者根据实际工程代码进行配置
ALIPAY_PUBLIC_KEY
支付宝公钥,由支付宝生成
有关详细信息,请参阅配置密钥
SIGN_TYPE
商户生成签名串使用的签名算法类型。目前支持RSA2和RSA,推荐使用RSA2
RSA2
接下来就可以使用alipayClient来调用具体的API了。AlipayClient只需要初始化一次,后续调用不同的API可以使用同一个alipayClient对象。
注意:
ISV/开发者可以通过第三方应用授权获取商家授权令牌(app_auth_token)作为请求参数,实现代表商家发起请求的能力。
第五步:调用接口
调用流程图
调用 JSAPI (faceVerify) 调用人脸采集。整个采集过程完全由人脸执行。采集完成后,通过回调函数返回采集结果。在采集过程中,客户端完成人脸采集过程和活体检测,然后将采集到的人脸特征数据上传到服务器进行进一步的活体检测,最后将采集结果返回给客户端。
调用查询接口(zoloz.identification.user.web.query)获取可信的采集结果。如果采集成功,可以通过该接口获取采集到的人脸照片。
主要步骤
版本要求:
调用接口my.ap.faceVerify,传入参数bizId和bizType,即可触发人脸采集。采集完成后,通过回调函数获取采集结果。
请注意,在 my.ap.faceVerify 调用返回之前,切记不要发起第二次 faceVerify 调用,否则会产生异常。例如,如果您的小程序通过单击页面上的按钮触发对 my.ap.faceVerify 的调用,请确保在调用返回之前禁用该按钮,以防止用户进行多次单击。
代码示例
my.ap.faceVerify({ bizId: '545689787654767653', //业务流水号,商户自行生成,需要保证唯一性,不超过64位 bizType: '1', //业务场景参数,‘1’代表人脸采集,请务必填写 useBackCamera: true, //传入此参数会唤起后置摄像头;非必填,不传默认唤起前置摄像头 success: (res) => { my.alert({ content: JSON.stringify(res), }); }, fail: (res) => { my.alert({ content: JSON.stringify(res), }); }});
成功认证结果示例
faceRetCode = 1000表示人脸采集成功,调用查询接口(zoloz.identification.user.web.query)可以成功获取照片,证明人脸采集成功。
{ faceRetCode: "1000", retCode: "OK_SUCCESS", retCodeSub: "Z5100", retMessageSub: "成功 (Z5100)", zimId: "7b6b72be1493cab72dd0a25877de329dd00"}undefined
注意retCode表示人脸识别可用成功,只有人脸识别可用时才能进行人脸采集。
调用人脸采集查询接口(zoloz.identification.user.web.query)获取人脸照片。以下请求示例代码以JAVA为例:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");ZolozIdentificationUserWebQueryRequest request = new ZolozIdentificationUserWebQueryRequest();request.setBizContent("{" +""biz_id":"5456897876546767654"," +""zim_id":"731be7f204a962b0486a9b64ea3050ae"," +""extern_param":"{"bizType":"1"}"" +"}");ZolozIdentificationUserWebQueryResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}undefined
成功响应的示例
如果采集成功,则imgStr对象中的值为人脸照片的base64编码字符串。
{ "zoloz_identification_user_web_query_response": { "code": "10000", "msg": "Success", "extern_info": "{"imgStr":"ApA4VVwOP1rqp8sotrcimna3c__9k","bizId":"5456897876546767654-doucao.wjp","zimMsg":"成功","zimCode":"Z5130"}" }, "sign": "SL1dSiE6XKKIta5w3ge3VSZE+71CdBtr8Ocw9WvRSZD3Tz6/vNaA2pWLBYdZcvrAHaMYa6J8V9c4nY3kdBK0EeU2afh+8CLTw6dnZfkO8tR5NOtJUb+M6qhxl0xKhpE+2GUonpCcJg1MHS0aMVXa/b6dhK/yZJQCdO1YnVNuzs8="}
失败响应示例
{ "zoloz_identification_user_web_query_response": { "code": "40004", "msg": "Business Failed", "sub_code": "INVALID_PARAMETER", "sub_msg": "参数有误抱歉,系统出错了,请您稍后再试 (Z5132)" }, "sign": "v/DjkviKs2ja3HO9ZZ94W8bcfAsLyRuGrZT/TlFm6FgGQv4qSm/94o1FjOaMCl/t8XIm89bBhk03PBJ099alDzjnj4RD6S9FYDV7CfjvHYjrzvVJzn47Gc1mWdOHZ38DFQLWIg1IbNKFmYdoR+NdY5nY/cwz3Al2wfEylvN1cbs="}
API列表
接口英文名称
接口说明
我的.ap.faceVerify
人脸合集
zoloz.identification.user.web.query
人脸采集结果查询
常见问题:如果一个用户有多个支付宝账户,调用人脸识别验证接口时返回的user_id是否相同?
A:首先返回用户上次使用的支付宝账号对应的user_id。
Q:真机调试报错 "retMessageSub":"{"error":4,"errorMessage":"Not authorized to call","message":"Not authorized to call","signature"怎么办: “N22104”}?
A:人脸抓拍功能需要在小程序后台添加人脸抓拍功能包并签约使用。请参考此文档访问指南
解决方案:可视化采集器(智能化采集)
目录:
1、视觉采集软件
使用CSS选择器的采集软件可以准确的提取我们的网页元素。从用户体验的角度来看,XPATH有一个可视化的操作页面,让我们上手非常容易,但是为什么CSS选择器一直被我们的采集软件占用,虽然CSS的使用比较复杂,但是可以准确的捕捉一些元素XPATH 无法定位的文件。
2.可视化数据采集
所以大部分采集软件都是XPATH和CSS并存
3、智能采集系统
从网页元素提取的角度来看,CSS选择器和XPath选择器是一样的。它们都帮助我们定位网页中的相关元素,只是在语法表达上有所区别。从用户的角度来看,通过视觉抓取页面,我们可以完成80%以上的网站宣传页面数据抓取,少部分可以通过CSS选择器来补充。两个选择器的组合使我们能够覆盖各种类型的网页。
4、智能信息采集
5、智能采集设备
在搜索结果中查看网页时,我们注意到它们在链接下方收录
一小段信息。这称为“描述”。描述是 SEO 的有用工具。简短、朗朗上口的描述有助于说服用户点击文章。虽然元描述并非我们网站的所有 SEO 方面都是最终的,但最好将它们分类以防止出现任何错误。
6、智能采集摄像系统
它们需要有特定的长度才能在搜索引擎结果中完整显示,并且它们需要对每个页面和 关键词 都是唯一的
7.实时采集可视化工具
优化我们的内容,当我们制定内容 SEO 策略时,我们可能认为越多越好。定期发布新内容有助于吸引新访问者访问我们的网站并保持人们的参与度。然而,大多数时候,答案不是数量,而是质量。
8.数据采集
和可视化
这就是内容优化发挥作用的地方。这是查看我们网站上现有内容并询问“我如何才能更好地优化它?”的过程。这通常并不意味着重写整篇文章。相反,它涉及考虑内容的某些方面。我们是否选择了正确的字数?查看涵盖同一主题的成功文章并检查其字数。
9.如何持续采集
可视化
10、智能数据采集控制器
我们是否尽可能有效地使用 关键词?找到合适的 关键词 是内容营销的重要组成部分。但密度也很重要。确保避免过度使用 关键词。关键词 的更多实例并不意味着它的排名更好 - 事实上恰恰相反。
我们是否涵盖相关主题?最好的文章涵盖多个用户查询。查找其他相关主题以收录
在我们的文章中。在我们花时间优化一个页面之后,我们会想知道它的表现如何。SEO Tools 的 CSS 文章抓取软件使我们能够访问 SEO。活动进度更新。
我们可能已经努力为我们的网站创建内容,但如果我们要获得 SEO 回报,用户需要坚持下去。搜索引擎将“停留时间”描述为其主要的 SEO 优先事项之一。顾名思义,这是用户停留在页面上并阅读它的时候。文章时间
结合CSS选择器和XPATH选择器的文章合集软件分享到此结束。通过简单准确的网页内容提取,我们可以快速获取我们需要的公共数据和内容,从而提高我们的工作效率。如果你喜欢这篇文章,不妨采集
点赞。您的支持是博主不断更新的动力。
主题测试文章,仅供测试使用。发布者:小新SEO,转载请注明出处: 查看全部
解决方案:支付宝小程序:人脸采集
产品描述
人脸识别是公共服务场所提高业务效率和用户体验的新途径。人脸采集是指在获得用户充分授权认可、充分保护用户隐私的前提下,获取符合质量要求的活人。人脸图片用于后续比对、识别等操作,提升商户服务质量。核心功能包括:
用户界面
调用过程
应用场景
人脸应用广泛,可应用于以下场景:
场景
描述
拍摄证件照
小程序提供拍摄证件照的功能,光线角度好。
团餐
在校园点餐场景中,录入学生人脸,用于刷脸点餐。
不建议使用通过人脸采集小程序返回给开发者的真人照片与开发者自己的比对源图在安全性较差的比对算法下进行身份验证。如果开发者需要验证身份,请使用支付宝身份验证?或其他开放通道人脸认证产品。由于支付宝身份验证产品拥有完备的风控体系和更安全的后台活体检测算法,具有非常强的抗攻击和防误识别能力。
注意:
小程序“人脸认证”开放能力全面升级为“支付宝认证”,推荐开发者使用“支付宝认证”能力;已签约上线“人脸认证”的小程序可继续使用。
访问要求
注意:
计费方式
自由的
接入指南第一步:创建小程序
要在您的小程序中使用人脸抓拍功能,您需要先完成开发者注册并创建一个小程序。
第二步:添加功能
小程序创建完成后,开发者可以在“能力列表”部分点击“添加能力”,为创建的小程序添加能力,如下图;开发者勾选人脸采集能力后,点击右下角的确定完成添加。
第三步:承包能力
人脸采集功能需要签名才能生效。请点击功能列表右侧的“立即注册”。签约成功后,状态会置为“Active”,即可调用人脸采集接口。
第四步:集成并配置SDK
服务端SDK需要商家在自己的服务端系统中集成,用于后续服务端接口调用。
下载服务端SDK

为了方便开发者调用开放接口,我们提供开放平台服务端SDK,包括JAVA、PHP、NodeJS、Python、.NET五种语言,封装了签名&验证、HTTP接口请求等基础功能,请下载相应语言版本的SDK并导入到您的开发项目中。
接口调用配置
在调用 SDK 之前需要对其进行初始化。以JAVA代码为例:
AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
关键参数说明:
配置参数
示例值解释
如何获取/示例值
网址
支付宝网关(固定)
APPID
创建应用后生成APPID
获取查看创建应用程序
APP_PRIVATE_KEY
开发者私钥,由开发者自己生成
获取配置密钥
格式
参数返回格式,只支持json
json(固定)
字符集
编码集,支持GBK/UTF-8
开发者根据实际工程代码进行配置
ALIPAY_PUBLIC_KEY
支付宝公钥,由支付宝生成
有关详细信息,请参阅配置密钥
SIGN_TYPE
商户生成签名串使用的签名算法类型。目前支持RSA2和RSA,推荐使用RSA2
RSA2
接下来就可以使用alipayClient来调用具体的API了。AlipayClient只需要初始化一次,后续调用不同的API可以使用同一个alipayClient对象。
注意:
ISV/开发者可以通过第三方应用授权获取商家授权令牌(app_auth_token)作为请求参数,实现代表商家发起请求的能力。
第五步:调用接口

调用流程图
调用 JSAPI (faceVerify) 调用人脸采集。整个采集过程完全由人脸执行。采集完成后,通过回调函数返回采集结果。在采集过程中,客户端完成人脸采集过程和活体检测,然后将采集到的人脸特征数据上传到服务器进行进一步的活体检测,最后将采集结果返回给客户端。
调用查询接口(zoloz.identification.user.web.query)获取可信的采集结果。如果采集成功,可以通过该接口获取采集到的人脸照片。
主要步骤
版本要求:
调用接口my.ap.faceVerify,传入参数bizId和bizType,即可触发人脸采集。采集完成后,通过回调函数获取采集结果。
请注意,在 my.ap.faceVerify 调用返回之前,切记不要发起第二次 faceVerify 调用,否则会产生异常。例如,如果您的小程序通过单击页面上的按钮触发对 my.ap.faceVerify 的调用,请确保在调用返回之前禁用该按钮,以防止用户进行多次单击。
代码示例
my.ap.faceVerify({ bizId: '545689787654767653', //业务流水号,商户自行生成,需要保证唯一性,不超过64位 bizType: '1', //业务场景参数,‘1’代表人脸采集,请务必填写 useBackCamera: true, //传入此参数会唤起后置摄像头;非必填,不传默认唤起前置摄像头 success: (res) => { my.alert({ content: JSON.stringify(res), }); }, fail: (res) => { my.alert({ content: JSON.stringify(res), }); }});
成功认证结果示例
faceRetCode = 1000表示人脸采集成功,调用查询接口(zoloz.identification.user.web.query)可以成功获取照片,证明人脸采集成功。
{ faceRetCode: "1000", retCode: "OK_SUCCESS", retCodeSub: "Z5100", retMessageSub: "成功 (Z5100)", zimId: "7b6b72be1493cab72dd0a25877de329dd00"}undefined
注意retCode表示人脸识别可用成功,只有人脸识别可用时才能进行人脸采集。
调用人脸采集查询接口(zoloz.identification.user.web.query)获取人脸照片。以下请求示例代码以JAVA为例:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");ZolozIdentificationUserWebQueryRequest request = new ZolozIdentificationUserWebQueryRequest();request.setBizContent("{" +""biz_id":"5456897876546767654"," +""zim_id":"731be7f204a962b0486a9b64ea3050ae"," +""extern_param":"{"bizType":"1"}"" +"}");ZolozIdentificationUserWebQueryResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}undefined
成功响应的示例
如果采集成功,则imgStr对象中的值为人脸照片的base64编码字符串。
{ "zoloz_identification_user_web_query_response": { "code": "10000", "msg": "Success", "extern_info": "{"imgStr":"ApA4VVwOP1rqp8sotrcimna3c__9k","bizId":"5456897876546767654-doucao.wjp","zimMsg":"成功","zimCode":"Z5130"}" }, "sign": "SL1dSiE6XKKIta5w3ge3VSZE+71CdBtr8Ocw9WvRSZD3Tz6/vNaA2pWLBYdZcvrAHaMYa6J8V9c4nY3kdBK0EeU2afh+8CLTw6dnZfkO8tR5NOtJUb+M6qhxl0xKhpE+2GUonpCcJg1MHS0aMVXa/b6dhK/yZJQCdO1YnVNuzs8="}
失败响应示例
{ "zoloz_identification_user_web_query_response": { "code": "40004", "msg": "Business Failed", "sub_code": "INVALID_PARAMETER", "sub_msg": "参数有误抱歉,系统出错了,请您稍后再试 (Z5132)" }, "sign": "v/DjkviKs2ja3HO9ZZ94W8bcfAsLyRuGrZT/TlFm6FgGQv4qSm/94o1FjOaMCl/t8XIm89bBhk03PBJ099alDzjnj4RD6S9FYDV7CfjvHYjrzvVJzn47Gc1mWdOHZ38DFQLWIg1IbNKFmYdoR+NdY5nY/cwz3Al2wfEylvN1cbs="}
API列表
接口英文名称
接口说明
我的.ap.faceVerify
人脸合集
zoloz.identification.user.web.query
人脸采集结果查询
常见问题:如果一个用户有多个支付宝账户,调用人脸识别验证接口时返回的user_id是否相同?
A:首先返回用户上次使用的支付宝账号对应的user_id。
Q:真机调试报错 "retMessageSub":"{"error":4,"errorMessage":"Not authorized to call","message":"Not authorized to call","signature"怎么办: “N22104”}?
A:人脸抓拍功能需要在小程序后台添加人脸抓拍功能包并签约使用。请参考此文档访问指南
解决方案:可视化采集器(智能化采集)
目录:
1、视觉采集软件
使用CSS选择器的采集软件可以准确的提取我们的网页元素。从用户体验的角度来看,XPATH有一个可视化的操作页面,让我们上手非常容易,但是为什么CSS选择器一直被我们的采集软件占用,虽然CSS的使用比较复杂,但是可以准确的捕捉一些元素XPATH 无法定位的文件。
2.可视化数据采集
所以大部分采集软件都是XPATH和CSS并存
3、智能采集系统
从网页元素提取的角度来看,CSS选择器和XPath选择器是一样的。它们都帮助我们定位网页中的相关元素,只是在语法表达上有所区别。从用户的角度来看,通过视觉抓取页面,我们可以完成80%以上的网站宣传页面数据抓取,少部分可以通过CSS选择器来补充。两个选择器的组合使我们能够覆盖各种类型的网页。
4、智能信息采集

5、智能采集设备
在搜索结果中查看网页时,我们注意到它们在链接下方收录
一小段信息。这称为“描述”。描述是 SEO 的有用工具。简短、朗朗上口的描述有助于说服用户点击文章。虽然元描述并非我们网站的所有 SEO 方面都是最终的,但最好将它们分类以防止出现任何错误。
6、智能采集摄像系统
它们需要有特定的长度才能在搜索引擎结果中完整显示,并且它们需要对每个页面和 关键词 都是唯一的
7.实时采集可视化工具
优化我们的内容,当我们制定内容 SEO 策略时,我们可能认为越多越好。定期发布新内容有助于吸引新访问者访问我们的网站并保持人们的参与度。然而,大多数时候,答案不是数量,而是质量。
8.数据采集
和可视化
这就是内容优化发挥作用的地方。这是查看我们网站上现有内容并询问“我如何才能更好地优化它?”的过程。这通常并不意味着重写整篇文章。相反,它涉及考虑内容的某些方面。我们是否选择了正确的字数?查看涵盖同一主题的成功文章并检查其字数。
9.如何持续采集
可视化

10、智能数据采集控制器
我们是否尽可能有效地使用 关键词?找到合适的 关键词 是内容营销的重要组成部分。但密度也很重要。确保避免过度使用 关键词。关键词 的更多实例并不意味着它的排名更好 - 事实上恰恰相反。
我们是否涵盖相关主题?最好的文章涵盖多个用户查询。查找其他相关主题以收录
在我们的文章中。在我们花时间优化一个页面之后,我们会想知道它的表现如何。SEO Tools 的 CSS 文章抓取软件使我们能够访问 SEO。活动进度更新。
我们可能已经努力为我们的网站创建内容,但如果我们要获得 SEO 回报,用户需要坚持下去。搜索引擎将“停留时间”描述为其主要的 SEO 优先事项之一。顾名思义,这是用户停留在页面上并阅读它的时候。文章时间
结合CSS选择器和XPATH选择器的文章合集软件分享到此结束。通过简单准确的网页内容提取,我们可以快速获取我们需要的公共数据和内容,从而提高我们的工作效率。如果你喜欢这篇文章,不妨采集
点赞。您的支持是博主不断更新的动力。
主题测试文章,仅供测试使用。发布者:小新SEO,转载请注明出处:
解决方案:labview100个实例之简单采集(2)
采集交流 • 优采云 发表了文章 • 0 个评论 • 131 次浏览 • 2022-11-23 08:27
目录
提示:文章写完后,目录可以
前言
之前做过一个很简单的程序,但总觉得不能体现labview真正的特点,所以打算做一个系列,让一些初学者容易理解这些。首先是模块化和功能封装的概念。
1.例子
这是一个完整的主程序框图,可以清楚的看到分为两大区域——“参数”设置区和“主界面”。主界面收录
四个区域,分别是修改频率较高的参数区、控制区(启停)、状态区和显示区。用于采集一段时间内的声音和电流信号。
运行效果为:
设置采集条件和数据存储路径,通过按钮控制采集的开始,程序按照指定的采样率采集一段时间的信号并保存时域数据(原创
数据,方便后期数据处理)。如果可能,你可以尝试运行一下来测试一下效果。
模块化与功能封装.zip-MCU文档资源-CSDN文库
2. 模块化与功能封装 1. 模块化
Labview的一大特点是程序往往以模块化的方式构建,也就是常说的子VI。
2.功能封装
如图所示,此时我们说这个程序使用了三个子VI,分别封装了采集、回放、存储三个功能。
在制作子VI时,需要明确需要封装的函数,输入输出的数据类型。在保证通用性的前提下,主程序框图应该是最简洁的。
总结
本例主要是简单说明Labview中子VI的功能以及函数封装的方便性。当我们创建一个子VI并赋予它特定的功能时,我们可以很方便地在项目的任何地方调用它,而不需要再次编辑重复的代码。
特别注意的是,当一个子VI被我们封装后,理论上我们可以直接在本程序中调用。但往往在一个大型项目中,一些子VI因为其功能而被频繁使用,我们需要考虑是否要重复调用它们。重复调用是指我们在某个时间多次调用同一个子VI,程序会等待并逐次执行每次调用,导致程序运行时间发生变化甚至数据冲突(因为一般一个子VI计算机只分配一块内存空间 同时调用时,我们不知道谁先调用并输出结果)。
我们可以在VI的属性——“执行”栏中将VI设置为可重入VI。这样,程序运行时,当在多个地方同时调用这个VI时,会创建不同的工作区,多个调用者的数据会分别存储,不会发生冲突和干扰。
★ 范例中提到的结构、文件、信号处理和信号分析的范例版本及后续计划为17版本,如需降级请及时联系我们。
解决方案:采购内容及技术要求
一、采购要求
一、项目建设背景
政府网站是现代政府在信息化条件下政府密切联系人民群众的重要桥梁,是网络时代政府履行职责的重要平台,是各级政府机关提供信息公开、回应关切、办事服务、互动交流的重要载体。近年来,党中央、国务院、四川省政府高度重视政府网站建设和管理工作,先后下发了多项关于加强政府网站建设的管理规定。从2015年4月起,国务院开展了全国政府网站普查工作,对政府网站的建设起到了前所未有的推动作用。
2017年5月,《国务院办公厅关于印发政府网站发展指引的通知》(国办发〔2017〕47号)发布,对政府网站集约化建设提出了详细的建设要求。德阳市政府网站集约化建设项目将以此为依据,并根据《四川省人民政府办公厅关于加强政府网站信息内容建设的实施意见》(川办发〔2015〕53号)和《德阳市人民政府办公室关于进一步做好“互联网+政务服务”有关工作的通知》(德办函〔2016〕99号)以及政府网站绩效考核的要求,以问题和需求为导向,以为民服务为根本宗旨,顺应公众的期盼,按照利企便民的原则,树立“以信息公开为基础、公共服务为核心”的理念,积极推进政府网站集约化平台建设、应用新技术拓展服务渠道,以增强网站用户体验、提高办事服务、实现信息共享,为公众提供优质、便捷、高效服务。
二、项目建设目标
根据国家和四川省政府网站绩效考核指标及其他相关政策文件中对“互联网+”环境下政府网站的定位,借鉴国内外领先政府网站的先进经验和趋势特点,以“技术先进、功能完备、服务智能、安全稳定”为建设原则,着重新技术应用,基于大数据平台,采用移动互联网等技术手段,建设德阳智慧型、实用化、个性化、集约化网站群管理平台,最终实现德阳市政府门户网站、40个市级部门网站(含德阳经开区网站、德阳高新区网站)、6个县(市、区)政府门户网站的集约化建设工作。建设总体目标如下:
1. 加强信息资源整合,搭建全市统一的政府网站信息资源库,有效管理全市政府网站信息资源。
2. 建立信息支撑体系,提供网站信息采集技术,丰富网站信息供给手段。能够通过集约化平台集中实现采集、发布信息和数据,实现主站与子站、子站与子站、子站与栏目和市级部门子站与县级部门专栏等之间的互联互通、信息复用,为信息公开提供平台支撑,充分发挥政府网站在政务公开中第一平台的作用。
3. 加强网站智能化建设,提供智能搜索、智能问答、智能推荐和无障碍访问等功能。可根据用户需求调整搜索排序、聚合相关服务等,实现“搜索即服务”。主动为社会公众提供智能、实用、便捷、精准、高效的网站服务,提升政府网站的公共服务能力和水平。
4. 建立健全网站内容保障监管体系,加强网站的运维、监管手段,提供切实有效的网站运维、监管能力,及时发现网站存在的问题。保证网站运行安全、稳定,服务内容全面、准确。
5. 提供统一、完善的网站互动交流功能,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。
6. 注重政务微博、微信等互联网新技术的应用,加强对移动终端应用功能的支持,丰富公众访问渠道,有效提高用户体验。
7.能够通过“深度链接”、各类接口整合等方式,实现全市统一的办事服务入口和数据开放入口;与有效与四川省政府信息公开目录管理系统、四川省一体化政务服务平台、德阳市政务信息资源共享平台等进行整合和对接,最终实现平台互联互通、信息资源共享。
8.围绕2018年国家和四川省政府网站绩效评估指标体系,对网站建设进行升级优化,提升德阳市政府门户网站排名,力争进入省内前10名;加强网站建设的方向性引导、有效激励服务改进措施,保障网站持续发展。
三、总体技术要求
(一)软件产品技术要求
1.本次项目的投标商必须采用先进且成熟的技术和产品,主要产品应具有云平台部署成功案例。
2.软件产品应具有网站集群化平台建设能力。
3.系统需支持大量用户访问和海量数据的存储、检索和管理,平台功能部署灵活统一。
4.产品具有安全、可优化、可扩展性能,易于二次开发,应免费提供接口。
5.系统应采用J2EE或其他符合行业发展方向的先进技术架构;
6.系统应用结构体系的表示层、业务层、数据层、访问层应分开,支持分布式部署,支持无限站点扩展;
7.系统应支持Oracle、MySQL、Microsoft SQL Server等主流数据库系统和主要国产化数据库系统;
8.网站系统兼容性强,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
9.系统支持双机热备部署模式。
(二)运行性能指标
1. 在网络稳定的环境下,系统后台单一操作的响应时间小于3秒;网站页面访问响应时间小于1秒。
2. 网站满足并发访问用户数不低于10000的访问请求。
3. 支持初始数据量不少于100万记录数,支持表空间自动扩充。
4. 系统能够实现满足网站面向服务的目标,最终实现服务化、构件化、松耦合的SOA体系架构。
5. 系统提供7×24小时的连续运行,平均系统年故障时间≤2个小时,平均故障修复时间≤30分钟。
6. 网页代码和标记设计尽可能简化,以节约带宽。
7. 网站要提供不间断服务,支持信息多个站点同时发布功能,单个站点故障或更新维护等不能影响其它站点的正常使用。
(三)安全性能要求
1. 系统应支持分布式部署,系统应支持静态页面发布。
2. 系统应建立基于角色和工作分工的权限控制机制,重要信息需具备有效的加密方式进行传递;系统应提供数据自动非本机转储备份和故障恢复等应急响应功能,具备完善的日志记录、审计和数据备份功能。
3. 具备良好的数据库安全策略。系统安全设计符合《计算机信息系统安全保护等级划分准则》(GB17859-1999)第三级(安全标记保护级)要求。
四、建设内容及功能性需求
此次项目招标主要目的是规划、搭建好德阳市政府网站集约化平台,并完成“中国·德阳”网的改版和40个市级政府部门网站(含德阳经开区网站、德阳高新区网站)的集约化建设,但不包括德阳市6县(市、区)政府门户网站集约化建设内容。德阳市政府网站集约化平台将部署在德阳市政务云上。具体建设内容如下:
(一)统一用户管理系统
将德阳市使用站群系统的所有用户统一管理起来,实现用户的属性管理,并将用户与组织机构相关联。
用户管理,提供对用户的增、删、改,可禁用和启用用户帐号,设置用户拥有的功能权限;可自定义用户组织架构;用户组管理,提供对用户组的增、删、改,设置用户组拥有的功能权限。
(二)信息资源库系统
以整合德阳市所有政府网站资源实现共享为目标,建设集约化网站信息资源库,实现对信息资源的统一分类、统一展现、统一监管及各模块之间的无缝调用,有效解决平台建设资源共享的问题。
1. 要求针对信息资源库建设提出相应的解决方案和产品,满足结构化和非结构化数据的数据库建设。
2. 要求系统提供标准管理体系,即涵盖已经发布的国家标准、企业标准、行业标准和地方标准,也可以管理系统自定义的数据字典。
3. 要求系统具有资源库管理,数据元管理,数据集管理,表单管理等数据库基础应用组件。
4. 要求系统提供分类管理能力,分类管理包括数据元分类管理,数据分类管理。
5. 要求系统提供资源管理能力,系统提供基本的数据录入功能,也可以使用数据交换平台,通过WebService或ETL工具进行数据交换。
6. 要求系统提供共享管理能力,包括:自定义分组管理,共享维护,共享授权。共享授权实现数据分级管理,可以对用户授权,也可以对分组授权。
7. 要求系统提供系统管理能力,包括用户管理,角色管理,授权管理,日志管理。
(三)集约化网站监管平台
以“统一标准体系、统一技术平台、统一安全防护、统一运维监管,集中管理信息数据,集中提供内容服务”为目标,结合网站属地化管理体系,建设德阳市政府网站集约化管理平台,实现站点管理、规范性检查、网站普查指标自检、网站访问监控、网站维护监控、网站运行监控等功能,满足网站集约化统一管理要求。具体功能如下:
1.站点监管
(1)提供站群系统内各子站基本信息管理功能,包括管理的站点名称、站点域名、站点描述信息、主办单位及联系人信息、网站备案信息等。
(2)按照《政府网站发展指引》要求提供各项网站规范性的监测功能,包括名称规范、域名规范、备案信息规范、模板规范、标签规范、栏目规范等一致性检查、冗余检查、属地化监测等。
2.网站普查指标监测
根据网站普查要求,提供网站指标监测功能,包括网站可用性监测、存在错误页面分析、页面关联分析、空白栏目监测、栏目更新频率监测、网站外链监测、敏感词及错别字扫描等。
3.网站访问监测
根据网站实际运行情况,可数字化或图表化展现网站运行监控的各项访问指标,可对指定时间段的访问情况进行统计、分析,并能生成统计分析报告(表)进行打印或导出。监测功能及内容如下:
(1)搜索引擎监控:包括访问人次、站内搜索次数、搜索结果点击次数、搜索结果点击率、搜索引擎排行、网站检索词排行等。
(2)网站访问监控:包括访问渠道、浏览量、访客数、平均停留时间、日访问变化趋势图等;
(3)浏览页数性能监控:包括系统连接时间、响应时间、下载时间以及无法访问次数等;
(4)智能报警策略:包括故障的持续时间、问题严重性分级、分类报警,报警通知方式支持邮件、短信等。
4.网站维护监测
(1)针对网站内容管理进行数据分析,包括网站栏目(栏目访问量、栏目信息量、栏目参与部门数和栏目参与人员数等)、部门信息(部门信息发布量、部门业务办理量和部门业务办结率等)和公共诉求(诉求目的、诉求内容分类、处理单位、满意度等)等数据的统计分析功能。
(2)提供系统站内通知功能,可对系统内各用户发送消息,解决系统管理人员日常工作沟通及信息共享。
5.网站运行检测
(1)支持对服务器硬件层进行监控,包括服务器的工作状态、处理器、内存、进程等。
(2)提供灵活、全面、便捷的监控方式,监管页面秒级刷新,运行高效、安全可靠。
6.系统日志管理
提供系统日志的管理界面,能详细记录系统操作日志,并形成日志信息或日志文件,可对日志文件进行导出。
(四)网站群管理平台
以站点管理为重点,支持集中式建设部署和分布式管理维护。
支持对历史信息的调入、调出,提供对信息的全流程跟踪管理。
支持与其它平台的无缝对接。系统接口可开放,支持网站扩展功能模块的安装调试,具有高集成、可扩展、易管理等特性。
采用XML、WebService等标准,提供组件化的统一数据接口,有效实现信息的采集、聚合。
1.站群管理系统
(1)要求实现页面展现与信息分离,删除或修改网页模板时不会对信息造成影响。
(2)站群管理系统支持站群下所有子站点的创建、修改、暂停、删除及服务器资源配置。
(3)系统提供多级授权分层管理机制,每个子站点都提供独立的站点管理功能,站点管理人员能够对子站点进行角色权限管理、资源管理、用户权限管理及站点统计等操作,保证用户在统一的平台下独立管理自己的子站点。
(4)站群系统内各站点之间可以共享数据源,保证各站点信息的一致性。
(5)系统支持密码强度管理、CA绑定等安全策略。
2.站点管理系统
(1)网站信息的发布具有静态信息发布和动态信息发布相结合的发布模式,用户可根据实际需要选择发布方式,以同时满足网站访问速度、并发访问量及网站交互功能的多重需求。
(2)系统支持对多种信息格式的发布,包括音频、视频等多媒体格式。
(3)系统支持增量发布与完全发布,支持定时发布和立即发布,可根据需要自定义发布方式。
(4)系统提供统一用户验证功能,通过账号、密码、验证码相结合的方式登陆到系统管理界面。
(5)内容维护人员只能对自己权限范围内的内容进行管理,无权看到并操作其他用户管理的内容。
(6)系统详细记录所有用户的系统操作,以便于查询和管理。
(7)系统提供权限组功能,具有相同权限的用户可划分为同一权限组。权限的分配可以详细到每一个栏目。
(8)提供系统登陆账号长时间无操作的自动注销功能,可自行设置注销时间。
(9)系统可根据自定义备份策略(如异地备份、定时备份等)进行站点数据备份,能对备份文件进行删除、下载、恢复管理。
3.内容管理系统
(1)具有网站内容采集、在线编辑、审核发布、敏感词过滤、错别字检测等功能,提供可视化编辑器,实现“所见即所得”的信息录入、编辑效果。
(2)支持文档录入、发布、预览、修改、删除等操作,拥有丰富的文档引用、复制、链接、移动、同步等操作功能。
(3)内容编辑器具有多图片上传、word和pdf等文档导入、一键排版、格式清理、去除空行、首行缩进等常用功能;
(4)各子站点具有独立、完善的信息采集、编发功能,可根据用户权限进行跨栏目、跨站点信息推送与共享。
(5)支持信息发布过程中的多级审核管理,能够针对不同站点、不同栏目设置不同审核流程;
(6)支持前台页面样式由模板进行控制,模板提供代码级修改,模板管理支持标签语法,模板可嵌套模板,也可嵌套标签;
(7)网站栏目能够自由移动,可定制栏目信息发布类型,可按权限获取不同栏目、不同站点(如内容管理系统、信息公开系统)的信息;
(8)信息录入具备文章、组图、链接、视频四种类型,能够对普通文本、图
片信息和音视频等多种流媒体信息进行发布和管理,满足信息多样化的需求;
(9)支持站点发布、分级栏目发布、信息单独发布等操作,并可以指定文档发布后在页面显示的顺序;
(10)支持静态发布、动态发布和动态静态相结合的发布方式。
(五)政府信息公开管理系统
根据部门业务和网站功能特点进行科学分析、认真梳理,合理规划频道和栏目,与四川省政府信息公开目录管理系统进行数据对接,有效实现德阳市政府信息公开数据在网站上的聚类、共享、展示。
(1)该系统必须完全符合《政府信息公开目录系统实施指引(试行)》(国办秘函[2009]6号)文件中的各项要求。
(2)要求系统提供灵活的元数据管理,以能适应不同类型的信息记录需要,元数据必需符合国家相关文件的要求,并具备元数据扩展功能;提供对多种类型的元数据字段支持。定义数据层、功能层、使用层规范,同时配以编码规则管理,支持批量修改,保持良好的扩展性;
(3)要求系统提供灵活的分类管理,可自由地将采集到的信息进行多渠道分类,包括主题分类、机构分类、体裁分类及服务对象分类。同时支持分类的自由扩展。
(4)要求系统提供灵活的目录管理功能,用户可根据公众的需要定义目录的展现内容,通过定义目录节点的生成规则,从而来获取相应的数据,形成最终的人性化目录;系统支持目录推荐功能,即上级政府建立完成的目录,可以作为“模板”推荐给下级单位。
(5)要求系统能够自定义索引号编码规则,依照信息公开标准对信息进行自动编码,生成信息索引号。当编码规则发生修改时,也可制定新规则,并批量修改信息索引号。
(6)要求系统提供良好的信息管理功能,从采集、标引、审核、发布到归档,完整记录信息生命周期活动。
(7)系统提供列表、简要、细览等展现形式,显示核心元数据,包括索引号、名称、内容概述、生成日期、文号等。
(8)系统应满足信息录入和审核权限的逐级分配,强化信息源头管理,保障信息发布安全。
(9)系统具有依申请公开功能,可对依申请公开信息进行接收、受理、审核、发布,并提供统计分析等功能,访问用户可实时查询依申请公开处理状态。
(10)要求系统提供综合的绩效评估模式,包括信息公开工作量评估、依申
请公开办结率和办结质量评估。
(六)互动交流系统
系统严格遵循SOA模块化设计思想,按照“高内聚,低耦合”原则,提供全面完善的网站互动交流功能,包括领导信箱、民意征集、在线调查、咨询投诉、网上信访、在线访谈等,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。具体功能要求如下:
1.在线访谈系统
(1)支持图文和视频同步的在线访谈,要求具有文字直播、图片直播、音频直播及视频直播四种功能形式;
(2)要求提供良好的人机对话界面,网友通过文字形式可实时提问,管理人员采集
和审核问题,主持人转达和引导提问,嘉宾对问题实时解答;
(3)管理员可查看在线用户情况,可以通过IP或用户名来禁止用户行为,可对用户发言内容设置过滤模式。
(4)主持人、嘉宾与网友的发言区要划分明确;
(5)系统必须具有访谈预告功能,访谈预告可采用文字、图片或视频方式展示访谈背景和相关资料。
(6)访谈过程中要确保文字、图片、音频、视频的流畅;
(7)对于历史访谈,可按照日期进行归档,形成历史访谈目录,网友可调阅历史访谈。
(8)对于已经完成的访谈,管理员可继续对访谈内容进行修改和编辑。
2.领导信箱系统
(1)系统具有工作流管理功能,可自定义信件办理流程,实现从受理、转办、承办、退回、办结的全流程管理。
(2)系统具有信件办理状态实时查询功能,来信人可根据信件编码、姓名、联系电话等对信件办理状态进行查询,信箱管理人员可通过关键字、信件编码、时间、部门、信件状态等条件进行查询。
(3)前台提供“信件选登”、“信件查询”、“我要写信”等功能,写信内容需收录
姓名、昵称、身份证号码、联系电话、电子邮件、信件标题、信件内容,可上传附件材料等,具有详实的展现形式,可对敏感词进行自动屏蔽。
(4)后台提供信件的回复、发布、选登等状态的查看及信件办理状态的统计功能,提供信件的“公开/不公开”选项功能。
3.意见征集系统
(1)针对社会公众关注的热点问题或者政策制定和工作成果开展民意征集活动,民意征集的各个主题要求布局清晰、合理,方便阅览;
(2)网友可根据征集主题的内容和背景资料发表自己的建议和观点,可以查看征集结果;
(3)系统后台可实时查看所有社会公众提交的意见和建议;
(4)意见征集结束后,前台只保留征集主题、内容、结果,网友不能再进行意见和建议的提交;
(5)能对网友发表的文字信息进行安全性检查。
4.网上调查系统
(1)管理员可根据不同的调查内容新建、修改、删除调查问卷。对于每个调查问卷可以对标题、摘要、内容、选项、调查项组成结构等进行管理,可灵活设计投票问卷风格;
(2)同一调查主题,可设置多个调查项;调查项应包括单选项调查、多选项调查、附加选项(填空)等调查类型;
(3)同一IP地址在设定时间内只允许提交一次投票,杜绝恶意投票行为发生;
(4)投票结果可通过表格、柱状图、饼图等形式进行展现。
(七)数据采集系统
(1)数据采集系统借助先进的信息抓取、信息分类和信息流转技术,实现对指定网站信息(包括但不限于中央政府网站、省政府网站、重要新闻网站和平台内外所需政府信息资源)的更新监测和有效采集。
(2)系统按照不同需要,可定点、定时监测和采集所需信息,并下载信息的图片、视频及附件等相关文件,将采集信息进行准确分类、整理、筛选,通过内容推送功能自动推送到指定栏目。
(3)管理员可在后台设置抓取的范围、关键字、抓取时间等参数,系统根据设置好的抓取策略进行信息自动抓取。
(4)用户可对采集到的信息按照日期、来源、标题进行检索、浏览;可以对信息内容与图片分类保存,支持信息分类的自定义。
(5)系统支持将网页中的信息内容按标题、作者、栏目、内容等进行提取;自动过滤网页中的无用信息、广告图片等,自动过滤重复的信息。
(6)对采集的信息可进行二次编辑、审核,可向网站群内各个子站栏目进行发布。
(八)无障碍浏览系统
(1)面向听力、视力等有障碍的特殊人群提供缩放字体、缩放页面、辅助光标、文本化网页和语音个性化调整等辅助浏览功能。
(2)具有全程自动语音提示、全程语音导航交互、光标语音指读与连读、文
字放大阅读专用屏、网页图文放大缩小、高对比阅读配色器、阅读辅助光标等功能。
(3)系统需界面友好、易操作,无需安装插件,支持各种主流浏览器。
(九)智能检索系统
(1)提供专业的政府网站检索功能,对政府网站检索进行分类引导,按照政策法规、办事事项、政府文件、新闻咨询等类别对用户检索内容进行归类整理,清晰引导用户进行查阅。
(2)数据检索范围应包括站群内各业务部门、各县(市、区)网站站点,可对不同类型数据源的数据进行检索。
(3)满足即搜即用原则,支持图片、视频格式信息的检索。
(4)支持关键字搜索、日期搜索。要求提供个性化检索结果功能,如检索结果分类导航展现、检索结果按不同维度(可以按系统,站点,栏目,区县,文档类型,时间单位,相似度等)过滤展示,检索结果可进行二次搜索。
(5)具有搜索关键词自动补全能力,动态分析公众搜索关键词,按照关键词的内在逻辑关系进行自动匹配,给出搜索提示,纠正用户输入错误。
(6)具有热词自动排序和显示功能,可自动统计搜索关键词的搜索频度,将某一时间段内搜索量较高的关键词作为搜索热词,并根据热度动态自动调整排序。
(7)支持拼音搜索功能,采用词语智能拼音匹配模式,并结合关键词提醒联想功能,实现拼音和中文友好联系的搜索功能。
(8)系统支持管理员定义屏蔽词和停用词的搜索,当用户输入收录
的词汇时,系统不展示搜索结果信息。
(9)支持多个关键词搜索和整句搜索。
(10)系统使用基于文档语义的技术实现同一站点内搜索结果信息的自动排重,即“相同”的文档在索引过程中仅被索引一次,解决大量相同文档的搜索问题,提高索引效率,帮助用户快速找到搜索结果。
(11)对含有图片的信息,其搜索结果列表应显示其缩略图;
(12)系统具有检索结果优先显示置顶功能。
(十)智能推荐系统
(1)根据网站用户访问行为,结合网站数据分析,找到网站访问热点,自动聚合相关信息(即相关文件、政策、咨询类信息),实现网站信息智能推荐。
(2)可根据关键词、热词等条件分析信息之间的直接联系或间接关系,自动分析、梳理、聚类展示。
(3)可自动进行专题信息汇聚,通过数据采集技术,获取相关信息进行集中
管理和存储,根据用户访问习惯,进行数据的重组、拼装,聚合,形成专题栏目;也可根据各专题的关注度,对推荐专题及相应的页面表现位置进行展示顺序的自动调整,供公众访问。
(十一)智能问答系统
(1)能够深度挖掘网站群信息内容,建立和完善智能应答知识库,可根据用户自定义规则,通过信息聚合技术,按照信息采集、聚合、挖掘和检索流程,实现跨部门、跨行业的信息整合与资源共享。
(2)能够自动将咨询问题保存入库,可自定义站点检索到相关咨询问题,可实时预处理用户的输入信息,根据输入内容与后台检索引擎交互,自动纠错,实时提示相关信息,引导类似问题进行解答。
(3)可利用信息资源库及应答知识库中的信息,即时自动回答用户提出的问题,向用户展示相关度较高的信息。
(4)能够充分使用站群内所有站点的信息资源,咨询问题答复内容可由平台下多个站点信息数据组成关联页面提供给用户。
(5)能够实现多样化展现方式,可以预分类政务资源,将多个网站中的同类栏目合并为一个分类,为用户按分类展现更全面精准的搜索结果。
(6)要求具备自学习功能,能够自动丰富知识库,对于无法解决的问题可自动转人工解答。
(十二)移动门户系统
(1)要求采用HTML5网站页面应自适应技术,能够实现不同移动终端(例如苹果、安卓系统) 访问移动门户时自适应展示,能够在各种访问终端下保持完整良好的页面布局和内容可读性。
(2)要求移动端与PC端使用同一域名进行访问,系统自动识别访问终端并自适应页面展示效果。
(3)要求移动门户所展示信息不再二次录入,统一由站点内容管理系统提供,以保证数据来源的统一性。
(4)要求提供最新新闻、政务公开、互动交流、解读回应、民意调查、舆论引导、政务服务、政府办公等信息内容的展示。
(5)要求支持可定制栏目访问。
五、其他需求说明
1.网站兼容性要求
要求网站页面具有很好的兼容性,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
2.UI/UE设计
(1)界面设计需要突出地方特色
(2)文字,图形色彩统一,搭配合理,界面清楚整洁,层次结构清楚。
(3)统一首页和其他各级页面的排版风格。
(4)页面富有时代气息和美感,色彩搭配稳重、合理、大气。
(5)多媒体、动画页面要求丰富而生动。
3.子站设计要求
(1)满足各子站个性化页面设计需求,根据各部门网站管理人员要求进行设计与实施。
(2)本次页面设计主要从以下几个方面进行规划:页面风格、页面人性化和易用性、页面内容、页面结构等,围绕信息公开、办事服务、互动交流等功能定位,设计门户网站页面框架,清晰、合理、科学展现网站内容,避免累赘和页面冗余。
4.历史数据迁移要求
(1)要求提出详尽的网站数据迁移方案。
(2)要求将实施集约化的网站的全部数据,收录
各站点栏目信息、新闻信息、公开信息、互动信息、用户信息、用户对应权限、图片、附件、多媒体文件等数据平稳迁移至德阳市政府网站集约化平台,确保不丢失任何有效数据,处理好新网站栏目信息与历史数据的对应关系。
(3)要求保证集约化网站切换的平滑过渡,做好数据的同步更新。
5.硬件及部署要求
投标人必须详细列出项目的硬件需求,即政务云平台虚拟机数量及资源参数,以及系统的部署方案。
六、项目实施、培训
(一)项目竣工验收要求
按中华人民共和国现行项目建设规范和合同规定的验收评定标准等要求进行验收。
根据施工进度情况,按照标志性工作成果划分,分期进行检查、验收。
2.实施要求
投标人应具体说明实施本项目拟采用方案,确保至少两人驻场实施,团队
组织方式和保障力量,中标单位实施过程中出现资源、速度、质量协调控制不力、采购方有权更换责任人。
3.测试要求
投标供应商在实施过程中必须制定整体的测试方案,保证各子系统联接正确,数据传送正常。测试方案要明确测试关键点,分单元测试、边缘测试、整体测试等。测试方法应包括模块测试、回归测试、压力测试、性能测试、功能测试、数据测试、安全测试、系统测试等。测试内容必须包括功能要求、可靠性、安全性、可扩充性、可维护性、平台移植性、整体性能、与其他平台接口等,系统试运行期不低于三个月。
4.验收要求
投标供应商应负责在项目用户验收前将系统的全部相关的系统软件,各阶段开发文档,平台及其他应用系统交互接口功能的源代码和数据表结构,以及有关产品的系统说明书、安装手册、维护手册、技术文件、资料及安装、测试、验收报告等文档汇集成册交付项目单位。只有文档齐全后方可组织验收。对整个项目的验收包括检查整个系统是否实现了招标人所要求的功能,是否与投标供应商提出的解决方案中既定目标功能完全一致。
投标供应商必须根据系统总体设计方案提出验收细则和验收文档清单(收录
需求调研、系统分析、软件设计、软件开发、系统测试、实施上线、运行维护等阶段),招标人将根据验收方案对系统每个部分逐一进行项目验收。
5.文档要求
投标供应商提供的技术文件应该真实、全面、完整、详细,应以中文书写。投标供应商提供的技术文件应是能满足系统运行所需的安装调试、操作使用及维护管理等的详细技术资料。
投标供应商应负责在项目最终验收时将系统从合同签定之日起所有关于本项目的文档资料(包括初步验收文档的版本更新和试运行期产生的文档)交付采购人。
招标人认为必要的其他文档。
(二)培训承诺
供应商技术培训及相关系统的基础培训,内容包括软件安装调试及初始化、使用等的基本操作培训。供应商须制定出详细完整的培训方案,包括培训的具体内容、培训方式(现场培训或集中培训)、人数、教师、日程安排、资料等。应能使采购人相关人员独立操作、维护、管理,确保系统能正常安全运行。
供应商应提供的详细培训方案必须包括:(1)集群管理员操作培训;(2)各
部门管理员、应用软件操作员等的基本操作培训。
实际培训时间和地点按中标人与采购人商定的为准。
七、售后服务技术需求
售后服务包括但不限于下列服务:
1.网站页面优化服务
(1)网站信息维护培训指导。包括网站信息的增、删、查、改等操作的指导和问题解答;添加图片及附件操作指导;网站静态页面生成等操作指导。
(2)网站页面的图片、文字排版和调整。包括网页图片的制作、更换、布局调整,文字的内容、格式、链接等的修改。
(3)保证网站页面显示正常。解决文字或图片内容撑出、内容不显示或显示不正确、页面文字出现乱码、页面出现错误报告、页面在有的浏览器上显示不正确、页面没有找到、网页不能访问等问题。
2. 网站内容管理平台及选件维护服务
(1)对国家及省政府最新要求的响应
及时响应国家及省政府对政府门户网站、集约化建设及互联网+政务服务相关内容的建设要求,对门户网站前台服务内容进行调整。
(2)模版维护服务
每月一次。包括:定期对现有网站巡检,对现有的模版存在的不足进行调优,如排版不合适、格式不统一、色调不一致、内容块错位、字体大小不一致、文字没对齐等情况,但不涉及到页面新的风格。对现有的模版调整,包括添加删除专题链接、页面局部细节样式调整,错字,错链,图标替换等,提交《网站模版优化记录》。
(3)常规检查维护
每月一次。包括:各服务器运行状况、存储空间状况、软件运行状况、备份系统状况等。并提出现有问题和解决方法,并提交《网站常规检查维护运行状况报告》。
(4)专题维护
根据用户需求提供专题制作协助服务。
(5)产品版本升级
不定期提供。主要帮助客户不断完善产品的功能和系统稳定性。每次升级要对升级的版本、工作做好日志记录,并提交《版本升级记录表》。
3、技术运维服务
(1)备份服务
对门户网站系统涉及到的内容进行备份,包括数据库每天备份、网站应用程
序备份、网站所有补丁备份、项目涉及到的文档进行备份等。提交《系统备份检查表》,内容包括备份联系人、联系电话、时间、路径、内容等。
(2)错误日志分析
对网站涉及到的所有日志(包括中间件等产品)记录要进行定期查看,找出错误内容。提交《日志错误分析表》。
4、服务质量要求
(1)质量保证期限及费用
系统验收合格、双方签署验收书之日起,为本次建设内容中的子站提供至少1年维保服务。在系统维护期内,开发的软件应提供免费升级服务。维保服务到期后,应承诺对系统的升级仅收取成本费。
(2)售后服务方案
中标人需要提供详细的售后服务方案,包括服务人员、措施、应急预案及相关流程等内容。在安装、调试及系统免费维护期内,必须提供系统故障的应急处理方案。承诺所投产品系统不存在“后门”问题。
(3)服务响应要求
中标人承诺提供现场服务人员,且能够提供7*24小时响应服务,一般问题30分钟之内解决,重大问题4小时内解决。
说明:
1、欢迎供应商提供服务保障等于或高于该基本要求的服务。
2、本章的要求不能作为资格性条件要求评标,如存在资格性条件要求,应当认定招标文件编制存在重大缺陷,评标委员会应当停止评标。 查看全部
解决方案:labview100个实例之简单采集(2)
目录
提示:文章写完后,目录可以
前言
之前做过一个很简单的程序,但总觉得不能体现labview真正的特点,所以打算做一个系列,让一些初学者容易理解这些。首先是模块化和功能封装的概念。
1.例子
这是一个完整的主程序框图,可以清楚的看到分为两大区域——“参数”设置区和“主界面”。主界面收录
四个区域,分别是修改频率较高的参数区、控制区(启停)、状态区和显示区。用于采集一段时间内的声音和电流信号。

运行效果为:
设置采集条件和数据存储路径,通过按钮控制采集的开始,程序按照指定的采样率采集一段时间的信号并保存时域数据(原创
数据,方便后期数据处理)。如果可能,你可以尝试运行一下来测试一下效果。
模块化与功能封装.zip-MCU文档资源-CSDN文库
2. 模块化与功能封装 1. 模块化
Labview的一大特点是程序往往以模块化的方式构建,也就是常说的子VI。
2.功能封装

如图所示,此时我们说这个程序使用了三个子VI,分别封装了采集、回放、存储三个功能。
在制作子VI时,需要明确需要封装的函数,输入输出的数据类型。在保证通用性的前提下,主程序框图应该是最简洁的。
总结
本例主要是简单说明Labview中子VI的功能以及函数封装的方便性。当我们创建一个子VI并赋予它特定的功能时,我们可以很方便地在项目的任何地方调用它,而不需要再次编辑重复的代码。
特别注意的是,当一个子VI被我们封装后,理论上我们可以直接在本程序中调用。但往往在一个大型项目中,一些子VI因为其功能而被频繁使用,我们需要考虑是否要重复调用它们。重复调用是指我们在某个时间多次调用同一个子VI,程序会等待并逐次执行每次调用,导致程序运行时间发生变化甚至数据冲突(因为一般一个子VI计算机只分配一块内存空间 同时调用时,我们不知道谁先调用并输出结果)。
我们可以在VI的属性——“执行”栏中将VI设置为可重入VI。这样,程序运行时,当在多个地方同时调用这个VI时,会创建不同的工作区,多个调用者的数据会分别存储,不会发生冲突和干扰。
★ 范例中提到的结构、文件、信号处理和信号分析的范例版本及后续计划为17版本,如需降级请及时联系我们。
解决方案:采购内容及技术要求
一、采购要求
一、项目建设背景
政府网站是现代政府在信息化条件下政府密切联系人民群众的重要桥梁,是网络时代政府履行职责的重要平台,是各级政府机关提供信息公开、回应关切、办事服务、互动交流的重要载体。近年来,党中央、国务院、四川省政府高度重视政府网站建设和管理工作,先后下发了多项关于加强政府网站建设的管理规定。从2015年4月起,国务院开展了全国政府网站普查工作,对政府网站的建设起到了前所未有的推动作用。
2017年5月,《国务院办公厅关于印发政府网站发展指引的通知》(国办发〔2017〕47号)发布,对政府网站集约化建设提出了详细的建设要求。德阳市政府网站集约化建设项目将以此为依据,并根据《四川省人民政府办公厅关于加强政府网站信息内容建设的实施意见》(川办发〔2015〕53号)和《德阳市人民政府办公室关于进一步做好“互联网+政务服务”有关工作的通知》(德办函〔2016〕99号)以及政府网站绩效考核的要求,以问题和需求为导向,以为民服务为根本宗旨,顺应公众的期盼,按照利企便民的原则,树立“以信息公开为基础、公共服务为核心”的理念,积极推进政府网站集约化平台建设、应用新技术拓展服务渠道,以增强网站用户体验、提高办事服务、实现信息共享,为公众提供优质、便捷、高效服务。
二、项目建设目标
根据国家和四川省政府网站绩效考核指标及其他相关政策文件中对“互联网+”环境下政府网站的定位,借鉴国内外领先政府网站的先进经验和趋势特点,以“技术先进、功能完备、服务智能、安全稳定”为建设原则,着重新技术应用,基于大数据平台,采用移动互联网等技术手段,建设德阳智慧型、实用化、个性化、集约化网站群管理平台,最终实现德阳市政府门户网站、40个市级部门网站(含德阳经开区网站、德阳高新区网站)、6个县(市、区)政府门户网站的集约化建设工作。建设总体目标如下:
1. 加强信息资源整合,搭建全市统一的政府网站信息资源库,有效管理全市政府网站信息资源。
2. 建立信息支撑体系,提供网站信息采集技术,丰富网站信息供给手段。能够通过集约化平台集中实现采集、发布信息和数据,实现主站与子站、子站与子站、子站与栏目和市级部门子站与县级部门专栏等之间的互联互通、信息复用,为信息公开提供平台支撑,充分发挥政府网站在政务公开中第一平台的作用。
3. 加强网站智能化建设,提供智能搜索、智能问答、智能推荐和无障碍访问等功能。可根据用户需求调整搜索排序、聚合相关服务等,实现“搜索即服务”。主动为社会公众提供智能、实用、便捷、精准、高效的网站服务,提升政府网站的公共服务能力和水平。
4. 建立健全网站内容保障监管体系,加强网站的运维、监管手段,提供切实有效的网站运维、监管能力,及时发现网站存在的问题。保证网站运行安全、稳定,服务内容全面、准确。
5. 提供统一、完善的网站互动交流功能,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。
6. 注重政务微博、微信等互联网新技术的应用,加强对移动终端应用功能的支持,丰富公众访问渠道,有效提高用户体验。
7.能够通过“深度链接”、各类接口整合等方式,实现全市统一的办事服务入口和数据开放入口;与有效与四川省政府信息公开目录管理系统、四川省一体化政务服务平台、德阳市政务信息资源共享平台等进行整合和对接,最终实现平台互联互通、信息资源共享。
8.围绕2018年国家和四川省政府网站绩效评估指标体系,对网站建设进行升级优化,提升德阳市政府门户网站排名,力争进入省内前10名;加强网站建设的方向性引导、有效激励服务改进措施,保障网站持续发展。
三、总体技术要求
(一)软件产品技术要求
1.本次项目的投标商必须采用先进且成熟的技术和产品,主要产品应具有云平台部署成功案例。
2.软件产品应具有网站集群化平台建设能力。
3.系统需支持大量用户访问和海量数据的存储、检索和管理,平台功能部署灵活统一。
4.产品具有安全、可优化、可扩展性能,易于二次开发,应免费提供接口。
5.系统应采用J2EE或其他符合行业发展方向的先进技术架构;
6.系统应用结构体系的表示层、业务层、数据层、访问层应分开,支持分布式部署,支持无限站点扩展;
7.系统应支持Oracle、MySQL、Microsoft SQL Server等主流数据库系统和主要国产化数据库系统;
8.网站系统兼容性强,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
9.系统支持双机热备部署模式。
(二)运行性能指标
1. 在网络稳定的环境下,系统后台单一操作的响应时间小于3秒;网站页面访问响应时间小于1秒。
2. 网站满足并发访问用户数不低于10000的访问请求。
3. 支持初始数据量不少于100万记录数,支持表空间自动扩充。
4. 系统能够实现满足网站面向服务的目标,最终实现服务化、构件化、松耦合的SOA体系架构。
5. 系统提供7×24小时的连续运行,平均系统年故障时间≤2个小时,平均故障修复时间≤30分钟。
6. 网页代码和标记设计尽可能简化,以节约带宽。
7. 网站要提供不间断服务,支持信息多个站点同时发布功能,单个站点故障或更新维护等不能影响其它站点的正常使用。
(三)安全性能要求
1. 系统应支持分布式部署,系统应支持静态页面发布。
2. 系统应建立基于角色和工作分工的权限控制机制,重要信息需具备有效的加密方式进行传递;系统应提供数据自动非本机转储备份和故障恢复等应急响应功能,具备完善的日志记录、审计和数据备份功能。
3. 具备良好的数据库安全策略。系统安全设计符合《计算机信息系统安全保护等级划分准则》(GB17859-1999)第三级(安全标记保护级)要求。
四、建设内容及功能性需求
此次项目招标主要目的是规划、搭建好德阳市政府网站集约化平台,并完成“中国·德阳”网的改版和40个市级政府部门网站(含德阳经开区网站、德阳高新区网站)的集约化建设,但不包括德阳市6县(市、区)政府门户网站集约化建设内容。德阳市政府网站集约化平台将部署在德阳市政务云上。具体建设内容如下:
(一)统一用户管理系统
将德阳市使用站群系统的所有用户统一管理起来,实现用户的属性管理,并将用户与组织机构相关联。
用户管理,提供对用户的增、删、改,可禁用和启用用户帐号,设置用户拥有的功能权限;可自定义用户组织架构;用户组管理,提供对用户组的增、删、改,设置用户组拥有的功能权限。
(二)信息资源库系统
以整合德阳市所有政府网站资源实现共享为目标,建设集约化网站信息资源库,实现对信息资源的统一分类、统一展现、统一监管及各模块之间的无缝调用,有效解决平台建设资源共享的问题。
1. 要求针对信息资源库建设提出相应的解决方案和产品,满足结构化和非结构化数据的数据库建设。
2. 要求系统提供标准管理体系,即涵盖已经发布的国家标准、企业标准、行业标准和地方标准,也可以管理系统自定义的数据字典。
3. 要求系统具有资源库管理,数据元管理,数据集管理,表单管理等数据库基础应用组件。
4. 要求系统提供分类管理能力,分类管理包括数据元分类管理,数据分类管理。
5. 要求系统提供资源管理能力,系统提供基本的数据录入功能,也可以使用数据交换平台,通过WebService或ETL工具进行数据交换。
6. 要求系统提供共享管理能力,包括:自定义分组管理,共享维护,共享授权。共享授权实现数据分级管理,可以对用户授权,也可以对分组授权。
7. 要求系统提供系统管理能力,包括用户管理,角色管理,授权管理,日志管理。
(三)集约化网站监管平台
以“统一标准体系、统一技术平台、统一安全防护、统一运维监管,集中管理信息数据,集中提供内容服务”为目标,结合网站属地化管理体系,建设德阳市政府网站集约化管理平台,实现站点管理、规范性检查、网站普查指标自检、网站访问监控、网站维护监控、网站运行监控等功能,满足网站集约化统一管理要求。具体功能如下:
1.站点监管
(1)提供站群系统内各子站基本信息管理功能,包括管理的站点名称、站点域名、站点描述信息、主办单位及联系人信息、网站备案信息等。
(2)按照《政府网站发展指引》要求提供各项网站规范性的监测功能,包括名称规范、域名规范、备案信息规范、模板规范、标签规范、栏目规范等一致性检查、冗余检查、属地化监测等。
2.网站普查指标监测
根据网站普查要求,提供网站指标监测功能,包括网站可用性监测、存在错误页面分析、页面关联分析、空白栏目监测、栏目更新频率监测、网站外链监测、敏感词及错别字扫描等。
3.网站访问监测
根据网站实际运行情况,可数字化或图表化展现网站运行监控的各项访问指标,可对指定时间段的访问情况进行统计、分析,并能生成统计分析报告(表)进行打印或导出。监测功能及内容如下:
(1)搜索引擎监控:包括访问人次、站内搜索次数、搜索结果点击次数、搜索结果点击率、搜索引擎排行、网站检索词排行等。
(2)网站访问监控:包括访问渠道、浏览量、访客数、平均停留时间、日访问变化趋势图等;
(3)浏览页数性能监控:包括系统连接时间、响应时间、下载时间以及无法访问次数等;
(4)智能报警策略:包括故障的持续时间、问题严重性分级、分类报警,报警通知方式支持邮件、短信等。
4.网站维护监测
(1)针对网站内容管理进行数据分析,包括网站栏目(栏目访问量、栏目信息量、栏目参与部门数和栏目参与人员数等)、部门信息(部门信息发布量、部门业务办理量和部门业务办结率等)和公共诉求(诉求目的、诉求内容分类、处理单位、满意度等)等数据的统计分析功能。
(2)提供系统站内通知功能,可对系统内各用户发送消息,解决系统管理人员日常工作沟通及信息共享。
5.网站运行检测
(1)支持对服务器硬件层进行监控,包括服务器的工作状态、处理器、内存、进程等。
(2)提供灵活、全面、便捷的监控方式,监管页面秒级刷新,运行高效、安全可靠。
6.系统日志管理
提供系统日志的管理界面,能详细记录系统操作日志,并形成日志信息或日志文件,可对日志文件进行导出。
(四)网站群管理平台
以站点管理为重点,支持集中式建设部署和分布式管理维护。
支持对历史信息的调入、调出,提供对信息的全流程跟踪管理。
支持与其它平台的无缝对接。系统接口可开放,支持网站扩展功能模块的安装调试,具有高集成、可扩展、易管理等特性。
采用XML、WebService等标准,提供组件化的统一数据接口,有效实现信息的采集、聚合。
1.站群管理系统
(1)要求实现页面展现与信息分离,删除或修改网页模板时不会对信息造成影响。
(2)站群管理系统支持站群下所有子站点的创建、修改、暂停、删除及服务器资源配置。
(3)系统提供多级授权分层管理机制,每个子站点都提供独立的站点管理功能,站点管理人员能够对子站点进行角色权限管理、资源管理、用户权限管理及站点统计等操作,保证用户在统一的平台下独立管理自己的子站点。
(4)站群系统内各站点之间可以共享数据源,保证各站点信息的一致性。
(5)系统支持密码强度管理、CA绑定等安全策略。
2.站点管理系统
(1)网站信息的发布具有静态信息发布和动态信息发布相结合的发布模式,用户可根据实际需要选择发布方式,以同时满足网站访问速度、并发访问量及网站交互功能的多重需求。
(2)系统支持对多种信息格式的发布,包括音频、视频等多媒体格式。
(3)系统支持增量发布与完全发布,支持定时发布和立即发布,可根据需要自定义发布方式。

(4)系统提供统一用户验证功能,通过账号、密码、验证码相结合的方式登陆到系统管理界面。
(5)内容维护人员只能对自己权限范围内的内容进行管理,无权看到并操作其他用户管理的内容。
(6)系统详细记录所有用户的系统操作,以便于查询和管理。
(7)系统提供权限组功能,具有相同权限的用户可划分为同一权限组。权限的分配可以详细到每一个栏目。
(8)提供系统登陆账号长时间无操作的自动注销功能,可自行设置注销时间。
(9)系统可根据自定义备份策略(如异地备份、定时备份等)进行站点数据备份,能对备份文件进行删除、下载、恢复管理。
3.内容管理系统
(1)具有网站内容采集、在线编辑、审核发布、敏感词过滤、错别字检测等功能,提供可视化编辑器,实现“所见即所得”的信息录入、编辑效果。
(2)支持文档录入、发布、预览、修改、删除等操作,拥有丰富的文档引用、复制、链接、移动、同步等操作功能。
(3)内容编辑器具有多图片上传、word和pdf等文档导入、一键排版、格式清理、去除空行、首行缩进等常用功能;
(4)各子站点具有独立、完善的信息采集、编发功能,可根据用户权限进行跨栏目、跨站点信息推送与共享。
(5)支持信息发布过程中的多级审核管理,能够针对不同站点、不同栏目设置不同审核流程;
(6)支持前台页面样式由模板进行控制,模板提供代码级修改,模板管理支持标签语法,模板可嵌套模板,也可嵌套标签;
(7)网站栏目能够自由移动,可定制栏目信息发布类型,可按权限获取不同栏目、不同站点(如内容管理系统、信息公开系统)的信息;
(8)信息录入具备文章、组图、链接、视频四种类型,能够对普通文本、图
片信息和音视频等多种流媒体信息进行发布和管理,满足信息多样化的需求;
(9)支持站点发布、分级栏目发布、信息单独发布等操作,并可以指定文档发布后在页面显示的顺序;
(10)支持静态发布、动态发布和动态静态相结合的发布方式。
(五)政府信息公开管理系统
根据部门业务和网站功能特点进行科学分析、认真梳理,合理规划频道和栏目,与四川省政府信息公开目录管理系统进行数据对接,有效实现德阳市政府信息公开数据在网站上的聚类、共享、展示。
(1)该系统必须完全符合《政府信息公开目录系统实施指引(试行)》(国办秘函[2009]6号)文件中的各项要求。
(2)要求系统提供灵活的元数据管理,以能适应不同类型的信息记录需要,元数据必需符合国家相关文件的要求,并具备元数据扩展功能;提供对多种类型的元数据字段支持。定义数据层、功能层、使用层规范,同时配以编码规则管理,支持批量修改,保持良好的扩展性;
(3)要求系统提供灵活的分类管理,可自由地将采集到的信息进行多渠道分类,包括主题分类、机构分类、体裁分类及服务对象分类。同时支持分类的自由扩展。
(4)要求系统提供灵活的目录管理功能,用户可根据公众的需要定义目录的展现内容,通过定义目录节点的生成规则,从而来获取相应的数据,形成最终的人性化目录;系统支持目录推荐功能,即上级政府建立完成的目录,可以作为“模板”推荐给下级单位。
(5)要求系统能够自定义索引号编码规则,依照信息公开标准对信息进行自动编码,生成信息索引号。当编码规则发生修改时,也可制定新规则,并批量修改信息索引号。
(6)要求系统提供良好的信息管理功能,从采集、标引、审核、发布到归档,完整记录信息生命周期活动。
(7)系统提供列表、简要、细览等展现形式,显示核心元数据,包括索引号、名称、内容概述、生成日期、文号等。
(8)系统应满足信息录入和审核权限的逐级分配,强化信息源头管理,保障信息发布安全。
(9)系统具有依申请公开功能,可对依申请公开信息进行接收、受理、审核、发布,并提供统计分析等功能,访问用户可实时查询依申请公开处理状态。
(10)要求系统提供综合的绩效评估模式,包括信息公开工作量评估、依申
请公开办结率和办结质量评估。
(六)互动交流系统
系统严格遵循SOA模块化设计思想,按照“高内聚,低耦合”原则,提供全面完善的网站互动交流功能,包括领导信箱、民意征集、在线调查、咨询投诉、网上信访、在线访谈等,以解决公众在实际工作和生活中所面临的问题,更好地为公众提供服务。具体功能要求如下:
1.在线访谈系统
(1)支持图文和视频同步的在线访谈,要求具有文字直播、图片直播、音频直播及视频直播四种功能形式;
(2)要求提供良好的人机对话界面,网友通过文字形式可实时提问,管理人员采集
和审核问题,主持人转达和引导提问,嘉宾对问题实时解答;
(3)管理员可查看在线用户情况,可以通过IP或用户名来禁止用户行为,可对用户发言内容设置过滤模式。
(4)主持人、嘉宾与网友的发言区要划分明确;
(5)系统必须具有访谈预告功能,访谈预告可采用文字、图片或视频方式展示访谈背景和相关资料。
(6)访谈过程中要确保文字、图片、音频、视频的流畅;
(7)对于历史访谈,可按照日期进行归档,形成历史访谈目录,网友可调阅历史访谈。
(8)对于已经完成的访谈,管理员可继续对访谈内容进行修改和编辑。
2.领导信箱系统
(1)系统具有工作流管理功能,可自定义信件办理流程,实现从受理、转办、承办、退回、办结的全流程管理。
(2)系统具有信件办理状态实时查询功能,来信人可根据信件编码、姓名、联系电话等对信件办理状态进行查询,信箱管理人员可通过关键字、信件编码、时间、部门、信件状态等条件进行查询。
(3)前台提供“信件选登”、“信件查询”、“我要写信”等功能,写信内容需收录
姓名、昵称、身份证号码、联系电话、电子邮件、信件标题、信件内容,可上传附件材料等,具有详实的展现形式,可对敏感词进行自动屏蔽。
(4)后台提供信件的回复、发布、选登等状态的查看及信件办理状态的统计功能,提供信件的“公开/不公开”选项功能。
3.意见征集系统
(1)针对社会公众关注的热点问题或者政策制定和工作成果开展民意征集活动,民意征集的各个主题要求布局清晰、合理,方便阅览;
(2)网友可根据征集主题的内容和背景资料发表自己的建议和观点,可以查看征集结果;
(3)系统后台可实时查看所有社会公众提交的意见和建议;
(4)意见征集结束后,前台只保留征集主题、内容、结果,网友不能再进行意见和建议的提交;
(5)能对网友发表的文字信息进行安全性检查。
4.网上调查系统
(1)管理员可根据不同的调查内容新建、修改、删除调查问卷。对于每个调查问卷可以对标题、摘要、内容、选项、调查项组成结构等进行管理,可灵活设计投票问卷风格;
(2)同一调查主题,可设置多个调查项;调查项应包括单选项调查、多选项调查、附加选项(填空)等调查类型;
(3)同一IP地址在设定时间内只允许提交一次投票,杜绝恶意投票行为发生;
(4)投票结果可通过表格、柱状图、饼图等形式进行展现。
(七)数据采集系统
(1)数据采集系统借助先进的信息抓取、信息分类和信息流转技术,实现对指定网站信息(包括但不限于中央政府网站、省政府网站、重要新闻网站和平台内外所需政府信息资源)的更新监测和有效采集。
(2)系统按照不同需要,可定点、定时监测和采集所需信息,并下载信息的图片、视频及附件等相关文件,将采集信息进行准确分类、整理、筛选,通过内容推送功能自动推送到指定栏目。
(3)管理员可在后台设置抓取的范围、关键字、抓取时间等参数,系统根据设置好的抓取策略进行信息自动抓取。
(4)用户可对采集到的信息按照日期、来源、标题进行检索、浏览;可以对信息内容与图片分类保存,支持信息分类的自定义。
(5)系统支持将网页中的信息内容按标题、作者、栏目、内容等进行提取;自动过滤网页中的无用信息、广告图片等,自动过滤重复的信息。
(6)对采集的信息可进行二次编辑、审核,可向网站群内各个子站栏目进行发布。
(八)无障碍浏览系统
(1)面向听力、视力等有障碍的特殊人群提供缩放字体、缩放页面、辅助光标、文本化网页和语音个性化调整等辅助浏览功能。
(2)具有全程自动语音提示、全程语音导航交互、光标语音指读与连读、文
字放大阅读专用屏、网页图文放大缩小、高对比阅读配色器、阅读辅助光标等功能。
(3)系统需界面友好、易操作,无需安装插件,支持各种主流浏览器。
(九)智能检索系统
(1)提供专业的政府网站检索功能,对政府网站检索进行分类引导,按照政策法规、办事事项、政府文件、新闻咨询等类别对用户检索内容进行归类整理,清晰引导用户进行查阅。
(2)数据检索范围应包括站群内各业务部门、各县(市、区)网站站点,可对不同类型数据源的数据进行检索。
(3)满足即搜即用原则,支持图片、视频格式信息的检索。
(4)支持关键字搜索、日期搜索。要求提供个性化检索结果功能,如检索结果分类导航展现、检索结果按不同维度(可以按系统,站点,栏目,区县,文档类型,时间单位,相似度等)过滤展示,检索结果可进行二次搜索。
(5)具有搜索关键词自动补全能力,动态分析公众搜索关键词,按照关键词的内在逻辑关系进行自动匹配,给出搜索提示,纠正用户输入错误。
(6)具有热词自动排序和显示功能,可自动统计搜索关键词的搜索频度,将某一时间段内搜索量较高的关键词作为搜索热词,并根据热度动态自动调整排序。
(7)支持拼音搜索功能,采用词语智能拼音匹配模式,并结合关键词提醒联想功能,实现拼音和中文友好联系的搜索功能。
(8)系统支持管理员定义屏蔽词和停用词的搜索,当用户输入收录
的词汇时,系统不展示搜索结果信息。
(9)支持多个关键词搜索和整句搜索。
(10)系统使用基于文档语义的技术实现同一站点内搜索结果信息的自动排重,即“相同”的文档在索引过程中仅被索引一次,解决大量相同文档的搜索问题,提高索引效率,帮助用户快速找到搜索结果。
(11)对含有图片的信息,其搜索结果列表应显示其缩略图;
(12)系统具有检索结果优先显示置顶功能。
(十)智能推荐系统
(1)根据网站用户访问行为,结合网站数据分析,找到网站访问热点,自动聚合相关信息(即相关文件、政策、咨询类信息),实现网站信息智能推荐。
(2)可根据关键词、热词等条件分析信息之间的直接联系或间接关系,自动分析、梳理、聚类展示。
(3)可自动进行专题信息汇聚,通过数据采集技术,获取相关信息进行集中
管理和存储,根据用户访问习惯,进行数据的重组、拼装,聚合,形成专题栏目;也可根据各专题的关注度,对推荐专题及相应的页面表现位置进行展示顺序的自动调整,供公众访问。

(十一)智能问答系统
(1)能够深度挖掘网站群信息内容,建立和完善智能应答知识库,可根据用户自定义规则,通过信息聚合技术,按照信息采集、聚合、挖掘和检索流程,实现跨部门、跨行业的信息整合与资源共享。
(2)能够自动将咨询问题保存入库,可自定义站点检索到相关咨询问题,可实时预处理用户的输入信息,根据输入内容与后台检索引擎交互,自动纠错,实时提示相关信息,引导类似问题进行解答。
(3)可利用信息资源库及应答知识库中的信息,即时自动回答用户提出的问题,向用户展示相关度较高的信息。
(4)能够充分使用站群内所有站点的信息资源,咨询问题答复内容可由平台下多个站点信息数据组成关联页面提供给用户。
(5)能够实现多样化展现方式,可以预分类政务资源,将多个网站中的同类栏目合并为一个分类,为用户按分类展现更全面精准的搜索结果。
(6)要求具备自学习功能,能够自动丰富知识库,对于无法解决的问题可自动转人工解答。
(十二)移动门户系统
(1)要求采用HTML5网站页面应自适应技术,能够实现不同移动终端(例如苹果、安卓系统) 访问移动门户时自适应展示,能够在各种访问终端下保持完整良好的页面布局和内容可读性。
(2)要求移动端与PC端使用同一域名进行访问,系统自动识别访问终端并自适应页面展示效果。
(3)要求移动门户所展示信息不再二次录入,统一由站点内容管理系统提供,以保证数据来源的统一性。
(4)要求提供最新新闻、政务公开、互动交流、解读回应、民意调查、舆论引导、政务服务、政府办公等信息内容的展示。
(5)要求支持可定制栏目访问。
五、其他需求说明
1.网站兼容性要求
要求网站页面具有很好的兼容性,支持IE、Chrome、FireFox和其他主流浏览器,支持安卓和IOS移动终端浏览。
2.UI/UE设计
(1)界面设计需要突出地方特色
(2)文字,图形色彩统一,搭配合理,界面清楚整洁,层次结构清楚。
(3)统一首页和其他各级页面的排版风格。
(4)页面富有时代气息和美感,色彩搭配稳重、合理、大气。
(5)多媒体、动画页面要求丰富而生动。
3.子站设计要求
(1)满足各子站个性化页面设计需求,根据各部门网站管理人员要求进行设计与实施。
(2)本次页面设计主要从以下几个方面进行规划:页面风格、页面人性化和易用性、页面内容、页面结构等,围绕信息公开、办事服务、互动交流等功能定位,设计门户网站页面框架,清晰、合理、科学展现网站内容,避免累赘和页面冗余。
4.历史数据迁移要求
(1)要求提出详尽的网站数据迁移方案。
(2)要求将实施集约化的网站的全部数据,收录
各站点栏目信息、新闻信息、公开信息、互动信息、用户信息、用户对应权限、图片、附件、多媒体文件等数据平稳迁移至德阳市政府网站集约化平台,确保不丢失任何有效数据,处理好新网站栏目信息与历史数据的对应关系。
(3)要求保证集约化网站切换的平滑过渡,做好数据的同步更新。
5.硬件及部署要求
投标人必须详细列出项目的硬件需求,即政务云平台虚拟机数量及资源参数,以及系统的部署方案。
六、项目实施、培训
(一)项目竣工验收要求
按中华人民共和国现行项目建设规范和合同规定的验收评定标准等要求进行验收。
根据施工进度情况,按照标志性工作成果划分,分期进行检查、验收。
2.实施要求
投标人应具体说明实施本项目拟采用方案,确保至少两人驻场实施,团队
组织方式和保障力量,中标单位实施过程中出现资源、速度、质量协调控制不力、采购方有权更换责任人。
3.测试要求
投标供应商在实施过程中必须制定整体的测试方案,保证各子系统联接正确,数据传送正常。测试方案要明确测试关键点,分单元测试、边缘测试、整体测试等。测试方法应包括模块测试、回归测试、压力测试、性能测试、功能测试、数据测试、安全测试、系统测试等。测试内容必须包括功能要求、可靠性、安全性、可扩充性、可维护性、平台移植性、整体性能、与其他平台接口等,系统试运行期不低于三个月。
4.验收要求
投标供应商应负责在项目用户验收前将系统的全部相关的系统软件,各阶段开发文档,平台及其他应用系统交互接口功能的源代码和数据表结构,以及有关产品的系统说明书、安装手册、维护手册、技术文件、资料及安装、测试、验收报告等文档汇集成册交付项目单位。只有文档齐全后方可组织验收。对整个项目的验收包括检查整个系统是否实现了招标人所要求的功能,是否与投标供应商提出的解决方案中既定目标功能完全一致。
投标供应商必须根据系统总体设计方案提出验收细则和验收文档清单(收录
需求调研、系统分析、软件设计、软件开发、系统测试、实施上线、运行维护等阶段),招标人将根据验收方案对系统每个部分逐一进行项目验收。
5.文档要求
投标供应商提供的技术文件应该真实、全面、完整、详细,应以中文书写。投标供应商提供的技术文件应是能满足系统运行所需的安装调试、操作使用及维护管理等的详细技术资料。
投标供应商应负责在项目最终验收时将系统从合同签定之日起所有关于本项目的文档资料(包括初步验收文档的版本更新和试运行期产生的文档)交付采购人。
招标人认为必要的其他文档。
(二)培训承诺
供应商技术培训及相关系统的基础培训,内容包括软件安装调试及初始化、使用等的基本操作培训。供应商须制定出详细完整的培训方案,包括培训的具体内容、培训方式(现场培训或集中培训)、人数、教师、日程安排、资料等。应能使采购人相关人员独立操作、维护、管理,确保系统能正常安全运行。
供应商应提供的详细培训方案必须包括:(1)集群管理员操作培训;(2)各
部门管理员、应用软件操作员等的基本操作培训。
实际培训时间和地点按中标人与采购人商定的为准。
七、售后服务技术需求
售后服务包括但不限于下列服务:
1.网站页面优化服务
(1)网站信息维护培训指导。包括网站信息的增、删、查、改等操作的指导和问题解答;添加图片及附件操作指导;网站静态页面生成等操作指导。
(2)网站页面的图片、文字排版和调整。包括网页图片的制作、更换、布局调整,文字的内容、格式、链接等的修改。
(3)保证网站页面显示正常。解决文字或图片内容撑出、内容不显示或显示不正确、页面文字出现乱码、页面出现错误报告、页面在有的浏览器上显示不正确、页面没有找到、网页不能访问等问题。
2. 网站内容管理平台及选件维护服务
(1)对国家及省政府最新要求的响应
及时响应国家及省政府对政府门户网站、集约化建设及互联网+政务服务相关内容的建设要求,对门户网站前台服务内容进行调整。
(2)模版维护服务
每月一次。包括:定期对现有网站巡检,对现有的模版存在的不足进行调优,如排版不合适、格式不统一、色调不一致、内容块错位、字体大小不一致、文字没对齐等情况,但不涉及到页面新的风格。对现有的模版调整,包括添加删除专题链接、页面局部细节样式调整,错字,错链,图标替换等,提交《网站模版优化记录》。
(3)常规检查维护
每月一次。包括:各服务器运行状况、存储空间状况、软件运行状况、备份系统状况等。并提出现有问题和解决方法,并提交《网站常规检查维护运行状况报告》。
(4)专题维护
根据用户需求提供专题制作协助服务。
(5)产品版本升级
不定期提供。主要帮助客户不断完善产品的功能和系统稳定性。每次升级要对升级的版本、工作做好日志记录,并提交《版本升级记录表》。
3、技术运维服务
(1)备份服务
对门户网站系统涉及到的内容进行备份,包括数据库每天备份、网站应用程
序备份、网站所有补丁备份、项目涉及到的文档进行备份等。提交《系统备份检查表》,内容包括备份联系人、联系电话、时间、路径、内容等。
(2)错误日志分析
对网站涉及到的所有日志(包括中间件等产品)记录要进行定期查看,找出错误内容。提交《日志错误分析表》。
4、服务质量要求
(1)质量保证期限及费用
系统验收合格、双方签署验收书之日起,为本次建设内容中的子站提供至少1年维保服务。在系统维护期内,开发的软件应提供免费升级服务。维保服务到期后,应承诺对系统的升级仅收取成本费。
(2)售后服务方案
中标人需要提供详细的售后服务方案,包括服务人员、措施、应急预案及相关流程等内容。在安装、调试及系统免费维护期内,必须提供系统故障的应急处理方案。承诺所投产品系统不存在“后门”问题。
(3)服务响应要求
中标人承诺提供现场服务人员,且能够提供7*24小时响应服务,一般问题30分钟之内解决,重大问题4小时内解决。
说明:
1、欢迎供应商提供服务保障等于或高于该基本要求的服务。
2、本章的要求不能作为资格性条件要求评标,如存在资格性条件要求,应当认定招标文件编制存在重大缺陷,评标委员会应当停止评标。
干货教程:【Python】抖音采集话题/音乐/用户作品和喜欢+调用Aria2下载+fire
采集交流 • 优采云 发表了文章 • 0 个评论 • 247 次浏览 • 2022-11-22 16:26
抖音集合开源仓库
介绍
Python 获取数据 + Vue 写入接口 + Aria2 下载
根据抖音的各种链接或ID,通过网页界面采集视频作品并下载到本地计算机。
支持用户主页链接或sec_uid/主题挑战和音乐配乐链接或ID。
支持下载喜欢的列表(需要喜欢的列表可见)。
使用0x00安装依赖项
在程序目录中打开命令行,然后输入
pip install -r requirements.txt
0x01 使用界面
双击打开启动.bat,或在程序目录中打开命令行,输入
python ui.py
0x02 直接修改 douyin.py 中的相关参数
完全不懂 Python 的朋友使用命令行或操作界面。
0x03 使用 exec.py 直接从命令行运行以查看命令列表,或使用 -h 参数查看帮助
python exec.py
python exec.py -h
python exec.py download -h
python exec.py download_batch -h
使用函数名称调用程序
--type 指定下载类型,默认值:--type=user
--limit 指定采集数量,默认值:--limit=0(不限制)
例如,采集
用户的所有作品:
python exec.py download https://v.douyin.com/xxxx/
python exec.py download 用户的secuid
例如,采集
用户喜欢的前 10 部作品:
python exec.py download MS4wLjABAAAAl7TJWjJJrnu11IlllB6Mi5V9VbAsQo1N987guPjctc8 --type=like --limit=10
python exec.py download 用户的secuid
例如,采集
音乐配乐的前 10 首作品:
python exec.py download https://v.douyin.com/xxxx/ --type=music --limit=10
python exec.py download 音乐ID --type=music --limit=10
TODO知识点:抖音相关Aria2相关Python相关命令行模块、火相关UI模块、pywebview相关抖音集合部分源码
# -*- encoding: utf-8 -*-
'''
@File : douyin.py
@Time : 2021年03月12日 18:16:57 星期五
@Author : erma0
@Version : 1.0
@Link : https://erma0.cn
@Desc : 抖音用户作品采集
'''
import json
import os
import time
from urllib.parse import parse_qs, urlparse
import requests
from download import Download
class Douyin(object):
"""
抖音用户类
采集作品列表
"""
def __init__(self, param: str, limit: int = 0):
"""
初始化用户信息
参数自动判断:ID/URL
"""
self.limit = limit
self.http = requests.Session()
self.url = ''
self.type = 'unknow'
self.download_path = '暂未定义目录'
# ↑ 预定义属性,避免调用时未定义 ↑
self.param = param.strip()
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq' # sign可以固定
self.__get_type() # 判断当前任务类型:链接/ID
self.aria2 = Download() # 初始化Aria2下载服务,先不指定目录了,在设置文件名的时候再加入目录
self.has_more = True
self.finish = False
# 字典格式方便入库用id做key/取值/修改对应数据,但是表格都接收数组
self.videosL = [] #列表格式
# self.videos = {} #字典格式
self.gids = {} # gid和作品序号映射
def __get_type(self):
"""
判断当前任务类型
链接/ID
"""
if '://' in self.param: # 链接
self.__url2redirect()
else: # ID
self.id = self.param
def __url2redirect(self):
"""
取302跳转地址
短连接转长链接
"""
headers = { # 以前作品需要解析去水印,要用到移动端UA,现在不用了
'User-Agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/89.0.4389.82'
}
try:
r = self.http.head(self.param, headers=headers, allow_redirects=False)
self.url = r.headers['Location']
except:
self.url = self.param
def __url2id(self):
try:
self.id = urlparse(self.url).path.split('/')[3]
except:
self.id = ''
def __url2uid(self):
try:
<p>
query = urlparse(self.url).query
self.id = parse_qs(query)['sec_uid'][0]
except:
self.id = ''
def get_sign(self):
"""
网页sign算法,现在不需要了,直接固定
"""
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq'
return self.sign
def get_user_info(self):
"""
取用户信息
查询结果在 self.user_info
"""
if self.url:
self.__url2uid()
url = 'https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid=' + self.id
try:
res = self.http.get(url).json()
info = res.get('user_info', dict())
except:
info = dict()
self.user_info = info
# 下载路径
username = '{}_{}_{}'.format(self.user_info.get('short_id', '0'),
self.user_info.get('nickname', '无昵称'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_challenge_info(self):
"""
取话题挑战信息
查询结果在 self.challenge_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/challenge/info/?ch_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('ch_info', dict())
except:
info = dict()
self.challenge_info = info
# 话题挑战下载路径
username = '{}_{}_{}'.format(self.challenge_info.get('cid', '0'),
self.challenge_info.get('cha_name', '无标题'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_music_info(self):
"""
取音乐原声信息
查询结果在 self.music_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/music/info/?music_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('music_info', dict())
except:
info = dict()
self.music_info = info
# 音乐原声下载路径
username = '{}_{}_{}'.format(self.music_info.get('mid', '0'), self.music_info.get('title', '无标题'),
self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def crawling_users_post(self):
"""
采集用户作品
"""
self.type = 'post'
self.__crawling_user()
def crawling_users_like(self):
"""
采集用户喜欢
"""
self.type = 'like'
self.__crawling_user()
def crawling_challenge(self):
"""
采集话题挑战
"""
self.type = 'challenge'
self.get_challenge_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... QFzfg
url = 'https://www.iesdouyin.com/web/api/v2/challenge/aweme/'
cursor = '0'
while self.has_more:
params = {
"ch_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('话题挑战采集出错')
print('话题挑战采集完成')
def crawling_music(self):
"""
采集音乐原声
"""
self.type = 'music'
self.get_music_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... OVC5j
url = 'https://www.iesdouyin.com/web/api/v2/music/list/aweme/'
cursor = '0'
while self.has_more:
params = {
"music_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('音乐原声采集出错')
print('音乐原声采集完成')
def __crawling_user(self):
"""
采集用户作品/喜欢
"""
self.get_user_info() # 取当前用户信息,昵称用做下载目录
max_cursor = 0
# https://www.iesdouyin.com/web/ ... tk%3D
# https://www.iesdouyin.com/web/ ... tk%3D
url = 'https://www.iesdouyin.com/web/api/v2/aweme/{}/'.format(self.type)
while self.has_more:
params = {
"sec_uid": self.id,
"count": "21",
"max_cursor": max_cursor,
"aid": "1128",
"_signature": self.sign,
"dytk": ""
}
try:
res = self.http.get(url, params=params).json()
max_cursor = res['max_cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('作品采集出错')
print('作品采集完成')
def __append_videos(self, res):
"""
数据入库
"""
if res.get('aweme_list'):
for item in res['aweme_list']:
info = item['statistics']
info.pop('forward_count')
info.pop('play_count')
info['desc'] = Download.title2path(item['desc']) # 需提前处理非法字符串
info['uri'] = item['video']['play_addr']['uri']
info['play_addr'] = item['video']['play_addr']['url_list'][0]
info['dynamic_cover'] = item['video']['dynamic_cover']['url_list'][0]
info['status'] = 0 # 下载进度状态;等待下载:0,下载中:0.xx;下载完成:1
# 列表格式
self.videosL.append(info)
# 字典格式
# self.videos[info['aweme_id']] = info
# 此处可以直接添加下载任务,不过考虑到下载占用网速,影响采集过程,所以采集完再下载
if self.limit:
more = len(self.videos) - self.limit
if more >= 0:
# 如果给出了限制采集数目,超出的删除后直接返回
self.has_more = False
# 列表格式
self.videosL = self.videosL[:self.limit]
# 字典格式
# for i in range(more):
# self.videos.popitem()
# return
else: # 还有作品的情况下没返回数据则进入这里
print('未采集完成,但返回作品列表为空')
def download_all(self):
"""
作品抓取完成后,统一添加下载任务
可选择在外部注册回调函数,监听下载任务状态
"""
for id, video in enumerate(self.videosL):
# for id, video in self.videos.items():
gid = self.aria2.download(url=video['play_addr'],
filename='{}/{}_{}.mp4'.format(self.download_path, video['aweme_id'],
video['desc'])
# ,options={'gid': id} # 指定gid
)
self.gids[gid] = id # 因为传入gid必须16位,所以就不指定gid了,另存一个字典映射
print('下载任务投递完成')</p>
技巧:拼多多大神是怎么复制抖音爆款上传到自己店铺的?这个工具无需授权
随着抖音小店的火爆,不少拼多多商家开始在抖音上寻找爆款商品,急需一款抖音宝到拼多多小店收款的工具。
今天要跟大家分享的是一款支持斗尚拼的工具。不仅可以采集复制宝物上架,还可以采集宝物进行分析优化。下面我主要介绍大家用的比较多的3个工具:
①宝贝复制:一键复制抖音小店宝贝上传至拼多多,支持批量采集
,可快速完成发货!
工具支持多次开启,无需授权,不绑定电脑。店铺团版支持5-200家店铺!
②图片处理器:抖音店铺宝贝图片一键采集
工具限时免费,快来试用吧~
本工具可以一键采集下载淘喜、拼多多、京东、豆店宝的主图、sku图、详情页、750详情图、主图视频、搜索列表展示图等,还可以自动拼接详情图片。
宝贝优化过程中,卖家可以采集竞品宝贝图片进行分析,并一键导出数据,方便美工学习和模仿。
③宝贝详情(评论/sku/买家秀/问大家)分析器:一键采集
抖音店铺宝贝评论/sku/买家秀/问大家
工具限时免费,快来试用吧~
一键采集
淘喜、拼多多、京东、豆店等各大平台评论、sku占比分析、下载买家秀等,并支持一键拆分评论根、根占比分析、挖掘产品卖点。重点采集
问大家,分析买家痛点。
工具免费分享,有需要的卖家可以免费试用!
下面,小编就为大家详细讲解一下拼多多宝贝复制工具的使用方法:
1.采集
宝贝
数据来源包括淘宝/天猫、1688、抖音小店、拼多多批发等平台。也就是说,卖家可以在淘宝、1688、抖音小店、批发商上采集
宝贝并上传到自己的店铺。
工具限时免费,快来试用吧~
淘宝平台采集宝贝数据,需要登录普通买家账号。如果采集
太多,可以在多个帐户之间切换。1688和淘宝账号一样。
无需登录即可采集
拼多多批发宝贝数据。如果您采集
了拼多多宝贝的数据,可以通过手机号和token登录。
多多宝的采集
方式可以通过关键词和分类采集
,也可以全店采集
、其他平台采集
、复制或批量导入。
2.上传配置
宝贝收好后,进入配置页面:
工具限时免费,快来试用吧~
还没有收到工具的卖家可以免费试用,还有限时会员权限!
一、价格
拼多多上的商品价格包括单价、单价、折扣价、最低SKU价等,采集
淘宝宝贝一般默认为折扣价,折扣价显示如下图:
如果优惠价格是临时活动,没有优惠后,源链接价格会上涨。
拼多多默认单价,可以通过加百分比、加减固定金额、指定价格等方式设置。
工具限时免费,快来试用吧~
2. 图片
主图可以默认不处理,也可以选择以下几张作为主图。采集到的淘宝宝贝只有5张主图,工具可以自动补全10张主图。
细节图也可以不处理,也可以去掉指定位置的地图,保留编号,也可以插入自定义细节图,自定义细节加水印。
对于采集到的淘宝宝贝,高度超过1500的详细图片可以自动压缩分割,压缩可以减少图片空间的占用。
注意:处理图片时,一定要勾选【使用图片空间上传图片】!如果你复制视频,你需要有上传视频的权限!
3.标题
标题设置包括标题清词(启用本地自定义过滤)、标题过滤词、标题替换(宝贝ID=新标题)等。标题可以通过添加前缀/后缀或直接替换来处理。
可以设置新标题只保留采集
宝贝标题前的字符数。特殊分类支持长标题校验【上传宝贝标题支持10个字符】。
标题重组可以分裂根,随机打乱和重组。
4.类别
因为商品类目是跨平台的,只是部分商品的类目分类会有所不同。需要手动指定四级类别(每个类别级别都必须选择),但大多数情况下默认匹配上一个类别。
5.单品
SKU规格配置,不同平台有不同的SKU属性,可以过滤/替换符号和违禁词,自动分割SKU名称和备注,商家也可以自定义SKU。
注意:如果没有sku,默认添加一个sku,最大数量限制为24个!
6.属性
商品类型可根据实际情况选择,如普通商品、虚拟商品、进口商品、积分卡或海外抄送个人邮寄等。
设置品牌(可以选择不使用该品牌或更换其他品牌),设置产品编码,是否支持假一赔十,7天无理由,坏了赔,是否秒-手/虚拟产品,您还可以自定义属性。
7. 运输
商家可以设置物流重量、物流类型、发货时间。
还没有收到工具的卖家,点击↓即可免费试用!
3.上传
点击保存设置后,会跳转至上传页面,如下图:
工具限时免费,快来试用吧~
卖家可以通过浏览器操作将宝贝信息上传至列表,保存至草稿箱,或直接上架。如果上传失败,则不会保存到草稿箱。
此外,该页面还可以清空上传列表,删除勾选的宝贝,去除上传成功导出失败的链接,选择运费模板,一键勾选跳过重复上传的宝贝。
繁琐的操作也变得简单方便。通过工具装货,不仅可以解放双手,还可以减少失误,大大提高工作效率。
4.宝贝管理
对于店铺宝贝,卖家可以在宝贝列表中选择时间范围内的店铺、类目、商品id数据,批量下架、修改价格和库存等,一键删除/清空宝贝。
工具限时免费,快来试用吧~
可设置清洁宝贝的创建时间、访问人数、采集
人数、销量等,并可一键导出数据,查看修改失败记录。
注:右键列表可以查看上一个宝贝的链接。
五、服务保障
这款宝贝复制工具不仅功能稳定,而且还有完善的服务体系。多名技术人员24/7在线,随时处理用户问题。
无论是工具安装问题,还是日常操作问题,卖家总能找到工作人员实时沟通。
同时,工具技术团队会定期采集
用户需求,进行有针对性的开发和研发,并保持工具功能版本不断更新,满足大家对商品的需求。
如果您需要工具,可以免费试用!
以上是宝贝复制工具的概况。功能稳定,服务保障完善。商户可以轻松完成装货操作,大大提高工作效率。 查看全部
干货教程:【Python】抖音采集话题/音乐/用户作品和喜欢+调用Aria2下载+fire
抖音集合开源仓库
介绍
Python 获取数据 + Vue 写入接口 + Aria2 下载
根据抖音的各种链接或ID,通过网页界面采集视频作品并下载到本地计算机。
支持用户主页链接或sec_uid/主题挑战和音乐配乐链接或ID。
支持下载喜欢的列表(需要喜欢的列表可见)。
使用0x00安装依赖项
在程序目录中打开命令行,然后输入
pip install -r requirements.txt
0x01 使用界面
双击打开启动.bat,或在程序目录中打开命令行,输入
python ui.py
0x02 直接修改 douyin.py 中的相关参数
完全不懂 Python 的朋友使用命令行或操作界面。
0x03 使用 exec.py 直接从命令行运行以查看命令列表,或使用 -h 参数查看帮助
python exec.py
python exec.py -h
python exec.py download -h
python exec.py download_batch -h
使用函数名称调用程序
--type 指定下载类型,默认值:--type=user
--limit 指定采集数量,默认值:--limit=0(不限制)
例如,采集
用户的所有作品:
python exec.py download https://v.douyin.com/xxxx/
python exec.py download 用户的secuid
例如,采集
用户喜欢的前 10 部作品:
python exec.py download MS4wLjABAAAAl7TJWjJJrnu11IlllB6Mi5V9VbAsQo1N987guPjctc8 --type=like --limit=10
python exec.py download 用户的secuid
例如,采集
音乐配乐的前 10 首作品:
python exec.py download https://v.douyin.com/xxxx/ --type=music --limit=10
python exec.py download 音乐ID --type=music --limit=10
TODO知识点:抖音相关Aria2相关Python相关命令行模块、火相关UI模块、pywebview相关抖音集合部分源码
# -*- encoding: utf-8 -*-
'''
@File : douyin.py
@Time : 2021年03月12日 18:16:57 星期五
@Author : erma0
@Version : 1.0
@Link : https://erma0.cn
@Desc : 抖音用户作品采集
'''
import json
import os
import time
from urllib.parse import parse_qs, urlparse
import requests
from download import Download
class Douyin(object):
"""
抖音用户类
采集作品列表
"""
def __init__(self, param: str, limit: int = 0):
"""
初始化用户信息
参数自动判断:ID/URL
"""
self.limit = limit
self.http = requests.Session()
self.url = ''
self.type = 'unknow'
self.download_path = '暂未定义目录'
# ↑ 预定义属性,避免调用时未定义 ↑
self.param = param.strip()
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq' # sign可以固定
self.__get_type() # 判断当前任务类型:链接/ID
self.aria2 = Download() # 初始化Aria2下载服务,先不指定目录了,在设置文件名的时候再加入目录
self.has_more = True
self.finish = False
# 字典格式方便入库用id做key/取值/修改对应数据,但是表格都接收数组
self.videosL = [] #列表格式
# self.videos = {} #字典格式
self.gids = {} # gid和作品序号映射
def __get_type(self):
"""
判断当前任务类型
链接/ID
"""
if '://' in self.param: # 链接
self.__url2redirect()
else: # ID
self.id = self.param
def __url2redirect(self):
"""
取302跳转地址
短连接转长链接
"""
headers = { # 以前作品需要解析去水印,要用到移动端UA,现在不用了
'User-Agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/89.0.4389.82'
}
try:
r = self.http.head(self.param, headers=headers, allow_redirects=False)
self.url = r.headers['Location']
except:
self.url = self.param
def __url2id(self):
try:
self.id = urlparse(self.url).path.split('/')[3]
except:
self.id = ''
def __url2uid(self):
try:
<p>

query = urlparse(self.url).query
self.id = parse_qs(query)['sec_uid'][0]
except:
self.id = ''
def get_sign(self):
"""
网页sign算法,现在不需要了,直接固定
"""
self.sign = 'TG2uvBAbGAHzG19a.rniF0xtrq'
return self.sign
def get_user_info(self):
"""
取用户信息
查询结果在 self.user_info
"""
if self.url:
self.__url2uid()
url = 'https://www.iesdouyin.com/web/api/v2/user/info/?sec_uid=' + self.id
try:
res = self.http.get(url).json()
info = res.get('user_info', dict())
except:
info = dict()
self.user_info = info
# 下载路径
username = '{}_{}_{}'.format(self.user_info.get('short_id', '0'),
self.user_info.get('nickname', '无昵称'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_challenge_info(self):
"""
取话题挑战信息
查询结果在 self.challenge_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/challenge/info/?ch_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('ch_info', dict())
except:
info = dict()
self.challenge_info = info
# 话题挑战下载路径
username = '{}_{}_{}'.format(self.challenge_info.get('cid', '0'),
self.challenge_info.get('cha_name', '无标题'), self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def get_music_info(self):
"""
取音乐原声信息
查询结果在 self.music_info
"""
if self.url:
self.__url2id()
url = 'https://www.iesdouyin.com/web/api/v2/music/info/?music_id=' + self.id
try:
res = self.http.get(url).json()
info = res.get('music_info', dict())
except:
info = dict()
self.music_info = info
# 音乐原声下载路径
username = '{}_{}_{}'.format(self.music_info.get('mid', '0'), self.music_info.get('title', '无标题'),
self.type)
self.download_path = Download.title2path(username) # 需提前处理非法字符串
def crawling_users_post(self):
"""
采集用户作品
"""
self.type = 'post'
self.__crawling_user()
def crawling_users_like(self):
"""
采集用户喜欢
"""
self.type = 'like'
self.__crawling_user()
def crawling_challenge(self):
"""
采集话题挑战
"""
self.type = 'challenge'
self.get_challenge_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... QFzfg
url = 'https://www.iesdouyin.com/web/api/v2/challenge/aweme/'
cursor = '0'
while self.has_more:
params = {
"ch_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('话题挑战采集出错')

print('话题挑战采集完成')
def crawling_music(self):
"""
采集音乐原声
"""
self.type = 'music'
self.get_music_info() # 取当前信息,用做下载目录
# https://www.iesdouyin.com/web/ ... OVC5j
url = 'https://www.iesdouyin.com/web/api/v2/music/list/aweme/'
cursor = '0'
while self.has_more:
params = {
"music_id": self.id,
"count": "21", # 可调大 初始值:9
"cursor": cursor,
"aid": "1128",
"screen_limit": "3",
"download_click_limit": "0",
"_signature": self.sign
}
try:
res = self.http.get(url, params=params).json()
cursor = res['cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('音乐原声采集出错')
print('音乐原声采集完成')
def __crawling_user(self):
"""
采集用户作品/喜欢
"""
self.get_user_info() # 取当前用户信息,昵称用做下载目录
max_cursor = 0
# https://www.iesdouyin.com/web/ ... tk%3D
# https://www.iesdouyin.com/web/ ... tk%3D
url = 'https://www.iesdouyin.com/web/api/v2/aweme/{}/'.format(self.type)
while self.has_more:
params = {
"sec_uid": self.id,
"count": "21",
"max_cursor": max_cursor,
"aid": "1128",
"_signature": self.sign,
"dytk": ""
}
try:
res = self.http.get(url, params=params).json()
max_cursor = res['max_cursor']
self.has_more = res['has_more']
self.__append_videos(res)
except:
print('作品采集出错')
print('作品采集完成')
def __append_videos(self, res):
"""
数据入库
"""
if res.get('aweme_list'):
for item in res['aweme_list']:
info = item['statistics']
info.pop('forward_count')
info.pop('play_count')
info['desc'] = Download.title2path(item['desc']) # 需提前处理非法字符串
info['uri'] = item['video']['play_addr']['uri']
info['play_addr'] = item['video']['play_addr']['url_list'][0]
info['dynamic_cover'] = item['video']['dynamic_cover']['url_list'][0]
info['status'] = 0 # 下载进度状态;等待下载:0,下载中:0.xx;下载完成:1
# 列表格式
self.videosL.append(info)
# 字典格式
# self.videos[info['aweme_id']] = info
# 此处可以直接添加下载任务,不过考虑到下载占用网速,影响采集过程,所以采集完再下载
if self.limit:
more = len(self.videos) - self.limit
if more >= 0:
# 如果给出了限制采集数目,超出的删除后直接返回
self.has_more = False
# 列表格式
self.videosL = self.videosL[:self.limit]
# 字典格式
# for i in range(more):
# self.videos.popitem()
# return
else: # 还有作品的情况下没返回数据则进入这里
print('未采集完成,但返回作品列表为空')
def download_all(self):
"""
作品抓取完成后,统一添加下载任务
可选择在外部注册回调函数,监听下载任务状态
"""
for id, video in enumerate(self.videosL):
# for id, video in self.videos.items():
gid = self.aria2.download(url=video['play_addr'],
filename='{}/{}_{}.mp4'.format(self.download_path, video['aweme_id'],
video['desc'])
# ,options={'gid': id} # 指定gid
)
self.gids[gid] = id # 因为传入gid必须16位,所以就不指定gid了,另存一个字典映射
print('下载任务投递完成')</p>
技巧:拼多多大神是怎么复制抖音爆款上传到自己店铺的?这个工具无需授权
随着抖音小店的火爆,不少拼多多商家开始在抖音上寻找爆款商品,急需一款抖音宝到拼多多小店收款的工具。
今天要跟大家分享的是一款支持斗尚拼的工具。不仅可以采集复制宝物上架,还可以采集宝物进行分析优化。下面我主要介绍大家用的比较多的3个工具:
①宝贝复制:一键复制抖音小店宝贝上传至拼多多,支持批量采集
,可快速完成发货!
工具支持多次开启,无需授权,不绑定电脑。店铺团版支持5-200家店铺!
②图片处理器:抖音店铺宝贝图片一键采集
工具限时免费,快来试用吧~
本工具可以一键采集下载淘喜、拼多多、京东、豆店宝的主图、sku图、详情页、750详情图、主图视频、搜索列表展示图等,还可以自动拼接详情图片。
宝贝优化过程中,卖家可以采集竞品宝贝图片进行分析,并一键导出数据,方便美工学习和模仿。
③宝贝详情(评论/sku/买家秀/问大家)分析器:一键采集
抖音店铺宝贝评论/sku/买家秀/问大家
工具限时免费,快来试用吧~
一键采集
淘喜、拼多多、京东、豆店等各大平台评论、sku占比分析、下载买家秀等,并支持一键拆分评论根、根占比分析、挖掘产品卖点。重点采集
问大家,分析买家痛点。
工具免费分享,有需要的卖家可以免费试用!
下面,小编就为大家详细讲解一下拼多多宝贝复制工具的使用方法:
1.采集
宝贝
数据来源包括淘宝/天猫、1688、抖音小店、拼多多批发等平台。也就是说,卖家可以在淘宝、1688、抖音小店、批发商上采集
宝贝并上传到自己的店铺。
工具限时免费,快来试用吧~
淘宝平台采集宝贝数据,需要登录普通买家账号。如果采集
太多,可以在多个帐户之间切换。1688和淘宝账号一样。
无需登录即可采集
拼多多批发宝贝数据。如果您采集
了拼多多宝贝的数据,可以通过手机号和token登录。
多多宝的采集
方式可以通过关键词和分类采集
,也可以全店采集
、其他平台采集
、复制或批量导入。
2.上传配置
宝贝收好后,进入配置页面:

工具限时免费,快来试用吧~
还没有收到工具的卖家可以免费试用,还有限时会员权限!
一、价格
拼多多上的商品价格包括单价、单价、折扣价、最低SKU价等,采集
淘宝宝贝一般默认为折扣价,折扣价显示如下图:
如果优惠价格是临时活动,没有优惠后,源链接价格会上涨。
拼多多默认单价,可以通过加百分比、加减固定金额、指定价格等方式设置。
工具限时免费,快来试用吧~
2. 图片
主图可以默认不处理,也可以选择以下几张作为主图。采集到的淘宝宝贝只有5张主图,工具可以自动补全10张主图。
细节图也可以不处理,也可以去掉指定位置的地图,保留编号,也可以插入自定义细节图,自定义细节加水印。
对于采集到的淘宝宝贝,高度超过1500的详细图片可以自动压缩分割,压缩可以减少图片空间的占用。
注意:处理图片时,一定要勾选【使用图片空间上传图片】!如果你复制视频,你需要有上传视频的权限!
3.标题
标题设置包括标题清词(启用本地自定义过滤)、标题过滤词、标题替换(宝贝ID=新标题)等。标题可以通过添加前缀/后缀或直接替换来处理。
可以设置新标题只保留采集
宝贝标题前的字符数。特殊分类支持长标题校验【上传宝贝标题支持10个字符】。
标题重组可以分裂根,随机打乱和重组。
4.类别
因为商品类目是跨平台的,只是部分商品的类目分类会有所不同。需要手动指定四级类别(每个类别级别都必须选择),但大多数情况下默认匹配上一个类别。
5.单品
SKU规格配置,不同平台有不同的SKU属性,可以过滤/替换符号和违禁词,自动分割SKU名称和备注,商家也可以自定义SKU。
注意:如果没有sku,默认添加一个sku,最大数量限制为24个!
6.属性

商品类型可根据实际情况选择,如普通商品、虚拟商品、进口商品、积分卡或海外抄送个人邮寄等。
设置品牌(可以选择不使用该品牌或更换其他品牌),设置产品编码,是否支持假一赔十,7天无理由,坏了赔,是否秒-手/虚拟产品,您还可以自定义属性。
7. 运输
商家可以设置物流重量、物流类型、发货时间。
还没有收到工具的卖家,点击↓即可免费试用!
3.上传
点击保存设置后,会跳转至上传页面,如下图:
工具限时免费,快来试用吧~
卖家可以通过浏览器操作将宝贝信息上传至列表,保存至草稿箱,或直接上架。如果上传失败,则不会保存到草稿箱。
此外,该页面还可以清空上传列表,删除勾选的宝贝,去除上传成功导出失败的链接,选择运费模板,一键勾选跳过重复上传的宝贝。
繁琐的操作也变得简单方便。通过工具装货,不仅可以解放双手,还可以减少失误,大大提高工作效率。
4.宝贝管理
对于店铺宝贝,卖家可以在宝贝列表中选择时间范围内的店铺、类目、商品id数据,批量下架、修改价格和库存等,一键删除/清空宝贝。
工具限时免费,快来试用吧~
可设置清洁宝贝的创建时间、访问人数、采集
人数、销量等,并可一键导出数据,查看修改失败记录。
注:右键列表可以查看上一个宝贝的链接。
五、服务保障
这款宝贝复制工具不仅功能稳定,而且还有完善的服务体系。多名技术人员24/7在线,随时处理用户问题。
无论是工具安装问题,还是日常操作问题,卖家总能找到工作人员实时沟通。
同时,工具技术团队会定期采集
用户需求,进行有针对性的开发和研发,并保持工具功能版本不断更新,满足大家对商品的需求。
如果您需要工具,可以免费试用!
以上是宝贝复制工具的概况。功能稳定,服务保障完善。商户可以轻松完成装货操作,大大提高工作效率。
解决方案:服务器监控——Cacti(全新版)
采集交流 • 优采云 发表了文章 • 0 个评论 • 130 次浏览 • 2022-11-22 09:19
MariaDB-client MariaDB-server
MariaDB-devel
PHP \//安装 LAMP 架构 PHP-SNMP
php-ldap
php-pdo
php-mysql
php-devel
PHP-梨
PHP 通用
PHP-GD
php-mbstring
php-xml
php-process
Net-SNMP
net-snmp-utils
net-snmp-libs
net-snmp-agent-libs
net-snmp-devel
RRDTOOL
rrdtool-php
rrdtool-perl
RRDTOOL-devel
GCC OpenSSL-DEVEL
DOS2UNIX
自动会议
自动制作
Binutils libtool
CPP 后缀
glibc-headers
内核标头
格利布-德维尔GD
GD-DEVEL
帮助2人
新冠酸酯
wget 补丁// 以上都是配置仙人掌所需的插件[root@aa ~]# vi /etc/httpd/conf/httpd.confServerName [root@aa ~]# vi /etc/httpd/
conf.d/php.confLoadModule php5_module modules/libphp5.so[root@aa ~]# vi /etc/php.inisafe_mode = off // Add date.timezone = PRC //Find modification [root@aa ~]# systemctl stop firewalld.service[root@aa ~]# setenforce 0[root@aa ~]# systemctl start httpd.service[root@aa ~]# systemctl start mariadb.service
成功启动 [root@aa ~]#
mysql_secure_installation // 按照提示初步设置 Mariadb,设置密码,删除匿名用户,打开根远程登录,刷新权限下方灯测试,先测试 PHP 健康状态 [root@aa ~]# vi /var/www/html/index.php // 加入测试页面 Win10 访问
PHP 工作正常,以下测试数据库连接 [root@aa ~]# mysql -uroot –p//登录数据库进行测试帐户仙人掌授权 MariaDB [(none)]> 创建数据库 仙人掌字符集 utf8 整理utf8_bin;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'%' 由 'admin123' 标识;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'localhost' 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/index.php // 替换 Windows 10 访问的测试页面
数据库连接没有问题
---------可以开始安装 cacti--------------[root@aa ~]# tar xf cacti-1。26. .tar.gz[root@aa ~]# MV 仙人掌-1。1。26 /var/www/html/cacti[root@aa ~]# mysql -ucacti -p cacti < /var/www/html/cacti/cacti。sql输入 password:// 密码 admin123 将仙人掌的数据库导入 [root@aa ~]# mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -urootmysql -pEnter password:// 密码是abc123,1。1。cacti 版本 26 需要导入时间数据库 [root@aa ~]# mysql -uroot –p//授予 cacti 用户对时间数据库 MariaDB [(none)] 的权限>授予 mysql 上的选择。time_zone_name “cacti”@“localhost” 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/cacti/include/config。
php$database_username = 'cacti'; $database_password = 'admin123';//要修改这两个项目,数据库不在本地计算机上,需要修改 $rdatabase 对应的条目并删除注释 [root@aa ~]# vi /etc/snmp/snmpd。 confcom2sec notConfigUser localhost public // 更改为环回地址 41access notConfigGroup “”anynoauth exact all none none// 将系统视图更改为所有 62view 全部收录
。180 // 删除 # 符号 85[root@aa ~]# systemctl restart snmpd。service[root@aa ~]# systemctl enable snmpd。service[root@aa ~]# useradd -r -M cacti[root@aa ~]# chown -R cacti。cacti /var/www/html/cacti/rra/[root@aa ~]# chown -R cacti。
cacti /var/www/html/cacti/log/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/resource/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/cache[root@aa ~]# chown -R apache。Apache /var/www/html/cacti/scripts
-----------安装仙人掌脊椎
为了优化数据轮询速度-----新版本的 Cacti 可以在没有 PHP 脚本的情况下采集
数据,并且集成了一个新的插件 spine 用于采集
数据[root@aa ~]# rpm -ivh help2man-1.41.1-3.el7.noarch.rpm//install spine dependencies[root@aa ~]# ln -s /usr/ lib64/libmysqlclient.so.18.0.0 /usr/lib64/libmysqlclient.so[root@aa ~]# tar xf cacti-spine-1.1.26.tar.gz[root@aa ~]# CD 仙人掌-脊柱-1.1.26[root@aa 仙人掌脊椎-1.1.26]# ./ 配置[root@aa 仙人掌脊-1.1.26]# 制作 &&制作 install[root@aa ~]# cp /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf[root@aa ~]# vi /usr/local/spine/ etc/spine.conf// 修改相关参数DB_HostlocalhostDB_DatabasecactiDB_UsercactiDB_Passadmin123DB_Port3306
RDB_HostlocalhostRDB_DatabasecactiRDB_UsercactiRDB_Passadmin123RDB_Port3306配置后,win10可以访问192.168.80.181/cacti/进行安装
发现没有安装mbstring和snmp,数据库参数设置有问题,我们来优化一下
安装两个软件包[root@aa ~]# rpm -ivh php-mbstring-5.4.16-42.el7.x86_64.rpm[root@aa ~]#
rpm -ivh php-snmp-5.4.16-42.el7.x86_64.rpm 转到数据库设置 [root@aa ~]# vi /etc/f.d/fcharacter_set_ 服务器 = utf8mb4collation_server = utf8mb4_unicode_cicharacter_set_client = utf8mb4max_connections = 100max_heap_table_size = 256Mmax_allowed_packet = 16777216join_buffer_size = 64Mtmp_table_size = 64Minnodb_file_per_table = ONinnodb_buffer_pool_size = 1024Minnodb_doublewrite = OFFinnodb_lock_wait_timeout = 50innodb_flush_log_at_timeout = 3innodb_read_io_线程 = 32innodb_write_io_threads = 16[root@aa ~]# 服务 MariaDB 重启[root@aa ~]# 服务 httpd 重启,然后访问网页安装
软件包已安装
数据库配置没有问题,然后直接下一步
根据要求选择安装后,初始用户名admin密码admin,输入后需要更改密码,密码有一定的复杂度,必须超过8位数字(必须收录
大写小写字符)。
登录成功----------------以下仙人掌监控设置------------------控制台 -> 设置 -> 路径 -> 在 Spine 配置文件路径 /usr/local/spine/bin/spine 中填写 spine 二进制文件
位置文本框 在文件路径文本框中填写配置文件路径 /usr/local/spine/etc/spine.conf,然后单击保存。
控制台 ->设置 -> 轮询器
-> 在轮询器类型下拉框中选择脊柱,然后单击保存。注意:如果使用 spine,则以下两个轮换时间和计划任务间隔应设置为每分钟
添加设备和图形后,需要重建采集
器缓存。控制台>系统实用程序>重建轮询器缓存
点击进入以下屏幕,无需设置
仙人掌的基本配置之后,
你需要在服务器上添加一个定时任务来采集
数据(PHP 中定时任务的间隔是 5 分钟,而我们使用 Spine 模式时,定时任务的间隔是 1 分钟)[root@aa cacti]# crontab –e*/1 * * * * /usr/bin/php /var/www/html/cacti/poller.php >> /tmp/ cacti_rrdtool.log我们去仙人掌检查管理 设备(设备)检查 Linux 状态为 UP, 注意不要着急 脊椎方式刚开始大约需要2-5分钟,有快有慢
您可以在下面创建一个图表来分析所选设备
选择GO
然后直接选择图形查看仙人掌加工后的图片
解决方案:降本增效利器?Share Creators智能数字资产管理系统真香!
降本增效似乎是一个持续而永恒的话题。尤其是今年,尤为重要~
疫情不知不觉已经伴随我们三年了。在各行各业都受到疫情冲击较大的背景下,降本增效对于很多企业来说不再是锦上添花,而可能是唯一的出路。
随着市场的缩小和竞争的加剧,在更加“体量”的行业环境下,如何通过提升自身效率来有效降低成本,是每个团队都面临的问题。
什么是降低成本?如何提高效率?
要回答这个问题,我先来看看各个团队每天都在经历什么:
您是否经常淹没在充满不同版本和各种文件的文件夹中?苦苦寻找,还是找不到最新的文件分享?当你终于找到自己需要的资源时,往往需要通过不同的通讯软件与内部同事和外部伙伴公开分享。
简单计算一下,制作一个游戏角色需要2个月左右,目前国内平均制作价格为1000元/天,一个丢失的文件损失约4万元。你现在的公司能保证每个文件的流程文件和最终文件都能妥善备份,并且随时可以找到吗?
设计行业往往伴随着大量的数字资产,文件种类繁多,种类繁多。一个CG 3D文件动辄几十甚至上百GB,每个文件都需要下载到本地才能查看。在多办公室远程办公场景下,一个简单的文件重命名可能需要几个小时才能下载到本地才能完成。
Dropbox、Google Drive、云盘等外部工具上传下载需要大量的等待时间。对方上传的文件在一段时间后下载链接失效,文件被删除。这些都是很常见的问题。更糟糕的是,如果文件没有及时妥善备份,往往会给企业带来巨大的经济损失,而实际案例更是数不胜数……
这些看似常规的数字资产的搜索、共享、传输和备份,往往浪费了太多的时间,消耗了太多的精力。
长此以往,何谈降本增效?
是时候做出一些改变了。
欲善其事,必先利其器
效率的提升离不开先进工具的帮助。
根据普华永道的一项调查,一款优秀的数字资产管理软件可以帮助被调查团队在一年内节省一个月的制作时间,效率得到大幅提升。Share Creators智能数字资产管理系统就是这样一款软件。
Share Creators智能数字资产管理系统
无论是企业、团队还是个人,无论团队是远程工作还是协同工作,我们都希望Share Creators强大、智能的数字资源管理系统能够有效提高您和您团队的工作效率。
先看一下demo:
申请免费试用:
简单理解,我们的产品就是“企业级谷歌”,可以高效的帮您备份、搜索、复用、版本控制之前所有的历史资源和文档:
1、AI智能搜索快速找到所需资源
Share Creators拥有业界领先的AI识别功能,可智能解析资源文件,让您轻松找到所有文件。即使我们忘记给文件命名,也能被AI识别,随时找到对应的资源。
同时,强大的人工智能标签结合自定义个人标签库+团队标签池功能,可大幅提升搜索精准度。
你觉得这就结束了吗?Share Creators还提供了多种搜索方式,用户可以通过颜色、名称、标签、文件类型、文件大小、横竖排版、上传时间等属性进行搜索。这些强大的搜索不仅限于图像、PSD、视频文件等内部文件,还包括 URL、Google Drive 等其他系统中的文件。
2.支持上百种资源格式在线高速预览和即时反馈
Share Creators全面支持100多种资源格式,快速在线实时预览。目前支持的格式包括:2D图片、3D FBX/OBJ、2D-SPINE动画、视频、音频、PPT、word等。将支持Maya和3dmax在线观看),轻松实现高速秒级在线预览。
同时,您还可以进行查看回复、实时分享等多项操作。评论回复时,只需停在3D模型或视频的某一帧进行标注反馈,非常方便。
3. 便捷易用的分享交流:外包商管理的利器
数字资产的共享是日常工作中使用频率最高的功能之一。您可以直接从Share Creators界面选择单个文件或共享整个文件夹内容,整个过程简单方便。
Share Creators新增访客模式,充分满足外部合作伙伴的接入需求,与外包商合作的进度管理和审核变得更加得心应手。不再翻聊天记录,回到原来的更新,却发现文件已经过期,无法下载。
同时,当您对外共享数字资产时,可以为共享内容设置只读和可编辑两种共享权限,在满足不同需求的同时,最大程度保护共享内容的安全。
在日常交流方面,Share Creators支持整合常用的交流工具。飞书、钉钉、企业微信、Slack等通讯工具都可以通过API方式集成到Share Creators中。这样一来,整个公司的组织人员就可以轻松导入。人员离职,只能在通讯工具中删除,资产访问权限自动关闭,无需管理双方用户列表。
4、从生产工具到游戏引擎,上下游全流程接入
Share Creators可以实现Photoshop、After Effect等上游制作工具的对接,Unity、Unreal等游戏引擎的对接,以及SVN、Perforce码控等下游制作工具的对接(逐步上线,部分软件对接已有得到支持)。
Share Creators即将开放更多API接口,实现设计和游戏行业常用软件的深度融合,让整个制作过程更加方便快捷。
5.一键轻松采集
资源
Share Creators强大的一键资源采集
功能,可以轻松帮助设计师解决资源采集
问题。
点击批量采集
,在网页查看需要采集
的图片,轻松完成一键采集
。选中的图片会自动保存在Share Creators个人文件夹中,供您日后使用。
Share Creators还有强大的页面截图和屏幕录制功能。您可以选择对页面特定区域、页面可见区域或整个页面进行一键截图。
6、本地资源实时备份
Share Creators可以将本地资源实时同步到服务器,同时支持权限管理,最大程度降低资产不合理丢失的风险;实时同步的文件也可以让团队成员轻松实现远程或移动办公。
在Globee2022信息技术世界大奖的评选中,Share Creators智能数字资产管理系统成功斩获三项大奖,其中,在年度数字资产管理软件评选中,以极高的含金量成功摘得金奖。
目前,全球许多游戏开发商和工作室都在使用Share Creators来提高他们的数字资产管理效率。无数事例表明,Share Creators智能数字资产管理系统已经成为帮助他们降本增效的利器。
针对不同规模的团队,Share Creators 提供了基于用户数量的座位版本;针对大型企业,Share Creators提供了不限制用户数量的企业版。
这就是你苦苦寻找的提升工作效率的神器吗?快来免费体验Share Creators智能数字资产管理系统吧!
申请免费试用:
或者随时联系 查看全部
解决方案:服务器监控——Cacti(全新版)
MariaDB-client MariaDB-server
MariaDB-devel
PHP \//安装 LAMP 架构 PHP-SNMP
php-ldap
php-pdo
php-mysql
php-devel
PHP-梨
PHP 通用
PHP-GD
php-mbstring
php-xml
php-process
Net-SNMP
net-snmp-utils
net-snmp-libs
net-snmp-agent-libs
net-snmp-devel
RRDTOOL
rrdtool-php
rrdtool-perl
RRDTOOL-devel
GCC OpenSSL-DEVEL
DOS2UNIX
自动会议
自动制作
Binutils libtool

CPP 后缀
glibc-headers
内核标头
格利布-德维尔GD
GD-DEVEL
帮助2人
新冠酸酯
wget 补丁// 以上都是配置仙人掌所需的插件[root@aa ~]# vi /etc/httpd/conf/httpd.confServerName [root@aa ~]# vi /etc/httpd/
conf.d/php.confLoadModule php5_module modules/libphp5.so[root@aa ~]# vi /etc/php.inisafe_mode = off // Add date.timezone = PRC //Find modification [root@aa ~]# systemctl stop firewalld.service[root@aa ~]# setenforce 0[root@aa ~]# systemctl start httpd.service[root@aa ~]# systemctl start mariadb.service
成功启动 [root@aa ~]#
mysql_secure_installation // 按照提示初步设置 Mariadb,设置密码,删除匿名用户,打开根远程登录,刷新权限下方灯测试,先测试 PHP 健康状态 [root@aa ~]# vi /var/www/html/index.php // 加入测试页面 Win10 访问
PHP 工作正常,以下测试数据库连接 [root@aa ~]# mysql -uroot –p//登录数据库进行测试帐户仙人掌授权 MariaDB [(none)]> 创建数据库 仙人掌字符集 utf8 整理utf8_bin;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'%' 由 'admin123' 标识;MariaDB [(none)]> 授予所有 ON cacti.* 到 'cacti'@'localhost' 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/index.php // 替换 Windows 10 访问的测试页面
数据库连接没有问题
---------可以开始安装 cacti--------------[root@aa ~]# tar xf cacti-1。26. .tar.gz[root@aa ~]# MV 仙人掌-1。1。26 /var/www/html/cacti[root@aa ~]# mysql -ucacti -p cacti < /var/www/html/cacti/cacti。sql输入 password:// 密码 admin123 将仙人掌的数据库导入 [root@aa ~]# mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -urootmysql -pEnter password:// 密码是abc123,1。1。cacti 版本 26 需要导入时间数据库 [root@aa ~]# mysql -uroot –p//授予 cacti 用户对时间数据库 MariaDB [(none)] 的权限>授予 mysql 上的选择。time_zone_name “cacti”@“localhost” 由 'admin123' 标识;MariaDB [(无)]>刷新权限;[root@aa ~]# vi /var/www/html/cacti/include/config。
php$database_username = 'cacti'; $database_password = 'admin123';//要修改这两个项目,数据库不在本地计算机上,需要修改 $rdatabase 对应的条目并删除注释 [root@aa ~]# vi /etc/snmp/snmpd。 confcom2sec notConfigUser localhost public // 更改为环回地址 41access notConfigGroup “”anynoauth exact all none none// 将系统视图更改为所有 62view 全部收录
。180 // 删除 # 符号 85[root@aa ~]# systemctl restart snmpd。service[root@aa ~]# systemctl enable snmpd。service[root@aa ~]# useradd -r -M cacti[root@aa ~]# chown -R cacti。cacti /var/www/html/cacti/rra/[root@aa ~]# chown -R cacti。
cacti /var/www/html/cacti/log/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/resource/[root@aa ~]# chown -R apache。apache /var/www/html/cacti/cache[root@aa ~]# chown -R apache。Apache /var/www/html/cacti/scripts
-----------安装仙人掌脊椎
为了优化数据轮询速度-----新版本的 Cacti 可以在没有 PHP 脚本的情况下采集
数据,并且集成了一个新的插件 spine 用于采集
数据[root@aa ~]# rpm -ivh help2man-1.41.1-3.el7.noarch.rpm//install spine dependencies[root@aa ~]# ln -s /usr/ lib64/libmysqlclient.so.18.0.0 /usr/lib64/libmysqlclient.so[root@aa ~]# tar xf cacti-spine-1.1.26.tar.gz[root@aa ~]# CD 仙人掌-脊柱-1.1.26[root@aa 仙人掌脊椎-1.1.26]# ./ 配置[root@aa 仙人掌脊-1.1.26]# 制作 &&制作 install[root@aa ~]# cp /usr/local/spine/etc/spine.conf.dist /usr/local/spine/etc/spine.conf[root@aa ~]# vi /usr/local/spine/ etc/spine.conf// 修改相关参数DB_HostlocalhostDB_DatabasecactiDB_UsercactiDB_Passadmin123DB_Port3306
RDB_HostlocalhostRDB_DatabasecactiRDB_UsercactiRDB_Passadmin123RDB_Port3306配置后,win10可以访问192.168.80.181/cacti/进行安装
发现没有安装mbstring和snmp,数据库参数设置有问题,我们来优化一下

安装两个软件包[root@aa ~]# rpm -ivh php-mbstring-5.4.16-42.el7.x86_64.rpm[root@aa ~]#
rpm -ivh php-snmp-5.4.16-42.el7.x86_64.rpm 转到数据库设置 [root@aa ~]# vi /etc/f.d/fcharacter_set_ 服务器 = utf8mb4collation_server = utf8mb4_unicode_cicharacter_set_client = utf8mb4max_connections = 100max_heap_table_size = 256Mmax_allowed_packet = 16777216join_buffer_size = 64Mtmp_table_size = 64Minnodb_file_per_table = ONinnodb_buffer_pool_size = 1024Minnodb_doublewrite = OFFinnodb_lock_wait_timeout = 50innodb_flush_log_at_timeout = 3innodb_read_io_线程 = 32innodb_write_io_threads = 16[root@aa ~]# 服务 MariaDB 重启[root@aa ~]# 服务 httpd 重启,然后访问网页安装
软件包已安装
数据库配置没有问题,然后直接下一步
根据要求选择安装后,初始用户名admin密码admin,输入后需要更改密码,密码有一定的复杂度,必须超过8位数字(必须收录
大写小写字符)。
登录成功----------------以下仙人掌监控设置------------------控制台 -> 设置 -> 路径 -> 在 Spine 配置文件路径 /usr/local/spine/bin/spine 中填写 spine 二进制文件
位置文本框 在文件路径文本框中填写配置文件路径 /usr/local/spine/etc/spine.conf,然后单击保存。
控制台 ->设置 -> 轮询器
-> 在轮询器类型下拉框中选择脊柱,然后单击保存。注意:如果使用 spine,则以下两个轮换时间和计划任务间隔应设置为每分钟
添加设备和图形后,需要重建采集
器缓存。控制台>系统实用程序>重建轮询器缓存
点击进入以下屏幕,无需设置
仙人掌的基本配置之后,
你需要在服务器上添加一个定时任务来采集
数据(PHP 中定时任务的间隔是 5 分钟,而我们使用 Spine 模式时,定时任务的间隔是 1 分钟)[root@aa cacti]# crontab –e*/1 * * * * /usr/bin/php /var/www/html/cacti/poller.php >> /tmp/ cacti_rrdtool.log我们去仙人掌检查管理 设备(设备)检查 Linux 状态为 UP, 注意不要着急 脊椎方式刚开始大约需要2-5分钟,有快有慢
您可以在下面创建一个图表来分析所选设备
选择GO
然后直接选择图形查看仙人掌加工后的图片
解决方案:降本增效利器?Share Creators智能数字资产管理系统真香!
降本增效似乎是一个持续而永恒的话题。尤其是今年,尤为重要~
疫情不知不觉已经伴随我们三年了。在各行各业都受到疫情冲击较大的背景下,降本增效对于很多企业来说不再是锦上添花,而可能是唯一的出路。
随着市场的缩小和竞争的加剧,在更加“体量”的行业环境下,如何通过提升自身效率来有效降低成本,是每个团队都面临的问题。
什么是降低成本?如何提高效率?
要回答这个问题,我先来看看各个团队每天都在经历什么:
您是否经常淹没在充满不同版本和各种文件的文件夹中?苦苦寻找,还是找不到最新的文件分享?当你终于找到自己需要的资源时,往往需要通过不同的通讯软件与内部同事和外部伙伴公开分享。
简单计算一下,制作一个游戏角色需要2个月左右,目前国内平均制作价格为1000元/天,一个丢失的文件损失约4万元。你现在的公司能保证每个文件的流程文件和最终文件都能妥善备份,并且随时可以找到吗?
设计行业往往伴随着大量的数字资产,文件种类繁多,种类繁多。一个CG 3D文件动辄几十甚至上百GB,每个文件都需要下载到本地才能查看。在多办公室远程办公场景下,一个简单的文件重命名可能需要几个小时才能下载到本地才能完成。
Dropbox、Google Drive、云盘等外部工具上传下载需要大量的等待时间。对方上传的文件在一段时间后下载链接失效,文件被删除。这些都是很常见的问题。更糟糕的是,如果文件没有及时妥善备份,往往会给企业带来巨大的经济损失,而实际案例更是数不胜数……
这些看似常规的数字资产的搜索、共享、传输和备份,往往浪费了太多的时间,消耗了太多的精力。
长此以往,何谈降本增效?
是时候做出一些改变了。
欲善其事,必先利其器
效率的提升离不开先进工具的帮助。
根据普华永道的一项调查,一款优秀的数字资产管理软件可以帮助被调查团队在一年内节省一个月的制作时间,效率得到大幅提升。Share Creators智能数字资产管理系统就是这样一款软件。
Share Creators智能数字资产管理系统
无论是企业、团队还是个人,无论团队是远程工作还是协同工作,我们都希望Share Creators强大、智能的数字资源管理系统能够有效提高您和您团队的工作效率。

先看一下demo:
申请免费试用:
简单理解,我们的产品就是“企业级谷歌”,可以高效的帮您备份、搜索、复用、版本控制之前所有的历史资源和文档:
1、AI智能搜索快速找到所需资源
Share Creators拥有业界领先的AI识别功能,可智能解析资源文件,让您轻松找到所有文件。即使我们忘记给文件命名,也能被AI识别,随时找到对应的资源。
同时,强大的人工智能标签结合自定义个人标签库+团队标签池功能,可大幅提升搜索精准度。
你觉得这就结束了吗?Share Creators还提供了多种搜索方式,用户可以通过颜色、名称、标签、文件类型、文件大小、横竖排版、上传时间等属性进行搜索。这些强大的搜索不仅限于图像、PSD、视频文件等内部文件,还包括 URL、Google Drive 等其他系统中的文件。
2.支持上百种资源格式在线高速预览和即时反馈
Share Creators全面支持100多种资源格式,快速在线实时预览。目前支持的格式包括:2D图片、3D FBX/OBJ、2D-SPINE动画、视频、音频、PPT、word等。将支持Maya和3dmax在线观看),轻松实现高速秒级在线预览。
同时,您还可以进行查看回复、实时分享等多项操作。评论回复时,只需停在3D模型或视频的某一帧进行标注反馈,非常方便。
3. 便捷易用的分享交流:外包商管理的利器
数字资产的共享是日常工作中使用频率最高的功能之一。您可以直接从Share Creators界面选择单个文件或共享整个文件夹内容,整个过程简单方便。
Share Creators新增访客模式,充分满足外部合作伙伴的接入需求,与外包商合作的进度管理和审核变得更加得心应手。不再翻聊天记录,回到原来的更新,却发现文件已经过期,无法下载。
同时,当您对外共享数字资产时,可以为共享内容设置只读和可编辑两种共享权限,在满足不同需求的同时,最大程度保护共享内容的安全。
在日常交流方面,Share Creators支持整合常用的交流工具。飞书、钉钉、企业微信、Slack等通讯工具都可以通过API方式集成到Share Creators中。这样一来,整个公司的组织人员就可以轻松导入。人员离职,只能在通讯工具中删除,资产访问权限自动关闭,无需管理双方用户列表。

4、从生产工具到游戏引擎,上下游全流程接入
Share Creators可以实现Photoshop、After Effect等上游制作工具的对接,Unity、Unreal等游戏引擎的对接,以及SVN、Perforce码控等下游制作工具的对接(逐步上线,部分软件对接已有得到支持)。
Share Creators即将开放更多API接口,实现设计和游戏行业常用软件的深度融合,让整个制作过程更加方便快捷。
5.一键轻松采集
资源
Share Creators强大的一键资源采集
功能,可以轻松帮助设计师解决资源采集
问题。
点击批量采集
,在网页查看需要采集
的图片,轻松完成一键采集
。选中的图片会自动保存在Share Creators个人文件夹中,供您日后使用。
Share Creators还有强大的页面截图和屏幕录制功能。您可以选择对页面特定区域、页面可见区域或整个页面进行一键截图。
6、本地资源实时备份
Share Creators可以将本地资源实时同步到服务器,同时支持权限管理,最大程度降低资产不合理丢失的风险;实时同步的文件也可以让团队成员轻松实现远程或移动办公。
在Globee2022信息技术世界大奖的评选中,Share Creators智能数字资产管理系统成功斩获三项大奖,其中,在年度数字资产管理软件评选中,以极高的含金量成功摘得金奖。
目前,全球许多游戏开发商和工作室都在使用Share Creators来提高他们的数字资产管理效率。无数事例表明,Share Creators智能数字资产管理系统已经成为帮助他们降本增效的利器。
针对不同规模的团队,Share Creators 提供了基于用户数量的座位版本;针对大型企业,Share Creators提供了不限制用户数量的企业版。
这就是你苦苦寻找的提升工作效率的神器吗?快来免费体验Share Creators智能数字资产管理系统吧!
申请免费试用:
或者随时联系
解决方案:如何使用 SkyWalking 给 Dubbo 服务做链路追踪?
采集交流 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-11-22 09:18
Skywalking监控截图:
Apache Skywalking(孵化器)简介
Apache Skywalking (Incubator) 专为微服务架构和云原生架构系统设计,支持分布式链路跟踪APM系统。Apache Skywalking(孵化器)通过加载探针采集
应用调用链接信息,对采集
到的调用链接信息进行分析,生成应用间关系、服务间关系和服务指标。Apache Skywalking (Incubating) 目前支持多种语言,包括 Java、.Net Core、Node.js 和 Go 语言。
目前Skywalking已经支持从6个可视化维度分析分布式系统的运行情况。
Dubbo与Apache Skywalking(孵化器)编写Dubbo示例程序
Dubbo示例程序已经上传到Github仓库。方便大家下载使用。
API工程
服务接口:
package org.apache.skywalking.demo.interfaces;<br /><br />public interface HelloService {<br /> String sayHello(String name);<br />}<br />
Dubbo服务提供项目
package org.apache.skywalking.demo.provider;<br /><br />@Service(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> protocol = "${dubbo.protocol.id}",<br /> registry = "${dubbo.registry.id}", timeout = 60000)<br />public class HelloServiceImpl implements HelloService {<br /><br /> public String sayHello(String name) {<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));<br /> return "Hello, " + name;<br /> }<br /><br />}<br />
消费者工程
package org.apache.skywalking.demo.consumer;<br /><br />@RestController<br />public class ConsumerController {<br /><br /> private static int COUNT = 0;<br /><br /> @Reference(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> url = "dubbo://localhost:20880", timeout = 60000)<br /> private HelloService helloService;<br /><br /> @GetMapping("/sayHello/{name}")<br /> public String sayHello(@PathVariable(name = "name") String name) {<br /> if ((COUNT++) % 3 == 0){<br /> throw new RuntimeException();<br /> }<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));<br /> return helloService.sayHello(name);<br /> }<br />}<br />
部署 Apache Skywalking(孵化器)
Apache Skywalking(孵化器)提供两种部署模式:单节点模式和集群模式。以下是单节点模式部署步骤。有关集群模式部署的详细信息,请参阅文档。
依赖第三方组件
JDK8+
弹性搜索 5.x
部署步骤
下载 Apache Skywalking 采集
器
部署弹性搜索
解压缩并启动 Skywalking Collector。运行 bin/startup.sh 命令启动 Skywalking Collector
启动示例程序
在启动示例程序之前,先执行编译打包命令:
./mvnw clean package<br />
启动服务提供者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-provider -Dskywalking.collector.servers=localhost:10800 dubbo-provider/target/dubbo-provider.jar<br />
启动服务消费者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-consumer -Dskywalking.collector.servers=localhost:10800 dubbo-consumer/target/dubbo-consumer.jar <br />
获得消费者提供的服务
curl http://localhost:8080/sayHello/test<br />
Skywalking监控截图:首页
/admin-guide/images/skywalking-dashboard.png 拓扑图
/admin-guide/images/skywalking-topology.png 应用视图
/admin-guide/images/skywalking-application.png
JVM信息
/admin-guide/images/skywalking-application_instance.png 服务视图
服务消费者:
/admin-guide/images/skywalking-service-consumer.png
服务提供者:
/admin-guide/images/skywalking-service-provider.png 跟踪视图
/admin-guide/images/skywalking-trace.png
跨度信息:
/admin-guide/images/skywalking-span-Info.png 报警视图
/admin-guide/images/skywalking-alarm.png
欢迎加入我的知识星球,一起探讨架构,交流源码。要加入,请按住下面的二维码:
知识星球上已更新源码,分析如下:
目前,《Dubbo源码解析》目录已在知识星球更新如下:
01.调试环境搭建
02.项目结构一览
03.配置配置
04.核心流程清单
05.扩展机制SPI
06.线程池
07.服务暴露Export
08. 服务参考 Refer
09.注册处
10.动态编译
11. 动态代理
12.服务调用Invoke
13.调用属性
14.过滤器
15.NIO 服务器
16.P2P服务器
解决方案:OZON平台产品审核不通过原因及产品上传常见错误
OZON官方有两种方式:单次上传和表单批量上传。上传后需要审核,目前是人工审核。很多卖家反映商品上传后“拒绝更新”,即商品审核不通过。是什么原因?
首先,确保您的产品或品牌可以在OZON上销售或不受限制。
二、首次上传填写商品信息前,一定要逐项查看填写的提示,并查看平台买家端的listing,可以有效避免出现明显错误。
三、卖家上传图片错误较多。上传前,他还查看了官方知识库中给出的详细上传图片要求。
以下是根据采集
到的买家反馈和实践经验总结的产品上传常见错误列表:
1.产品图片:图片底色偏暗或杂乱。上传的时候主图最好是无价的白底图(灰底图也可以),白色的东西可以深色,总之一定要干净整洁,尤其是主图,尺寸等信息不应该出现在图片中,只展示商品的全部内容,也应该整体展示,而不是只展示商品的一部分。对于服装,主要图片应显示在正面。
2. 多SKU:一个产品只能上传一个SKU。主副图颜色必须与SKU数量一致,同一商品不能出现多个SKU。请注意,这是一个严重的问题。
3.商品分类:上传商品时商品分类选择有问题,分类不确定。建议在买家网站上搜索并确认产品类别后再进行选择。
4、品牌问题:选择没有品牌的产品,但在产品栏目、图片或说明中显示品牌信息,或产品品牌信息不一致。
5.产品描述:描述太短,尺寸大小不对,收录
广告信息。
最后,如果产品已上传但未通过审核,将鼠标移到提醒编号上,系统通常会显示失败原因。 查看全部
解决方案:如何使用 SkyWalking 给 Dubbo 服务做链路追踪?
Skywalking监控截图:
Apache Skywalking(孵化器)简介
Apache Skywalking (Incubator) 专为微服务架构和云原生架构系统设计,支持分布式链路跟踪APM系统。Apache Skywalking(孵化器)通过加载探针采集
应用调用链接信息,对采集
到的调用链接信息进行分析,生成应用间关系、服务间关系和服务指标。Apache Skywalking (Incubating) 目前支持多种语言,包括 Java、.Net Core、Node.js 和 Go 语言。
目前Skywalking已经支持从6个可视化维度分析分布式系统的运行情况。
Dubbo与Apache Skywalking(孵化器)编写Dubbo示例程序
Dubbo示例程序已经上传到Github仓库。方便大家下载使用。
API工程
服务接口:
package org.apache.skywalking.demo.interfaces;<br /><br />public interface HelloService {<br /> String sayHello(String name);<br />}<br />
Dubbo服务提供项目
package org.apache.skywalking.demo.provider;<br /><br />@Service(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> protocol = "${dubbo.protocol.id}",<br /> registry = "${dubbo.registry.id}", timeout = 60000)<br />public class HelloServiceImpl implements HelloService {<br /><br /> public String sayHello(String name) {<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));<br /> return "Hello, " + name;<br /> }<br /><br />}<br />
消费者工程
package org.apache.skywalking.demo.consumer;<br /><br />@RestController<br />public class ConsumerController {<br /><br /> private static int COUNT = 0;<br /><br /> @Reference(version = "${demo.service.version}",<br /> application = "${dubbo.application.id}",<br /> url = "dubbo://localhost:20880", timeout = 60000)<br /> private HelloService helloService;<br /><br /> @GetMapping("/sayHello/{name}")<br /> public String sayHello(@PathVariable(name = "name") String name) {<br /> if ((COUNT++) % 3 == 0){<br /> throw new RuntimeException();<br /> }<br /> LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));<br /> return helloService.sayHello(name);<br /> }<br />}<br />
部署 Apache Skywalking(孵化器)
Apache Skywalking(孵化器)提供两种部署模式:单节点模式和集群模式。以下是单节点模式部署步骤。有关集群模式部署的详细信息,请参阅文档。
依赖第三方组件
JDK8+
弹性搜索 5.x
部署步骤
下载 Apache Skywalking 采集
器
部署弹性搜索
解压缩并启动 Skywalking Collector。运行 bin/startup.sh 命令启动 Skywalking Collector
启动示例程序
在启动示例程序之前,先执行编译打包命令:

./mvnw clean package<br />
启动服务提供者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-provider -Dskywalking.collector.servers=localhost:10800 dubbo-provider/target/dubbo-provider.jar<br />
启动服务消费者
java -jar -javaagent:$AGENT_PATH/skywalking-agent.jar -Dskywalking.agent.application_code=dubbo-consumer -Dskywalking.collector.servers=localhost:10800 dubbo-consumer/target/dubbo-consumer.jar <br />
获得消费者提供的服务
curl http://localhost:8080/sayHello/test<br />
Skywalking监控截图:首页
/admin-guide/images/skywalking-dashboard.png 拓扑图
/admin-guide/images/skywalking-topology.png 应用视图
/admin-guide/images/skywalking-application.png
JVM信息
/admin-guide/images/skywalking-application_instance.png 服务视图
服务消费者:
/admin-guide/images/skywalking-service-consumer.png
服务提供者:
/admin-guide/images/skywalking-service-provider.png 跟踪视图
/admin-guide/images/skywalking-trace.png

跨度信息:
/admin-guide/images/skywalking-span-Info.png 报警视图
/admin-guide/images/skywalking-alarm.png
欢迎加入我的知识星球,一起探讨架构,交流源码。要加入,请按住下面的二维码:
知识星球上已更新源码,分析如下:
目前,《Dubbo源码解析》目录已在知识星球更新如下:
01.调试环境搭建
02.项目结构一览
03.配置配置
04.核心流程清单
05.扩展机制SPI
06.线程池
07.服务暴露Export
08. 服务参考 Refer
09.注册处
10.动态编译
11. 动态代理
12.服务调用Invoke
13.调用属性
14.过滤器
15.NIO 服务器
16.P2P服务器
解决方案:OZON平台产品审核不通过原因及产品上传常见错误
OZON官方有两种方式:单次上传和表单批量上传。上传后需要审核,目前是人工审核。很多卖家反映商品上传后“拒绝更新”,即商品审核不通过。是什么原因?
首先,确保您的产品或品牌可以在OZON上销售或不受限制。
二、首次上传填写商品信息前,一定要逐项查看填写的提示,并查看平台买家端的listing,可以有效避免出现明显错误。

三、卖家上传图片错误较多。上传前,他还查看了官方知识库中给出的详细上传图片要求。
以下是根据采集
到的买家反馈和实践经验总结的产品上传常见错误列表:
1.产品图片:图片底色偏暗或杂乱。上传的时候主图最好是无价的白底图(灰底图也可以),白色的东西可以深色,总之一定要干净整洁,尤其是主图,尺寸等信息不应该出现在图片中,只展示商品的全部内容,也应该整体展示,而不是只展示商品的一部分。对于服装,主要图片应显示在正面。
2. 多SKU:一个产品只能上传一个SKU。主副图颜色必须与SKU数量一致,同一商品不能出现多个SKU。请注意,这是一个严重的问题。

3.商品分类:上传商品时商品分类选择有问题,分类不确定。建议在买家网站上搜索并确认产品类别后再进行选择。
4、品牌问题:选择没有品牌的产品,但在产品栏目、图片或说明中显示品牌信息,或产品品牌信息不一致。
5.产品描述:描述太短,尺寸大小不对,收录
广告信息。
最后,如果产品已上传但未通过审核,将鼠标移到提醒编号上,系统通常会显示失败原因。
分享文章:织梦CMS实现复制文章自动加出处信息(织梦文章调用标签)
采集交流 • 优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2022-11-21 02:29
如果你发现自己辛辛苦苦创作的很多文章被别人复制或采集
,没有留下一个链接,你会不会非常生气和郁闷?好在我们还有一些基本的保护措施可以减少损失,那就是使用javascript来实现对文章原作者的基本版权保护。复制或采集
时,会自动添加文章出处。其实这个功能的实现代码很简单,只需要在内容页模板(article_*.htm)的区域添加代码即可:
document.body.oncopy = function (){
<p>
setTimeout(function (){
var text = clipboardData.getData("text");
if (text){
texttext = text + "rn本文转载于{dede:global.cfg_webname/}:{dede:global.cfg_basehost/}-原文链接:"+location.href;
clipboardData.setData("text", text);
}
},100)
}
</p>
嗯,赶快试试吧!
技巧:什么工具可以输入关键词自动生成文章?
一、文章采集工具来源
文章采集、聚合、二次收录、权重站维护程序
普通的文章采集、批量采集和发布已经不能满足搜索引擎的需求。懂基本百度相似度算法simhash算法的人应该都做过文章相似度检测。经过我的实际测试,大部分伪原创文章搜索引擎都可以识别文章,真正优质的文章不仅要原创,还要有完整的语义,能够完全帮助用户解决问题。比如像一个短视频平台,如果一个视频从头到尾都是废话,没有回答开头提出的问题,那你是不是要评论喷作者废话,跑题了;所以文章实用,第一时间解决用户心中的疑惑,这是一篇好文章,
今天我们就来看看自媒体文章采集工具:
现在比较实用的媒体文章采集工具有易写文章采集工具,可以批量采集媒体文章,可以选择不同的媒体平台,还可以选择内容发布时间,输入你要搜索的内容即可 关键词,可以获得很多相关的内容素材,可以选择下载,视频采集方法同理。
什么是自媒体文章采集工具?
自媒体文章采集工具,顾名思义,就是一款可以采集自媒体文章的工具。
本工具可以采集
海量文章和图片,为你的创作带来灵感,操作简单方便。
对于素材需求高的工作室和公司,使用这个工具会节省很多时间。
2、趣快拍AI搜索聚合文章及问答采集工具
通过整合百度(百度知乎)、搜狗(搜狗问答)、360(360问答)、新浪(新浪爱客)、今日头条(悟空问答)、知乎(知乎问答、知乎话题)以及自媒体平台今日头条,搜狐、百家号利用自动语义检测算法、相似度检测算法、段落拆分与组合,将不同文章中语义最接近的段落进行整合,生成聚合优质文章。第一,可以满足百度的相似度算法;原创优质文章段落,三是可以自定义内容模板,增加内容模板的原创性,这是普通采集工具无法企及的。
问答聚合文章
网站日常秒收三、文章收录工具聚合程序介绍
支持Google SEO文章生成100多种语言的外贸软文,支持开源CMS自动发布。(目前支持zblog、WordPress、织梦cms、帝国cms、迅锐cms、小旋风蜘蛛池等自动收发布自动上传),支持文章定时定量发布,支持html与纯文本相互转换。通过IF-TDF算法、simHash、NLP、段落分词、完备的语义检测算法,匹配优质内容,多搜索引擎内容聚合,提高内容原创性和可读性;同时可以自定义内容模板,实现内容模板页面的多样性原创。
AI搜索提取文章合集
------------------by文子seo-button: 61910465----------------
[配置]
;搜索引擎(单篇文章模板只能设置这个)
searchengine=知乎、今日头条、新浪、百度、搜狗、360
;采集页数(默认采集第一页,多页会影响文章生成速度)
页=1
;文本长度(采集内容不得低于此文本长度)
字符长度=20
;标题样式(关键词和联想词不可移动)
titletype=关键词 联想词
;同一篇文章允许被调用的次数
时间 = 3
;是否删除原图
delimg=否
;平台名称,
;z-blog 自动发布:z-blog;
;帝国自动发布:diguo
;织梦自动发布:dede;
;wordpress 自动发布:wordpress;
;小旋风式文章; 小轩风;
;迅锐CMS自动发布:xunrui;
;留空会把生成的文章保存到shengcheng文件夹
平台=z-博客
;生成的文章数
publish_num=1000
;发布间隔秒
发布时间=300
;定时更新,每天固定时间运行程序(如果不定时,留空即可)
固定时间=
;是否打开全文翻译成英文,翻译是yes,不翻译是no
翻译=否
;自动检测要翻译的语言,默认auto
sl=自动
tl=en
;html是否转为文本格式,转为yes,不转为no
html_text=否 查看全部
分享文章:织梦CMS实现复制文章自动加出处信息(织梦文章调用标签)
如果你发现自己辛辛苦苦创作的很多文章被别人复制或采集
,没有留下一个链接,你会不会非常生气和郁闷?好在我们还有一些基本的保护措施可以减少损失,那就是使用javascript来实现对文章原作者的基本版权保护。复制或采集
时,会自动添加文章出处。其实这个功能的实现代码很简单,只需要在内容页模板(article_*.htm)的区域添加代码即可:
document.body.oncopy = function (){
<p>

setTimeout(function (){
var text = clipboardData.getData("text");
if (text){
texttext = text + "rn本文转载于{dede:global.cfg_webname/}:{dede:global.cfg_basehost/}-原文链接:"+location.href;
clipboardData.setData("text", text);

}
},100)
}
</p>
嗯,赶快试试吧!
技巧:什么工具可以输入关键词自动生成文章?
一、文章采集工具来源
文章采集、聚合、二次收录、权重站维护程序
普通的文章采集、批量采集和发布已经不能满足搜索引擎的需求。懂基本百度相似度算法simhash算法的人应该都做过文章相似度检测。经过我的实际测试,大部分伪原创文章搜索引擎都可以识别文章,真正优质的文章不仅要原创,还要有完整的语义,能够完全帮助用户解决问题。比如像一个短视频平台,如果一个视频从头到尾都是废话,没有回答开头提出的问题,那你是不是要评论喷作者废话,跑题了;所以文章实用,第一时间解决用户心中的疑惑,这是一篇好文章,
今天我们就来看看自媒体文章采集工具:
现在比较实用的媒体文章采集工具有易写文章采集工具,可以批量采集媒体文章,可以选择不同的媒体平台,还可以选择内容发布时间,输入你要搜索的内容即可 关键词,可以获得很多相关的内容素材,可以选择下载,视频采集方法同理。
什么是自媒体文章采集工具?
自媒体文章采集工具,顾名思义,就是一款可以采集自媒体文章的工具。
本工具可以采集
海量文章和图片,为你的创作带来灵感,操作简单方便。
对于素材需求高的工作室和公司,使用这个工具会节省很多时间。
2、趣快拍AI搜索聚合文章及问答采集工具
通过整合百度(百度知乎)、搜狗(搜狗问答)、360(360问答)、新浪(新浪爱客)、今日头条(悟空问答)、知乎(知乎问答、知乎话题)以及自媒体平台今日头条,搜狐、百家号利用自动语义检测算法、相似度检测算法、段落拆分与组合,将不同文章中语义最接近的段落进行整合,生成聚合优质文章。第一,可以满足百度的相似度算法;原创优质文章段落,三是可以自定义内容模板,增加内容模板的原创性,这是普通采集工具无法企及的。
问答聚合文章
网站日常秒收三、文章收录工具聚合程序介绍
支持Google SEO文章生成100多种语言的外贸软文,支持开源CMS自动发布。(目前支持zblog、WordPress、织梦cms、帝国cms、迅锐cms、小旋风蜘蛛池等自动收发布自动上传),支持文章定时定量发布,支持html与纯文本相互转换。通过IF-TDF算法、simHash、NLP、段落分词、完备的语义检测算法,匹配优质内容,多搜索引擎内容聚合,提高内容原创性和可读性;同时可以自定义内容模板,实现内容模板页面的多样性原创。

AI搜索提取文章合集
------------------by文子seo-button: 61910465----------------
[配置]
;搜索引擎(单篇文章模板只能设置这个)
searchengine=知乎、今日头条、新浪、百度、搜狗、360
;采集页数(默认采集第一页,多页会影响文章生成速度)
页=1
;文本长度(采集内容不得低于此文本长度)
字符长度=20
;标题样式(关键词和联想词不可移动)
titletype=关键词 联想词
;同一篇文章允许被调用的次数
时间 = 3
;是否删除原图
delimg=否
;平台名称,
;z-blog 自动发布:z-blog;
;帝国自动发布:diguo
;织梦自动发布:dede;

;wordpress 自动发布:wordpress;
;小旋风式文章; 小轩风;
;迅锐CMS自动发布:xunrui;
;留空会把生成的文章保存到shengcheng文件夹
平台=z-博客
;生成的文章数
publish_num=1000
;发布间隔秒
发布时间=300
;定时更新,每天固定时间运行程序(如果不定时,留空即可)
固定时间=
;是否打开全文翻译成英文,翻译是yes,不翻译是no
翻译=否
;自动检测要翻译的语言,默认auto
sl=自动
tl=en
;html是否转为文本格式,转为yes,不转为no
html_text=否
解决方案:CN113726526A_人脸数据采集、验证的方法、设备及系统在审
采集交流 • 优采云 发表了文章 • 0 个评论 • 115 次浏览 • 2022-11-20 08:17
人脸数据采集、验证的方法、设备及系统
技术领域
本申请涉及信息技术领域,尤其涉及一种人脸数据采集、验证的方法、设备及系统。
背景技术
随着信息技术的发展,越来越多的场景中会使用到人脸识别技术。在使用人脸识别技术时,首先需要采集人脸数据,然后将采集到的人脸数据发送给处理设备中进行人脸识别。该上述过程中存在着人脸数据重放攻击风险,即攻击者使用此前交易中截获的人脸数据,或者在其他渠道获取的用户人脸数据,在人脸识别的通讯报文中进行替换,从而伪冒用户达到欺骗识别设备的目的。目前的解决方案一般是通过对报文完整性的保护来进行防范,如使用报文签名或者计算报文MAC(Media Access Control,介质访问控制)地址的方式,但是此种并不能从采集源头上防止重放攻击,仍然存在一定的安全风险。
发明内容
本申请的一个目的是提供一种人脸数据采集、验证的方案,用以解决现有方案中无法从采集源头上防止了重放攻击的问题。
本申请实施例提供了一种人脸数据采集方法,所述方法包括:
采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
本申请实施例还提供了一种人脸数据验证方法,所述方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
所述人脸识别服务器对收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种人脸数据采集和验证的方法,该方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
采集设备获取所述随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集的采集设备,所述采集设备包括:
数据接收装置,用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;
视频采集模块,用于采集人脸样本;
人脸输出模块,用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,其中,所述人脸识别服务器包括:
数据收发模块,用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
数据处理模块,用于生成所述随机数,对收录
设备公钥的数字证书进行证书验证,在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集和验证的系统,该系统包括:
采集设备,用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
人脸识别服务器,用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种计算设备,该设备包括用于存储计算机程序指令的存储器和用于执行计算机程序指令的处理器,其中,当该计算机程序指令被该处理器执行时,触发所述设备执行所述的方法。
此外,本申请实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现所述的方法。
本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
附图说明
通过阅读参照以下附图所作的对非限制性实施例所作的详细描述,本申请的其它特征、目的和优点将会变得更明显:
图1为本申请实施例中采集设备在实现人脸数据采集方法时的处理流程图;
图2为本申请实施例中可信人脸数据的一种数据构成示意图;
图3为本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程图;
图4为采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程图;
图5为本申请实施例提供的一种人脸数据采集和验证的方法的处理流程图;
图6为本申请实施例提供的另一种人脸数据采集和验证的方法的处理流程图;
图7为本申请实施例提供的一种计算设备的结构示意图;
附图中相同或相似的附图标记代表相同或相似的部件。
具体实施方式
下面结合附图对本申请作进一步详细描述。
在本申请一个典型的配置中,终端、服务网络的设备均包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体,可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的装置或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。
本申请实施例提供了一种人脸数据采集及验证方法,由采集设备实现人脸数据的采集,并由人脸识别服务器实现人脸数据的验证,该方案在采集设备上就对人脸样本添加了用于校验的内容,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
在实际场景中,所述采集设备可以是具有视频采集及信息处理功能的电子设备,例如收录
摄像头以及数据处理芯片的设备。其中,所述摄像头可以是能够采集彩色图像的普通摄像头,或者也可以是能够采集深度信息、红外信息等额外信息的摄像头。所述人脸识别服务器在实现时可以包括但不限于单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现,可以用于实现设置闹钟时的部分处理功能。在此,云由基于云计算(Cloud Computing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
图1示出了本申请实施例中采集设备在实现人脸数据采集方法时的处理流程,包括以下处理步骤:
步骤S101,采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本。所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
步骤S102,采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。其中,所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
步骤S103,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
图3示出了本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程,包括以下处理步骤:
步骤S301,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
步骤S302,人脸识别服务器获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得。
步骤S303,人脸识别服务器对收录
设备公钥的数字证书进行证书验证。其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
步骤S304,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
步骤S305,在通过签名验证后,所述人脸识别服务器对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数进行验证,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。由此,人脸识别服务器在生成对应于本次人脸数据采集的随机数,并将其提供给采集设备时,可以接收本地业务终端发送的随机数获取请求,而后根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
图4示出了采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程,具体流程包括准备阶段和使用阶段。其中,准备阶段的流程如下:
P1)为采集设备配置设备ID(即设备标识)和设备可信密钥对,其中设备ID是与每台采集设备一一对应的,设备可信密钥对可以是每台采集设备一套,也可以是一批次采集设备共享一套。在使用阶段之前,将设备ID和其对应的设备可信密钥对中的设备公钥上传到可信管理服务器上。
P2)采集设备在出厂时,在每一台采集设备写入其对应的设备ID,用来唯一标识该采集设备;另外,需要在采集设备中写入设备可信密钥对的设备私钥以及对应的设备公钥证书。
P3)人脸识别服务器从可信管理服务器获取到其用以签发设备公钥证书的私钥所对应的公钥。
使用阶段的流程如下:
S1)用户在本地业务终端上发起业务请求,例如实际场景中可以是人脸认证、人脸识别等与需要基于人脸数据实现的业务请求,本地业务终端从人脸识别服务器请求一个随机数;
S2)本地业务终端调用采集设备对用户进行人脸采集,并将随机数发送给采集设备;
S3)采集设备对用户人脸的原创
样本进行采集后,经过质量判断和活体检测后,作为人脸样本与设备标识、传入的随机数等信息一起使用设备私钥进行签名,获得人脸数据签名,然后与收录
设备公钥的数字证书一起形成可信人脸数据后,返回给本地业务终端。
S4)本地业务终端将获得的可信人脸数据块送至人脸识别服务器进行处理。
S5)人脸识别服务器对可信人脸数据进行验证,具体方法为:先使用可信管理服务器公钥验证可信人脸数据中附带的数字证书的合法性。如果验证通过,则使用该数字证书中的设备公钥,验证可信人脸数据中的人脸数据签名的合法性。如果验证通过,则验证可信人脸数据中的随机数与人脸识别服务器生成并保存的随机数是否一致。如果一致,则认为验证通过,可以使用该可信人脸数据中的人脸样本进行后续业务处理,例如进行人脸注册或者人脸识别等;
S6)人脸识别服务器返回处理结果给本地业务终端,例如人脸注册或者人脸识别的结果是否成功。
基于前述人脸数据的采集方案和验证方案,本申请实施例还提供了一种人脸数据采集和验证的方法,该方法所涉及的人脸识别服务器和采集设备的交互过程如下图5所示,包括如下步骤:
步骤S501,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
步骤S502,采集设备获取所述随机数,并采集人脸样本;
步骤S503,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S504,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S505,所述人脸识别服务器获取由采集设备生成的可信人脸数据;
步骤S506,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S507,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S508,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的一些实施例中,实现人脸数据采集和验证的方法时,还可以包括本地业务终端,所述本地业务终端与人脸识别服务器、采集设备之间的交互过程如下图6所示,包括如下步骤:
步骤S601,本地业务终端获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令;
步骤S602,本地业务终端向所述人脸识别服务器发送随机数获取请求;
步骤S603,人脸识别服务器根据所述随机数获取请求生成对应于本次人脸数据采集的随机数;
步骤S604,人脸识别服务器向所述本地业务终端返回所述随机数;
步骤S605,本地业务终端向所述采集设备发送采集调用指令和所述随机数;
步骤S606,采集设备获取所述随机数,并根据采集调用指令采集人脸样本;
步骤S607,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S608,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S609,所述人脸识别服务器获取由采集设备生成的可信人脸数据。采集设备在生成可信人脸数据之后,可以先将其发送给本地业务终端,再由本地业务终端将可信人脸数据发送至人脸识别服务器。
步骤S610,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S611,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S612,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
基于同一发明构思,本申请实施例中还提供了用于人脸数据采集的采集设备、用于人脸数据验证的人脸识别服务器以及用于实现人脸数据采集和验证的系统,所述采集设备、人脸识别服务器和系统对应的方法是前述实施例中相应方法,并且其解决问题的原理与该方法相似。
本申请实施例提供的一种用于人脸数据采集的采集设备的结构可以至少包括数据接收装置、视频采集模块和人脸输出模块。其中,所述数据接收装置用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;所述视频采集模块用于采集人脸样本;所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
由此,本申请的一些实施例中,所述视频采集模块可以包括采集单元和检测评估单元,所述采集单元用于采集人脸的原创
样本,而所述检测评估单元用于对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在获得待签名数据和人脸数据签名之后,人脸输出模块可以根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。由此,本申请的一些实施例中,所述采集设备还可以包括数据接收模块,该数据接收模块用于在获取人脸的原创
样本之前,获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,该人脸识别服务器可以包括数据收发模块和数据处理模块。其中,数据收发模块用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得人脸数据签名。
所述数据处理模块用于生成所述随机数,以及根据可信人脸数据进行各种验证,包括用于对收录
设备公钥的数字证书进行证书验证、使用所述数字证书中的设备公钥对人脸数据签名进行签名验证以及对校验数据进行校验数据验证。
其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
在通过证书验证后,所述人脸识别服务器的数据处理模块使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
在通过签名验证后,所述人脸识别服务器的数据处理模块对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,所述数据收发模块还用于接收本地业务终端发送的随机数获取请求,并向所述本地业务终端返回随机数,以使所述本地业务终端将所述随机数提供给采集设备;所述数据处理模块还用于根据所述随机数获取请求生成随机数。即用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。
此外,本申请的一些实施例还提供了一种用于人脸数据采集和验证的系统,系统至少包括采集设备和人脸识别服务器。
采集设备用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
人脸识别服务器则用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请的另一实施例中,所述该系统还可以包括本地业务终端。所述本地业务终端用于获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令,并向所述人脸识别服务器发送随机数获取请求;获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;以及向所述采集设备发送采集调用指令和所述随机数。
所述采集装置在采集人脸样本时,可以根据所述采集调用指令采集人脸样本;而所述人脸识别服务器在提供随机数时,可以根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
综上所述,本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
另外,本申请的一部分可被应用为计算机程序产品,例如计算机程序指令,当其被计算机执行时,通过该计算机的操作,可以调用或提供根据本申请的方法和/或技术方案。而调用本申请的方法的程序指令,可能被存储在固定的或可移动的记录介质中,和/或通过广播或其他信号承载媒体中的数据流而被传输,和/或被存储在根据程序指令运行的计算机设备的工作存储器中。在此,根据本申请的一些实施例包括一个如图7所示的计算设备,该设备包括存储有计算机可读指令的一个或多个存储器710和用于执行计算机可读指令的处理器720,其中,当该计算机可读指令被该处理器执行时,使得所述设备执行基于前述本申请的多个实施例的方法和/或技术方案。
此外,本申请的一些实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现前述本申请的多个实施例的方法和/或技术方案。
需要注意的是,本申请可在软件和/或软件与硬件的组合体中被实施,例如,可采用专用集成电路(ASIC)、通用目的计算机或任何其他类似硬件设备来实现。在一些实施例中,本申请的软件程序可以通过处理器执行以实现上文步骤或功能。同样地,本申请的软件程序(包括相关的数据结构)可以被存储到计算机可读记录介质中,例如,RAM存储器,磁或光驱动器或软磁盘及类似设备。另外,本申请的一些步骤或功能可采用硬件来实现,例如,作为与处理器配合从而执行各个步骤或功能的电路。
对于本领域技术人员而言,显然本申请不限于上述示范性实施例的细节,而且在不背离本申请的精神或基本特征的情况下,能够以其他的具体形式实现本申请。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本申请的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本申请内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。装置权利要求中陈述的多个单元或装置也可以由一个单元或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
整套解决方案:优采云
采集器之PBOOTCMS入库
网上已经有优采云
采集
器的使用方法。
我正在使用从云端下载的 优采云
PBOOTCMS 规则。但是在使用的时候发现在存储选择中只能存储新闻中心、新闻动态和公司动态三个类别。
今天我们就来说说如何修改存储列。顺带从头到尾说说优采云
的使用方法。
大哥step:下载插件。
首先我们在后台云平台上搜索PBOOT找到这个插件,然后下载。
看一下,这里可以看到一个APP的logo:PbootDemoSkycaiji
这个方法就是下载官方插件的方法。或者,您可以自己发布一个插件。
自己发布还是官方下载都无所谓。如果不是很熟悉,直接使用官方插件即可。
第 2 步:让我们创建一个新任务。
你可以随意填写。
然后点击:采集器设置
根据需要填写这些内容。
然后设置其他三个,比较简单。在此不再赘述。
第 3 步:让我们点击发布设置。
按选择,然后选择绑定。
这时候会报错。由于PBOOCMS不是系统已知的CMS,所以需要添加:@pboot
下面的插件会显示我们自己创建安装的插件。选择您使用的那个。如果我选择从云平台下载的pboot示例。
根据需要填写相关选项。
这时我们会发现,在分类栏目中,我们只能看到三个栏目:新闻中心、公司新闻、行业新闻。
这也是我们今天要讲的重点。
正如我们刚才所说,这是要记住的事情。这实际上是发布时调用的 PHP 文件。具体路径为: 在你的优采云
采集
网站的根目录下,找到这个文件夹:
\\plugin\\release\\cms
可以看到,有两个与刚才APP名称同名的PHP文件。你使用哪个插件对应修改哪个PHP文件。
我用的是官方的PbootDemoSkycaiji,我们打开这个PHP文件。
在醉酒的底部我们看到
public function param_option_category(){
<p>
$catsDb=$this->db()->table('__CONTENT_SORT__')->where("contenttpl='news.html'")->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}</p>
它指定了一个news.html,如果你改成:case.html,你会在优采云
的后台看到publication classification变成了一个case栏。因此,如果我们要显示所有的列,我们可以这样修改。
public function param_option_category(){
$catsDb=$this->db()->table('__CONTENT_SORT__')->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}
然后回到发布后台,就可以看到了。列出所有列。然后正常采集
和释放。 查看全部
解决方案:CN113726526A_人脸数据采集、验证的方法、设备及系统在审
人脸数据采集、验证的方法、设备及系统
技术领域
本申请涉及信息技术领域,尤其涉及一种人脸数据采集、验证的方法、设备及系统。
背景技术
随着信息技术的发展,越来越多的场景中会使用到人脸识别技术。在使用人脸识别技术时,首先需要采集人脸数据,然后将采集到的人脸数据发送给处理设备中进行人脸识别。该上述过程中存在着人脸数据重放攻击风险,即攻击者使用此前交易中截获的人脸数据,或者在其他渠道获取的用户人脸数据,在人脸识别的通讯报文中进行替换,从而伪冒用户达到欺骗识别设备的目的。目前的解决方案一般是通过对报文完整性的保护来进行防范,如使用报文签名或者计算报文MAC(Media Access Control,介质访问控制)地址的方式,但是此种并不能从采集源头上防止重放攻击,仍然存在一定的安全风险。
发明内容
本申请的一个目的是提供一种人脸数据采集、验证的方案,用以解决现有方案中无法从采集源头上防止了重放攻击的问题。
本申请实施例提供了一种人脸数据采集方法,所述方法包括:
采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
本申请实施例还提供了一种人脸数据验证方法,所述方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
所述人脸识别服务器对收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种人脸数据采集和验证的方法,该方法包括:
人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
采集设备获取所述随机数,并采集人脸样本;
所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
所述人脸识别服务器获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集的采集设备,所述采集设备包括:
数据接收装置,用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;
视频采集模块,用于采集人脸样本;
人脸输出模块,用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,其中,所述人脸识别服务器包括:
数据收发模块,用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据,其中,所述可信人脸数据包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得;
数据处理模块,用于生成所述随机数,对收录
设备公钥的数字证书进行证书验证,在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种用于人脸数据采集和验证的系统,该系统包括:
采集设备,用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
人脸识别服务器,用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请实施例还提供了一种计算设备,该设备包括用于存储计算机程序指令的存储器和用于执行计算机程序指令的处理器,其中,当该计算机程序指令被该处理器执行时,触发所述设备执行所述的方法。
此外,本申请实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现所述的方法。
本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
附图说明
通过阅读参照以下附图所作的对非限制性实施例所作的详细描述,本申请的其它特征、目的和优点将会变得更明显:
图1为本申请实施例中采集设备在实现人脸数据采集方法时的处理流程图;
图2为本申请实施例中可信人脸数据的一种数据构成示意图;
图3为本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程图;
图4为采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程图;
图5为本申请实施例提供的一种人脸数据采集和验证的方法的处理流程图;
图6为本申请实施例提供的另一种人脸数据采集和验证的方法的处理流程图;

图7为本申请实施例提供的一种计算设备的结构示意图;
附图中相同或相似的附图标记代表相同或相似的部件。
具体实施方式
下面结合附图对本申请作进一步详细描述。
在本申请一个典型的配置中,终端、服务网络的设备均包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体,可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的装置或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。
本申请实施例提供了一种人脸数据采集及验证方法,由采集设备实现人脸数据的采集,并由人脸识别服务器实现人脸数据的验证,该方案在采集设备上就对人脸样本添加了用于校验的内容,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
在实际场景中,所述采集设备可以是具有视频采集及信息处理功能的电子设备,例如收录
摄像头以及数据处理芯片的设备。其中,所述摄像头可以是能够采集彩色图像的普通摄像头,或者也可以是能够采集深度信息、红外信息等额外信息的摄像头。所述人脸识别服务器在实现时可以包括但不限于单个网络服务器、多个网络服务器集或基于云计算的计算机集合等实现,可以用于实现设置闹钟时的部分处理功能。在此,云由基于云计算(Cloud Computing)的大量主机或网络服务器构成,其中,云计算是分布式计算的一种,由一群松散耦合的计算机集组成的一个虚拟计算机。
图1示出了本申请实施例中采集设备在实现人脸数据采集方法时的处理流程,包括以下处理步骤:
步骤S101,采集设备获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本。所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
步骤S102,采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。其中,所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
步骤S103,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
图3示出了本申请实施例提供的人脸识别服务器在实现人脸数据验证方法时的处理流程,包括以下处理步骤:
步骤S301,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;
步骤S302,人脸识别服务器获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得。
步骤S303,人脸识别服务器对收录
设备公钥的数字证书进行证书验证。其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
步骤S304,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
步骤S305,在通过签名验证后,所述人脸识别服务器对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数进行验证,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。由此,人脸识别服务器在生成对应于本次人脸数据采集的随机数,并将其提供给采集设备时,可以接收本地业务终端发送的随机数获取请求,而后根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
图4示出了采用本申请实施提供的方案实现人脸数据采集和验证时各方设备之间的交互流程,具体流程包括准备阶段和使用阶段。其中,准备阶段的流程如下:
P1)为采集设备配置设备ID(即设备标识)和设备可信密钥对,其中设备ID是与每台采集设备一一对应的,设备可信密钥对可以是每台采集设备一套,也可以是一批次采集设备共享一套。在使用阶段之前,将设备ID和其对应的设备可信密钥对中的设备公钥上传到可信管理服务器上。
P2)采集设备在出厂时,在每一台采集设备写入其对应的设备ID,用来唯一标识该采集设备;另外,需要在采集设备中写入设备可信密钥对的设备私钥以及对应的设备公钥证书。
P3)人脸识别服务器从可信管理服务器获取到其用以签发设备公钥证书的私钥所对应的公钥。
使用阶段的流程如下:
S1)用户在本地业务终端上发起业务请求,例如实际场景中可以是人脸认证、人脸识别等与需要基于人脸数据实现的业务请求,本地业务终端从人脸识别服务器请求一个随机数;
S2)本地业务终端调用采集设备对用户进行人脸采集,并将随机数发送给采集设备;
S3)采集设备对用户人脸的原创
样本进行采集后,经过质量判断和活体检测后,作为人脸样本与设备标识、传入的随机数等信息一起使用设备私钥进行签名,获得人脸数据签名,然后与收录
设备公钥的数字证书一起形成可信人脸数据后,返回给本地业务终端。
S4)本地业务终端将获得的可信人脸数据块送至人脸识别服务器进行处理。
S5)人脸识别服务器对可信人脸数据进行验证,具体方法为:先使用可信管理服务器公钥验证可信人脸数据中附带的数字证书的合法性。如果验证通过,则使用该数字证书中的设备公钥,验证可信人脸数据中的人脸数据签名的合法性。如果验证通过,则验证可信人脸数据中的随机数与人脸识别服务器生成并保存的随机数是否一致。如果一致,则认为验证通过,可以使用该可信人脸数据中的人脸样本进行后续业务处理,例如进行人脸注册或者人脸识别等;
S6)人脸识别服务器返回处理结果给本地业务终端,例如人脸注册或者人脸识别的结果是否成功。
基于前述人脸数据的采集方案和验证方案,本申请实施例还提供了一种人脸数据采集和验证的方法,该方法所涉及的人脸识别服务器和采集设备的交互过程如下图5所示,包括如下步骤:
步骤S501,人脸识别服务器生成对应于本次人脸数据采集的随机数,并将其提供给采集设备;
步骤S502,采集设备获取所述随机数,并采集人脸样本;
步骤S503,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S504,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S505,所述人脸识别服务器获取由采集设备生成的可信人脸数据;

步骤S506,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S507,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S508,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的一些实施例中,实现人脸数据采集和验证的方法时,还可以包括本地业务终端,所述本地业务终端与人脸识别服务器、采集设备之间的交互过程如下图6所示,包括如下步骤:
步骤S601,本地业务终端获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令;
步骤S602,本地业务终端向所述人脸识别服务器发送随机数获取请求;
步骤S603,人脸识别服务器根据所述随机数获取请求生成对应于本次人脸数据采集的随机数;
步骤S604,人脸识别服务器向所述本地业务终端返回所述随机数;
步骤S605,本地业务终端向所述采集设备发送采集调用指令和所述随机数;
步骤S606,采集设备获取所述随机数,并根据采集调用指令采集人脸样本;
步骤S607,所述采集设备将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,其中,所述校验数据包括所述随机数;
步骤S608,所述采集设备根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据;
步骤S609,所述人脸识别服务器获取由采集设备生成的可信人脸数据。采集设备在生成可信人脸数据之后,可以先将其发送给本地业务终端,再由本地业务终端将可信人脸数据发送至人脸识别服务器。
步骤S610,所述人脸识别服务器对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;
步骤S611,在通过证书验证后,所述人脸识别服务器使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;
步骤S612,在通过签名验证后,所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
基于同一发明构思,本申请实施例中还提供了用于人脸数据采集的采集设备、用于人脸数据验证的人脸识别服务器以及用于实现人脸数据采集和验证的系统,所述采集设备、人脸识别服务器和系统对应的方法是前述实施例中相应方法,并且其解决问题的原理与该方法相似。
本申请实施例提供的一种用于人脸数据采集的采集设备的结构可以至少包括数据接收装置、视频采集模块和人脸输出模块。其中,所述数据接收装置用于获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;所述视频采集模块用于采集人脸样本;所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,并根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据,其中,所述校验数据包括所述随机数。
所述人脸样本可以是收录
人脸图像的视频数据和/或人脸3D数据,可以通过各类具有视频采集功能的装置实现,例如RGB摄像头、深度摄像头等。
在本申请的一些实施例中,可以将摄像头直接采集到的数据作为人脸的原创
样本,而后对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。其中,所述质量评估是指对人脸的原创
样本的质量进行评估,以判断采集到的数据是否符合后续人脸识别处理的要求。对图像进行质量评估后,避免将不符合识别要求的人脸样本进行人脸识别,可以提高后续人脸识别处理时的准确度。实际场景中,可以根据人脸图像区域占整体图像区域的大小、人脸图像的清晰度、图像中收录
的人脸的完整度、人脸的姿态和角度、人脸的光照情况等进行质量评估,通过设定阈值的方式判断上述的质量评估项是否满足要求,若满足要求,则判定为通过质量评估;若不满足要求,则判定为未通过质量评估。例如,本实施例中可以设定质量评估项包括:人脸图像区域占整体图像区域是否大于60%,人脸完整度大于90%,人脸正面与镜头的角度小于20°,若采集的原创
样本符合所有的阈值,则可以认为该原创
样本通过了质量评估。
活体检测是用于确定采集的原创
样本是否来自于用户本人活体,而不是来自于攻击者持有的图片、视频或者面具等假体,从而进一步提升安全性。在实际场景中,活体检测可以根据应用场景的不同,而采用不同的检测方式,例如若用于采集原创
样本的摄像头仅可以获取二维图像数据,则可以采用动作配合式的活体检测,由显示屏等输出装置提示用户执行相应的动作,由于假体一般无法根据提示做出相应的动作,因此可以根据二维图像数据判定用户是否在预设时间内做出了相应的动作,从而判断采集到的原创
样本是否来自于活体。若用于采集原创
样本的摄像头还可以采集到红外信息、深度信息等,则可以采用利用红外或者深度图像的活体检测方式。
由此,本申请的一些实施例中,所述视频采集模块可以包括采集单元和检测评估单元,所述采集单元用于采集人脸的原创
样本,而所述检测评估单元用于对所述原创
样本进行质量评估和/或活体检测,将通过质量评估和/或活体检测的原创
样本作为人脸样本。
在本申请实施例中,可以根据实际应用场景的需求同时采用质量评估和活体检测,或者也可以仅采用其中一种。例如在本实施例中,会对原创
样本同时进行质量评估和活体检测,仅当同时通过质量评估和活体检测后,该人脸的原创
样本才会作为人脸样本,被用于后续的处理,否则可以重新采集原创
样本直至通过质量评估和活体检测。
所述人脸输出模块用于将人脸样本和校验数据作为待签名数据,使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名。所述校验数据用于在后续验证过程中使用,可以包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。每一次生成的随机数都对应于一次的人脸数据采集和验证,例如人脸识别服务器生成一个随机数RN1后,会通过相应的方式将该随机数RN1提供至采集设备,采集设备会在成功采集到一次人脸样本F1后,该随机数RN1会与本次采集到的人脸样本F1一起作为待签名数据。若采集设备进行下一次采集时,则不会再使用随机数RN1,而是会获得人脸识别服务器生成的一个新的随机数RN2。由此,人脸识别服务器在生成随机数RN1后,将其保存,当获取到人脸样本F1对应的可信人脸数据之后,可以将其中的随机数与保存的随机数比较,若都是RN1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在本申请的另一些实施例中,所述校验数据还可以包括预先为所述采集设备分配的设备标识,由此可以同时使用随机数和设备标识作为校验数据的内容。所述设备标识与采集设备对应,预先为采集设备分配的方式可以在采集设备出厂时由厂商通过安全的方式生成并写入到采集设备内,或者也可以在采集设备初始化时由用户进行注册、申请等。每台采集设备可以有一个唯一的设备标识,即设备标识与采集设备一一对应。由此,将所述采集设备的设备标识作为校验数据中的一项内容之后,人脸识别服务器可以通过其它方式获取并存储采集设备的设备标识,在获取到人脸样本F1对应的可信人脸数据之后,可以将其中的设备标识与预先存储的设备标识比较,若两者都是ID1,则验证通过,否则,可以认为获得的数据不安全,验证未通过。
在获得待签名数据和人脸数据签名之后,人脸输出模块可以根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。例如,当待签名数据收录
人脸样本、设备标识、随机数时,可信人脸数据中的数据构成可以如图2所示。
所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA(Certificate Authority、证书授权)机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
在本申请的一些实施例中,采集设备在生成可信人脸数据之后,可以将所述可信人脸数据提供给至人脸识别服务器,以使所述人脸识别服务器对所述可信人脸数据进行验证。
在实际场景中,采集设备可以基于本地业务终端发送的采集调用指令来触发人脸数据的采集。由此,本申请的一些实施例中,所述采集设备还可以包括数据接收模块,该数据接收模块用于在获取人脸的原创
样本之前,获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数。其中,本地业务终端可以是具有人脸验证、人脸注册等功能的设备,当用户在本地业务终端执行特定的操作后,会启动相应的业务处理流程。例如,当用户点击某一按钮后,即启动了人脸注册的业务处理流程,此时本地业务终端会生成相应的业务请求,该业务请求可以收录
了采集调用指令,发送给采集设备后即可触发采集设备执行前述的人脸数据采集方法。
同时,本地业务终端启动了人脸注册的业务处理流程后,会向人脸识别服务器请求一个随机数,人脸识别服务器会根据该随机数获取请求生成一个随机数并返回给本地业务终端。本地业务终端向采集终端发送的业务请求中也可以收录
该随机数,由此使得采集设备可以将该随机数添加至可信人脸数据,以实现后续的验证过程。即,采集设备在获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数,并采集人脸样本时,可以获取本地业务终端发送的采集调用指令和对应于本次人脸数据采集的随机数,并根据所述采集调用指令采集人脸样本。其中,所述采集调用指令由所述本地业务终端在获取到用户发起的人脸识别业务请求后生成,所述随机数由所述人脸识别服务器生成,并由所述本地业务终端在获取到用户发起的人脸识别业务请求后向所述人脸识别服务器请求获取。
本申请实施例还提供了一种用于人脸数据验证的人脸识别服务器,该人脸识别服务器可以包括数据收发模块和数据处理模块。其中,数据收发模块用于将对应于本次人脸数据采集的随机数提供给采集设备,以使所述采集设备生成收录
所述随机数的可信人脸数据;以及获取由采集设备生成的可信人脸数据。所述可信人脸数据的生成过程可以参考前述内容,此处不再赘述,可信人脸数据中包括待签名数据、人脸数据签名和收录
设备公钥的数字证书,所述待签名数据包括所述采集设备采集到的人脸样本和校验数据,所述校验数据包括所述随机数,所述人脸数据签名由采集设备使用预先为所述采集设备分配的设备私钥进行签名获得人脸数据签名。
所述数据处理模块用于生成所述随机数,以及根据可信人脸数据进行各种验证,包括用于对收录
设备公钥的数字证书进行证书验证、使用所述数字证书中的设备公钥对人脸数据签名进行签名验证以及对校验数据进行校验数据验证。
其中,所述设备公钥和设备私钥为一个密钥对,可以预先生成后,人脸数据的采集和验证过程中使用。而所述收录
设备公钥的数字证书可以来自于可信管理服务器,所述可信管理服务器可以是CA机构的服务器,可用于证明该数字证书中的设备公钥是合法、可信的。
数字证书中的内容可以包括至少收录
设备公钥的待签名数据,使用可信管理服务器私钥对该待签名数据进行签名后所获得的数字签名。在验证过程中,人脸识别服务器可以预先获取可信管理服务器公钥,使用可信管理服务器公钥对数字证书中的数字签名进行解密,获得数字签名的原文,进而与数字证书本身所携带的、至少收录
设备公钥的待签名数据进行比较,若完全一致,则说明数字证书验证通过。此外,若可信管理服务器私钥处理收录
设备公钥的待签名数据之前,对该待签名数据进行过哈希计算,则验证时使用可信管理服务器公钥解密获得的原文即为进行哈希计算后的摘要。此时,人脸识别服务器要对数字证书中本身所携带、至少收录
设备公钥的待签名数据采用同样的哈希算法进行计算,获取到摘要之后,与通过可信管理服务器公钥解密获得的摘要进行比较,若两者完全一致,则说明数字证书验证通过。
在通过证书验证后,所述人脸识别服务器的数据处理模块使用所述数字证书中的设备公钥对人脸数据签名进行签名验证。由于可信人脸数据中的人脸数据签名由待签名数据通过设备私钥加密获得,因此理论上可以使用设备公钥对人脸数据签解密获得数据原文,即收录
人脸样本和校验数据的待签名数据。由此,对人脸数据签名进行验证过程与数字证书的验证过程类似,此处不再水煮,其区别在于数据签名的验证过程使用的密钥为设备公钥,而数字证书的验证过程使用的密钥为可信管理服务器公钥。当人脸数据签名验证通过后,可以认为可信人脸数据中的待签名数,即人脸样本和校验数据是合法、可信的,可以用于后续的处理。
在通过签名验证后,所述人脸识别服务器的数据处理模块对校验数据进行验证。在本申请的一些实施例中,所述校验数据包括由人脸识别服务器生成的、对应于本次人脸数据采集的随机数。由此,人脸识别服务器对校验数据进行验证时,可以采用校验数据中的随机数,即所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
在本申请的另一些实施例中,若同时采用随机数和设备标识进行验证时,则所述人脸识别服务器对校验数据中收录
的随机数与生成后保存的随机数进行比较,以及对校验数据中收录
的设备标识与预先存储的、所述采集设备的设备标识进行比较,若两个比较结果均为相同,确认通过校验数据验证。
在实际场景中,所述数据收发模块还用于接收本地业务终端发送的随机数获取请求,并向所述本地业务终端返回随机数,以使所述本地业务终端将所述随机数提供给采集设备;所述数据处理模块还用于根据所述随机数获取请求生成随机数。即用于验证的随机数是人脸识别服务器在接收本地业务终端发送的随机数获取请求后,根据所述随机数获取请求生成,并向所述本地业务终端返回的。
此外,本申请的一些实施例还提供了一种用于人脸数据采集和验证的系统,系统至少包括采集设备和人脸识别服务器。
采集设备用于获取对应于本次人脸数据采集的随机数,并采集人脸样本;将所述人脸样本和校验数据作为待签名数据,并使用预先为所述采集设备分配的设备私钥进行签名,获得人脸数据签名,所述校验数据包括所述随机数;以及根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书,获得可信人脸数据。
人脸识别服务器则用于人脸识别服务器生成所述随机数,并将其提供给采集设备;获取由采集设备生成的可信人脸数据,并对所述可信人脸数据中收录
设备公钥的数字证书进行证书验证;在通过证书验证后,使用所述数字证书中的设备公钥对人脸数据签名进行签名验证;以及在通过签名验证后,对校验数据中收录
的随机数与生成后保存的随机数进行比较,基于相同的比较结果确认通过校验数据验证。
本申请的另一实施例中,所述该系统还可以包括本地业务终端。所述本地业务终端用于获取用户发起的人脸识别业务请求,根据所述人脸识别业务请求生成采集调用指令,并向所述人脸识别服务器发送随机数获取请求;获取由人脸识别服务器生成的、对应于本次人脸数据采集的随机数;以及向所述采集设备发送采集调用指令和所述随机数。
所述采集装置在采集人脸样本时,可以根据所述采集调用指令采集人脸样本;而所述人脸识别服务器在提供随机数时,可以根据所述随机数获取请求生成对应于本次人脸数据采集的随机数,并向所述本地业务终端返回所述随机数,以使所述本地业务终端将所述随机数提供给采集设备。
综上所述,本申请实施例提供的方案中,采集设备在采集到人脸样本后,将人脸样本与收录
随机数的校验数据一起构成待签名数据,使用设备私钥进行签名获得人脸数据签名,进而根据所述待签名数据、人脸数据签名和收录
设备公钥的数字证书获得可信人脸数据。人脸识别服务器在对采集设备生成的可信人脸数据进行验证时,依次对收录
设备公钥的数字证书、人脸数据签名以及校验数据进行验证,在通过这些验证之后,即完成验证的过程,从而可将人脸样本进行业务处理。由于该方案在采集设备上就对人脸样本添加了用于校验的内容,其中收录
的随机数仅对应于本次人脸数据采集,有效提高了安全性,即时传输的通讯报文被攻击者替换,也无法通过后续的验证,因此从采集源头上防止了重放攻击。
另外,本申请的一部分可被应用为计算机程序产品,例如计算机程序指令,当其被计算机执行时,通过该计算机的操作,可以调用或提供根据本申请的方法和/或技术方案。而调用本申请的方法的程序指令,可能被存储在固定的或可移动的记录介质中,和/或通过广播或其他信号承载媒体中的数据流而被传输,和/或被存储在根据程序指令运行的计算机设备的工作存储器中。在此,根据本申请的一些实施例包括一个如图7所示的计算设备,该设备包括存储有计算机可读指令的一个或多个存储器710和用于执行计算机可读指令的处理器720,其中,当该计算机可读指令被该处理器执行时,使得所述设备执行基于前述本申请的多个实施例的方法和/或技术方案。
此外,本申请的一些实施例还提供了一种计算机可读介质,其上存储有计算机程序指令,所述计算机可读指令可被处理器执行以实现前述本申请的多个实施例的方法和/或技术方案。
需要注意的是,本申请可在软件和/或软件与硬件的组合体中被实施,例如,可采用专用集成电路(ASIC)、通用目的计算机或任何其他类似硬件设备来实现。在一些实施例中,本申请的软件程序可以通过处理器执行以实现上文步骤或功能。同样地,本申请的软件程序(包括相关的数据结构)可以被存储到计算机可读记录介质中,例如,RAM存储器,磁或光驱动器或软磁盘及类似设备。另外,本申请的一些步骤或功能可采用硬件来实现,例如,作为与处理器配合从而执行各个步骤或功能的电路。
对于本领域技术人员而言,显然本申请不限于上述示范性实施例的细节,而且在不背离本申请的精神或基本特征的情况下,能够以其他的具体形式实现本申请。因此,无论从哪一点来看,均应将实施例看作是示范性的,而且是非限制性的,本申请的范围由所附权利要求而不是上述说明限定,因此旨在将落在权利要求的等同要件的含义和范围内的所有变化涵括在本申请内。不应将权利要求中的任何附图标记视为限制所涉及的权利要求。此外,显然“包括”一词不排除其他单元或步骤,单数不排除复数。装置权利要求中陈述的多个单元或装置也可以由一个单元或装置通过软件或者硬件来实现。第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
整套解决方案:优采云
采集器之PBOOTCMS入库
网上已经有优采云
采集
器的使用方法。
我正在使用从云端下载的 优采云
PBOOTCMS 规则。但是在使用的时候发现在存储选择中只能存储新闻中心、新闻动态和公司动态三个类别。
今天我们就来说说如何修改存储列。顺带从头到尾说说优采云
的使用方法。
大哥step:下载插件。
首先我们在后台云平台上搜索PBOOT找到这个插件,然后下载。
看一下,这里可以看到一个APP的logo:PbootDemoSkycaiji
这个方法就是下载官方插件的方法。或者,您可以自己发布一个插件。
自己发布还是官方下载都无所谓。如果不是很熟悉,直接使用官方插件即可。
第 2 步:让我们创建一个新任务。
你可以随意填写。
然后点击:采集器设置
根据需要填写这些内容。
然后设置其他三个,比较简单。在此不再赘述。

第 3 步:让我们点击发布设置。
按选择,然后选择绑定。
这时候会报错。由于PBOOCMS不是系统已知的CMS,所以需要添加:@pboot
下面的插件会显示我们自己创建安装的插件。选择您使用的那个。如果我选择从云平台下载的pboot示例。
根据需要填写相关选项。
这时我们会发现,在分类栏目中,我们只能看到三个栏目:新闻中心、公司新闻、行业新闻。
这也是我们今天要讲的重点。
正如我们刚才所说,这是要记住的事情。这实际上是发布时调用的 PHP 文件。具体路径为: 在你的优采云
采集
网站的根目录下,找到这个文件夹:
\\plugin\\release\\cms
可以看到,有两个与刚才APP名称同名的PHP文件。你使用哪个插件对应修改哪个PHP文件。
我用的是官方的PbootDemoSkycaiji,我们打开这个PHP文件。
在醉酒的底部我们看到
public function param_option_category(){
<p>

$catsDb=$this->db()->table('__CONTENT_SORT__')->where("contenttpl='news.html'")->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}</p>
它指定了一个news.html,如果你改成:case.html,你会在优采云
的后台看到publication classification变成了一个case栏。因此,如果我们要显示所有的列,我们可以这样修改。
public function param_option_category(){
$catsDb=$this->db()->table('__CONTENT_SORT__')->limit(100)->select();//文章分类
$catList=array();
foreach ($catsDb as $cat){
$catList[$cat['id']]=$cat['name'];
}
return $catList;
}
然后回到发布后台,就可以看到了。列出所有列。然后正常采集
和释放。
解决方案:Windows平台实现Unity下窗体|摄像头|屏幕采集并推送至RTMP服务器
采集交流 • 优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-11-19 07:31
技术背景
随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业的虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。
基于此,许多开发者苦于 Unity 环境中缺乏低延迟的推拉流解决方案。几年前,我们在Unity环境下推出了一款跨平台的低延迟RTMP|RTSP直播播放器,解决了很多问题。延迟关键的使用场景。
随着时间的推移,越来越多的开发者联系我们,希望我们能够在Unity环境下推出RTMP推送模块,从Unity中获取实时数据,实现延迟更低、效率更高的数据传输和推送。基于此,我们发布了Unity环境下的RTMP推送模块。
本文以Windows平台为例。数据来源为Unity窗口、摄像头或整屏、编码传输模块、或调用大牛直播SDK(官方)的原生接口。简单的界面是一个预览:
技术实现 1. 基本初始化
private bool InitSDK()
{
if (!is_pusher_sdk_init_)
{
// 设置日志路径(请确保目录存在)
String log_path = "D:\\pulisherlog";
NTSmartLog.NT_SL_SetPath(log_path);
UInt32 isInited = NTSmartPublisherSDK.NT_PB_Init(0, IntPtr.Zero);
if (isInited != 0)
{
Debug.Log("调用NT_PB_Init失败..");
return false;
}
is_pusher_sdk_init_ = true;
}
return true;
}
2.调用Open()接口获取推送实例
public bool OpenPublisherHandle(uint video_option, uint audio_option)
{
if (publisher_handle_ != IntPtr.Zero)
{
return true;
}
publisher_handle_count_ = 0;
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_Open(out publisher_handle_,
video_option, audio_option, 0, IntPtr.Zero))
{
return false;
}
if (publisher_handle_ != IntPtr.Zero)
{
pb_event_call_back_ = new NT_PB_SDKEventCallBack(PbEventCallBack);
NTSmartPublisherSDK.NT_PB_SetEventCallBack(publisher_handle_, IntPtr.Zero, pb_event_call_back_);
return true;
}
else
{
return false;
}
}
3.初始化参数配置
这里需要注意的是,如果要采集unity窗口,需要设置图层模式,先填充一层RGBA黑色背景,再添加一层用于叠加外部数据。
private void SetCommonOptionToPublisherSDK()
{
if (!IsPublisherHandleAvailable())
{
Debug.Log("SetCommonOptionToPublisherSDK, publisher handle with null..");
return;
}
NTSmartPublisherSDK.NT_PB_ClearLayersConfig(publisher_handle_, 0,
0, IntPtr.Zero);
if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_LAYER)
{
// 第0层填充RGBA矩形, 目的是保证帧率, 颜色就填充全黑
int red = 0;
int green = 0;
int blue = 0;
int alpha = 255;
NT_PB_RGBARectangleLayerConfig rgba_layer_c0 = new NT_PB_RGBARectangleLayerConfig();
rgba_layer_c0.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE;
rgba_layer_c0.base_.index_ = 0;
rgba_layer_c0.base_.enable_ = 1;
rgba_layer_c0.base_.region_.x_ = 0;
rgba_layer_c0.base_.region_.y_ = 0;
rgba_layer_c0.base_.region_.width_ = video_width_;
rgba_layer_c0.base_.region_.height_ = video_height_;
rgba_layer_c0.base_.offset_ = Marshal.OffsetOf(rgba_layer_c0.GetType(), "base_").ToInt32();
rgba_layer_c0.base_.cb_size_ = (uint)Marshal.SizeOf(rgba_layer_c0);
rgba_layer_c0.red_ = System.BitConverter.GetBytes(red)[0];
rgba_layer_c0.green_ = System.BitConverter.GetBytes(green)[0];
rgba_layer_c0.blue_ = System.BitConverter.GetBytes(blue)[0];
rgba_layer_c0.alpha_ = System.BitConverter.GetBytes(alpha)[0];
IntPtr rgba_conf = Marshal.AllocHGlobal(Marshal.SizeOf(rgba_layer_c0));
Marshal.StructureToPtr(rgba_layer_c0, rgba_conf, true);
UInt32 rgba_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
rgba_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE,
0, IntPtr.Zero);
Marshal.FreeHGlobal(rgba_conf);
NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();
external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 1;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;
external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);
IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));
Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);
UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,
0, IntPtr.Zero);
Marshal.FreeHGlobal(external_layer_conf);
}
<p>
else if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_CAMERA)
{
CameraInfo camera = cameras_[cur_sel_camera_index_];
NT_PB_VideoCaptureCapability cap = camera.capabilities_[cur_sel_camera_resolutions_index_];
SetVideoCaptureDeviceBaseParameter(camera.id_.ToString(), (UInt32)cap.width_, (UInt32)cap.height_);
}
SetFrameRate((UInt32)CalBitRate(edit_key_frame_, video_width_, video_height_));
Int32 type = 0; //软编码
Int32 encoder_id = 1;
UInt32 codec_id = (UInt32)NTCommonMediaDefine.NT_MEDIA_CODEC_ID.NT_MEDIA_CODEC_ID_H264;
Int32 param1 = 0;
SetVideoEncoder(type, encoder_id, codec_id, param1);
SetVideoQualityV2(CalVideoQuality(video_width_, video_height_, is_h264_encoder));
SetVideoMaxBitRate((CalMaxKBitRate(edit_key_frame_, video_width_, video_height_, false)));
SetVideoKeyFrameInterval((edit_key_frame_));
if (is_h264_encoder)
{
SetVideoEncoderProfile(1);
}
SetVideoEncoderSpeed(CalVideoEncoderSpeed(video_width_, video_height_, is_h264_encoder));
// 音频相关设置
SetAuidoInputDeviceId(0);
SetPublisherAudioCodecType(1);
SetPublisherMute(is_mute);
SetEchoCancellation(0, 0);
SetNoiseSuppression(0);
SetAGC(0);
SetVAD(0);
SetInputAudioVolume(Convert.ToSingle(edit_audio_input_volume_));
}
</p>
4.数据采集
摄像头和屏幕数据采集依然调用原生SDK接口,本文不再赘述。如果需要采集Unity形式的数据,可以参考如下代码:
if ( texture_ == null || video_width_ != Screen.width || video_height_ != Screen.height)
{
Debug.Log("OnPostRender screen changed++ scr_width: " + Screen.width + " scr_height: " + Screen.height);
if (screen_image_ != IntPtr.Zero)
{
Marshal.FreeHGlobal(screen_image_);
screen_image_ = IntPtr.Zero;
}
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
video_width_ = Screen.width;
video_height_ = Screen.height;
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.BGRA32, false);
screen_image_ = Marshal.AllocHGlobal(video_width_ * 4 * video_height_);
Debug.Log("OnPostRender screen changed--");
return;
}
texture_.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);
texture_.Apply();
从纹理中,通过调用 GetRawTextureData() 获取原创数据。
5、数据对接
获取原创数据后,通过调用系统封装的OnPostRGBAData()接口将数据传递给SDK层。
6.本地数据预览
public bool StartPreview()
{
if(CheckPublisherHandleAvailable() == false)
return false;
video_preview_image_callback_ = new NT_PB_SDKVideoPreviewImageCallBack(SDKVideoPreviewImageCallBack);
NTSmartPublisherSDK.NT_PB_SetVideoPreviewImageCallBack(publisher_handle_, (int)NTSmartPublisherDefine.NT_PB_E_IMAGE_FORMAT.NT_PB_E_IMAGE_FORMAT_RGB32, IntPtr.Zero, video_preview_image_callback_);
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPreview(publisher_handle_, 0, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
return false;
}
publisher_handle_count_++;
is_previewing_ = true;
return true;
}
public void StopPreview()
{
if (is_previewing_ == false) return;
is_previewing_ = false;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPreview(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
设置好预览后,处理预览的数据回调
//预览数据回调
public void SDKVideoPreviewImageCallBack(IntPtr handle, IntPtr user_data, IntPtr image)
{
NT_PB_Image pb_image = (NT_PB_Image)Marshal.PtrToStructure(image, typeof(NT_PB_Image));
NT_VideoFrame pVideoFrame = new NT_VideoFrame();
pVideoFrame.width_ = pb_image.width_;
pVideoFrame.height_ = pb_image.height_;
<p>
pVideoFrame.stride_ = pb_image.stride_[0];
Int32 argb_size = pb_image.stride_[0] * pb_image.height_;
pVideoFrame.plane_data_ = new byte[argb_size];
if (argb_size > 0)
{
Marshal.Copy(pb_image.plane_[0],pVideoFrame.plane_data_,0, argb_size);
}
{
cur_image_ = pVideoFrame;
}
}
</p>
7.相关事件回调处理
private void PbEventCallBack(IntPtr handle, IntPtr user_data,
UInt32 event_id,
Int64 param1,
Int64 param2,
UInt64 param3,
UInt64 param4,
[MarshalAs(UnmanagedType.LPStr)] String param5,
[MarshalAs(UnmanagedType.LPStr)] String param6,
IntPtr param7)
{
String event_log = "";
switch (event_id)
{
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTING:
event_log = "连接中";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTION_FAILED:
event_log = "连接失败";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTED:
event_log = "已连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_DISCONNECTED:
event_log = "断开连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
default:
break;
}
if(OnLogEventMsg != null) OnLogEventMsg.Invoke(event_id, event_log);
}
8.开始推送,停止推送
public bool StartPublisher(String url)
{
if (CheckPublisherHandleAvailable() == false) return false;
if (publisher_handle_ == IntPtr.Zero)
{
return false;
}
if (!String.IsNullOrEmpty(url))
{
NTSmartPublisherSDK.NT_PB_SetURL(publisher_handle_, url, IntPtr.Zero);
}
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPublisher(publisher_handle_, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
return false;
}
publisher_handle_count_++;
is_publishing_ = true;
return true;
}
public void StopPublisher()
{
if (is_publishing_ == false) return;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPublisher(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
}
9.关闭实例
public void Close()
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
总结
经测试,在Unity环境下,通过高效数据采集,编码推送,配合SmartPlayer播放,整体延迟可以控制在毫秒级,适合大部分Unity对延迟和稳定性的要求环境恶劣的场景。
解决方案:利用ROS采集VLP-16激光雷达数据
启动VLP-16激光雷达,想用ROS采集雷达数据,按照现有的教程总有一些小问题,现在分享自己成功采集的数据,希望对那些刚进坑的人有所帮助。
我使用 Ubuntu 16.04+ 动力学系统
1. 安装驱动程序
sudo apt-get install ros-kinetic-velodyne
2. 配置网络以连接到激光雷达(无需关闭无线):
修改 IPv4:在有线网络中
更改为手动
IP 地址为 192.168.1.77,
子网掩码为 255.255.255.0,网关为 192.168.1.1。然后连接激光雷达,
打开浏览器输入192.168.1.201,查看激光雷达配置文件。
每次连接雷达时,输入以下两个命令:
sudo ifconfig enp2s0 192.168.1.123
sudo 路由添加 192.168.1.201 enp2s0
3. 创建 ROS 项目:
MKDIR -P catkin_velodyne/SRC
光盘catkin_velodyne/SRC
git 克隆
光盘..
Rosdep install --from-path src --ignore-src --rosdistro kinetic -y
catkin_make
Source devel/setup.bash
4.将Velodyne XML文件转换为ROS节点的YAML文件,VLP-16.xml据说在免费的USB闪存盘中,反正没找到
我从互联网上下载了一个。请记住将下面的地址更改为您的 VLP-16 .xml文件的地址。
rosrun velodyne_pointcloud gen_calibration.py ~/VLP-16.xml (更改为你自己保存的目录)。
5. 加载:
roslaunch velodyne_pointcloud VLP16_points.launch calibration:=~/VLP-16.yaml (更改为你自己保存的目录)。
6、点云图实时展示:
Rosrun Rviz Rviz -F velodyne
然后按主题添加
rviz 添加 PointCloud2,并在主题中输入 /velodyne_points,这样得到的 3D 点云图就可以实时展示。
7. 记录数据:
我看到的教程是用 rosbagrecord-oout/velodyne_points 命令获取 /velodyne_points 主题的数据,但是当我去分析保存的数据时,发现里面的雷达数据被处理了,反正我根本无法解读。我想获取雷达原创UDP报文中的信息来生成距离和强度图像,所以我保存了/velodyne_packets这个主题的数据,保存的数据是收录UDP的正文,每76个UDP数据包(每周扫描360度)都有一个时间戳,然后根据手册就可以从数据中获取距离和强度信息。
罗斯巴格记录 -O 文件名 /velodyne_packets 查看全部
解决方案:Windows平台实现Unity下窗体|摄像头|屏幕采集并推送至RTMP服务器
技术背景
随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业的虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。
基于此,许多开发者苦于 Unity 环境中缺乏低延迟的推拉流解决方案。几年前,我们在Unity环境下推出了一款跨平台的低延迟RTMP|RTSP直播播放器,解决了很多问题。延迟关键的使用场景。
随着时间的推移,越来越多的开发者联系我们,希望我们能够在Unity环境下推出RTMP推送模块,从Unity中获取实时数据,实现延迟更低、效率更高的数据传输和推送。基于此,我们发布了Unity环境下的RTMP推送模块。
本文以Windows平台为例。数据来源为Unity窗口、摄像头或整屏、编码传输模块、或调用大牛直播SDK(官方)的原生接口。简单的界面是一个预览:
技术实现 1. 基本初始化
private bool InitSDK()
{
if (!is_pusher_sdk_init_)
{
// 设置日志路径(请确保目录存在)
String log_path = "D:\\pulisherlog";
NTSmartLog.NT_SL_SetPath(log_path);
UInt32 isInited = NTSmartPublisherSDK.NT_PB_Init(0, IntPtr.Zero);
if (isInited != 0)
{
Debug.Log("调用NT_PB_Init失败..");
return false;
}
is_pusher_sdk_init_ = true;
}
return true;
}
2.调用Open()接口获取推送实例
public bool OpenPublisherHandle(uint video_option, uint audio_option)
{
if (publisher_handle_ != IntPtr.Zero)
{
return true;
}
publisher_handle_count_ = 0;
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_Open(out publisher_handle_,
video_option, audio_option, 0, IntPtr.Zero))
{
return false;
}
if (publisher_handle_ != IntPtr.Zero)
{
pb_event_call_back_ = new NT_PB_SDKEventCallBack(PbEventCallBack);
NTSmartPublisherSDK.NT_PB_SetEventCallBack(publisher_handle_, IntPtr.Zero, pb_event_call_back_);
return true;
}
else
{
return false;
}
}
3.初始化参数配置
这里需要注意的是,如果要采集unity窗口,需要设置图层模式,先填充一层RGBA黑色背景,再添加一层用于叠加外部数据。
private void SetCommonOptionToPublisherSDK()
{
if (!IsPublisherHandleAvailable())
{
Debug.Log("SetCommonOptionToPublisherSDK, publisher handle with null..");
return;
}
NTSmartPublisherSDK.NT_PB_ClearLayersConfig(publisher_handle_, 0,
0, IntPtr.Zero);
if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_LAYER)
{
// 第0层填充RGBA矩形, 目的是保证帧率, 颜色就填充全黑
int red = 0;
int green = 0;
int blue = 0;
int alpha = 255;
NT_PB_RGBARectangleLayerConfig rgba_layer_c0 = new NT_PB_RGBARectangleLayerConfig();
rgba_layer_c0.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE;
rgba_layer_c0.base_.index_ = 0;
rgba_layer_c0.base_.enable_ = 1;
rgba_layer_c0.base_.region_.x_ = 0;
rgba_layer_c0.base_.region_.y_ = 0;
rgba_layer_c0.base_.region_.width_ = video_width_;
rgba_layer_c0.base_.region_.height_ = video_height_;
rgba_layer_c0.base_.offset_ = Marshal.OffsetOf(rgba_layer_c0.GetType(), "base_").ToInt32();
rgba_layer_c0.base_.cb_size_ = (uint)Marshal.SizeOf(rgba_layer_c0);
rgba_layer_c0.red_ = System.BitConverter.GetBytes(red)[0];
rgba_layer_c0.green_ = System.BitConverter.GetBytes(green)[0];
rgba_layer_c0.blue_ = System.BitConverter.GetBytes(blue)[0];
rgba_layer_c0.alpha_ = System.BitConverter.GetBytes(alpha)[0];
IntPtr rgba_conf = Marshal.AllocHGlobal(Marshal.SizeOf(rgba_layer_c0));
Marshal.StructureToPtr(rgba_layer_c0, rgba_conf, true);
UInt32 rgba_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
rgba_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_RGBA_RECTANGLE,
0, IntPtr.Zero);
Marshal.FreeHGlobal(rgba_conf);
NT_PB_ExternalVideoFrameLayerConfig external_layer_c1 = new NT_PB_ExternalVideoFrameLayerConfig();
external_layer_c1.base_.type_ = (Int32)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME;
external_layer_c1.base_.index_ = 1;
external_layer_c1.base_.enable_ = 1;
external_layer_c1.base_.region_.x_ = 0;
external_layer_c1.base_.region_.y_ = 0;
external_layer_c1.base_.region_.width_ = video_width_;
external_layer_c1.base_.region_.height_ = video_height_;
external_layer_c1.base_.offset_ = Marshal.OffsetOf(external_layer_c1.GetType(), "base_").ToInt32();
external_layer_c1.base_.cb_size_ = (uint)Marshal.SizeOf(external_layer_c1);
IntPtr external_layer_conf = Marshal.AllocHGlobal(Marshal.SizeOf(external_layer_c1));
Marshal.StructureToPtr(external_layer_c1, external_layer_conf, true);
UInt32 external_r = NTSmartPublisherSDK.NT_PB_AddLayerConfig(publisher_handle_, 0,
external_layer_conf, (int)NTSmartPublisherDefine.NT_PB_E_LAYER_TYPE.NT_PB_E_LAYER_TYPE_EXTERNAL_VIDEO_FRAME,
0, IntPtr.Zero);
Marshal.FreeHGlobal(external_layer_conf);
}
<p>

else if (video_option == NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_CAMERA)
{
CameraInfo camera = cameras_[cur_sel_camera_index_];
NT_PB_VideoCaptureCapability cap = camera.capabilities_[cur_sel_camera_resolutions_index_];
SetVideoCaptureDeviceBaseParameter(camera.id_.ToString(), (UInt32)cap.width_, (UInt32)cap.height_);
}
SetFrameRate((UInt32)CalBitRate(edit_key_frame_, video_width_, video_height_));
Int32 type = 0; //软编码
Int32 encoder_id = 1;
UInt32 codec_id = (UInt32)NTCommonMediaDefine.NT_MEDIA_CODEC_ID.NT_MEDIA_CODEC_ID_H264;
Int32 param1 = 0;
SetVideoEncoder(type, encoder_id, codec_id, param1);
SetVideoQualityV2(CalVideoQuality(video_width_, video_height_, is_h264_encoder));
SetVideoMaxBitRate((CalMaxKBitRate(edit_key_frame_, video_width_, video_height_, false)));
SetVideoKeyFrameInterval((edit_key_frame_));
if (is_h264_encoder)
{
SetVideoEncoderProfile(1);
}
SetVideoEncoderSpeed(CalVideoEncoderSpeed(video_width_, video_height_, is_h264_encoder));
// 音频相关设置
SetAuidoInputDeviceId(0);
SetPublisherAudioCodecType(1);
SetPublisherMute(is_mute);
SetEchoCancellation(0, 0);
SetNoiseSuppression(0);
SetAGC(0);
SetVAD(0);
SetInputAudioVolume(Convert.ToSingle(edit_audio_input_volume_));
}
</p>
4.数据采集
摄像头和屏幕数据采集依然调用原生SDK接口,本文不再赘述。如果需要采集Unity形式的数据,可以参考如下代码:
if ( texture_ == null || video_width_ != Screen.width || video_height_ != Screen.height)
{
Debug.Log("OnPostRender screen changed++ scr_width: " + Screen.width + " scr_height: " + Screen.height);
if (screen_image_ != IntPtr.Zero)
{
Marshal.FreeHGlobal(screen_image_);
screen_image_ = IntPtr.Zero;
}
if (texture_ != null)
{
UnityEngine.Object.Destroy(texture_);
texture_ = null;
}
video_width_ = Screen.width;
video_height_ = Screen.height;
texture_ = new Texture2D(video_width_, video_height_, TextureFormat.BGRA32, false);
screen_image_ = Marshal.AllocHGlobal(video_width_ * 4 * video_height_);
Debug.Log("OnPostRender screen changed--");
return;
}
texture_.ReadPixels(new Rect(0, 0, video_width_, video_height_), 0, 0, false);
texture_.Apply();
从纹理中,通过调用 GetRawTextureData() 获取原创数据。
5、数据对接
获取原创数据后,通过调用系统封装的OnPostRGBAData()接口将数据传递给SDK层。
6.本地数据预览
public bool StartPreview()
{
if(CheckPublisherHandleAvailable() == false)
return false;
video_preview_image_callback_ = new NT_PB_SDKVideoPreviewImageCallBack(SDKVideoPreviewImageCallBack);
NTSmartPublisherSDK.NT_PB_SetVideoPreviewImageCallBack(publisher_handle_, (int)NTSmartPublisherDefine.NT_PB_E_IMAGE_FORMAT.NT_PB_E_IMAGE_FORMAT_RGB32, IntPtr.Zero, video_preview_image_callback_);
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPreview(publisher_handle_, 0, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
return false;
}
publisher_handle_count_++;
is_previewing_ = true;
return true;
}
public void StopPreview()
{
if (is_previewing_ == false) return;
is_previewing_ = false;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPreview(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
设置好预览后,处理预览的数据回调
//预览数据回调
public void SDKVideoPreviewImageCallBack(IntPtr handle, IntPtr user_data, IntPtr image)
{
NT_PB_Image pb_image = (NT_PB_Image)Marshal.PtrToStructure(image, typeof(NT_PB_Image));
NT_VideoFrame pVideoFrame = new NT_VideoFrame();
pVideoFrame.width_ = pb_image.width_;
pVideoFrame.height_ = pb_image.height_;
<p>

pVideoFrame.stride_ = pb_image.stride_[0];
Int32 argb_size = pb_image.stride_[0] * pb_image.height_;
pVideoFrame.plane_data_ = new byte[argb_size];
if (argb_size > 0)
{
Marshal.Copy(pb_image.plane_[0],pVideoFrame.plane_data_,0, argb_size);
}
{
cur_image_ = pVideoFrame;
}
}
</p>
7.相关事件回调处理
private void PbEventCallBack(IntPtr handle, IntPtr user_data,
UInt32 event_id,
Int64 param1,
Int64 param2,
UInt64 param3,
UInt64 param4,
[MarshalAs(UnmanagedType.LPStr)] String param5,
[MarshalAs(UnmanagedType.LPStr)] String param6,
IntPtr param7)
{
String event_log = "";
switch (event_id)
{
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTING:
event_log = "连接中";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTION_FAILED:
event_log = "连接失败";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_CONNECTED:
event_log = "已连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_DISCONNECTED:
event_log = "断开连接";
if (!String.IsNullOrEmpty(param5))
{
event_log = event_log + " url:" + param5;
}
break;
default:
break;
}
if(OnLogEventMsg != null) OnLogEventMsg.Invoke(event_id, event_log);
}
8.开始推送,停止推送
public bool StartPublisher(String url)
{
if (CheckPublisherHandleAvailable() == false) return false;
if (publisher_handle_ == IntPtr.Zero)
{
return false;
}
if (!String.IsNullOrEmpty(url))
{
NTSmartPublisherSDK.NT_PB_SetURL(publisher_handle_, url, IntPtr.Zero);
}
if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartPublisher(publisher_handle_, IntPtr.Zero))
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
return false;
}
publisher_handle_count_++;
is_publishing_ = true;
return true;
}
public void StopPublisher()
{
if (is_publishing_ == false) return;
publisher_handle_count_--;
NTSmartPublisherSDK.NT_PB_StopPublisher(publisher_handle_);
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
is_publishing_ = false;
}
9.关闭实例
public void Close()
{
if (0 == publisher_handle_count_)
{
NTSmartPublisherSDK.NT_PB_Close(publisher_handle_);
publisher_handle_ = IntPtr.Zero;
}
}
总结
经测试,在Unity环境下,通过高效数据采集,编码推送,配合SmartPlayer播放,整体延迟可以控制在毫秒级,适合大部分Unity对延迟和稳定性的要求环境恶劣的场景。
解决方案:利用ROS采集VLP-16激光雷达数据
启动VLP-16激光雷达,想用ROS采集雷达数据,按照现有的教程总有一些小问题,现在分享自己成功采集的数据,希望对那些刚进坑的人有所帮助。
我使用 Ubuntu 16.04+ 动力学系统
1. 安装驱动程序
sudo apt-get install ros-kinetic-velodyne
2. 配置网络以连接到激光雷达(无需关闭无线):
修改 IPv4:在有线网络中
更改为手动
IP 地址为 192.168.1.77,
子网掩码为 255.255.255.0,网关为 192.168.1.1。然后连接激光雷达,
打开浏览器输入192.168.1.201,查看激光雷达配置文件。
每次连接雷达时,输入以下两个命令:

sudo ifconfig enp2s0 192.168.1.123
sudo 路由添加 192.168.1.201 enp2s0
3. 创建 ROS 项目:
MKDIR -P catkin_velodyne/SRC
光盘catkin_velodyne/SRC
git 克隆
光盘..
Rosdep install --from-path src --ignore-src --rosdistro kinetic -y
catkin_make
Source devel/setup.bash
4.将Velodyne XML文件转换为ROS节点的YAML文件,VLP-16.xml据说在免费的USB闪存盘中,反正没找到

我从互联网上下载了一个。请记住将下面的地址更改为您的 VLP-16 .xml文件的地址。
rosrun velodyne_pointcloud gen_calibration.py ~/VLP-16.xml (更改为你自己保存的目录)。
5. 加载:
roslaunch velodyne_pointcloud VLP16_points.launch calibration:=~/VLP-16.yaml (更改为你自己保存的目录)。
6、点云图实时展示:
Rosrun Rviz Rviz -F velodyne
然后按主题添加
rviz 添加 PointCloud2,并在主题中输入 /velodyne_points,这样得到的 3D 点云图就可以实时展示。
7. 记录数据:
我看到的教程是用 rosbagrecord-oout/velodyne_points 命令获取 /velodyne_points 主题的数据,但是当我去分析保存的数据时,发现里面的雷达数据被处理了,反正我根本无法解读。我想获取雷达原创UDP报文中的信息来生成距离和强度图像,所以我保存了/velodyne_packets这个主题的数据,保存的数据是收录UDP的正文,每76个UDP数据包(每周扫描360度)都有一个时间戳,然后根据手册就可以从数据中获取距离和强度信息。
罗斯巴格记录 -O 文件名 /velodyne_packets
最新版:jquery基础快速教程和“jquery之本”框架教程(免费版)
采集交流 • 优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2022-11-18 10:28
文章采集调用ie,然后经过前端转换输出html加js让用户点击页面,点击后执行相应的动作,js代码通过后端返回页面并获取交互数据,进行展示,整个过程不涉及到网页的加载,即flash,难度稍微低些,另外,在实现这个前端功能的时候,可以用jquery框架,总的来说还是要具备一定的前端功底以及网络编程的基础,如果是小白也没有关系,现在也有免费开源的jquery框架,直接通过mvc的模式进行开发。
开发效率还是挺高的,最新版本的一些工具提供了大量的mvc模式开发示例视频教程,供大家学习交流。首页:jquery基础快速教程和“jquery之本”框架教程(免费版)“jquery之本”框架教程(付费版)下载:链接密码:n50b具体参见:jquery教程_jquery框架教程精讲_android开发_视频教程_免费教程大全当然在学习过程中,有不懂的问题可以关注我的公众号回复:jquery,获取相应的教程视频以及后端js开发教程!。
写几个页面,就熟练了,
已经给jquery提交了,他们回答的还挺详细的。 查看全部
最新版:jquery基础快速教程和“jquery之本”框架教程(免费版)
文章采集调用ie,然后经过前端转换输出html加js让用户点击页面,点击后执行相应的动作,js代码通过后端返回页面并获取交互数据,进行展示,整个过程不涉及到网页的加载,即flash,难度稍微低些,另外,在实现这个前端功能的时候,可以用jquery框架,总的来说还是要具备一定的前端功底以及网络编程的基础,如果是小白也没有关系,现在也有免费开源的jquery框架,直接通过mvc的模式进行开发。

开发效率还是挺高的,最新版本的一些工具提供了大量的mvc模式开发示例视频教程,供大家学习交流。首页:jquery基础快速教程和“jquery之本”框架教程(免费版)“jquery之本”框架教程(付费版)下载:链接密码:n50b具体参见:jquery教程_jquery框架教程精讲_android开发_视频教程_免费教程大全当然在学习过程中,有不懂的问题可以关注我的公众号回复:jquery,获取相应的教程视频以及后端js开发教程!。

写几个页面,就熟练了,
已经给jquery提交了,他们回答的还挺详细的。
教程:dedecms织梦TAG标签调用代码
采集交流 • 优采云 发表了文章 • 0 个评论 • 134 次浏览 • 2022-11-17 02:51
标签标签
是一种自己定义的关键词,比分类更准确、更具体,可以概括文章主要内容,合理使用TAG标签,可以让你发表的文章更容易检索。
很多网站首页、列表页和文章页都用超链接调用TAG关键词,有利于蜘蛛搜索和抓取,也有利于用户点击,那么如何在织梦dedecms系统的网站上实现此功能呢?对此,做网站吧,整理出以下方法供大家使用:
1、TaT ?B 6g 标签 o V % 的语法解释
基本语法:
{dede:tag row='30' sort='new' getall='0′}
c B 8 r///a/dedejq/[field:link/]'>[field:tag /]
{/dede:tag}
参数说明:
row=K z 9 W k \ B * x '30' 呼叫号码为 30
sort='new' 排序 月, 兰特, 周
getall='0' 获取当前内容页面 TAG 标记的类型 0,以及获取所有 TAG 标记的类型 1。
基础模板字段:链接、标记
2. 最新的标签标签称为
{dede:tag row='30' sort='new'}[字段:突出显示/]
([字段:结果/])
{/dede:tag}
3.调用本月热门标签标签
{dede:tag row='30' sort='month'}I d s d stp:///a/dedejq/[field:link/]'>[field:
tagname/]([field:result/])
{/dede:tag}
4. 随机标签调用
{deu } ^de:tag row='60' sort='rand'}
$ J | m W 5 F /a/dedejq/[field:link/]'>[field:highlight/]([field:result/])
{/dede:tag}
5. 采集热 [# W 0 V N L n – 门标签,转换后刷新
模板代码:
{dede:tag row='10' sort='month' }
, E y u mom/a/dedejq/[field:link/]'>[field:tagname/] &o : T # hlt;/a>
{/dede:tag}
^ e 8 {t language=“JavaScript”>
偏移量){
tag_a.className=“tag”+(rnd-offsc y 2 4et);
}
}
}/
/–>
CSS代码:
.tag1 { color:h Z j j m G i + X#339900; font-weight:bold; }
.tag2 { color:#e65730; }
.tag3 { color:#00b9da; }
.tag4 { color:#FG 2 4 C +E3981; 7 5 ) T [ Jfont-weighW Z P 7 } G &t:bold; font-size:14px; }
6. 在页面文章调用标签标签
{J w % = S y p 8 gdede:tag table='dede_search_keywords' sort='keyword' row='2′ ifd O b y F=“}
\ L \dedejq/[field:link/]' target=_i 7 * # _blank>[field:tag /]
{/dede:tag}
或
{dede:fie# n : 2 [ r XLD name='Keywords' runphp='yes' }
if(!empty(@me)){
$kws = 爆炸(' ',@me);
@me = “”;
foreach($kws as $k){
@me .= “O / x 4 # '/tag.php?/$k/'>$k ”;
}
@me= str_repla' $ F 0 }ce('+', ' ',trim(@me));
}
{/dede:field}
7. 列表页调用 TAG 标签的两个 b # k F w D 方法
dedecms列表中的默认值无法调用 tag\q v C; _ X 标签。Do 网站 G * { r p i, 7 n 为您提供以下不同版本的标签标签调用 T D G A p A are you 方法:
(1)、de, w \decms 5.7 调用方法
首先,找到 include\helpers\archive.helper.php 文件(注:有些朋友会有疑问,首页和频道,列表应该添加不同的调用,但我开始用列表页面测试,成功;添加 m \ b v q r 首页后,测试也进入了 D Y G R U Y T + D 功能显示,所以我没有继续深入研究,另外,这个文件的内容发生了变化,在后台文件是无法更改的,提示 _&0 7 是注入 sql,所以要在 ftp 中找到这个文件来更改 0。)
在底部添加:
函数; f G GetTags_list($aid)
{
全球$dsql;
$tags = “;
$query = “从'ma_taglisi v \ at'中选择标签,其中aid='$aid'”;
~ w T $dsql->Execute('tag',$query);
0 I 5 + 2 y a s whil' j % s ~ we($row = $dsql->GetArray('tag'))
{
$tags .= ($tags==“ ?“9 R.Q e #<^ ) \ n 6;a hreb E H f Q uf='“.urlencode($row['tag']).”' &gl f _t;Y ] R 5 L t # = G“.$row['tag'].”“ : ','.”O % V x b ^ .i P /tags.php?/“.urlencode($row['tag']).”' >“.$row['tag'].”“);
}
返回 $tau P % @ rgs;
}
那么Q I S + v b H k,加上:,这里列表需要调用标签标签
[字段:id 函数=GetTags_list(@me)/]
以完成。
(2)、dedecms 5K T y W + C g j.6 版本 G \ G Y # |G本的调用方法
方法一:
只需在模板需要的地方添加以下代码:
[字段:ID runphp=yes]
$tsql = new DedeSql(false);
$tags = “B F e –;
$tsql->SetQuery(“选择 i.tag 从 dede_taglist t 左连接 dede_tagindex i on i.id=t.tid 其中 t.an / ;E Zid='@me'“);
$tsql-e ) ;>ExG V q @ecute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “”.$row['tag'].“ &k u blt;/a>”;
}
@me=$tags;
[/字段:id]
注意:此步骤无法在 dede 5.7 中实现。
方法2:
打开 dedecms根目录 T k Y ~include/common.func.php,在底部的 “!k ?A b O?>“在以下代码之前:
让我们做网站:列表页调用标签的方法
函数列表标签($aid)
{
$tsql = new DedeSql(false);
$tags = “;{ ( n : u X ' , m
$tsql->SetQuery(“Select i.tag FrM .o 9 Oom dt 7 ;2 j ] ^ede_taglist t left join dede_tagindex i on i.id=t.tid where t.aid='$aid'“);
$tsql->执行('t');
whi– x W s e – ale($row = $tsql->GetArray('t',MYSQL_ASSOC)){7 C \ j
$tags .= “D ( & 6lencode($row['tag']).” /'>“.$rowj 0 Y ? x v z o J['tag'].”";
}% W ?z F |_ = i
雷图]U Y骨灰盒$tags;
}
{@ ? n i 2 0 , 5 4dede:field.id runphp=yes}
$tsql = new DedeSql(false);
$tags = “;
$tsql->SetQuery(“Select i.tag From ded\ } q |e_taglist t left join dede_tak f 4gindex i on i.id=t.tid where t.aid='@me'”);
$' 1 ~tsql->Execute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “e D Hhp?/”.urlencode($row['tag']).“' >”.$row['tag'].“”;
}
@me=$# A F ytags;
{/dede:field.id}
添加代码 6 j't*$x 后,可以使用列表页:
{m s s C $dede:field.id function=“listtag(@me)”/}
以调用标签标签。
方法三:
inc_functions.php 添加 :
函数列表标记($aid){
$tsql = new DedeSql(p ' w x 8 Q 3 s tfalse);
$tags = “;
$tsql->SetQuery(“Select i.tagname From xkzzz_tag_list t left join xkzzz_tu 4 t \ 0 { x gag_index i on i.id=t.tid where t.aid='$aid'”);
$tsql->执行('t');
while($row = $tsql->Getj [ x &Array('t'{ N f M K v S,MYSQL_AO r _ 0 |SSOC)){
$tags .= “s 1 j { ~ + !/tag.php?/”.urlencodeE # 6 [ z H 0 V Y($row['tagname']).“' >”.$rowu F G y A ,['tagname'].“”;
}
+ _ c j c 6 d 返回$tags;
}
然后添加 :,其中列表页位于
[字段:ID 函数=“列表标记(@me)”/]
可以调出来,但是这个方法也需要更改程序文件,看不懂代码的朋友,慎用吧!
8. 首页调用该方法文章 Tg j LAG 标签
如果您网站使用 dedecms v5.7 可以使用以下标签:
径直
[field:id function=GetTags(@me)/]
可以调出,但不能调出g Y # k x s T O \没有连接,为了添加标签标签的链接,还需要做到以下几点:
首先,注 4 + z { # 。E % 删除 130 行收录/帮助程序/存档.helper.php 文件
$tags .= ($tags==“ ? $row['标签'] : ','.$row['标签']);
用以下?!C 语句替换,当然是 J { |R 您还可以添加自己的样式:
$tags .= “_ % k a !php?/”.urlencode($row['tag']).“ /'>”.$row['tag'].”";
添加 # z ; ! p t ] o 下一代 { 0 H R i 代码:
if ( ! function_exists(7 h * Y 0 r Q'GetTagk')){
函数 GetTagk($aid)
{@ / ! ; * K { i
全球$dsql;
$tagk = “;
$query = “选择标签,从'ma_taglist'中辅助,其中aid='$aid'”;
$dsql->Execute('tagD v ^ n b',$query);
while($row = $dsql->GetArray('tag'))
{
$tagk .= ($t\ Z * & \ } 3agk==“n 1 i ? $row['tag'] : ','.$row['tag']);
}
返回 $ta 2 V )O { mgk;
}
}
然后,打开 dede/a( h m^ Jrticle_edit.php 找到:
$tags = Gf I j DetTags($aid);
添加以下内容:
$t( H e ~ M T 8 | *agk = GetTagk($o Q D Jaid);
打开 dede/tempj x z t F n h mlets/article_edit.htm 再次调用标签标签
学习笔记:学python,怎么能不学习scrapy呢
本文分享自华为云社区《学python怎么能不学scrapy?本博客带你学起来-云社区-华为云》,作者:橡皮擦。
在正式写爬虫案例之前,我们先系统地了解一下scrapy。
scrapy安装和简单操作
使用命令pip install scrapy进行安装。安装成功后,需要采集几个网址,方便后续学习使用。
安装完成后,直接在控制台输入scrapy,出现如下命令即表示安装成功。
> scrapy
Scrapy 2.5.0 - no active project
Usage:
scrapy [options] [args]
Available commands:
上图是scrapy内置命令列表,标准格式的scrapy,可以通过scrapy -h查看指定命令的帮助手册。
scrapy中有两种命令,一种是全局的,一种是项目中的。后者需要进入scrapy目录才能运行。
这些命令一开始不需要完全记住,随时可以查看。还有几个比较常用的,例如:
**scrpy 启动项目**
该命令首先根据项目名称创建一个文件夹,然后在该文件夹下创建一个scrpy项目。这一步是所有后续代码的起点。
> scrapy startproject my_scrapy
> New Scrapy project 'my_scrapy', using template directory 'e:\pythonproject\venv\lib\site-packages\scrapy\templates\project', created in: # 一个新的 scrapy 项目被创建了,使用的模板是 XXX,创建的位置是 XXX
E:\pythonProject\滚雪球学Python第4轮\my_scrapy
You can start your first spider with: # 开启你的第一个爬虫程序
cd my_scrapy # 进入文件夹
scrapy genspider example example.com # 使用项目命令创建爬虫文件
以上内容添加了一些评论,可以对照学习。默认生成的文件位于 python 运行时目录中。如果要修改项目目录,请使用如下格式化命令:
scrapy startproject myproject [project_dir]
例如
scrapy startproject myproject d:/d1
命令基于模板创建的项目结构如下,其中红色下划线为项目目录,绿色下划线为scrapy项目。如果要运行项目命令,首先要进入项目目录下红色下划线的my_scrapy文件夹。控制项目。
下面生成爬虫文件
使用命令scrapy genspider [-t template]生成爬虫文件。该方法是快捷操作,也可以手动创建。创建的爬虫文件会出现在当前目录或项目文件夹下的spiders文件夹中,name为爬虫名称,domain用于爬虫文件中allowed_domains和start_urls数据,[-t template]表示可以选择生成文件模板。
要查看所有模板,请使用以下命令,默认模板是 basic。
> scrapy genspider -l
basic
crawl
csvfeed
xmlfeed
创建第一个scrapy爬虫文件,测试命令如下:
>scrapy genspider pm imspm.com
Created spider 'pm' using template 'basic' in module:
my_project.spiders.pm
这时在spiders文件夹中,出现了pm.py文件,文件内容如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['imspm.com']
start_urls = ['http://imspm.com/']
def parse(self, response):
pass
测试 scrapy 爬虫运行
使用命令scrapy crawl,spider是上面生成的爬虫文件名,如果出现如下内容,说明爬虫加载正确。
>scrapy crawl pm
2021-10-02 21:34:34 [scrapy.utils.log] INFO: Scrapy 2.5.0 started (bot: my_project)
[...]
scrapy的基本应用
scrapy 的工作流程非常简单:
采集首页源码;分析首页源码,获取下一页链接;请求下一页的源代码;解析源码,获取下一页的源码;[…] 过程中,提取到目标数据后,保存。
下面给大家展示一个scrapy的完整案例应用,作为爬虫120案例scrapy部分的第一个例子。
> scrapy startproject my_project 爬虫
> cd 爬虫
<p>
> scrapy genspider pm imspm.com</p>
得到项目结构如下:
对上图中部分文件的简要说明。
使用scrapy crawl pm运行爬虫后,所有的输出和描述如下:
上面代码的请求次数是7次,因为pm.py文件中默认没有添加www。如果添加此内容,则请求数变为 4。
当前pm.py文件代码如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['www.imspm.com']
start_urls = ['http://www.imspm.com/']
def parse(self, response):
print(response.text)
其中的parse是指请求start_urls中的地址,得到response后的回调函数,通过参数response的.text属性直接输出网页源码。
获取到源码后,需要对源码进行解析存储
在存储之前,需要手动定义一个数据结构,在items.py文件中实现,修改代码中的类名,MyProjectItem → ArticleItem。
import scrapy
class ArticleItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
author = scrapy.Field() # 作者
修改pm.py文件中的parse函数,增加网页解析相关操作。这个操作类似于pyquery的知识点,直接观察代码就可以掌握。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for item in list_item:
title = item.css('.title::text').extract_first() # 直接获取文本
url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
author = item.css('.author::text').extract_first() # 直接获取文本
print(title, url, author)
response.css 方法返回一个选择器列表,可以对其进行迭代,然后对其中的对象调用 css 方法。
在pm.py中导入items.py中的ArticleItem类,然后按照如下代码修改:
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
<p>
item['author'] = author
yield item</p>
这时候scrapy爬虫运行时,会出现如下提示信息。
至此一个单页爬虫就完成了
接下来再次修改parse函数,解析完第一页后,再解析第二页的数据。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first() # 获取下一页链接
# print(next)
# 再次生成一个请求
yield scrapy.Request(url=next, callback=self.parse)
上面代码中,变量next代表下一页的地址,通过response.css函数获取链接。请重点学习css选择器。
产量下降。request(url=next, callback=self.parse)表示重新创建一个请求,请求的回调函数是parse自身,代码运行效果如下。
如果要保存运行结果,只需运行以下命令即可。
scrapy crawl pm -o pm.json
如果要将每条数据存储为单独的一行,请使用以下命令 scrapy crawl pm -o pm.jl 。
生成的文件还支持csv、xml、marchal、pickle,大家可以自己试试。
让我们使用数据管道
打开pipelines.py文件,修改类名MyProjectPipeline→TitlePipeline,然后编译如下代码:
class TitlePipeline:
def process_item(self, item, spider): # 移除标题中的空格
if item["title"]:
item["title"] = item["title"].strip()
return item
else:
return DropItem("异常数据")
此代码用于去除标题中的左右空格。
写入后需要在settings.py文件中开启ITEM_PIPELINES配置。
ITEM_PIPELINES = {
'my_project.pipelines.TitlePipeline': 300,
}
300是PIPELINES操作的优先顺序,可以根据需要修改。再次运行爬虫代码,你会发现标题的左右空格已经被去掉了。
至此,一个scrapy的基础爬虫就写好了。
戳下方关注,第一时间了解华为云的新鲜技术~
华为云博客_大数据博客_人工智能博客_云计算博客_开发者中心-华为云 查看全部
教程:dedecms织梦TAG标签调用代码
标签标签
是一种自己定义的关键词,比分类更准确、更具体,可以概括文章主要内容,合理使用TAG标签,可以让你发表的文章更容易检索。
很多网站首页、列表页和文章页都用超链接调用TAG关键词,有利于蜘蛛搜索和抓取,也有利于用户点击,那么如何在织梦dedecms系统的网站上实现此功能呢?对此,做网站吧,整理出以下方法供大家使用:
1、TaT ?B 6g 标签 o V % 的语法解释
基本语法:
{dede:tag row='30' sort='new' getall='0′}
c B 8 r///a/dedejq/[field:link/]'>[field:tag /]
{/dede:tag}
参数说明:
row=K z 9 W k \ B * x '30' 呼叫号码为 30
sort='new' 排序 月, 兰特, 周
getall='0' 获取当前内容页面 TAG 标记的类型 0,以及获取所有 TAG 标记的类型 1。
基础模板字段:链接、标记
2. 最新的标签标签称为
{dede:tag row='30' sort='new'}[字段:突出显示/]
([字段:结果/])
{/dede:tag}
3.调用本月热门标签标签
{dede:tag row='30' sort='month'}I d s d stp:///a/dedejq/[field:link/]'>[field:
tagname/]([field:result/])
{/dede:tag}
4. 随机标签调用
{deu } ^de:tag row='60' sort='rand'}
$ J | m W 5 F /a/dedejq/[field:link/]'>[field:highlight/]([field:result/])
{/dede:tag}
5. 采集热 [# W 0 V N L n – 门标签,转换后刷新
模板代码:
{dede:tag row='10' sort='month' }
, E y u mom/a/dedejq/[field:link/]'>[field:tagname/] &o : T # hlt;/a>
{/dede:tag}
^ e 8 {t language=“JavaScript”>
偏移量){
tag_a.className=“tag”+(rnd-offsc y 2 4et);
}
}
}/
/–>
CSS代码:
.tag1 { color:h Z j j m G i + X#339900; font-weight:bold; }
.tag2 { color:#e65730; }
.tag3 { color:#00b9da; }
.tag4 { color:#FG 2 4 C +E3981; 7 5 ) T [ Jfont-weighW Z P 7 } G &t:bold; font-size:14px; }
6. 在页面文章调用标签标签
{J w % = S y p 8 gdede:tag table='dede_search_keywords' sort='keyword' row='2′ ifd O b y F=“}
\ L \dedejq/[field:link/]' target=_i 7 * # _blank>[field:tag /]
{/dede:tag}
或
{dede:fie# n : 2 [ r XLD name='Keywords' runphp='yes' }
if(!empty(@me)){
$kws = 爆炸(' ',@me);
@me = “”;
foreach($kws as $k){
@me .= “O / x 4 # '/tag.php?/$k/'>$k ”;
}

@me= str_repla' $ F 0 }ce('+', ' ',trim(@me));
}
{/dede:field}
7. 列表页调用 TAG 标签的两个 b # k F w D 方法
dedecms列表中的默认值无法调用 tag\q v C; _ X 标签。Do 网站 G * { r p i, 7 n 为您提供以下不同版本的标签标签调用 T D G A p A are you 方法:
(1)、de, w \decms 5.7 调用方法
首先,找到 include\helpers\archive.helper.php 文件(注:有些朋友会有疑问,首页和频道,列表应该添加不同的调用,但我开始用列表页面测试,成功;添加 m \ b v q r 首页后,测试也进入了 D Y G R U Y T + D 功能显示,所以我没有继续深入研究,另外,这个文件的内容发生了变化,在后台文件是无法更改的,提示 _&0 7 是注入 sql,所以要在 ftp 中找到这个文件来更改 0。)
在底部添加:
函数; f G GetTags_list($aid)
{
全球$dsql;
$tags = “;
$query = “从'ma_taglisi v \ at'中选择标签,其中aid='$aid'”;
~ w T $dsql->Execute('tag',$query);
0 I 5 + 2 y a s whil' j % s ~ we($row = $dsql->GetArray('tag'))
{
$tags .= ($tags==“ ?“9 R.Q e #<^ ) \ n 6;a hreb E H f Q uf='“.urlencode($row['tag']).”' &gl f _t;Y ] R 5 L t # = G“.$row['tag'].”“ : ','.”O % V x b ^ .i P /tags.php?/“.urlencode($row['tag']).”' >“.$row['tag'].”“);
}
返回 $tau P % @ rgs;
}
那么Q I S + v b H k,加上:,这里列表需要调用标签标签
[字段:id 函数=GetTags_list(@me)/]
以完成。
(2)、dedecms 5K T y W + C g j.6 版本 G \ G Y # |G本的调用方法
方法一:
只需在模板需要的地方添加以下代码:
[字段:ID runphp=yes]
$tsql = new DedeSql(false);
$tags = “B F e –;
$tsql->SetQuery(“选择 i.tag 从 dede_taglist t 左连接 dede_tagindex i on i.id=t.tid 其中 t.an / ;E Zid='@me'“);
$tsql-e ) ;>ExG V q @ecute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “”.$row['tag'].“ &k u blt;/a>”;
}
@me=$tags;
[/字段:id]
注意:此步骤无法在 dede 5.7 中实现。
方法2:
打开 dedecms根目录 T k Y ~include/common.func.php,在底部的 “!k ?A b O?>“在以下代码之前:
让我们做网站:列表页调用标签的方法
函数列表标签($aid)
{
$tsql = new DedeSql(false);
$tags = “;{ ( n : u X ' , m
$tsql->SetQuery(“Select i.tag FrM .o 9 Oom dt 7 ;2 j ] ^ede_taglist t left join dede_tagindex i on i.id=t.tid where t.aid='$aid'“);
$tsql->执行('t');
whi– x W s e – ale($row = $tsql->GetArray('t',MYSQL_ASSOC)){7 C \ j
$tags .= “D ( & 6lencode($row['tag']).” /'>“.$rowj 0 Y ? x v z o J['tag'].”";
}% W ?z F |_ = i
雷图]U Y骨灰盒$tags;
}
{@ ? n i 2 0 , 5 4dede:field.id runphp=yes}
$tsql = new DedeSql(false);
$tags = “;

$tsql->SetQuery(“Select i.tag From ded\ } q |e_taglist t left join dede_tak f 4gindex i on i.id=t.tid where t.aid='@me'”);
$' 1 ~tsql->Execute('t');
while($row = $tsql->GetArray('t',MYSQL_ASSOC)){
$tags .= “e D Hhp?/”.urlencode($row['tag']).“' >”.$row['tag'].“”;
}
@me=$# A F ytags;
{/dede:field.id}
添加代码 6 j't*$x 后,可以使用列表页:
{m s s C $dede:field.id function=“listtag(@me)”/}
以调用标签标签。
方法三:
inc_functions.php 添加 :
函数列表标记($aid){
$tsql = new DedeSql(p ' w x 8 Q 3 s tfalse);
$tags = “;
$tsql->SetQuery(“Select i.tagname From xkzzz_tag_list t left join xkzzz_tu 4 t \ 0 { x gag_index i on i.id=t.tid where t.aid='$aid'”);
$tsql->执行('t');
while($row = $tsql->Getj [ x &Array('t'{ N f M K v S,MYSQL_AO r _ 0 |SSOC)){
$tags .= “s 1 j { ~ + !/tag.php?/”.urlencodeE # 6 [ z H 0 V Y($row['tagname']).“' >”.$rowu F G y A ,['tagname'].“”;
}
+ _ c j c 6 d 返回$tags;
}
然后添加 :,其中列表页位于
[字段:ID 函数=“列表标记(@me)”/]
可以调出来,但是这个方法也需要更改程序文件,看不懂代码的朋友,慎用吧!
8. 首页调用该方法文章 Tg j LAG 标签
如果您网站使用 dedecms v5.7 可以使用以下标签:
径直
[field:id function=GetTags(@me)/]
可以调出,但不能调出g Y # k x s T O \没有连接,为了添加标签标签的链接,还需要做到以下几点:
首先,注 4 + z { # 。E % 删除 130 行收录/帮助程序/存档.helper.php 文件
$tags .= ($tags==“ ? $row['标签'] : ','.$row['标签']);
用以下?!C 语句替换,当然是 J { |R 您还可以添加自己的样式:
$tags .= “_ % k a !php?/”.urlencode($row['tag']).“ /'>”.$row['tag'].”";
添加 # z ; ! p t ] o 下一代 { 0 H R i 代码:
if ( ! function_exists(7 h * Y 0 r Q'GetTagk')){
函数 GetTagk($aid)
{@ / ! ; * K { i
全球$dsql;
$tagk = “;
$query = “选择标签,从'ma_taglist'中辅助,其中aid='$aid'”;
$dsql->Execute('tagD v ^ n b',$query);
while($row = $dsql->GetArray('tag'))
{
$tagk .= ($t\ Z * & \ } 3agk==“n 1 i ? $row['tag'] : ','.$row['tag']);
}
返回 $ta 2 V )O { mgk;
}
}
然后,打开 dede/a( h m^ Jrticle_edit.php 找到:
$tags = Gf I j DetTags($aid);
添加以下内容:
$t( H e ~ M T 8 | *agk = GetTagk($o Q D Jaid);
打开 dede/tempj x z t F n h mlets/article_edit.htm 再次调用标签标签
学习笔记:学python,怎么能不学习scrapy呢
本文分享自华为云社区《学python怎么能不学scrapy?本博客带你学起来-云社区-华为云》,作者:橡皮擦。
在正式写爬虫案例之前,我们先系统地了解一下scrapy。
scrapy安装和简单操作
使用命令pip install scrapy进行安装。安装成功后,需要采集几个网址,方便后续学习使用。
安装完成后,直接在控制台输入scrapy,出现如下命令即表示安装成功。
> scrapy
Scrapy 2.5.0 - no active project
Usage:
scrapy [options] [args]
Available commands:
上图是scrapy内置命令列表,标准格式的scrapy,可以通过scrapy -h查看指定命令的帮助手册。
scrapy中有两种命令,一种是全局的,一种是项目中的。后者需要进入scrapy目录才能运行。
这些命令一开始不需要完全记住,随时可以查看。还有几个比较常用的,例如:
**scrpy 启动项目**
该命令首先根据项目名称创建一个文件夹,然后在该文件夹下创建一个scrpy项目。这一步是所有后续代码的起点。
> scrapy startproject my_scrapy
> New Scrapy project 'my_scrapy', using template directory 'e:\pythonproject\venv\lib\site-packages\scrapy\templates\project', created in: # 一个新的 scrapy 项目被创建了,使用的模板是 XXX,创建的位置是 XXX
E:\pythonProject\滚雪球学Python第4轮\my_scrapy
You can start your first spider with: # 开启你的第一个爬虫程序
cd my_scrapy # 进入文件夹
scrapy genspider example example.com # 使用项目命令创建爬虫文件
以上内容添加了一些评论,可以对照学习。默认生成的文件位于 python 运行时目录中。如果要修改项目目录,请使用如下格式化命令:
scrapy startproject myproject [project_dir]
例如
scrapy startproject myproject d:/d1
命令基于模板创建的项目结构如下,其中红色下划线为项目目录,绿色下划线为scrapy项目。如果要运行项目命令,首先要进入项目目录下红色下划线的my_scrapy文件夹。控制项目。
下面生成爬虫文件
使用命令scrapy genspider [-t template]生成爬虫文件。该方法是快捷操作,也可以手动创建。创建的爬虫文件会出现在当前目录或项目文件夹下的spiders文件夹中,name为爬虫名称,domain用于爬虫文件中allowed_domains和start_urls数据,[-t template]表示可以选择生成文件模板。
要查看所有模板,请使用以下命令,默认模板是 basic。
> scrapy genspider -l
basic
crawl
csvfeed
xmlfeed
创建第一个scrapy爬虫文件,测试命令如下:
>scrapy genspider pm imspm.com
Created spider 'pm' using template 'basic' in module:
my_project.spiders.pm
这时在spiders文件夹中,出现了pm.py文件,文件内容如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['imspm.com']
start_urls = ['http://imspm.com/']
def parse(self, response):
pass
测试 scrapy 爬虫运行
使用命令scrapy crawl,spider是上面生成的爬虫文件名,如果出现如下内容,说明爬虫加载正确。
>scrapy crawl pm
2021-10-02 21:34:34 [scrapy.utils.log] INFO: Scrapy 2.5.0 started (bot: my_project)
[...]
scrapy的基本应用
scrapy 的工作流程非常简单:
采集首页源码;分析首页源码,获取下一页链接;请求下一页的源代码;解析源码,获取下一页的源码;[…] 过程中,提取到目标数据后,保存。
下面给大家展示一个scrapy的完整案例应用,作为爬虫120案例scrapy部分的第一个例子。
> scrapy startproject my_project 爬虫
> cd 爬虫
<p>

> scrapy genspider pm imspm.com</p>
得到项目结构如下:
对上图中部分文件的简要说明。
使用scrapy crawl pm运行爬虫后,所有的输出和描述如下:
上面代码的请求次数是7次,因为pm.py文件中默认没有添加www。如果添加此内容,则请求数变为 4。
当前pm.py文件代码如下:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['www.imspm.com']
start_urls = ['http://www.imspm.com/']
def parse(self, response):
print(response.text)
其中的parse是指请求start_urls中的地址,得到response后的回调函数,通过参数response的.text属性直接输出网页源码。
获取到源码后,需要对源码进行解析存储
在存储之前,需要手动定义一个数据结构,在items.py文件中实现,修改代码中的类名,MyProjectItem → ArticleItem。
import scrapy
class ArticleItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
author = scrapy.Field() # 作者
修改pm.py文件中的parse函数,增加网页解析相关操作。这个操作类似于pyquery的知识点,直接观察代码就可以掌握。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for item in list_item:
title = item.css('.title::text').extract_first() # 直接获取文本
url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
author = item.css('.author::text').extract_first() # 直接获取文本
print(title, url, author)
response.css 方法返回一个选择器列表,可以对其进行迭代,然后对其中的对象调用 css 方法。
在pm.py中导入items.py中的ArticleItem类,然后按照如下代码修改:
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
<p>

item['author'] = author
yield item</p>
这时候scrapy爬虫运行时,会出现如下提示信息。
至此一个单页爬虫就完成了
接下来再次修改parse函数,解析完第一页后,再解析第二页的数据。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first() # 获取下一页链接
# print(next)
# 再次生成一个请求
yield scrapy.Request(url=next, callback=self.parse)
上面代码中,变量next代表下一页的地址,通过response.css函数获取链接。请重点学习css选择器。
产量下降。request(url=next, callback=self.parse)表示重新创建一个请求,请求的回调函数是parse自身,代码运行效果如下。
如果要保存运行结果,只需运行以下命令即可。
scrapy crawl pm -o pm.json
如果要将每条数据存储为单独的一行,请使用以下命令 scrapy crawl pm -o pm.jl 。
生成的文件还支持csv、xml、marchal、pickle,大家可以自己试试。
让我们使用数据管道
打开pipelines.py文件,修改类名MyProjectPipeline→TitlePipeline,然后编译如下代码:
class TitlePipeline:
def process_item(self, item, spider): # 移除标题中的空格
if item["title"]:
item["title"] = item["title"].strip()
return item
else:
return DropItem("异常数据")
此代码用于去除标题中的左右空格。
写入后需要在settings.py文件中开启ITEM_PIPELINES配置。
ITEM_PIPELINES = {
'my_project.pipelines.TitlePipeline': 300,
}
300是PIPELINES操作的优先顺序,可以根据需要修改。再次运行爬虫代码,你会发现标题的左右空格已经被去掉了。
至此,一个scrapy的基础爬虫就写好了。
戳下方关注,第一时间了解华为云的新鲜技术~
华为云博客_大数据博客_人工智能博客_云计算博客_开发者中心-华为云
解决方案:VS2022基于C语言的动态链接库创建与调用
采集交流 • 优采云 发表了文章 • 0 个评论 • 325 次浏览 • 2022-11-17 00:21
//extern "C",告诉编译器它所修饰的代码按c语言方式编译
//"__declspec(dllexport)",告诉编译器和链接器此函数需要从DLL导出
extern "C" _declspec(dllexport) int Sour_Initialize(char* rsrcname);
//函数原型所依赖的lib文件
#pragma comment(lib, "test.lib")
5.关闭一些错误警告
对于 Visual Studio 库中的许多函数、成员函数、函数模板和全局变量,此错误已弃用。一些函数/变量(例如 POSIX 和 Microsoft 特定函数)已被弃用,因为它们现在使用不同的首选名称。一些 C 运行时库函数已被弃用,因为它们不安全,现在有更安全的变体。其他函数/变量已弃用,因为它们已过时。弃用消息通常包括已弃用函数或全局变量的建议替换。
我这里试试没有错,在函数声明的头文件中加入如下代码,直接关闭提示
#pragma warning(disable : 4996)
<p>
</p>
6.编译
生成的库需要在32位环境下编译,这里选择x86
如果成功,在项目文件夹中寻找DEBUG文件夹,会生成需要的DLL文件和LIB文件
三、调用动态链接库 1、创建项目
选择控制台应用程序
2.复制dll文件和lib文件
将刚刚创建的dll文件和lib文件复制到本项目的文件夹中
3. 添加.dll、.lib、.h文件
将声明函数原型的.dll文件、.lib文件和.h文件添加到项目中
4.修改.h文件
在.h文件中添加以下代码
#pragma once
//函数原型所依赖的lib库
#pragma comment(lib, "test.lib")
//刚刚生成的lib库
#pragma comment(lib, "TestDLL.lib")
将函数声明前的“extern "C" _declspec(dllexport)" 更改为 "extern "C" _declspec(dllimport)"
extern "C" _declspec(dllimport) int Sour_Initialize(char* rsrcname);
5.main函数编写调用逻辑
在你写的函数的main函数中调用就可以了。
核心方法:内容和标记SEO分析工具
您的 网站 页面排名因素来自 网站 内容和标记。因此,优化内容并尽量减少标记中的错误非常重要。
1.SEO浏览器
SEO 浏览器是最古老的免费 SEO 工具之一,但它仍然非常有用。该工具是 100% 免费的,它提供两种模式:简单模式和高级模式。简单模式像基于文本的 Web 浏览器(例如,lynx)一样显示给定的 URL。高级模式提供基于文本的 URL 视图,它还包括总结 URL 内容的有用信息(例如页面标题、元标记、页面大小、字数、IP 地址等)。
2. 复制景观
Copyscape 是一种使用免费增值模式的在线重复内容检测工具。您只需输入页面的 URL,该工具就会返回重复该 URL 内容的页面列表。对于免费帐户,该工具仅显示前十名结果,并且该工具每月仅允许来自任何给定站点的一定数量的请求(此限制与通过 IP 提交请求无关)。
3.W3C 标记验证服务
W3C 标记验证服务 标记验证服务是一个免费的在线工具,用于检查与给定 URI 关联的 Web 文档的标记有效性。您只需输入一个 URI,该工具就会检查它的正确性(基于其文档类型的语法)。最后,该工具会显示在验证过程中发现的错误和警告的逐项列表(具有相应的行号和列号)。
历史上的今天: 查看全部
解决方案:VS2022基于C语言的动态链接库创建与调用
//extern "C",告诉编译器它所修饰的代码按c语言方式编译
//"__declspec(dllexport)",告诉编译器和链接器此函数需要从DLL导出
extern "C" _declspec(dllexport) int Sour_Initialize(char* rsrcname);
//函数原型所依赖的lib文件
#pragma comment(lib, "test.lib")
5.关闭一些错误警告
对于 Visual Studio 库中的许多函数、成员函数、函数模板和全局变量,此错误已弃用。一些函数/变量(例如 POSIX 和 Microsoft 特定函数)已被弃用,因为它们现在使用不同的首选名称。一些 C 运行时库函数已被弃用,因为它们不安全,现在有更安全的变体。其他函数/变量已弃用,因为它们已过时。弃用消息通常包括已弃用函数或全局变量的建议替换。
我这里试试没有错,在函数声明的头文件中加入如下代码,直接关闭提示
#pragma warning(disable : 4996)
<p>

</p>
6.编译
生成的库需要在32位环境下编译,这里选择x86
如果成功,在项目文件夹中寻找DEBUG文件夹,会生成需要的DLL文件和LIB文件
三、调用动态链接库 1、创建项目
选择控制台应用程序
2.复制dll文件和lib文件
将刚刚创建的dll文件和lib文件复制到本项目的文件夹中
3. 添加.dll、.lib、.h文件
将声明函数原型的.dll文件、.lib文件和.h文件添加到项目中
4.修改.h文件

在.h文件中添加以下代码
#pragma once
//函数原型所依赖的lib库
#pragma comment(lib, "test.lib")
//刚刚生成的lib库
#pragma comment(lib, "TestDLL.lib")
将函数声明前的“extern "C" _declspec(dllexport)" 更改为 "extern "C" _declspec(dllimport)"
extern "C" _declspec(dllimport) int Sour_Initialize(char* rsrcname);
5.main函数编写调用逻辑
在你写的函数的main函数中调用就可以了。
核心方法:内容和标记SEO分析工具
您的 网站 页面排名因素来自 网站 内容和标记。因此,优化内容并尽量减少标记中的错误非常重要。
1.SEO浏览器

SEO 浏览器是最古老的免费 SEO 工具之一,但它仍然非常有用。该工具是 100% 免费的,它提供两种模式:简单模式和高级模式。简单模式像基于文本的 Web 浏览器(例如,lynx)一样显示给定的 URL。高级模式提供基于文本的 URL 视图,它还包括总结 URL 内容的有用信息(例如页面标题、元标记、页面大小、字数、IP 地址等)。
2. 复制景观
Copyscape 是一种使用免费增值模式的在线重复内容检测工具。您只需输入页面的 URL,该工具就会返回重复该 URL 内容的页面列表。对于免费帐户,该工具仅显示前十名结果,并且该工具每月仅允许来自任何给定站点的一定数量的请求(此限制与通过 IP 提交请求无关)。

3.W3C 标记验证服务
W3C 标记验证服务 标记验证服务是一个免费的在线工具,用于检查与给定 URI 关联的 Web 文档的标记有效性。您只需输入一个 URI,该工具就会检查它的正确性(基于其文档类型的语法)。最后,该工具会显示在验证过程中发现的错误和警告的逐项列表(具有相应的行号和列号)。
历史上的今天:
技巧:“手把手”的性能优化文章来了!
采集交流 • 优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2022-11-16 12:37
通过setFactory,我们不仅可以控制View的生成,甚至可以将一个View变成另一个View。比如文章中,我们把TextView变成了Button。
后续的换皮和一些黑白的方案都是以此为基础。
这意味着我们现在可以:
在运行时,接管某个View的生成,也就是我们可以去掉单个View标签的反射逻辑。
相似代码:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}
<br />
但是一般网上的项目都很大,可能会有各种自定义的View,类似上面的if else,怎么写呢?
先采集,再手写?
如何采集项目中使用的所有View?
假设我们采集了,如果是手写,项目一般都是增量的,那新加的View呢?
我们可以看到我们面临两个问题:
如何采集项目中xml中使用的View;
如何保证编写的View生成代码兼容项目的正常迭代;
3 确定方案
目标已经在这里确定了。
在xml->View的过程中,去掉反射相关的逻辑
下面说一下如何解决我们面临的两个问题:
1、如何采集项目中xml中使用的View;
采集所有xml中用到的View,有一个简单的思路,我们可以解析项目中所有的layout.xml文件,但是项目中的layout.xml文件有各个module,有些依赖的aars需要解压太难.
仔细想想,在我们apk的生成过程中,资源应该是需要合并的,是否是解析某个Task合并后的产物。
确实,具体的实现会在后面说到。
我们来看第二个问题:
2、如何保证编写的View生成代码兼容项目的正常迭代;
我们已经能够采集所有使用过的视图列表,因此为此:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}<br />
逻辑规则,简单,编译时生成一个代码类,完成相关的转换代码生成。这里我选择apt。
有了xml->View转换逻辑的代码类,只需要在运行时使用LayoutFactory注入即可。
3.找到安全的注入逻辑
大家都知道我们View生成相关的逻辑在LayoutInflater下面的代码中:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,<br /> boolean ignoreThemeAttr) {<br /> // ...<br /> View view;<br /> if (mFactory2 != null) {<br /> view = mFactory2.onCreateView(parent, name, context, attrs);<br /> } else if (mFactory != null) {<br /> view = mFactory.onCreateView(name, context, attrs);<br /> } else {<br /> view = null;<br /> }<br /><br /> if (view == null && mPrivateFactory != null) {<br /> view = mPrivateFactory.onCreateView(parent, name, context, attrs);<br /> }<br /><br /> if (view == null) {<br /> final Object lastContext = mConstructorArgs[0];<br /> mConstructorArgs[0] = context;<br /> try {<br /> if (-1 == name.indexOf('.')) {<br /> view = onCreateView(parent, name, attrs);<br /> } else {<br /> view = createView(name, null, attrs);<br /> }<br /> } finally {<br /> mConstructorArgs[0] = lastContext;<br /> }<br /> }<br /><br /> return view;<br /><br />}<br />
<br />
View通过mFactory2、mFactory和mPrivateFactory。建不完,后面等待的就是反思。
前两个工厂和支持包一般用于扩展功能,比如TextView->AppCompatTextView。
我们考虑使用 mPrivateFactory。使用mPrivateFactory的好处是,在当前版本中,mPrivateFactory是Activity,所以我们只需要重写Activity的onCreateView即可:
这样一来,完全不需要hooks,也不会干扰appcompat相关的生成逻辑,可谓是零风险。
4 开始实施
1.获取项目中使用的控件名称列表
我新建了一个工程,在布局文件中写了一些自定义控件,分别叫MyMainView1、MyMainView、MyMainView3、MyMainView4,布局文件就不贴了。
正如我们之前所说,我们需要在构建apk的过程中找到一个合适的注入点来完成这个任务。
那么在apk构建过程中,什么时候会合并资源呢?
我们把构建过程中的所有任务打印出来,输入命令:
./gradlew app:assembleDebug --console=plain<br />
<br />
输出:
>Task :app:preBuild UP-TO-DATE<br />> Task :app:preDebugBuild UP-TO-DATE<br />> Task :app:checkDebugManifest UP-TO-DATE<br />> Task :app:generateDebugBuildConfig UP-TO-DATE<br />> Task :app:javaPreCompileDebug UP-TO-DATE<br />> Task :app:mainApkListPersistenceDebug UP-TO-DATE<br />> Task :app:generateDebugResValues UP-TO-DATE<br />> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE<br />> Task :app:mergeDebugShaders UP-TO-DATE<br />> Task :app:compileDebugShaders UP-TO-DATE<br />> Task :app:generateDebugAssets UP-TO-DATE<br />> Task :app:compileDebugAidl NO-SOURCE<br />> Task :app:compileDebugRenderscript NO-SOURCE<br />> Task :app:generateDebugResources UP-TO-DATE<br />> Task :app:mergeDebugResources UP-TO-DATE<br />> Task :app:processDebugManifest UP-TO-DATE<br />> Task :app:processDebugResources UP-TO-DATE<br />> Task :app:compileDebugJavaWithJavac UP-TO-DATE<br />> Task :app:compileDebugSources UP-TO-DATE<br />> Task :app:mergeDebugAssets UP-TO-DATE<br />> Task :app:processDebugJavaRes NO-SOURCE<br />> Task :app:mergeDebugJavaResource UP-TO-DATE<br />> Task :app:transformClassesWithDexBuilderForDebug UP-TO-DATE<br />> Task :app:checkDebugDuplicateClasses UP-TO-DATE<br />> Task :app:validateSigningDebug UP-TO-DATE<br />> Task :app:mergeExtDexDebug UP-TO-DATE<br />> Task :app:mergeDexDebug UP-TO-DATE<br />> Task :app:signingConfigWriterDebug UP-TO-DATE<br />> Task :app:mergeDebugJniLibFolders UP-TO-DATE<br />> Task :app:mergeDebugNativeLibs UP-TO-DATE<br />> Task :app:stripDebugDebugSymbols UP-TO-DATE<br />> Task :app:packageDebug UP-TO-DATE<br />> Task :app:assembleDebug UP-TO-DATE<br />
<br />
哪一个最像?一看就有一个Task叫:mergeDebugResources,就是这样。
对应build目录,还有一个mergeDebugResources目录:
注意里面有一个merger.xml,里面收录了整个项目所有资源的合并内容。
我们打开看看:
关注里面type=layout的相关标签。
<br />
<br />
可以看到收录我们布局文件的路径,那么我们只需要解析这个merger.xml,然后在里面找到所有type=layout的标签,然后解析出布局文件的实际路径,然后解析出相应的layout xml来获取控件的名称。
对了,这个任务需要注入到mergeDebugResources中执行。
如何注入任务?
很简单:
project.afterEvaluate {<br /> def mergeDebugResourcesTask = project.tasks.findByName("mergeDebugResources")<br /> if (mergeDebugResourcesTask != null) {<br /> def resParseDebugTask = project.tasks.create("ResParseDebugTask", ResParseTask.class)<br /> resParseDebugTask.isDebug = true<br /> mergeDebugResourcesTask.finalizedBy(resParseDebugTask);<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
我们首先找到mergeDebugResources任务,然后注入一个ResParseTask任务。
然后在ResParseTask中完成文件解析:
<br />
class ResParseTask extends DefaultTask {<br /> File viewNameListFile<br /> boolean isDebug<br /> HashSet viewSet = new HashSet()<br /> // 自己根据输出几个添加<br /> List ignoreViewNameList = Arrays.asList("include", "fragment", "merge", "view","DateTimeView")<br /><br /> @TaskAction<br /> void doTask() {<br /><br /> File distDir = new File(project.buildDir, "tmp_custom_views")<br /> if (!distDir.exists()) {<br /> distDir.mkdirs()<br /> }<br /> viewNameListFile = new File(distDir, "custom_view_final.txt")<br /> if (viewNameListFile.exists()) {<br /> viewNameListFile.delete()<br /> }<br /> viewNameListFile.createNewFile()<br /> viewSet.clear()<br /> viewSet.addAll(ignoreViewNameList)<br /><br /> try {<br /> File resMergeFile = new File(project.buildDir, "/intermediates/incremental/merge" + (isDebug ? "Debug" : "Release") + "Resources/merger.xml")<br /><br /> println("resMergeFile:${resMergeFile.getAbsolutePath()} === ${resMergeFile.exists()}")<br /><br /> if (!resMergeFile.exists()) {<br /> return<br /> }<br /><br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(resMergeFile)<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /><br /> } catch (Throwable e) {<br /> e.printStackTrace()<br /> }<br /><br /> }<br /><br /> void parseNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> if (node.name() == "file" && node.attributes.get("type") == "layout") {<br /> String layoutPath = node.attributes.get("path")<br /> try {<br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(layoutPath)<br /><br /> String viewName = result.name();<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /> } catch (Throwable e) {<br /> e.printStackTrace();<br /> }<br /><br /> } else {<br /> node.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /> }<br /><br /> void parseLayoutNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> String viewName = node.name()<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (node.childNodes().size() <br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
代码很简单,主要就是解析merge.xml,找到所有的布局文件,然后解析xml,最后输出到build目录。
我们都把代码写在位于项目根目录的view_opt.gradle中,应用在app的build.gradle中:
<br />
apply from: rootProject.file('view_opt.gradle')<br />
<br />
然后我们再次运行assembleDebug,输出:
注意上面我们还有一个ignoreViewNameList对象,我们过滤了一些特殊的标签,比如:“include”、“fragment”、“merge”、“view”,你可以根据输出结果自行添加。
输出是:
可以看到是去重View的名字。
在这里提一下,很多同学看到写gradle脚本都会感到害怕。其实很简单。你可以只写Java。如果不熟悉语法,可以用Java写。没有什么特别的。
在这一点上,我们有所有使用的视图的名称。
2.apt生成代理类
有了所有用到的View的名字,然后我们用apt生成一个代理类和代理方法。
要使用 apt,我们需要创建 3 个新模块:
ViewOptAnnotation:存储注解;
ViewOptProcessor:放注解处理器相关代码;
ViewOptApi:放相关API。
关于Apt的基础知识就不说了。这块知识太复杂了。你可以自己查一下。后面我会把demo上传到github,大家自己看看。
直接看我们的核心Processor类:
<p>@AutoService(Processor.class)<br />public class ViewCreatorProcessor extends AbstractProcessor {<br /><br /> private Messager mMessager;<br /><br /><br /> @Override<br /> public synchronized void init(ProcessingEnvironment processingEnvironment) {<br /> super.init(processingEnvironment);<br /> mMessager = processingEnv.getMessager();<br /> }<br /><br /> @Override<br /> public boolean process(Set 查看全部
技巧:“手把手”的性能优化文章来了!
通过setFactory,我们不仅可以控制View的生成,甚至可以将一个View变成另一个View。比如文章中,我们把TextView变成了Button。
后续的换皮和一些黑白的方案都是以此为基础。
这意味着我们现在可以:
在运行时,接管某个View的生成,也就是我们可以去掉单个View标签的反射逻辑。
相似代码:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}
<br />
但是一般网上的项目都很大,可能会有各种自定义的View,类似上面的if else,怎么写呢?
先采集,再手写?
如何采集项目中使用的所有View?
假设我们采集了,如果是手写,项目一般都是增量的,那新加的View呢?
我们可以看到我们面临两个问题:
如何采集项目中xml中使用的View;
如何保证编写的View生成代码兼容项目的正常迭代;
3 确定方案
目标已经在这里确定了。
在xml->View的过程中,去掉反射相关的逻辑
下面说一下如何解决我们面临的两个问题:
1、如何采集项目中xml中使用的View;
采集所有xml中用到的View,有一个简单的思路,我们可以解析项目中所有的layout.xml文件,但是项目中的layout.xml文件有各个module,有些依赖的aars需要解压太难.
仔细想想,在我们apk的生成过程中,资源应该是需要合并的,是否是解析某个Task合并后的产物。
确实,具体的实现会在后面说到。
我们来看第二个问题:
2、如何保证编写的View生成代码兼容项目的正常迭代;
我们已经能够采集所有使用过的视图列表,因此为此:
if ("LinearLayout".equals(name)){<br /> View view = new LinearLayout(context, attrs);<br /> return view;<br />}<br />
逻辑规则,简单,编译时生成一个代码类,完成相关的转换代码生成。这里我选择apt。
有了xml->View转换逻辑的代码类,只需要在运行时使用LayoutFactory注入即可。
3.找到安全的注入逻辑
大家都知道我们View生成相关的逻辑在LayoutInflater下面的代码中:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,<br /> boolean ignoreThemeAttr) {<br /> // ...<br /> View view;<br /> if (mFactory2 != null) {<br /> view = mFactory2.onCreateView(parent, name, context, attrs);<br /> } else if (mFactory != null) {<br /> view = mFactory.onCreateView(name, context, attrs);<br /> } else {<br /> view = null;<br /> }<br /><br /> if (view == null && mPrivateFactory != null) {<br /> view = mPrivateFactory.onCreateView(parent, name, context, attrs);<br /> }<br /><br /> if (view == null) {<br /> final Object lastContext = mConstructorArgs[0];<br /> mConstructorArgs[0] = context;<br /> try {<br /> if (-1 == name.indexOf('.')) {<br /> view = onCreateView(parent, name, attrs);<br /> } else {<br /> view = createView(name, null, attrs);<br /> }<br /> } finally {<br /> mConstructorArgs[0] = lastContext;<br /> }<br /> }<br /><br /> return view;<br /><br />}<br />
<br />
View通过mFactory2、mFactory和mPrivateFactory。建不完,后面等待的就是反思。
前两个工厂和支持包一般用于扩展功能,比如TextView->AppCompatTextView。
我们考虑使用 mPrivateFactory。使用mPrivateFactory的好处是,在当前版本中,mPrivateFactory是Activity,所以我们只需要重写Activity的onCreateView即可:
这样一来,完全不需要hooks,也不会干扰appcompat相关的生成逻辑,可谓是零风险。
4 开始实施
1.获取项目中使用的控件名称列表
我新建了一个工程,在布局文件中写了一些自定义控件,分别叫MyMainView1、MyMainView、MyMainView3、MyMainView4,布局文件就不贴了。
正如我们之前所说,我们需要在构建apk的过程中找到一个合适的注入点来完成这个任务。
那么在apk构建过程中,什么时候会合并资源呢?
我们把构建过程中的所有任务打印出来,输入命令:
./gradlew app:assembleDebug --console=plain<br />
<br />
输出:
>Task :app:preBuild UP-TO-DATE<br />> Task :app:preDebugBuild UP-TO-DATE<br />> Task :app:checkDebugManifest UP-TO-DATE<br />> Task :app:generateDebugBuildConfig UP-TO-DATE<br />> Task :app:javaPreCompileDebug UP-TO-DATE<br />> Task :app:mainApkListPersistenceDebug UP-TO-DATE<br />> Task :app:generateDebugResValues UP-TO-DATE<br />> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE<br />> Task :app:mergeDebugShaders UP-TO-DATE<br />> Task :app:compileDebugShaders UP-TO-DATE<br />> Task :app:generateDebugAssets UP-TO-DATE<br />> Task :app:compileDebugAidl NO-SOURCE<br />> Task :app:compileDebugRenderscript NO-SOURCE<br />> Task :app:generateDebugResources UP-TO-DATE<br />> Task :app:mergeDebugResources UP-TO-DATE<br />> Task :app:processDebugManifest UP-TO-DATE<br />> Task :app:processDebugResources UP-TO-DATE<br />> Task :app:compileDebugJavaWithJavac UP-TO-DATE<br />> Task :app:compileDebugSources UP-TO-DATE<br />> Task :app:mergeDebugAssets UP-TO-DATE<br />> Task :app:processDebugJavaRes NO-SOURCE<br />> Task :app:mergeDebugJavaResource UP-TO-DATE<br />> Task :app:transformClassesWithDexBuilderForDebug UP-TO-DATE<br />> Task :app:checkDebugDuplicateClasses UP-TO-DATE<br />> Task :app:validateSigningDebug UP-TO-DATE<br />> Task :app:mergeExtDexDebug UP-TO-DATE<br />> Task :app:mergeDexDebug UP-TO-DATE<br />> Task :app:signingConfigWriterDebug UP-TO-DATE<br />> Task :app:mergeDebugJniLibFolders UP-TO-DATE<br />> Task :app:mergeDebugNativeLibs UP-TO-DATE<br />> Task :app:stripDebugDebugSymbols UP-TO-DATE<br />> Task :app:packageDebug UP-TO-DATE<br />> Task :app:assembleDebug UP-TO-DATE<br />
<br />
哪一个最像?一看就有一个Task叫:mergeDebugResources,就是这样。
对应build目录,还有一个mergeDebugResources目录:
注意里面有一个merger.xml,里面收录了整个项目所有资源的合并内容。
我们打开看看:
关注里面type=layout的相关标签。
<br />
<br />
可以看到收录我们布局文件的路径,那么我们只需要解析这个merger.xml,然后在里面找到所有type=layout的标签,然后解析出布局文件的实际路径,然后解析出相应的layout xml来获取控件的名称。
对了,这个任务需要注入到mergeDebugResources中执行。
如何注入任务?
很简单:
project.afterEvaluate {<br /> def mergeDebugResourcesTask = project.tasks.findByName("mergeDebugResources")<br /> if (mergeDebugResourcesTask != null) {<br /> def resParseDebugTask = project.tasks.create("ResParseDebugTask", ResParseTask.class)<br /> resParseDebugTask.isDebug = true<br /> mergeDebugResourcesTask.finalizedBy(resParseDebugTask);<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
我们首先找到mergeDebugResources任务,然后注入一个ResParseTask任务。
然后在ResParseTask中完成文件解析:
<br />
class ResParseTask extends DefaultTask {<br /> File viewNameListFile<br /> boolean isDebug<br /> HashSet viewSet = new HashSet()<br /> // 自己根据输出几个添加<br /> List ignoreViewNameList = Arrays.asList("include", "fragment", "merge", "view","DateTimeView")<br /><br /> @TaskAction<br /> void doTask() {<br /><br /> File distDir = new File(project.buildDir, "tmp_custom_views")<br /> if (!distDir.exists()) {<br /> distDir.mkdirs()<br /> }<br /> viewNameListFile = new File(distDir, "custom_view_final.txt")<br /> if (viewNameListFile.exists()) {<br /> viewNameListFile.delete()<br /> }<br /> viewNameListFile.createNewFile()<br /> viewSet.clear()<br /> viewSet.addAll(ignoreViewNameList)<br /><br /> try {<br /> File resMergeFile = new File(project.buildDir, "/intermediates/incremental/merge" + (isDebug ? "Debug" : "Release") + "Resources/merger.xml")<br /><br /> println("resMergeFile:${resMergeFile.getAbsolutePath()} === ${resMergeFile.exists()}")<br /><br /> if (!resMergeFile.exists()) {<br /> return<br /> }<br /><br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(resMergeFile)<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /><br /> } catch (Throwable e) {<br /> e.printStackTrace()<br /> }<br /><br /> }<br /><br /> void parseNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> if (node.name() == "file" && node.attributes.get("type") == "layout") {<br /> String layoutPath = node.attributes.get("path")<br /> try {<br /> XmlSlurper slurper = new XmlSlurper()<br /> GPathResult result = slurper.parse(layoutPath)<br /><br /> String viewName = result.name();<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (result.children() != null) {<br /> result.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /> } catch (Throwable e) {<br /> e.printStackTrace();<br /> }<br /><br /> } else {<br /> node.childNodes().forEachRemaining({ o -><br /> if (o instanceof Node) {<br /> parseNode(o)<br /> }<br /> })<br /> }<br /><br /> }<br /><br /> void parseLayoutNode(Node node) {<br /> if (node == null) {<br /> return<br /> }<br /> String viewName = node.name()<br /> if (viewSet.add(viewName)) {<br /> viewNameListFile.append("${viewName}\n")<br /> }<br /> if (node.childNodes().size() <br /> if (o instanceof Node) {<br /> parseLayoutNode(o)<br /> }<br /> })<br /> }<br /><br />}<br />
<br />
根目录:view_opt.gradle
代码很简单,主要就是解析merge.xml,找到所有的布局文件,然后解析xml,最后输出到build目录。
我们都把代码写在位于项目根目录的view_opt.gradle中,应用在app的build.gradle中:
<br />
apply from: rootProject.file('view_opt.gradle')<br />
<br />
然后我们再次运行assembleDebug,输出:

注意上面我们还有一个ignoreViewNameList对象,我们过滤了一些特殊的标签,比如:“include”、“fragment”、“merge”、“view”,你可以根据输出结果自行添加。
输出是:
可以看到是去重View的名字。
在这里提一下,很多同学看到写gradle脚本都会感到害怕。其实很简单。你可以只写Java。如果不熟悉语法,可以用Java写。没有什么特别的。
在这一点上,我们有所有使用的视图的名称。
2.apt生成代理类
有了所有用到的View的名字,然后我们用apt生成一个代理类和代理方法。
要使用 apt,我们需要创建 3 个新模块:
ViewOptAnnotation:存储注解;
ViewOptProcessor:放注解处理器相关代码;
ViewOptApi:放相关API。
关于Apt的基础知识就不说了。这块知识太复杂了。你可以自己查一下。后面我会把demo上传到github,大家自己看看。
直接看我们的核心Processor类:
<p>@AutoService(Processor.class)<br />public class ViewCreatorProcessor extends AbstractProcessor {<br /><br /> private Messager mMessager;<br /><br /><br /> @Override<br /> public synchronized void init(ProcessingEnvironment processingEnvironment) {<br /> super.init(processingEnvironment);<br /> mMessager = processingEnv.getMessager();<br /> }<br /><br /> @Override<br /> public boolean process(Set
推荐文章:想写一篇高引用的综述文章?你需要这样做!
采集交流 • 优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2022-11-16 12:28
这是社科学术圈推送的第2307篇文章文章
打开topic-experiment-publishing,每一步都需要阅读文献,但是这几个步骤的文献并不全面。从解决一个问题的开始到解决一个问题的结束,所有的具体文献都涉及到。要想全面把握整个题目的走向,写综述是非常有必要的。而且,经过长时间的相关研究,写一篇评论文章有以下好处:
在很大程度上可以提高把握整个学科方向的能力。通过详细、全面的文献检索和阅读,可以全面掌握和了解本课题的发展脉络、研究进展和最新成果。
其次,是对自己作品的总结和升华。经过多年的相关研究,我心中一定有很多的思考和疑问。这时候,大量的阅读就是对自己固有知识的一个归纳升华的过程。写完应该有顿悟的感觉。
再次,对以后的实验研究具有重要的指导作用。写好review之后,通过对整个项目方向的了解,知道哪些问题已经解决,哪些地方还存在问题,哪些问题是热点问题,哪些是难点骨头,是制约项目发展的关键. 这样,就可以有针对性地设计以后的实验。
在小的方面,评论也是一个文章。现在国内的评价都是看个人成绩,总结也是一种发表文章的方式。另一方面,你可以提高你在同龄人中的地位。一般来说,评论 文章 比研究 文章 有更多的引用,从而提高了它们在同行中的知名度。
《文献检索准备工作》
在开始写评论之前,一个重要的准备工作就是文献检索。审查文章 需要全面,并且必须综合审查中审查的问题。因此,有必要进行详尽的文献检索。
这里说的全面,并不是说下载阅读几十年的所有文章。这将是太多的工作。这是一。第二,早期的文章可能已经总结过了。因此,只需寻找一些综述 文章。这里的综合指的是更多的关键词搜索和更多的数据库搜索。先说关键词,每个作者对关键词的偏好不同,在新兴领域没有统一术语的时候,多改几个关键词是很有必要的。除了数据库,由于各个数据库收录的期刊并不全面,所以重要的搜索工具在这里必不可少。
获取相关文献还有两个技巧。一个是我读过的文章中引用的文献。这个很容易理解,文末的参考资料就是这样。另外就是看哪个文章引用了你读过的文章,也是相关文献。例如,谷歌学术有一个引用计数,你可以通过点击查看哪些文章引用了这篇文章文章。
通过以上几种方法,才能找到所有相关文献。
“大量阅读以备不时之需”
找到所有的文献之后,下一步就是开始阅读了。
首先,没必要全部看完,时间太长,工作量太大。但是,应该通读最近两年的文章。两年是对一个相对热门的领域进行全面概述 文章 的合理时间点。近两年的文章要通读重点,这也是复习的重点。不通读就知道解决了什么问题,如何解决是不够的;没看完就写点评有点不负责任。
两年前的文章完全没必要看,因为你可以从这两年的文章里的序言里看对这些文章的评论,就可以了也看了评论文章获取相关信息。这些文章可以重点阅读摘要,也有针对某个问题的针对性阅读。
“如何阅读文件”
阅读数百份文件并非易事。如果你只是浏览它们,你只能留下一个大概的印象。一段时间后或者随着阅读文档的增多,这种模糊的印象也会消失。知识点的记忆是写作和创作的基础。我不记得如何组织语言。就算查了,也不知道从几百份文件,几千页里查到哪里去。
我的导师教我要辩证地看书,边想边记,不能在书上乱写。对我来说,“好记性不如烂笔头”更适合我,也适合我的德国同事。他们将文件打印在A4纸上,并用荧光笔标出重要的句子。看完后,抄写在A5纸上,作为选集书到原稿上。摘录的才是真正对你有用的知识点。大多数其他 文章 都是伏笔,或者已经在你的记忆中。“划重点+读书笔记”可以有效帮助记忆。
虽然一开始这样看很慢,但是随着文档写了十多二十篇,积累多了,后面的摘录就会越来越少。还有,你的阅读速度越来越快。
《文件管理》
下载数百个文档后,文档流水线就成了问题。对于文献管理,Endnote就是这样一个专业,它可以有效地组织庞大的文献,并为您提供全面的信息,如作者、期刊、年份、标题、卷页码和摘要。有些期刊在投稿的时候需要DOI,Endnote也可以。Endnote在文章的编排中起着巨大的作用,是写评论、写论文、写书的必备工具。
虽然电子版很方便,但我还是更喜欢看纸质版。我喜欢把文件打印出来,统一编号(和Endnote一致,Endnote中的Label可以加编号),打孔,放在活页夹里。
“文章 的架构”
文学阅读是一个从“说得过去”、“说得过去”、“大是大非”到“无事生非”的过程。
我刚开始读书。由于本人知识有限,之前文章提出的方法和结果对我来说都是全新的,我的知识储备不足以判断观点。因此,当你刚开始阅读时,你会完全接受文章中的所有内容,很难提出有问题的观点,你阅读的任何内容都是“有理有据”的。看了十八篇文章,明白了更多的方法和观点,有些可能会有不同的看法。这是因为疑惑会跳出来,我会挑剔我读到的论据,但我不能仅仅依靠一两篇文章文章就断定一种方法完全优于另一种方法。每种方法都有其优缺点,从而达到“似是而非”的境界。只有看到足够多的文章才能做出完整的评价,得到的对比结果也有足够的论据。这时,已经达到了“大是大非”的境界。
一篇评论文章,一部分是综合别人的作品,一部分是讨论自己的观点。大是大非只是全面的一步,还应该更进一步。通过对“大是大非”的把握,要能够发现新问题、新优势或劣势,提出改进方法,对今后的工作和发展前景提出建议和设想。更有什者,跳出对原实验细枝末节的讨论,从更高的层次,从原理、方法和系统上进行评价。这当然是非常困难的。所以,大部分的总结文章都是总结而不总结,以至于读者看完后对过去有所了解,但对未来还是茫然无措。当然,
如果看完之后能做到“大是大非”的经济,就可以开始写作了。写作时,首先要搭建一个框架,对要概括的内容进行分类、细分。分得越细越好,至少三级,三级标题下可能还有四五级标题。这样做有以下好处:
@frame 要审查并缩小范围的问题。不要让你的写作“随心所欲”,偏离了方向,失去了重心。也容易分清主次,而不是抓眉毛胡子。这不是在写一本书,没有太多的空间来全面讨论,所以限制你的评论范围。
@写作压力小。一想到写文章文章,就想到“至少写5000字,看100篇文档”,瞬间压力倍增,不知从何下手。细分之后,你需要考虑的就是讨论某个方法的某个参数,只需要一小段文字。它非常容易,可以立即完成,没有太大的压力。
@有顺序地。所有要讨论的问题都列在那里,就像一个TO-DO LIST,完成一项划掉一项,一项一项,有条不紊,进度非常直观。
《写作的小细节》
文章细分成小节后,就可以开始完成每个小节了。下面介绍几个非常有效的小技巧。
@注意写作的连贯性:最好一口气写完,写A的时候不要想着B。这里有两个意思。写A题时,找到B题有用的材料;另一个意思是你在写A题的时候发现了B题的错误、遗漏或者其他问题。这时候不要停下来,直接用便利贴做笔记(我习惯用ONENOTE做笔记采集材料)。做完笔记,继续写A题,直到写完。我们回过头来梳理B题。
@二手文献:为了证明一个结论,可能需要引用文章主题之外的文献,或者需要从文献中引用的文献中寻找证据,这称为二手文献。文献中被他人引用的数据一定要核对,避免错引文献、错引数据。
@图片处理:一个是图片的版权问题,这个不用担心。当你投稿给期刊时,期刊的编辑会处理;二是画质。从其他文档中提取图片时,不要使用截图,因为图片的分辨率不够。PDF文件要用PHOTOSHOP打开,裁剪出需要的图片,然后保存为TIFF/JPEG格式。PPT中绘制的图片,不要使用PPT的“图片另存为”功能,分辨率太弱。应该说是把PPT保存成PDF,然后用PHOTOSHOP处理。
@references 的修改。前期写作时,必须用ENDNOTE对插入WORD的文档进行索引。如果文章已经形成,则ENDNOTE已经导出了参考文献,其他作者修改后,需要增删参考文献。添加或删除文档将更改其他文档的索引号。这时候很容易出错。我用的是下面的方法:在每个要更改的文档的索引中加上“*”;在“*”后添加新的参考索引号;使用搜索功能确认每一个需要改的文档都用“*”连接(应该出现两次,比如添加引用121、122应该有两个,121*122、122*123,即121变成 122,122 变成 123);删除“*”和之前的索引号。
@英语句子,短句胜于长句。被人理解才是最重要的。简短的句子很容易理解。太多的定语从句会让人头晕目眩。
“文章 的亮点”
一篇文章文章必须要有一些“干货”,才能被更多人引用。所以在你写之前,看看你下载的 文章 的引用。哪个 文章 获得了最多的引用?为什么?
从我个人引用文章的习惯来看,下面的文章会被引用:
@第一篇文章:该领域的开创性工作,不引用是不合理的;
@milestone文章:文章达到最高、最高、最大、最快等,或者突出的进步,应该注明;
@正在讨论核心问题。
另外,我也喜欢引用结论性的句子,比如某项技术的优点……;以及量化的句子,比如70%的文章目前都采用了某种方法。
如果你能在你的评论中提供这些内容,那肯定会增加其他引用的数量。前三个干货是研究型文章的东西,后两个就不简单了。第一个需要你自己总结,第二个需要大量的统计。
分享文章:文章伪原创检查(在线文章伪原创)
本文阅读提示:在线文章伪原创,文章伪原创软件移动版,文章采集伪原创
文章伪原创检查工具在线 zoding(文章伪原创),4 个经典 SEO 伪原创|谷歌搜索引擎:pR劫持,5个常规工件
网站共同点和伪原创是SEO伪项目,1支持多个平台的SEO伪原创
SEO伪原创检测工具伪原创,1并支持多个平台的SEO伪原创
SEO伪原创检测工具在线伪原创,2并支持多种快速替换的SEO伪原创
搜索引擎优化
伪原创检测工具伪原创,3并支持多种快速替换的SEO伪原创
SEO伪原创检测工具在线伪原创,1支持图文组合的快速伪原创
SEO伪原创检测工具伪原创,1并支持多种快速替换的SEO伪原创
SEO伪原创检测工具,1支持图文组合的多版本伪原创
SEO伪原创检测工具,2支持重大修改
SEO伪原创,3大伪原创成本测试
SEO伪原创文章工具,1个搜索引擎与文章库集成
SEO 伪原创文章工具,1 个集成关键词
SEO伪原创文章工具,1个集成关键词,搜索量关键词
SEO伪原创文章工具,2密度的组织关键词
SEO伪原创文章工具,3.优化网站内部链
SEO伪原创文章工具,1网站结构优化
SEO伪原创文章工具,1网站结构优化:平面结构。辅助导航。痕迹导航。子导航。野外站。特殊优化2.内容页面优化:(优化最新文章。推荐文章。热门文章 3页面加载速度(秒) 4.页面代码压缩和简化
SEO伪原创文章工具,2个面包屑来指导页面。 301重定向第五代。图像标签 6.网站 TDK写作 7.关键词密度控制8.在单词标签周围使用关键字 9.粗体关键字等 10.合理使用NO11。分页代码优化SEO 伪原创文章工具
、3SEO 伪原创文章工具站点地图设置
SEO 伪原创文章工具,1 网站结构优化 2.网站地图优化提交。主动推送。自动推送)。
SEO伪原创文章工具,4个优化的关键词布局
SEO伪原创文章工具,1选择和识别核心关键词。长尾关键词延伸。关键词工具词挖掘研究。竞争对手网站关键词分享研究成果
搜索引擎优化伪原创文章工具,
相关文章 查看全部
推荐文章:想写一篇高引用的综述文章?你需要这样做!
这是社科学术圈推送的第2307篇文章文章
打开topic-experiment-publishing,每一步都需要阅读文献,但是这几个步骤的文献并不全面。从解决一个问题的开始到解决一个问题的结束,所有的具体文献都涉及到。要想全面把握整个题目的走向,写综述是非常有必要的。而且,经过长时间的相关研究,写一篇评论文章有以下好处:
在很大程度上可以提高把握整个学科方向的能力。通过详细、全面的文献检索和阅读,可以全面掌握和了解本课题的发展脉络、研究进展和最新成果。
其次,是对自己作品的总结和升华。经过多年的相关研究,我心中一定有很多的思考和疑问。这时候,大量的阅读就是对自己固有知识的一个归纳升华的过程。写完应该有顿悟的感觉。
再次,对以后的实验研究具有重要的指导作用。写好review之后,通过对整个项目方向的了解,知道哪些问题已经解决,哪些地方还存在问题,哪些问题是热点问题,哪些是难点骨头,是制约项目发展的关键. 这样,就可以有针对性地设计以后的实验。
在小的方面,评论也是一个文章。现在国内的评价都是看个人成绩,总结也是一种发表文章的方式。另一方面,你可以提高你在同龄人中的地位。一般来说,评论 文章 比研究 文章 有更多的引用,从而提高了它们在同行中的知名度。
《文献检索准备工作》
在开始写评论之前,一个重要的准备工作就是文献检索。审查文章 需要全面,并且必须综合审查中审查的问题。因此,有必要进行详尽的文献检索。
这里说的全面,并不是说下载阅读几十年的所有文章。这将是太多的工作。这是一。第二,早期的文章可能已经总结过了。因此,只需寻找一些综述 文章。这里的综合指的是更多的关键词搜索和更多的数据库搜索。先说关键词,每个作者对关键词的偏好不同,在新兴领域没有统一术语的时候,多改几个关键词是很有必要的。除了数据库,由于各个数据库收录的期刊并不全面,所以重要的搜索工具在这里必不可少。
获取相关文献还有两个技巧。一个是我读过的文章中引用的文献。这个很容易理解,文末的参考资料就是这样。另外就是看哪个文章引用了你读过的文章,也是相关文献。例如,谷歌学术有一个引用计数,你可以通过点击查看哪些文章引用了这篇文章文章。
通过以上几种方法,才能找到所有相关文献。
“大量阅读以备不时之需”
找到所有的文献之后,下一步就是开始阅读了。
首先,没必要全部看完,时间太长,工作量太大。但是,应该通读最近两年的文章。两年是对一个相对热门的领域进行全面概述 文章 的合理时间点。近两年的文章要通读重点,这也是复习的重点。不通读就知道解决了什么问题,如何解决是不够的;没看完就写点评有点不负责任。

两年前的文章完全没必要看,因为你可以从这两年的文章里的序言里看对这些文章的评论,就可以了也看了评论文章获取相关信息。这些文章可以重点阅读摘要,也有针对某个问题的针对性阅读。
“如何阅读文件”
阅读数百份文件并非易事。如果你只是浏览它们,你只能留下一个大概的印象。一段时间后或者随着阅读文档的增多,这种模糊的印象也会消失。知识点的记忆是写作和创作的基础。我不记得如何组织语言。就算查了,也不知道从几百份文件,几千页里查到哪里去。
我的导师教我要辩证地看书,边想边记,不能在书上乱写。对我来说,“好记性不如烂笔头”更适合我,也适合我的德国同事。他们将文件打印在A4纸上,并用荧光笔标出重要的句子。看完后,抄写在A5纸上,作为选集书到原稿上。摘录的才是真正对你有用的知识点。大多数其他 文章 都是伏笔,或者已经在你的记忆中。“划重点+读书笔记”可以有效帮助记忆。
虽然一开始这样看很慢,但是随着文档写了十多二十篇,积累多了,后面的摘录就会越来越少。还有,你的阅读速度越来越快。
《文件管理》
下载数百个文档后,文档流水线就成了问题。对于文献管理,Endnote就是这样一个专业,它可以有效地组织庞大的文献,并为您提供全面的信息,如作者、期刊、年份、标题、卷页码和摘要。有些期刊在投稿的时候需要DOI,Endnote也可以。Endnote在文章的编排中起着巨大的作用,是写评论、写论文、写书的必备工具。
虽然电子版很方便,但我还是更喜欢看纸质版。我喜欢把文件打印出来,统一编号(和Endnote一致,Endnote中的Label可以加编号),打孔,放在活页夹里。
“文章 的架构”
文学阅读是一个从“说得过去”、“说得过去”、“大是大非”到“无事生非”的过程。
我刚开始读书。由于本人知识有限,之前文章提出的方法和结果对我来说都是全新的,我的知识储备不足以判断观点。因此,当你刚开始阅读时,你会完全接受文章中的所有内容,很难提出有问题的观点,你阅读的任何内容都是“有理有据”的。看了十八篇文章,明白了更多的方法和观点,有些可能会有不同的看法。这是因为疑惑会跳出来,我会挑剔我读到的论据,但我不能仅仅依靠一两篇文章文章就断定一种方法完全优于另一种方法。每种方法都有其优缺点,从而达到“似是而非”的境界。只有看到足够多的文章才能做出完整的评价,得到的对比结果也有足够的论据。这时,已经达到了“大是大非”的境界。
一篇评论文章,一部分是综合别人的作品,一部分是讨论自己的观点。大是大非只是全面的一步,还应该更进一步。通过对“大是大非”的把握,要能够发现新问题、新优势或劣势,提出改进方法,对今后的工作和发展前景提出建议和设想。更有什者,跳出对原实验细枝末节的讨论,从更高的层次,从原理、方法和系统上进行评价。这当然是非常困难的。所以,大部分的总结文章都是总结而不总结,以至于读者看完后对过去有所了解,但对未来还是茫然无措。当然,
如果看完之后能做到“大是大非”的经济,就可以开始写作了。写作时,首先要搭建一个框架,对要概括的内容进行分类、细分。分得越细越好,至少三级,三级标题下可能还有四五级标题。这样做有以下好处:
@frame 要审查并缩小范围的问题。不要让你的写作“随心所欲”,偏离了方向,失去了重心。也容易分清主次,而不是抓眉毛胡子。这不是在写一本书,没有太多的空间来全面讨论,所以限制你的评论范围。
@写作压力小。一想到写文章文章,就想到“至少写5000字,看100篇文档”,瞬间压力倍增,不知从何下手。细分之后,你需要考虑的就是讨论某个方法的某个参数,只需要一小段文字。它非常容易,可以立即完成,没有太大的压力。
@有顺序地。所有要讨论的问题都列在那里,就像一个TO-DO LIST,完成一项划掉一项,一项一项,有条不紊,进度非常直观。

《写作的小细节》
文章细分成小节后,就可以开始完成每个小节了。下面介绍几个非常有效的小技巧。
@注意写作的连贯性:最好一口气写完,写A的时候不要想着B。这里有两个意思。写A题时,找到B题有用的材料;另一个意思是你在写A题的时候发现了B题的错误、遗漏或者其他问题。这时候不要停下来,直接用便利贴做笔记(我习惯用ONENOTE做笔记采集材料)。做完笔记,继续写A题,直到写完。我们回过头来梳理B题。
@二手文献:为了证明一个结论,可能需要引用文章主题之外的文献,或者需要从文献中引用的文献中寻找证据,这称为二手文献。文献中被他人引用的数据一定要核对,避免错引文献、错引数据。
@图片处理:一个是图片的版权问题,这个不用担心。当你投稿给期刊时,期刊的编辑会处理;二是画质。从其他文档中提取图片时,不要使用截图,因为图片的分辨率不够。PDF文件要用PHOTOSHOP打开,裁剪出需要的图片,然后保存为TIFF/JPEG格式。PPT中绘制的图片,不要使用PPT的“图片另存为”功能,分辨率太弱。应该说是把PPT保存成PDF,然后用PHOTOSHOP处理。
@references 的修改。前期写作时,必须用ENDNOTE对插入WORD的文档进行索引。如果文章已经形成,则ENDNOTE已经导出了参考文献,其他作者修改后,需要增删参考文献。添加或删除文档将更改其他文档的索引号。这时候很容易出错。我用的是下面的方法:在每个要更改的文档的索引中加上“*”;在“*”后添加新的参考索引号;使用搜索功能确认每一个需要改的文档都用“*”连接(应该出现两次,比如添加引用121、122应该有两个,121*122、122*123,即121变成 122,122 变成 123);删除“*”和之前的索引号。
@英语句子,短句胜于长句。被人理解才是最重要的。简短的句子很容易理解。太多的定语从句会让人头晕目眩。
“文章 的亮点”
一篇文章文章必须要有一些“干货”,才能被更多人引用。所以在你写之前,看看你下载的 文章 的引用。哪个 文章 获得了最多的引用?为什么?
从我个人引用文章的习惯来看,下面的文章会被引用:
@第一篇文章:该领域的开创性工作,不引用是不合理的;
@milestone文章:文章达到最高、最高、最大、最快等,或者突出的进步,应该注明;
@正在讨论核心问题。
另外,我也喜欢引用结论性的句子,比如某项技术的优点……;以及量化的句子,比如70%的文章目前都采用了某种方法。
如果你能在你的评论中提供这些内容,那肯定会增加其他引用的数量。前三个干货是研究型文章的东西,后两个就不简单了。第一个需要你自己总结,第二个需要大量的统计。
分享文章:文章伪原创检查(在线文章伪原创)
本文阅读提示:在线文章伪原创,文章伪原创软件移动版,文章采集伪原创
文章伪原创检查工具在线 zoding(文章伪原创),4 个经典 SEO 伪原创|谷歌搜索引擎:pR劫持,5个常规工件
网站共同点和伪原创是SEO伪项目,1支持多个平台的SEO伪原创
SEO伪原创检测工具伪原创,1并支持多个平台的SEO伪原创
SEO伪原创检测工具在线伪原创,2并支持多种快速替换的SEO伪原创
搜索引擎优化
伪原创检测工具伪原创,3并支持多种快速替换的SEO伪原创
SEO伪原创检测工具在线伪原创,1支持图文组合的快速伪原创

SEO伪原创检测工具伪原创,1并支持多种快速替换的SEO伪原创
SEO伪原创检测工具,1支持图文组合的多版本伪原创
SEO伪原创检测工具,2支持重大修改
SEO伪原创,3大伪原创成本测试
SEO伪原创文章工具,1个搜索引擎与文章库集成
SEO 伪原创文章工具,1 个集成关键词
SEO伪原创文章工具,1个集成关键词,搜索量关键词
SEO伪原创文章工具,2密度的组织关键词
SEO伪原创文章工具,3.优化网站内部链

SEO伪原创文章工具,1网站结构优化
SEO伪原创文章工具,1网站结构优化:平面结构。辅助导航。痕迹导航。子导航。野外站。特殊优化2.内容页面优化:(优化最新文章。推荐文章。热门文章 3页面加载速度(秒) 4.页面代码压缩和简化
SEO伪原创文章工具,2个面包屑来指导页面。 301重定向第五代。图像标签 6.网站 TDK写作 7.关键词密度控制8.在单词标签周围使用关键字 9.粗体关键字等 10.合理使用NO11。分页代码优化SEO 伪原创文章工具
、3SEO 伪原创文章工具站点地图设置
SEO 伪原创文章工具,1 网站结构优化 2.网站地图优化提交。主动推送。自动推送)。
SEO伪原创文章工具,4个优化的关键词布局
SEO伪原创文章工具,1选择和识别核心关键词。长尾关键词延伸。关键词工具词挖掘研究。竞争对手网站关键词分享研究成果
搜索引擎优化伪原创文章工具,
相关文章