文章采集调用

文章采集调用

文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))

采集交流优采云 发表了文章 • 0 个评论 • 122 次浏览 • 2022-02-06 04:10 • 来自相关话题

  文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))
  首先,明确必须满足两个要求:
  1、调用指定的section
  2、调用文章来收录指定的关键字
  相关文档调用
  {dede:likeart titlelen='24' 行='10'}
  [字段:标题/]
  {/dede:likeart}
  注意:这是dede官方的调用模板,但是调用依据还不清楚!
  调用指定部分
  {dede:arclist typeid='??ĿID' row='10' titlelen='20'}
  [字段:文本链接/]
  {/dede:arclist}
  这是我想要实现的目标:
  指定栏目的调用(ID=4)相关新闻(关键词调用关键词或标题)
  {dede:arclist typeid='4' row='10' titlelen='20' 关键字=''}
  [字段:文本链接/]
  {/dede:arclist}
  代码 1
  
  效果一:
  
  代码 2:
  
  效果二:
  
  此时,如果你只是一个关键词,那就没问题了。以下键是我的 关键词 将要调用的:即keyword='{dede:field 或者我称之为标题
  关键字='{dede:field/}'
  但是,这很少使用,因为调用了模板。没有人希望所有 文章 都调用同一个关键字!
  博主推荐方法:
  -------------------------------------------------- ----------------------------------
  放置在 文章 模板页面中
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  表示取所有列中所有相关的文章(与当前文章的关键字相关),标题最大长度32,最大显示10,不显示缩略图.
  或者
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"Higher 3 Chinese")'/}
  你可以找到文章,其标题收录“大三中文”,或“大三”或“中文”
  例如,这一段:
  相关文章
  {dede:likeart titlelen='24' 行='10'}
  [字段:文本链接/]
  {/dede:likeart}
  只需将其更改为:
  相关文章
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  基于关键字的相关文章在用户体验和SEO方面非常好
  唯一的缺点是生成静态的时候会慢很多
  -------------------------------------------------- ------------------------------------------------
  附1:arclist中的关键字如何调用当前文档的关键字(dedecms织梦技术论坛)
  附2:{dede:arclist}的学习心得,调用文章或者软件的任意领域
  附上3、dedecms实现{dede:arclist keyword='[field:title/]'}的效果
  【Arclist标签】这个标签是Dedecms中最常用的标签,也叫free list标签,其中hotart、coolart、likeart、artlist、imglist、imginfolist、specart、autolist都是这个标签定义的别名扩展自不同属性的标签。功能说明:获取指定文档列表适用范围:封面模板、列表模板、文档模板基本语法:
  {dede:arclist typeid='' row='' col='' titlelen='' infolen=''
  imgwidth='' imgheight='' listtype='' orderby='' 关键字=''}
  底层模板(InnerText)
  {/dede:arclist} 属性说明:
  [1] typeid=''表示列ID,列表模板和文件模板中一般不需要指定。允许在封面模板中使用“,”表示多栏;
  [2] row='' 表示返回文档列表的总数;
  [3] col='' 表示显示多少列(默认为单列);
  [4] titlelen=''表示标题长度;
  [5] infolen='' 表示内容介绍的长度;
  [6] imgwidth='' 表示缩略图的宽度;
  [7] imgheight='' 表示缩略图高度;
  [8] type=''表示文件类型,为空值时为普通文件,不使用该属性,或type='all'
  § type='commend'时,表示推荐文档,相当于{dede:coolart}{/dede:coolart}
  § 当type='image'时,表示必须收录缩略图的文档,相当于{dede:imglist}{/dede:imglist}, {dede:imginfolist}{/dede:imginfolist}
  § 当type='spec'时,表示特殊主题,相当于mark {dede:specart}{/dede:specart}
  以上属性值可以组合使用,如:type='commend image'表示推荐图片文档
  [9] orderby=''表示排序方式,默认为senddate根据发布时间排列。
  § orderby='hot' 或 orderby='click' 表示按点击次数排序
  § orderby='pubdate' 按发布时间排列(即前台允许更改的时间值)
  § orderby='sortrank' 按 文章 的新排序等级排序(如果要使用顶行 文章,请使用此属性)
  § orderby='id' 排序 文章ID
  § orderby='postnum' 按 文章 评论数排序
  § orderby='rand' 随机获取指定条件的文档列表
  [10] orderway='' 取值为desc或asc,指定是降序排序还是按顺序排序,默认为降序。
  [11]keyword=''表示收录指定关键字的文档列表,多个关键字用“,”隔开
  [12] channelid='' 表示具体频道模型ID,内置频道:topic(-1), 文章(1), Atlas(2), Flash( 4),软件(3)
  [13]limit='start,end'表示记录的限制范围,row属性必须等于“end-start”,mysql的limit语句从0开始,如“limit 0,5”表示取对于前五条记录,“limit 5,5”表示从第五条记录中删除五条记录。使用该属性后,行属性将失效。
  [14] att='value' 表示自定义属性值
  [15] subday='天数' 表示文档的天数,通常用于获取指定天数的热门文档、推荐文档、热门评论文档等
  [16] partsort='列数'表示自动获取父列所有子列的列ID。该属性仅在标记为 {dede:autolist}{/dede:autolist} 时有效。
  底层模板字段:
  ID(同id),title,iscommend,color,typeid,ismake,description(同info),writer,shorttitle,memberid
  pubdate, senddate, arcrank, click, litpic (same as picname), typedir, typename,
  arcurl(与文件名相同)、typeurl、stime(发布日期的“0000-00-00”格式)、
  textlink,typelink,imglink,图像
  在:
  文本链接 = 标题
  类型链接 = 类型名称
  链接=
  
  图片 =
  
  字段调用方法:[field:varname/]
  喜欢:
  {dede:arclist infolen='100'}
  [字段:文本链接/]
  [字段:信息/]
  {/dede:arclist}
  注意:底层模板中的Field实现也是织梦标签的一种形式,所以支持使用PHP语法、Function扩展等功能
  例如:为当天发布的内容添加(新)标志
  [字段:发送日期运行php ='是']
  $ntime = 时间();
  $一天 = 3600 * 24;
  如果(($ntime-@我) 查看全部

  文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))
  首先,明确必须满足两个要求:
  1、调用指定的section
  2、调用文章来收录指定的关键字
  相关文档调用
  {dede:likeart titlelen='24' 行='10'}
  [字段:标题/]
  {/dede:likeart}
  注意:这是dede官方的调用模板,但是调用依据还不清楚!
  调用指定部分
  {dede:arclist typeid='??ĿID' row='10' titlelen='20'}
  [字段:文本链接/]
  {/dede:arclist}
  这是我想要实现的目标:
  指定栏目的调用(ID=4)相关新闻(关键词调用关键词或标题)
  {dede:arclist typeid='4' row='10' titlelen='20' 关键字=''}
  [字段:文本链接/]
  {/dede:arclist}
  代码 1
  
  效果一:
  
  代码 2:
  
  效果二:
  
  此时,如果你只是一个关键词,那就没问题了。以下键是我的 关键词 将要调用的:即keyword='{dede:field 或者我称之为标题
  关键字='{dede:field/}'
  但是,这很少使用,因为调用了模板。没有人希望所有 文章 都调用同一个关键字!
  博主推荐方法:
  -------------------------------------------------- ----------------------------------
  放置在 文章 模板页面中
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  表示取所有列中所有相关的文章(与当前文章的关键字相关),标题最大长度32,最大显示10,不显示缩略图.
  或者
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"Higher 3 Chinese")'/}
  你可以找到文章,其标题收录“大三中文”,或“大三”或“中文”
  例如,这一段:
  相关文章
  {dede:likeart titlelen='24' 行='10'}
  [字段:文本链接/]
  {/dede:likeart}
  只需将其更改为:
  相关文章
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  基于关键字的相关文章在用户体验和SEO方面非常好
  唯一的缺点是生成静态的时候会慢很多
  -------------------------------------------------- ------------------------------------------------
  附1:arclist中的关键字如何调用当前文档的关键字(dedecms织梦技术论坛)
  附2:{dede:arclist}的学习心得,调用文章或者软件的任意领域
  附上3、dedecms实现{dede:arclist keyword='[field:title/]'}的效果
  【Arclist标签】这个标签是Dedecms中最常用的标签,也叫free list标签,其中hotart、coolart、likeart、artlist、imglist、imginfolist、specart、autolist都是这个标签定义的别名扩展自不同属性的标签。功能说明:获取指定文档列表适用范围:封面模板、列表模板、文档模板基本语法:
  {dede:arclist typeid='' row='' col='' titlelen='' infolen=''
  imgwidth='' imgheight='' listtype='' orderby='' 关键字=''}
  底层模板(InnerText)
  {/dede:arclist} 属性说明:
  [1] typeid=''表示列ID,列表模板和文件模板中一般不需要指定。允许在封面模板中使用“,”表示多栏;
  [2] row='' 表示返回文档列表的总数;
  [3] col='' 表示显示多少列(默认为单列);
  [4] titlelen=''表示标题长度;
  [5] infolen='' 表示内容介绍的长度;
  [6] imgwidth='' 表示缩略图的宽度;
  [7] imgheight='' 表示缩略图高度;
  [8] type=''表示文件类型,为空值时为普通文件,不使用该属性,或type='all'
  § type='commend'时,表示推荐文档,相当于{dede:coolart}{/dede:coolart}
  § 当type='image'时,表示必须收录缩略图的文档,相当于{dede:imglist}{/dede:imglist}, {dede:imginfolist}{/dede:imginfolist}
  § 当type='spec'时,表示特殊主题,相当于mark {dede:specart}{/dede:specart}
  以上属性值可以组合使用,如:type='commend image'表示推荐图片文档
  [9] orderby=''表示排序方式,默认为senddate根据发布时间排列。
  § orderby='hot' 或 orderby='click' 表示按点击次数排序
  § orderby='pubdate' 按发布时间排列(即前台允许更改的时间值)
  § orderby='sortrank' 按 文章 的新排序等级排序(如果要使用顶行 文章,请使用此属性)
  § orderby='id' 排序 文章ID
  § orderby='postnum' 按 文章 评论数排序
  § orderby='rand' 随机获取指定条件的文档列表
  [10] orderway='' 取值为desc或asc,指定是降序排序还是按顺序排序,默认为降序。
  [11]keyword=''表示收录指定关键字的文档列表,多个关键字用“,”隔开
  [12] channelid='' 表示具体频道模型ID,内置频道:topic(-1), 文章(1), Atlas(2), Flash( 4),软件(3)
  [13]limit='start,end'表示记录的限制范围,row属性必须等于“end-start”,mysql的limit语句从0开始,如“limit 0,5”表示取对于前五条记录,“limit 5,5”表示从第五条记录中删除五条记录。使用该属性后,行属性将失效。
  [14] att='value' 表示自定义属性值
  [15] subday='天数' 表示文档的天数,通常用于获取指定天数的热门文档、推荐文档、热门评论文档等
  [16] partsort='列数'表示自动获取父列所有子列的列ID。该属性仅在标记为 {dede:autolist}{/dede:autolist} 时有效。
  底层模板字段:
  ID(同id),title,iscommend,color,typeid,ismake,description(同info),writer,shorttitle,memberid
  pubdate, senddate, arcrank, click, litpic (same as picname), typedir, typename,
  arcurl(与文件名相同)、typeurl、stime(发布日期的“0000-00-00”格式)、
  textlink,typelink,imglink,图像
  在:
  文本链接 = 标题
  类型链接 = 类型名称
  链接=
  
  图片 =
  
  字段调用方法:[field:varname/]
  喜欢:
  {dede:arclist infolen='100'}
  [字段:文本链接/]
  [字段:信息/]
  {/dede:arclist}
  注意:底层模板中的Field实现也是织梦标签的一种形式,所以支持使用PHP语法、Function扩展等功能
  例如:为当天发布的内容添加(新)标志
  [字段:发送日期运行php ='是']
  $ntime = 时间();
  $一天 = 3600 * 24;
  如果(($ntime-@我)

文章采集调用( 大型网站反而很少尤其尤其是门户网站的问题!(上))

采集交流优采云 发表了文章 • 0 个评论 • 107 次浏览 • 2022-02-03 22:20 • 来自相关话题

  文章采集调用(
大型网站反而很少尤其尤其是门户网站的问题!(上))
  
  我学习 Python 已经有一段时间了。在学习的过程中,我不断地实践所学的各种知识。我做的最多的是爬虫,也就是简单的数据采集,里面有采集图片(这个是最多的……),有的下载电影,有的和学习有关,比如爬虫ppt模板,当然我也写过诸如收发邮件、自动登录论坛发帖、验证码相关操作等等!
  这些脚本有一个共同点,它们都与网络相关,并且总是使用一些获取链接的方法。我在这里总结一下,分享给正在学习的人。
  安装相关
  其实python的各个版本差别不大,不用太担心使用3.6或者3.7.
  至于我们经常使用的库,建议大家先了解安装哪些库,安装哪些库。
  有的同学会纠结,库装不上。这个推荐大家搜索一下:python whl 是第一个。其中每个库都有不同的版本。选择对应的下载,用pip安装文件的全路径安装。!
  例如:pip install d:\requests_download-0.1.2-py2.py3-none-any.whl
  最基本的抓取站——获取源码
  导入请求#导入库
  html = requests.get(url)#获取源代码
  html.encoding='utf-8'#指定收录中文的网页源码的编码格式,具体格式一般存在于源码的meta标签中
  对于静态网页
  网站反“反爬”
  大部分网站(各种中小网站)都需要你的代码有headers信息,如果没有,会直接拒绝你的访问!大型网站很少,尤其是门户网站网站,如新浪新闻、今日头条图集、百度图片爬虫等。@>!
  对于有防爬措施的网站,大部分都可以按照添加UA信息的顺序添加到headers数据(字典格式)中——添加HOST和Referer(防盗链)信息!代码格式 requestts.get(url,headers=headers)
  UA信息就是浏览器信息,告诉对方我们是什么浏览器。通常,我们可以采集相关信息来制作一个UA池。我们可以在需要的时候调用,也可以随机调用,防止被网站发现,注意是的,如果是移动端,一定要注意移动端网页的区别和 PC 终端。例如,我们更喜欢移动端作为微博爬虫。其抗爬网能力远低于PC端。@网站 反爬很厉害,可以到手机端(手机登录复制url),说不定有惊喜!
  
  HOST信息,网站的主机信息,这个一般不变
  Referer信息,这是“防盗链”的关键信息。简单来说就是你来到当前页面的地方,破解也很简单,把url放进去就行了!
  如果上面的方法还是绕不过反爬的话,那就比较麻烦了,把所有信息都写在headers里。
  终极反“反爬”:学硒,少年!
  保存文件
  其实可以简单的分为两类:字符串内容保存和其他内容保存!简单2行代码即可解决
  
  a+是文本末尾的附加书写方式,适合字符串内容的书写。注意排版。也可以在'a+'后面加上参数encoding='utf-8'来指定保存文本的编码格式
  wb为二进制写入方式,适用于找到对象的真实下载地址后,以二进制方式下载文件
  
  待续
  篇幅有限,本来想写完的,但是有人说我写的太多了,没人看。. . 这很尴尬!那就先写到这里吧!
  也是时候重新整理一下以下内容了,大概是:自动登录(cookie池)和登录、ip代理、验证码(这是个大项目)以及scarpy框架的一些注意事项。
  有其他技能或者问题的同学也可以在评论区写,一起讨论吧!
  写在最后
  喜欢这篇文章文章或者认为这篇文章文章对你有帮助的读者可以关注或者点播转发,私信小编001获取最新python数据和0副本2018年小编整理的。基础入门教程,欢迎初学者和高级朋友 查看全部

  文章采集调用(
大型网站反而很少尤其尤其是门户网站的问题!(上))
  
  我学习 Python 已经有一段时间了。在学习的过程中,我不断地实践所学的各种知识。我做的最多的是爬虫,也就是简单的数据采集,里面有采集图片(这个是最多的……),有的下载电影,有的和学习有关,比如爬虫ppt模板,当然我也写过诸如收发邮件、自动登录论坛发帖、验证码相关操作等等!
  这些脚本有一个共同点,它们都与网络相关,并且总是使用一些获取链接的方法。我在这里总结一下,分享给正在学习的人。
  安装相关
  其实python的各个版本差别不大,不用太担心使用3.6或者3.7.
  至于我们经常使用的库,建议大家先了解安装哪些库,安装哪些库。
  有的同学会纠结,库装不上。这个推荐大家搜索一下:python whl 是第一个。其中每个库都有不同的版本。选择对应的下载,用pip安装文件的全路径安装。!
  例如:pip install d:\requests_download-0.1.2-py2.py3-none-any.whl
  最基本的抓取站——获取源码
  导入请求#导入库
  html = requests.get(url)#获取源代码
  html.encoding='utf-8'#指定收录中文的网页源码的编码格式,具体格式一般存在于源码的meta标签中
  对于静态网页
  网站反“反爬”
  大部分网站(各种中小网站)都需要你的代码有headers信息,如果没有,会直接拒绝你的访问!大型网站很少,尤其是门户网站网站,如新浪新闻、今日头条图集、百度图片爬虫等。@>!
  对于有防爬措施的网站,大部分都可以按照添加UA信息的顺序添加到headers数据(字典格式)中——添加HOST和Referer(防盗链)信息!代码格式 requestts.get(url,headers=headers)
  UA信息就是浏览器信息,告诉对方我们是什么浏览器。通常,我们可以采集相关信息来制作一个UA池。我们可以在需要的时候调用,也可以随机调用,防止被网站发现,注意是的,如果是移动端,一定要注意移动端网页的区别和 PC 终端。例如,我们更喜欢移动端作为微博爬虫。其抗爬网能力远低于PC端。@网站 反爬很厉害,可以到手机端(手机登录复制url),说不定有惊喜!
  
  HOST信息,网站的主机信息,这个一般不变
  Referer信息,这是“防盗链”的关键信息。简单来说就是你来到当前页面的地方,破解也很简单,把url放进去就行了!
  如果上面的方法还是绕不过反爬的话,那就比较麻烦了,把所有信息都写在headers里。
  终极反“反爬”:学硒,少年!
  保存文件
  其实可以简单的分为两类:字符串内容保存和其他内容保存!简单2行代码即可解决
  
  a+是文本末尾的附加书写方式,适合字符串内容的书写。注意排版。也可以在'a+'后面加上参数encoding='utf-8'来指定保存文本的编码格式
  wb为二进制写入方式,适用于找到对象的真实下载地址后,以二进制方式下载文件
  
  待续
  篇幅有限,本来想写完的,但是有人说我写的太多了,没人看。. . 这很尴尬!那就先写到这里吧!
  也是时候重新整理一下以下内容了,大概是:自动登录(cookie池)和登录、ip代理、验证码(这是个大项目)以及scarpy框架的一些注意事项。
  有其他技能或者问题的同学也可以在评论区写,一起讨论吧!
  写在最后
  喜欢这篇文章文章或者认为这篇文章文章对你有帮助的读者可以关注或者点播转发,私信小编001获取最新python数据和0副本2018年小编整理的。基础入门教程,欢迎初学者和高级朋友

文章采集调用(打开servlet-api源码可见继承和response获取方式)

采集交流优采云 发表了文章 • 0 个评论 • 140 次浏览 • 2022-02-03 22:19 • 来自相关话题

  文章采集调用(打开servlet-api源码可见继承和response获取方式)
  为了从请求中提取body和header,使代码的改动尽可能小,进入容器的请求必须被统一拦截,否则代码必须嵌入到所有的HttpServlet实现类中。在这里,我们需要再次感谢 servlet 说明符为我们提供的过滤机制。
  该规范指定过滤器是一段可重用的代码,用于转换 HTTP 请求、响应和标头信息的内容。过滤器通常不会为请求创建响应,而是修改或调整请求和响应。其中,filter主要提供四种拦截方式:
  这里我们只使用 REQUEST 模式。配置过滤器后,我们可以从过滤器的doFilter方法中获取HttpServletRequest和HttpServletResponse(简称请求和响应)。
  获取标题
  在上面,我们通过过滤机制获得了请求和响应。打开对应的源码实现,我们可以找到如下API:
  
  规范为我们提供了一个 API 来直接获取标头。通过结合 getHeaderNames() 和 getHeader(String name) 方法,我们可以轻松获取请求和响应中的标头。
  得到身体
  获取请求体和响应体的方法大致相同。这里以request为例,后面会调整差异。
  从请求API中我们可以发现body在java中是以ServletInputStream的形式存储的,而ServletInputStream是一个继承的InputStream。如果我们直接读取,用户获取到的body会是空的(因为InputStream只能读取一次),除非可以把指针放回去)。这里需要用到servlet的包装机制。
  Servlet 中的包装器
  有的人可能不会用到requestWrapper和responseWrapper,这里简单介绍一下。wrapper 是通过继承 servlet 规范中的 HttpServletResponseWrapper 和 HttpServletRequestWrapper 实现的装饰模式。相当于请求和响应的一个shell,类似于java中的代理,这样操作请求和响应的所有动作都会经过我们自定义的wrapper,使得在请求中重复获取body成为可能和回应。
  编写自己的包装器
  我们以 request 为例来说明如何编写自定义包装器。打开servlet-api源码可以看到HttpServletRequestWrapper继承了ServletRequestWrapper,实现了HttpServletRequest接口。
  
  并且大部分方法已经在 ServletRequestWrapper 中为我们实现了。
  
  我们只需要重写我们关心的几个方法,例如:getInputStream和getReader等。
  
  当用户尝试调用 getReader 或 getInputStream 时,我们将其替换为自己的流,并额外提供一个 getContent() 方法来提前读取 StringBuilder 或 byte[] 中的正文内容进行提取。
  编写好自定义包装器后,我们可以将其放入我们上面定义的过滤器中,替换原来的请求。然后把用户的请求变成我们的requestWrapper。
  优化提取逻辑
  上面提到的方法等价于预先读取收录body的inputStream,并将其存储在一个中间byte[]或StringBuilder中。当用户调用 getInputStream 时,byte[] 或 StringBuilder 被转换为 inputStream 返回给用户。如果用户根本不关心这个http请求的body,也就是用户根本不使用这个请求的body,那么我们提前把它读出来,相当于做了无用功(浪费宝贵的 CPU 时间和内存资源)。如何保证inputStream在用户使用时是只读的,当用户或后续逻辑多次获取body时,是我们的优化目标。
  对于答案,我们继续从源码中寻找。既然我们的数据在 inputStream 中,我们就跟着源码看看是怎么读取的。在servlet规范中,inputStream被封装成ServletInputStream,ServletInputStream提供了readLine方法。往里面看,可以看到它们都调用了inputStream中的read方法,如下图:
  
  既然read方法是一个统一的入口,那我们只要自定义一个ServletInputStream,重写里面的read()方法,就可以修改所有的read方法吗?答案是肯定的。只要用户调用了read方法,我们就悄悄地把我们关心的内容复制一份,这样我们只在用户使用body的时候才去采集。
  下一步是如何确保用户调用 read 多次,我们总是只读取一次。在这里,我们需要使用一个 AtomicBoolean 标志,当执行完整读取时将其设置为 true,否则设置为 false。最终效果如下:
  
  举一反三
  在这里,我们使用 servlet 规范中的过滤器和包装器机制来获取进入我们容器(tomcat)的所有 http 请求的主体和标头。这个能力在我们实际生产中可以进一步扩展,比如:我们需要在客户端加密一些敏感数据然后在服务端进行统一解密,格式化客户端发送的数据格式等等。可以限制你的是你的想象力。希望本次技术分享对您以后的工作和生活有所帮助。
  总结
  读完这篇文章,读者应该可以在不影响原代码的情况下,通过简单的代码获取所有进入容器的http请求的body和header。虽然可能需要适配一些特殊的技术栈,比如如果项目中使用了jersey,参数等信息以application/x-www-form-urlencoded的形式传递,而服务端不使用@ FormParam注解获取参数,那么我们获取body后,用户将无法获取参数;例如,如何区分媒体类型,如果是图像,则不会被提取。但我们已经验证,这条路是可行的,而且是成功的一半。 查看全部

  文章采集调用(打开servlet-api源码可见继承和response获取方式)
  为了从请求中提取body和header,使代码的改动尽可能小,进入容器的请求必须被统一拦截,否则代码必须嵌入到所有的HttpServlet实现类中。在这里,我们需要再次感谢 servlet 说明符为我们提供的过滤机制。
  该规范指定过滤器是一段可重用的代码,用于转换 HTTP 请求、响应和标头信息的内容。过滤器通常不会为请求创建响应,而是修改或调整请求和响应。其中,filter主要提供四种拦截方式:
  这里我们只使用 REQUEST 模式。配置过滤器后,我们可以从过滤器的doFilter方法中获取HttpServletRequest和HttpServletResponse(简称请求和响应)。
  获取标题
  在上面,我们通过过滤机制获得了请求和响应。打开对应的源码实现,我们可以找到如下API:
  
  规范为我们提供了一个 API 来直接获取标头。通过结合 getHeaderNames() 和 getHeader(String name) 方法,我们可以轻松获取请求和响应中的标头。
  得到身体
  获取请求体和响应体的方法大致相同。这里以request为例,后面会调整差异。
  从请求API中我们可以发现body在java中是以ServletInputStream的形式存储的,而ServletInputStream是一个继承的InputStream。如果我们直接读取,用户获取到的body会是空的(因为InputStream只能读取一次),除非可以把指针放回去)。这里需要用到servlet的包装机制。
  Servlet 中的包装器
  有的人可能不会用到requestWrapper和responseWrapper,这里简单介绍一下。wrapper 是通过继承 servlet 规范中的 HttpServletResponseWrapper 和 HttpServletRequestWrapper 实现的装饰模式。相当于请求和响应的一个shell,类似于java中的代理,这样操作请求和响应的所有动作都会经过我们自定义的wrapper,使得在请求中重复获取body成为可能和回应。
  编写自己的包装器
  我们以 request 为例来说明如何编写自定义包装器。打开servlet-api源码可以看到HttpServletRequestWrapper继承了ServletRequestWrapper,实现了HttpServletRequest接口。
  
  并且大部分方法已经在 ServletRequestWrapper 中为我们实现了。
  
  我们只需要重写我们关心的几个方法,例如:getInputStream和getReader等。
  
  当用户尝试调用 getReader 或 getInputStream 时,我们将其替换为自己的流,并额外提供一个 getContent() 方法来提前读取 StringBuilder 或 byte[] 中的正文内容进行提取。
  编写好自定义包装器后,我们可以将其放入我们上面定义的过滤器中,替换原来的请求。然后把用户的请求变成我们的requestWrapper。
  优化提取逻辑
  上面提到的方法等价于预先读取收录body的inputStream,并将其存储在一个中间byte[]或StringBuilder中。当用户调用 getInputStream 时,byte[] 或 StringBuilder 被转换为 inputStream 返回给用户。如果用户根本不关心这个http请求的body,也就是用户根本不使用这个请求的body,那么我们提前把它读出来,相当于做了无用功(浪费宝贵的 CPU 时间和内存资源)。如何保证inputStream在用户使用时是只读的,当用户或后续逻辑多次获取body时,是我们的优化目标。
  对于答案,我们继续从源码中寻找。既然我们的数据在 inputStream 中,我们就跟着源码看看是怎么读取的。在servlet规范中,inputStream被封装成ServletInputStream,ServletInputStream提供了readLine方法。往里面看,可以看到它们都调用了inputStream中的read方法,如下图:
  
  既然read方法是一个统一的入口,那我们只要自定义一个ServletInputStream,重写里面的read()方法,就可以修改所有的read方法吗?答案是肯定的。只要用户调用了read方法,我们就悄悄地把我们关心的内容复制一份,这样我们只在用户使用body的时候才去采集。
  下一步是如何确保用户调用 read 多次,我们总是只读取一次。在这里,我们需要使用一个 AtomicBoolean 标志,当执行完整读取时将其设置为 true,否则设置为 false。最终效果如下:
  
  举一反三
  在这里,我们使用 servlet 规范中的过滤器和包装器机制来获取进入我们容器(tomcat)的所有 http 请求的主体和标头。这个能力在我们实际生产中可以进一步扩展,比如:我们需要在客户端加密一些敏感数据然后在服务端进行统一解密,格式化客户端发送的数据格式等等。可以限制你的是你的想象力。希望本次技术分享对您以后的工作和生活有所帮助。
  总结
  读完这篇文章,读者应该可以在不影响原代码的情况下,通过简单的代码获取所有进入容器的http请求的body和header。虽然可能需要适配一些特殊的技术栈,比如如果项目中使用了jersey,参数等信息以application/x-www-form-urlencoded的形式传递,而服务端不使用@ FormParam注解获取参数,那么我们获取body后,用户将无法获取参数;例如,如何区分媒体类型,如果是图像,则不会被提取。但我们已经验证,这条路是可行的,而且是成功的一半。

文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)

采集交流优采云 发表了文章 • 0 个评论 • 120 次浏览 • 2022-02-01 08:04 • 来自相关话题

  文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)
  文章采集调用有:知乎api、搜狗搜索等渠道。实际上在正式回答前,我是不知道知乎api的,于是花了一个下午搞清楚了。[调用知乎api的教程(持续更新)](-union-china.html)为了照顾到国内用户的使用习惯,我只有调用苹果的api的分享特性。
  2017年6月23日,我遇到这个问题后,马上访问知乎app客户端发现并没有什么问题,于是我给知乎app做了本地代码抓包,验证没有问题,但是随后就发现知乎有多处服务异常,其中包括appstore应用信息不正确,我得去appstore问问苹果,也可能是我手机问题,然后就联系appstore客服。苹果客服说是app被review了,需要重新修改后重审,随后我就联系了反馈渠道,收到了积极响应,app客服说抓包时机是先抓取appstore信息,再抓取app本地信息,在抓取全部app和网页的信息,现在苹果就在和知乎协商这个问题,期间app客服还收到苹果漏洞的报道,苹果客服对我这个问题很负责,说过段时间苹果会给知乎反馈,顺利通过。现在一直都安心不少。附图我通过抓包问苹果客服问题。
  我来补充一下。应该是内存管理策略的问题。苹果服务器代码写入后每一个线程是只会被处理一次。这就是你看到的闪退,是因为你正在通过web服务器抓包分享。但是苹果服务器并没有review你的app是否能正常下载。会先给你分享一个无效的app然后再去扫描一次app。这样就会造成闪退。 查看全部

  文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)
  文章采集调用有:知乎api、搜狗搜索等渠道。实际上在正式回答前,我是不知道知乎api的,于是花了一个下午搞清楚了。[调用知乎api的教程(持续更新)](-union-china.html)为了照顾到国内用户的使用习惯,我只有调用苹果的api的分享特性。
  2017年6月23日,我遇到这个问题后,马上访问知乎app客户端发现并没有什么问题,于是我给知乎app做了本地代码抓包,验证没有问题,但是随后就发现知乎有多处服务异常,其中包括appstore应用信息不正确,我得去appstore问问苹果,也可能是我手机问题,然后就联系appstore客服。苹果客服说是app被review了,需要重新修改后重审,随后我就联系了反馈渠道,收到了积极响应,app客服说抓包时机是先抓取appstore信息,再抓取app本地信息,在抓取全部app和网页的信息,现在苹果就在和知乎协商这个问题,期间app客服还收到苹果漏洞的报道,苹果客服对我这个问题很负责,说过段时间苹果会给知乎反馈,顺利通过。现在一直都安心不少。附图我通过抓包问苹果客服问题。
  我来补充一下。应该是内存管理策略的问题。苹果服务器代码写入后每一个线程是只会被处理一次。这就是你看到的闪退,是因为你正在通过web服务器抓包分享。但是苹果服务器并没有review你的app是否能正常下载。会先给你分享一个无效的app然后再去扫描一次app。这样就会造成闪退。

文章采集调用(selenium爬取流程安装自动模块,代理批量采集 )

采集交流优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-02-01 07:02 • 来自相关话题

  文章采集调用(selenium爬取流程安装自动模块,代理批量采集
)
  硒爬行过程
  安装python selenium自动模块,使用selenium中的webdriver驱动浏览器获取cookies登录微信公众号后台;
  使用webdriver功能需要安装对应浏览器的驱动插件。
  注意:谷歌浏览器版本和chromedriver需要对应,否则启动时会报错。
  微信公众号登录地址:
  微信公众号文章的接口地址可以在微信公众号后台创建,可以从超链接函数中获取:
  搜索公众号名称
  获取要爬取的公众号fakeid
  选择要爬取的公众号,获取文章的接口地址
  文章列表翻页和内容获取
  
  AnyProxy 代理批量采集
  1、微信客户端:可以是安装了微信应用的手机,也可以是电脑上的安卓模拟器。
  2、微信个人账号:采集的内容,不仅需要微信客户端,采集还需要微信个人账号。
  3、本地代理服务器系统:将公众号历史消息页面中的文章列表通过Anyproxy代理服务器发送到自己的服务器。
  4、文章列表分析存储系统,分析文章列表并构建采集队列,实现批量采集内容。
  Fiddler 设置代理并抓包
  通过捕获和分析多个账户,可以确定:
  _biz:这个14位的字符串是每个公众号的“id”,可以从搜狗的微信平台获取。
  uin:与访客相关,微信ID
  key:与访问的公众号相关
  步:
  1、编写按钮向导脚本,在手机端自动点击公众号文章的列表页面,即“查看历史消息”;
  2、使用fiddler代理劫持​​手机访问,将URL转发到php编写的本地网页;
  3、将接收到的URL备份到php网页上的数据库中;
  4、使用python从数据库中检索URL,然后进行正常爬取。
  潜在问题:
  如果只是想爬文章内容,貌似没有访问频率限制,但是如果想爬读点赞数,一定频率后返回值会变空。
  付费平台
  例如,如果你只是想看数据,你可以不花钱只看每日清单。如果你需要访问自己的系统,他们也提供了一个api接口
  3 项目步骤
  3.1基本原则
  目标爬取微信平台网站收录大部分优质微信公众号文章,会定期更新。经过测试,发现对爬虫更加友好。
  1、网站页面排版和排版规则,不同公众号以链接中的账号区分
  公众号采集下的2、文章也有定时翻页:id号每翻一页+12
  所以过程思路是
  获取预查询微信公众号ID(不是直接显示的名字,而是信息名片中的ID号,一般由数字和字母组成)
  请求一个html页面判断公众号是否被更改收录
  如果没有收录,页面显示结果为:404 页面不存在,可以直接用正则表达式匹配提示信息
  正则匹配查找目标公众号的最大页数收录文章
  解析请求的页面,提取 文章 链接和标题文本
  保存信息提取结果
  调用pdfkit和wkhtmltopdf转换网页
  3.2环境
  win10(64位)
  蜘蛛(蟒蛇3.6)
  安装转换工具包 wkhtmltopdf
  要求
  pdf工具包
  3.3 公众号信息检索
  通过向目标url发起requset请求,获取页面的html信息,然后调用正则方法匹配两条信息
  1、公众号是否存在
  2、如果存在,最大文章收录页数是多少
  
  当公众号存在时,直接调用request解析目标请求链接。
  
  注意目标爬虫网站必须添加headers,否则会直接拒绝访问
  3.4 正则解析、提取链接和文章标题
  以下代码用于从 html 文本中解析链接和标题文本信息
  
  3.5 自动跳转页面
  下面的代码通过循环递增赋值来改变url中的页码参数
  
  3.6去除标题中的非法字符
  因为windows下的file命令,有些字符不能使用,所以需要使用正则剔除
  itle = re.sub('[/:*?"|]', '', info.loc[indexs]['title'])
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  
  3.8 生成的 PDF 结果
  
  4 结果显示
  
  ​
   查看全部

  文章采集调用(selenium爬取流程安装自动模块,代理批量采集
)
  硒爬行过程
  安装python selenium自动模块,使用selenium中的webdriver驱动浏览器获取cookies登录微信公众号后台;
  使用webdriver功能需要安装对应浏览器的驱动插件。
  注意:谷歌浏览器版本和chromedriver需要对应,否则启动时会报错。
  微信公众号登录地址:
  微信公众号文章的接口地址可以在微信公众号后台创建,可以从超链接函数中获取:
  搜索公众号名称
  获取要爬取的公众号fakeid
  选择要爬取的公众号,获取文章的接口地址
  文章列表翻页和内容获取
  
  AnyProxy 代理批量采集
  1、微信客户端:可以是安装了微信应用的手机,也可以是电脑上的安卓模拟器。
  2、微信个人账号:采集的内容,不仅需要微信客户端,采集还需要微信个人账号。
  3、本地代理服务器系统:将公众号历史消息页面中的文章列表通过Anyproxy代理服务器发送到自己的服务器。
  4、文章列表分析存储系统,分析文章列表并构建采集队列,实现批量采集内容。
  Fiddler 设置代理并抓包
  通过捕获和分析多个账户,可以确定:
  _biz:这个14位的字符串是每个公众号的“id”,可以从搜狗的微信平台获取。
  uin:与访客相关,微信ID
  key:与访问的公众号相关
  步:
  1、编写按钮向导脚本,在手机端自动点击公众号文章的列表页面,即“查看历史消息”;
  2、使用fiddler代理劫持​​手机访问,将URL转发到php编写的本地网页;
  3、将接收到的URL备份到php网页上的数据库中;
  4、使用python从数据库中检索URL,然后进行正常爬取。
  潜在问题:
  如果只是想爬文章内容,貌似没有访问频率限制,但是如果想爬读点赞数,一定频率后返回值会变空。
  付费平台
  例如,如果你只是想看数据,你可以不花钱只看每日清单。如果你需要访问自己的系统,他们也提供了一个api接口
  3 项目步骤
  3.1基本原则
  目标爬取微信平台网站收录大部分优质微信公众号文章,会定期更新。经过测试,发现对爬虫更加友好。
  1、网站页面排版和排版规则,不同公众号以链接中的账号区分
  公众号采集下的2、文章也有定时翻页:id号每翻一页+12
  所以过程思路是
  获取预查询微信公众号ID(不是直接显示的名字,而是信息名片中的ID号,一般由数字和字母组成)
  请求一个html页面判断公众号是否被更改收录
  如果没有收录,页面显示结果为:404 页面不存在,可以直接用正则表达式匹配提示信息
  正则匹配查找目标公众号的最大页数收录文章
  解析请求的页面,提取 文章 链接和标题文本
  保存信息提取结果
  调用pdfkit和wkhtmltopdf转换网页
  3.2环境
  win10(64位)
  蜘蛛(蟒蛇3.6)
  安装转换工具包 wkhtmltopdf
  要求
  pdf工具包
  3.3 公众号信息检索
  通过向目标url发起requset请求,获取页面的html信息,然后调用正则方法匹配两条信息
  1、公众号是否存在
  2、如果存在,最大文章收录页数是多少
  
  当公众号存在时,直接调用request解析目标请求链接。
  
  注意目标爬虫网站必须添加headers,否则会直接拒绝访问
  3.4 正则解析、提取链接和文章标题
  以下代码用于从 html 文本中解析链接和标题文本信息
  
  3.5 自动跳转页面
  下面的代码通过循环递增赋值来改变url中的页码参数
  
  3.6去除标题中的非法字符
  因为windows下的file命令,有些字符不能使用,所以需要使用正则剔除
  itle = re.sub('[/:*?"|]', '', info.loc[indexs]['title'])
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  
  3.8 生成的 PDF 结果
  
  4 结果显示
  
  ​
  

文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])

采集交流优采云 发表了文章 • 0 个评论 • 157 次浏览 • 2022-01-31 06:05 • 来自相关话题

  文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])
  2021-06-21转载地址
  ◆◆10
  拥护萌 2013/01/30 用户互动14,482 次浏览
  
  本文内容
  [隐藏]
  常萌最近一直在思考WordPress大学的设计,特别是如何做好注册用户体验。考虑添加一个文章采集功能,让大家可以采集自己喜欢的文章,然后在页面上生成一个列表,在侧边栏显示最近采集的文章,这样,你以后可以轻松找到你需要的文章。于是我找到了 WP Favorite Posts,一个 WordPress文章 采集插件,试用了一下,感觉还不错。
  WP采集帖子简介
  WP Favorite Posts是一款不错的WordPress文章采集插件,可以在文章页面添加采集按钮,用户可以点击采集自己的文章,并可以将自己展示在一个特殊页面采集文章,还支持“最近采集文章(每个人都看到自己的)”和“全站最多采集文章”两个小工具。
  最值得一提的 WP Favorite Posts 通过浏览器 cookie 和数据库存储用户的采集数据,也就是说游客也可以采集 文章,当然游客的采集数据是通过 cookie 保存的,如果删除浏览器的cookie,采集数据会丢失,所以建议采集后注册用户,可以保存在数据库中,不会丢失。
  WP Favorite Posts 安装设置
  1.在后台插件安装页面搜索WP采集贴在线安装,或下载WP采集贴。
  2.启用后,在设置-采集帖子中,可以设置相关设置(如果不懂英文,就用翻译工具翻译)
  
  可设置各种提示
  
  设置好后就可以使用插件了。
  如何使用 WP 采集帖子
  1.如何显示“采集链接”
  您可以选择在第一张图片的界面中自动插入文章页眉或页脚,或者在single.php或page.php的主题文件中使用如下代码自定义位置:
  1
  如果您只想在某些文章 中显示采集链接,则可以在编辑文章 时将以下短代码添加到文章:
  1
  [wpfp-link]
  2.小部件调用。您可以在外观中看到两个可用的小部件 - 小部件,您可以自己设置它们。
  3.添加采集列表页面。这个页面是用来显示所有用户采集的页面文章。可以在页面中新建一个页面,然后在内容中加入如下调用代码,显示用户的采集列表(每个用户只能看到自己的采集列表)
  1
  [wp-favorite-posts]
  
  WP 最喜欢的帖子高级提示(备用)
  以下是我在论坛上看到的一些高级功能,但还没有测试过。记录它们以备将来使用。
  1.调用文章的采集夹
  最简单的方法是循环使用下面的代码,直接调用:
  1
  如果上述方法不起作用,可以考虑以下方法:
  在主题的functions.php中添加以下代码
  1
2
3
4
5
6
7
8
9
10
11
12
13
  function wpfp_get_current_count() {
global $wpdb;
$current_post = get_the_ID();
$query = "SELECT post_id, meta_value, post_status FROM $wpdb->postmeta";
$query .= " LEFT JOIN $wpdb->posts ON post_id=$wpdb->posts.ID";
$query .= " WHERE post_status='publish' AND meta_key='wpfp_favorites' AND post_id = '".$current_post."'";
$results = $wpdb->get_results($query);
if ($results) {
foreach ($results as $o):
echo $o->meta_value;
endforeach;
}else {echo( '0' );}
}
  使用下面的代码调用
  1
  2.另一种调用采集夹列表的方法
  如果想直接在主题文件中修改显示采集列表,可以使用如下调用函数
  1
  3.获取一个用户的采集数量
  该插件默认使用收录的 wpfp-page-template.php 文件来显示采集夹列表。如果想在列表上方显示采集的数量,可以参考以下代码:
  1
2
3
4
5
6
   if ($favorite_post_ids){
$user_favorite_count = count($favorite_post_ids);
echo '<p>您已收藏了 '.$user_favorite_count.' 篇文章';
}else{
echo '您目前还没有收藏任何文章!';
}</p>
  4.删除文章后统计不准确
  网站删除了一些文章,如果用户之前采集过这些文章,他们的采集数据中仍然收录这些文章的ID,导致采集的统计不准确。
  
  找到插件的wpfp-page-template.php文件,添加如下代码:
  1
2
3
4
5
6
7
8
9
10
   /*remove deleted posts cmhello*/
foreach ($favorite_post_ids as $id) {
if ( FALSE === get_post_status( $id ) ) {
$favorite_post_ids = array_diff($favorite_post_ids, array($id));
$favorite_post_ids = array_values($favorite_post_ids);
wpfp_update_user_meta($favorite_post_ids);
}
}
$favorite_post_ids = wpfp_get_user_meta();
/*//remove deleted posts cmhello*/
  
  分类:
  技术要点:
  相关文章: 查看全部

  文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])
  2021-06-21转载地址
  ◆◆10
  拥护萌 2013/01/30 用户互动14,482 次浏览
  
  本文内容
  [隐藏]
  常萌最近一直在思考WordPress大学的设计,特别是如何做好注册用户体验。考虑添加一个文章采集功能,让大家可以采集自己喜欢的文章,然后在页面上生成一个列表,在侧边栏显示最近采集的文章,这样,你以后可以轻松找到你需要的文章。于是我找到了 WP Favorite Posts,一个 WordPress文章 采集插件,试用了一下,感觉还不错。
  WP采集帖子简介
  WP Favorite Posts是一款不错的WordPress文章采集插件,可以在文章页面添加采集按钮,用户可以点击采集自己的文章,并可以将自己展示在一个特殊页面采集文章,还支持“最近采集文章(每个人都看到自己的)”和“全站最多采集文章”两个小工具。
  最值得一提的 WP Favorite Posts 通过浏览器 cookie 和数据库存储用户的采集数据,也就是说游客也可以采集 文章,当然游客的采集数据是通过 cookie 保存的,如果删除浏览器的cookie,采集数据会丢失,所以建议采集后注册用户,可以保存在数据库中,不会丢失。
  WP Favorite Posts 安装设置
  1.在后台插件安装页面搜索WP采集贴在线安装,或下载WP采集贴。
  2.启用后,在设置-采集帖子中,可以设置相关设置(如果不懂英文,就用翻译工具翻译)
  
  可设置各种提示
  
  设置好后就可以使用插件了。
  如何使用 WP 采集帖子
  1.如何显示“采集链接”
  您可以选择在第一张图片的界面中自动插入文章页眉或页脚,或者在single.php或page.php的主题文件中使用如下代码自定义位置:
  1
  如果您只想在某些文章 中显示采集链接,则可以在编辑文章 时将以下短代码添加到文章:
  1
  [wpfp-link]
  2.小部件调用。您可以在外观中看到两个可用的小部件 - 小部件,您可以自己设置它们。
  3.添加采集列表页面。这个页面是用来显示所有用户采集的页面文章。可以在页面中新建一个页面,然后在内容中加入如下调用代码,显示用户的采集列表(每个用户只能看到自己的采集列表)
  1
  [wp-favorite-posts]
  
  WP 最喜欢的帖子高级提示(备用)
  以下是我在论坛上看到的一些高级功能,但还没有测试过。记录它们以备将来使用。
  1.调用文章的采集夹
  最简单的方法是循环使用下面的代码,直接调用:
  1
  如果上述方法不起作用,可以考虑以下方法:
  在主题的functions.php中添加以下代码
  1
2
3
4
5
6
7
8
9
10
11
12
13
  function wpfp_get_current_count() {
global $wpdb;
$current_post = get_the_ID();
$query = "SELECT post_id, meta_value, post_status FROM $wpdb->postmeta";
$query .= " LEFT JOIN $wpdb->posts ON post_id=$wpdb->posts.ID";
$query .= " WHERE post_status='publish' AND meta_key='wpfp_favorites' AND post_id = '".$current_post."'";
$results = $wpdb->get_results($query);
if ($results) {
foreach ($results as $o):
echo $o->meta_value;
endforeach;
}else {echo( '0' );}
}
  使用下面的代码调用
  1
  2.另一种调用采集夹列表的方法
  如果想直接在主题文件中修改显示采集列表,可以使用如下调用函数
  1
  3.获取一个用户的采集数量
  该插件默认使用收录的 wpfp-page-template.php 文件来显示采集夹列表。如果想在列表上方显示采集的数量,可以参考以下代码:
  1
2
3
4
5
6
   if ($favorite_post_ids){
$user_favorite_count = count($favorite_post_ids);
echo '<p>您已收藏了 '.$user_favorite_count.' 篇文章';
}else{
echo '您目前还没有收藏任何文章!';
}</p>
  4.删除文章后统计不准确
  网站删除了一些文章,如果用户之前采集过这些文章,他们的采集数据中仍然收录这些文章的ID,导致采集的统计不准确。
  
  找到插件的wpfp-page-template.php文件,添加如下代码:
  1
2
3
4
5
6
7
8
9
10
   /*remove deleted posts cmhello*/
foreach ($favorite_post_ids as $id) {
if ( FALSE === get_post_status( $id ) ) {
$favorite_post_ids = array_diff($favorite_post_ids, array($id));
$favorite_post_ids = array_values($favorite_post_ids);
wpfp_update_user_meta($favorite_post_ids);
}
}
$favorite_post_ids = wpfp_get_user_meta();
/*//remove deleted posts cmhello*/
  
  分类:
  技术要点:
  相关文章:

文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)

采集交流优采云 发表了文章 • 0 个评论 • 99 次浏览 • 2022-01-28 15:22 • 来自相关话题

  文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)
  本文介绍如何在应用程序中使用客户端javascript脚本来提高程序的执行效率,实现更多的功能。
  一、ASP.Net 和 Javascript
  .Net是微软下一代战略的核心,ASP.Net是.Net战略在Web开发中的具体实现。它继承了 ASP 的简单易用,克服了 ASP 程序结构差,难以阅读和理解的缺点。特别是服务器端控件和事件驱动模式的引入,使得Web应用程序的开发更接近于过去桌面程序的开发。
  在介绍 ASP.Net 的各种文章 和书籍中,重点是服务器控件和 .Net Framework SDK,因为这是 ASP.Net 最新和最具革命性的改进;相反,过去在Web开发中占据重要地位的客户端脚本Javascript(包括VBScript)却很少被提及。似乎使用服务器端程序,不再需要客户端脚本。但是,服务器端程序需要浏览器和 Web 服务器之间的交互。对于ASP.Net来说,就是一个页​​面提交,需要来回发送大量的数据,输入验证或者删除确认等很多任务都是完全可以的。用 Javascript 实现。因此,在 ASP.Net 中如何使用 Javascript 还是有必要探索的。
  二、Javascript应用实例
  1.在页面上的一个服务器控件中添加一个Javascript事件
  最后生成的服务器控件还是普通的HTML,比如生成输入文本。表单中的每个 HTML 控件都有自己的 Javascript 事件,例如 Textbox 有 onchange 事件,Button 有 onclick 事件,Listbox 有 onchange 事件等。要将客户端事件添加到服务器控件,请使用 Attributes 属性。Attributes 属性是所有服务器控件都有的属性,用于在最终生成的 HTML 中添加一些自定义标签。假设Web Form上有一个保存按钮btnSave,你想在用户点击这个按钮时提示用户是否真的要保存(例如,一旦保存就不能恢复等),你应该添加Page_Load 事件的以下代码:
  如果不是 page.isPostBack() 那么
  btnSave.Attributes.Add("onclick","Javascript:return Confirm('Are you sure to save?');")
  万一
  注意,return 是不可避免的,否则即使用户点击取消,数据仍然会被保存。
  2.为Datagrid中的每一行添加Javascript事件
  假设Datagrid的每一行都有一个删除按钮,我们想在用户点击这个按钮时提示用户是否真的要删除这条记录,以防用户点击了错误的行,或者只是不小心点击了删除按钮.
  不管删除按钮的名字是什么,都不能像上例那样直接引用,因为每一行都有这样一个按钮,它是Datagrid中的一个子控件。在这种情况下,您需要使用 Datagrid 的 OnItemDataBound 事件。OnItemDataBound 事件发生在Datagrid 的每一行数据绑定到Datagrid 之后(即,一行触发一次)。首先在Datagrid的声明中加入如下代码:
  …这里的列定义
  这里说明当 OnItemDataBound 事件发生时调用 ItemDataBound 方法,并在代码隐藏文件中添加该方法的定义:
  Sub ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
  如果 e.Item.ItemType ListItemType.Header 和 e.Item.ItemType ListItemType.Footer 那么
  Dim oDeleteButton As LinkBut​​ton = e.Item.Cells(5).Controls(0)
  oDeleteButton.Attributes("onclick") = "javascript:return Confirm ('Are you sure you want to delete" &amp; DataBinder.Eval(e.Item.DataItem, "m_sName") &amp; "?')"
  万一
  结束子
  由于Datagrid的页眉行和页脚行也会触发这个事件,首先确定触发这个事件的行不是页眉行和页脚行。这里假设Delete按钮位于Datagrid的第6列(第一列是0),Datagrid的Datasource收录一个名为“m_sName”的列
  3、编辑状态下Datagrid中控件的引用
  Datagrid 的内置编辑功能使其成为记录字段较少时的一种编辑方法。用户无需进入单独的页面编辑记录,直接点击编辑按钮即可进入当前行的编辑模式。另一方面,有一些Javascript程序需要引用控件的名称。例如,很多程序在要求用户输入日期时提供了日期控件来保证日期格式的有效性。当用户单击控件图标时,将弹出一个新窗口供用户选择日期。此时需要将显示日期的文本框的 ID 提供给新窗口,以便在用户选择日期时将值回填到文本框中。
  如果是普通的服务器文本框控件,其ID与生成的HTML输入框的ID相同;但是在Datagrid的编辑状态下,两个ID不一样(原因同上例),需要使用控件的ClientID属性。
  Protected Sub ItemEdit(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
  将 sDateCtrl 调暗为字符串
  sDateCtrl = grd1. 项目(e.Item.ItemIndex)。单元格(2). FindControl("txtDate") . ClientID
  结束子
  这里假设 ItemEdit 方法是 Dategrid 的 OnItemEdit 事件处理程序,并且 Datagrid 的第三列收录一个名为 txtDate 的服务器文本框控件。
  4.参考ASP.Net自动生成的Javascript程序
  所谓“服务器端控件”是针对开发者的,在生成的HTML源程序中没有服务器端和客户端的区别,都是标准的HTML、DHTML和Javascript。它响应用户输入是因为每个控件的事件处理程序最终都会生成一个脚本,该脚本重新提交页面以使 Web 服务器有机会再次响应和处理。通常我们不必知道这个脚本是什么或者直接调用这个脚本,但是在某些情况下,适当地调用这个脚本可以简化很多工作。请看以下两个例子。
  ● 单击数据网格中的任意位置以选择一行
  Datagrid 提供了一个内置的选择按钮,当单击该按钮时选择当前行(您可以设置 SelectedItemStyle 属性以使当前行具有不同的外观)。然而,用户可能更习惯于点击任何位置来选择一行。完全自己实现这个功能是相当麻烦的。一个好主意是添加一个选择按钮,但将列隐藏,并在单击任何行时调用该按钮生成的 Javascript。
  Sub Item_Bound(ByVal sender As Object, ByVal e As DataGridItemEventArgs )
  将 itemType 调暗为 ListItemType
  itemType = CType(e.Item.ItemType, ListItemType)
  If (itemType ListItemType.Header) 和 _
  (itemType ListItemType.Footer) 和 _
  (itemType ListItemType.Separator) 然后
  Dim oSelect As LinkBut​​ton = CType(e.Item.Cells(5).Controls(0), LinkBut​​ton)
  e.Item.Attributes("onclick") = Page.GetPostBackClientHyperlink(oSelect, "")
  结束子
  这假设选择按钮在第 6 列。e.Item 代表一行,从生成的 HTML 的角度来看,每个都添加了一个 onclick 事件。Page.GetPostBackClientHyperLink方法返回页面中LinkBut​​ton控件生成的客户端脚本,其中第一个参数为Linkbutton控件,第二个参数为传递给该控件的参数,一般为空。如果不是LinkBut​​ton控件,还有一个类似的函数GetPostBackClientEvent,读者可以参考MSDN。
  ● 服务器生成的脚本与手动添加的脚本冲突
  服务器控件的服务器事件一般对应客户端控件的相应事件。例如,Dropdownlist 的 SelectedIndexChanged 事件对应 HTML 的 onchange 事件。如果要手动添加onchange事件,客户端会产生两个onchange,浏览器会忽略一个。比如,每当Dropdownlist中的某个选项发生变化时,用户都想保​​存到数据库中(虽然不是很常见,但是有这样的需求),但同时也想提醒用户是否真的有必要保存。显然,保存的代码应该放在SelectedIndexChanged事件中,提醒工作应该手动加上onchange事件。结果是只能执行两个 onchanges 中的一个。
  Page_Load 方法如下:
  将 sCmd 调暗为字符串
  sCmd=Page.GetPostBackClientHyperlink(btnUpdate, "")
  如果不是 page.isPostback 那么
  下拉列表1.Attributes.add("onchange","ConfirmUpdate(""" &amp; sCmd &amp; """)")
  万一
  ConfirmUpdate函数如下
  Javascript eval 函数在这里用于调用收录在字符串中的命令。需要注意的是,收录命令的字符串不能用单引号括起来,因为自动生成的脚本中收录单引号,所以这里用两个双引号来表示字符串本身的双引号。
  三、结束语
  以上简要讨论了在ASP.Net中插入Javascript的几种情况。在服务器程序中合理插入客户端Javascript脚本,可以提高程序的运行效率,提供更友好的用户界面。
  参考示例: 查看全部

  文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)
  本文介绍如何在应用程序中使用客户端javascript脚本来提高程序的执行效率,实现更多的功能。
  一、ASP.Net 和 Javascript
  .Net是微软下一代战略的核心,ASP.Net是.Net战略在Web开发中的具体实现。它继承了 ASP 的简单易用,克服了 ASP 程序结构差,难以阅读和理解的缺点。特别是服务器端控件和事件驱动模式的引入,使得Web应用程序的开发更接近于过去桌面程序的开发。
  在介绍 ASP.Net 的各种文章 和书籍中,重点是服务器控件和 .Net Framework SDK,因为这是 ASP.Net 最新和最具革命性的改进;相反,过去在Web开发中占据重要地位的客户端脚本Javascript(包括VBScript)却很少被提及。似乎使用服务器端程序,不再需要客户端脚本。但是,服务器端程序需要浏览器和 Web 服务器之间的交互。对于ASP.Net来说,就是一个页​​面提交,需要来回发送大量的数据,输入验证或者删除确认等很多任务都是完全可以的。用 Javascript 实现。因此,在 ASP.Net 中如何使用 Javascript 还是有必要探索的。
  二、Javascript应用实例
  1.在页面上的一个服务器控件中添加一个Javascript事件
  最后生成的服务器控件还是普通的HTML,比如生成输入文本。表单中的每个 HTML 控件都有自己的 Javascript 事件,例如 Textbox 有 onchange 事件,Button 有 onclick 事件,Listbox 有 onchange 事件等。要将客户端事件添加到服务器控件,请使用 Attributes 属性。Attributes 属性是所有服务器控件都有的属性,用于在最终生成的 HTML 中添加一些自定义标签。假设Web Form上有一个保存按钮btnSave,你想在用户点击这个按钮时提示用户是否真的要保存(例如,一旦保存就不能恢复等),你应该添加Page_Load 事件的以下代码:
  如果不是 page.isPostBack() 那么
  btnSave.Attributes.Add("onclick","Javascript:return Confirm('Are you sure to save?');")
  万一
  注意,return 是不可避免的,否则即使用户点击取消,数据仍然会被保存。
  2.为Datagrid中的每一行添加Javascript事件
  假设Datagrid的每一行都有一个删除按钮,我们想在用户点击这个按钮时提示用户是否真的要删除这条记录,以防用户点击了错误的行,或者只是不小心点击了删除按钮.
  不管删除按钮的名字是什么,都不能像上例那样直接引用,因为每一行都有这样一个按钮,它是Datagrid中的一个子控件。在这种情况下,您需要使用 Datagrid 的 OnItemDataBound 事件。OnItemDataBound 事件发生在Datagrid 的每一行数据绑定到Datagrid 之后(即,一行触发一次)。首先在Datagrid的声明中加入如下代码:
  …这里的列定义
  这里说明当 OnItemDataBound 事件发生时调用 ItemDataBound 方法,并在代码隐藏文件中添加该方法的定义:
  Sub ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
  如果 e.Item.ItemType ListItemType.Header 和 e.Item.ItemType ListItemType.Footer 那么
  Dim oDeleteButton As LinkBut​​ton = e.Item.Cells(5).Controls(0)
  oDeleteButton.Attributes("onclick") = "javascript:return Confirm ('Are you sure you want to delete" &amp; DataBinder.Eval(e.Item.DataItem, "m_sName") &amp; "?')"
  万一
  结束子
  由于Datagrid的页眉行和页脚行也会触发这个事件,首先确定触发这个事件的行不是页眉行和页脚行。这里假设Delete按钮位于Datagrid的第6列(第一列是0),Datagrid的Datasource收录一个名为“m_sName”的列
  3、编辑状态下Datagrid中控件的引用
  Datagrid 的内置编辑功能使其成为记录字段较少时的一种编辑方法。用户无需进入单独的页面编辑记录,直接点击编辑按钮即可进入当前行的编辑模式。另一方面,有一些Javascript程序需要引用控件的名称。例如,很多程序在要求用户输入日期时提供了日期控件来保证日期格式的有效性。当用户单击控件图标时,将弹出一个新窗口供用户选择日期。此时需要将显示日期的文本框的 ID 提供给新窗口,以便在用户选择日期时将值回填到文本框中。
  如果是普通的服务器文本框控件,其ID与生成的HTML输入框的ID相同;但是在Datagrid的编辑状态下,两个ID不一样(原因同上例),需要使用控件的ClientID属性。
  Protected Sub ItemEdit(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
  将 sDateCtrl 调暗为字符串
  sDateCtrl = grd1. 项目(e.Item.ItemIndex)。单元格(2). FindControl("txtDate") . ClientID
  结束子
  这里假设 ItemEdit 方法是 Dategrid 的 OnItemEdit 事件处理程序,并且 Datagrid 的第三列收录一个名为 txtDate 的服务器文本框控件。
  4.参考ASP.Net自动生成的Javascript程序
  所谓“服务器端控件”是针对开发者的,在生成的HTML源程序中没有服务器端和客户端的区别,都是标准的HTML、DHTML和Javascript。它响应用户输入是因为每个控件的事件处理程序最终都会生成一个脚本,该脚本重新提交页面以使 Web 服务器有机会再次响应和处理。通常我们不必知道这个脚本是什么或者直接调用这个脚本,但是在某些情况下,适当地调用这个脚本可以简化很多工作。请看以下两个例子。
  ● 单击数据网格中的任意位置以选择一行
  Datagrid 提供了一个内置的选择按钮,当单击该按钮时选择当前行(您可以设置 SelectedItemStyle 属性以使当前行具有不同的外观)。然而,用户可能更习惯于点击任何位置来选择一行。完全自己实现这个功能是相当麻烦的。一个好主意是添加一个选择按钮,但将列隐藏,并在单击任何行时调用该按钮生成的 Javascript。
  Sub Item_Bound(ByVal sender As Object, ByVal e As DataGridItemEventArgs )
  将 itemType 调暗为 ListItemType
  itemType = CType(e.Item.ItemType, ListItemType)
  If (itemType ListItemType.Header) 和 _
  (itemType ListItemType.Footer) 和 _
  (itemType ListItemType.Separator) 然后
  Dim oSelect As LinkBut​​ton = CType(e.Item.Cells(5).Controls(0), LinkBut​​ton)
  e.Item.Attributes("onclick") = Page.GetPostBackClientHyperlink(oSelect, "")
  结束子
  这假设选择按钮在第 6 列。e.Item 代表一行,从生成的 HTML 的角度来看,每个都添加了一个 onclick 事件。Page.GetPostBackClientHyperLink方法返回页面中LinkBut​​ton控件生成的客户端脚本,其中第一个参数为Linkbutton控件,第二个参数为传递给该控件的参数,一般为空。如果不是LinkBut​​ton控件,还有一个类似的函数GetPostBackClientEvent,读者可以参考MSDN。
  ● 服务器生成的脚本与手动添加的脚本冲突
  服务器控件的服务器事件一般对应客户端控件的相应事件。例如,Dropdownlist 的 SelectedIndexChanged 事件对应 HTML 的 onchange 事件。如果要手动添加onchange事件,客户端会产生两个onchange,浏览器会忽略一个。比如,每当Dropdownlist中的某个选项发生变化时,用户都想保​​存到数据库中(虽然不是很常见,但是有这样的需求),但同时也想提醒用户是否真的有必要保存。显然,保存的代码应该放在SelectedIndexChanged事件中,提醒工作应该手动加上onchange事件。结果是只能执行两个 onchanges 中的一个。
  Page_Load 方法如下:
  将 sCmd 调暗为字符串
  sCmd=Page.GetPostBackClientHyperlink(btnUpdate, "")
  如果不是 page.isPostback 那么
  下拉列表1.Attributes.add("onchange","ConfirmUpdate(""" &amp; sCmd &amp; """)")
  万一
  ConfirmUpdate函数如下
  Javascript eval 函数在这里用于调用收录在字符串中的命令。需要注意的是,收录命令的字符串不能用单引号括起来,因为自动生成的脚本中收录单引号,所以这里用两个双引号来表示字符串本身的双引号。
  三、结束语
  以上简要讨论了在ASP.Net中插入Javascript的几种情况。在服务器程序中合理插入客户端Javascript脚本,可以提高程序的运行效率,提供更友好的用户界面。
  参考示例:

文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))

采集交流优采云 发表了文章 • 0 个评论 • 96 次浏览 • 2022-01-25 09:01 • 来自相关话题

  文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))
  智能标签调用多表多模型调用文章
  1、调用多模型的最新文章
  [e:loop={'select * from (
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_movie where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_news where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_photo where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_flash where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_article where newstime) a order by newstime desc limit 10',10,24,1}]
  [/e:循环]
  Empire cms 从多个表中调用最新信息。演示代码为默认数据表下全站最新10张图片信息。您可以根据需要附加条件,实现全站点击、全站头条、全站推荐等。
  -------------------------------------------------- -------------------------------------------
  2、调用多模型的最新文章
  [e:循环={'
  select title,titleurl,titlepic from [!db.pre!]ecms_photo Union All
  select title,titleurl,titlepic from [!db.pre!]ecms_download Union All
  从 [!db.pre!]ecms_news',0,24,0}] 中选择标题、标题网址、标题图片
  [/e:循环]
  注:以上调用为三种模型中的文章(图片模型:photo,下载模型:download,新闻模型:news)
  三个模型通过“Union All”连接调用
  如果使用指定列: where classid in(46,47,51),
  如果调用建议附加:并且isgood=1,
  如果附加了指定的调用次数:limit 10 查看全部

  文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))
  智能标签调用多表多模型调用文章
  1、调用多模型的最新文章
  [e:loop={'select * from (
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_movie where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_news where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_photo where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_flash where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_article where newstime) a order by newstime desc limit 10',10,24,1}]
  [/e:循环]
  Empire cms 从多个表中调用最新信息。演示代码为默认数据表下全站最新10张图片信息。您可以根据需要附加条件,实现全站点击、全站头条、全站推荐等。
  -------------------------------------------------- -------------------------------------------
  2、调用多模型的最新文章
  [e:循环={'
  select title,titleurl,titlepic from [!db.pre!]ecms_photo Union All
  select title,titleurl,titlepic from [!db.pre!]ecms_download Union All
  从 [!db.pre!]ecms_news',0,24,0}] 中选择标题、标题网址、标题图片
  [/e:循环]
  注:以上调用为三种模型中的文章(图片模型:photo,下载模型:download,新闻模型:news)
  三个模型通过“Union All”连接调用
  如果使用指定列: where classid in(46,47,51),
  如果调用建议附加:并且isgood=1,
  如果附加了指定的调用次数:limit 10

文章采集调用(文章页面内容建设的不良现状及解决办法)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-25 08:16 • 来自相关话题

  文章采集调用(文章页面内容建设的不良现状及解决办法)
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,也伤害了 网站 自己。文章 页面也可以使用随机调用,让每篇文章有文章 展示和曝光的机会
  
  图 25545-1:
  如何做好文章内容页面的SEO推广,面向营销的网站建设完成后也需要做SEO推广。@网站列表,网站详细页面也优化。面向营销的网站内容页面,文章页面也需要优化。
  内容页面建设现状不佳:在文章页面内容的创建中,很多站长经常使用的两种方法是采集和伪原创,既是投机取巧又是省时的行为. 但长此以往,无异于饮毒解渴网站。
  我们创建网站并吸引客户浏览。我们的宗旨是为客户提供能够创造价值的内容。如果存在大量的采集内容,并且所有网站都相同,如果是伪原创特别是软件实现&lt; @伪原创,由于同义词替换、格式打乱等行为,呈现的内容会产生误导,更何况不值得浏览。
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,还伤害了 网站 自己。
  内容页面是SEO推广的好方法之一。因为可以添加很多锚文本,所以被很多站长广泛使用,也是做长尾关键词的好方法。这里要提醒站长们,锚链的&lt;关键词要自然广泛,并不是所有的锚链都是一样的,容易导致过度优化。建议使用不同的关键词,指向不同的相关页面,做好长尾词的相关优化。
  1)很多网站 流量来自文章 页面。确保在标题、描述、关键词 中收录 关键词 或用户正在搜索的短语。
  SEO推广关键词密度是指搜索关键词出现的频率。举个例子:一篇文章200字的文章,你的关键词中出现的字数除以总字数的20,也就是说关键词@的密度&gt; 为 10%。在不影响用户体验的前提下,关键词密度尽量不高。关键词 的密度必须合理。文章页面关键词推荐浓度2-8%更自然。
  阅读文章的用户一般需要浏览几篇文章文章才能找到自己想要的详细答案。所以推荐相关的文章可以降低网页的跳出率。
  我们还要适当引导顾客,多做一些符合大众口味的热点文章。热点文章一般是查看相关信息后对其他新闻感兴趣的用户,这也是降低网页跳出率的一种方式。一个方法。
  5)文章页面也可以使用随机调用,让每个文章都有机会展示和曝光,不一定是最新的文章。
  SEO 随机推广一个名为 网站 的页面,并随机显示 文章。搜索引擎蜘蛛每次在爬网站的过程中都能发现不同的东西,可以知道这个页面并没有什么变化,会定期更新。建议固定页面更新频率。这将吸引更多的蜘蛛来抢我们的 网站。提供企业网站的收录量,从而为企业带来更多的免费流量。 查看全部

  文章采集调用(文章页面内容建设的不良现状及解决办法)
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,也伤害了 网站 自己。文章 页面也可以使用随机调用,让每篇文章有文章 展示和曝光的机会
  
  图 25545-1:
  如何做好文章内容页面的SEO推广,面向营销的网站建设完成后也需要做SEO推广。@网站列表,网站详细页面也优化。面向营销的网站内容页面,文章页面也需要优化。
  内容页面建设现状不佳:在文章页面内容的创建中,很多站长经常使用的两种方法是采集和伪原创,既是投机取巧又是省时的行为. 但长此以往,无异于饮毒解渴网站。
  我们创建网站并吸引客户浏览。我们的宗旨是为客户提供能够创造价值的内容。如果存在大量的采集内容,并且所有网站都相同,如果是伪原创特别是软件实现&lt; @伪原创,由于同义词替换、格式打乱等行为,呈现的内容会产生误导,更何况不值得浏览。
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,还伤害了 网站 自己。
  内容页面是SEO推广的好方法之一。因为可以添加很多锚文本,所以被很多站长广泛使用,也是做长尾关键词的好方法。这里要提醒站长们,锚链的&lt;关键词要自然广泛,并不是所有的锚链都是一样的,容易导致过度优化。建议使用不同的关键词,指向不同的相关页面,做好长尾词的相关优化。
  1)很多网站 流量来自文章 页面。确保在标题、描述、关键词 中收录 关键词 或用户正在搜索的短语。
  SEO推广关键词密度是指搜索关键词出现的频率。举个例子:一篇文章200字的文章,你的关键词中出现的字数除以总字数的20,也就是说关键词@的密度&gt; 为 10%。在不影响用户体验的前提下,关键词密度尽量不高。关键词 的密度必须合理。文章页面关键词推荐浓度2-8%更自然。
  阅读文章的用户一般需要浏览几篇文章文章才能找到自己想要的详细答案。所以推荐相关的文章可以降低网页的跳出率。
  我们还要适当引导顾客,多做一些符合大众口味的热点文章。热点文章一般是查看相关信息后对其他新闻感兴趣的用户,这也是降低网页跳出率的一种方式。一个方法。
  5)文章页面也可以使用随机调用,让每个文章都有机会展示和曝光,不一定是最新的文章。
  SEO 随机推广一个名为 网站 的页面,并随机显示 文章。搜索引擎蜘蛛每次在爬网站的过程中都能发现不同的东西,可以知道这个页面并没有什么变化,会定期更新。建议固定页面更新频率。这将吸引更多的蜘蛛来抢我们的 网站。提供企业网站的收录量,从而为企业带来更多的免费流量。

文章采集调用(QT+openCV操做的这部分,其余还没时间看 )

采集交流优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2022-01-24 11:16 • 来自相关话题

  文章采集调用(QT+openCV操做的这部分,其余还没时间看
)
  今天写的QT+openCV实现了拍照拍照功能。应用
  我在互联网上采集了很多信息。 QT 没有用于操作相机的特殊类。这个必须自己写。网上也有很多关于openCV和V4l的介绍。因为我的项目要在window下开发,所以选择了openCV。因为之前没用过openCV,所以只看了openCVS摄像头的操作这部分,剩下的没来得及看。功能
  openCV:学习
  第一次下载来自 2.3.1。安装后发现没有lib库,所以选择了2.1
  的ui
  openCV中文学习pdf:这个
  现在,我们开始详细介绍如何在QT中直播采集相机数据。温泉
  打开QTcreator(我用的是QT中文版2.3).net
  创建一个新的小部件项目指针
  
  在界面上放两个标签,显示相机拍摄的数据和照片采集。或者
  
  编辑camaraget.h文件视频
  #ifndef CAMARAGET_H
#define CAMARAGET_H

#include
#include
#include // 设置采集数据的间隔时间

#include //包含opencv库头文件
#include

namespace Ui {
class camaraGet;
}

class camaraGet : public QWidget
{
Q_OBJECT

public:
explicit camaraGet(QWidget *parent = 0);
~camaraGet();

private slots:
void openCamara(); // 打开摄像头
void readFarme(); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照

private:
Ui::camaraGet *ui;
QTimer *timer;
QImage *imag;
CvCapture *cam;// 视频获取结构, 用来做为视频获取函数的一个参数
IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
};

#endif // CAMARAGET_H
  编辑 camaraget.cpp
  #include "camaraget.h"
#include "ui_camaraget.h"

camaraGet::camaraGet(QWidget *parent) :
QWidget(parent),
ui(new Ui::camaraGet)
{
ui->setupUi(this);

cam = NULL;
timer = new QTimer(this);
imag = new QImage(); // 初始化

/*信号和槽*/
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
}

/******************************
********* 打开摄像头 ***********
*******************************/
void camaraGet::openCamara()
{
cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频

timer->start(33); // 开始计时,超时则发出timeout()信号
}

/*********************************
********* 读取摄像头信息 ***********
**********************************/
void camaraGet::readFarme()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*************************
********* 拍照 ***********
**************************/
void camaraGet::takingPictures()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧

// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);

ui->label_2->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*******************************
***关闭摄像头,释放资源,必须释放***
********************************/
void camaraGet::closeCamara()
{
timer->stop(); // 中止读取数据。

cvReleaseCapture(&cam);//释放内存;
}

camaraGet::~camaraGet()
{
delete ui;
}
  好了,所有代码都OK了(当然项目建好的时候会生成main.cpp,不用改),但是现在点击运行,还是会报错,为什么由于尚未收录 openCV 库。
  在 *.pro 文件中添加:
  INCLUDEPATH+=C:\OpenCV2.1\include\opencv
   LIBS += C:\OpenCV2.1\lib\highgui210.lib \
   C:\OpenCV2.1\lib\cxcore210.lib \
   C:\OpenCV2.1\lib\cv210.lib
  OK,大功告成,运行后,在widget中点击打开摄像头,就可以看到自己了。运行后的效果:
  
  后来发现这个效果不是很好,于是改了:改后的运行效果也贴出来:
  我改了一句:
  QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
  改成了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();
   查看全部

  文章采集调用(QT+openCV操做的这部分,其余还没时间看
)
  今天写的QT+openCV实现了拍照拍照功能。应用
  我在互联网上采集了很多信息。 QT 没有用于操作相机的特殊类。这个必须自己写。网上也有很多关于openCV和V4l的介绍。因为我的项目要在window下开发,所以选择了openCV。因为之前没用过openCV,所以只看了openCVS摄像头的操作这部分,剩下的没来得及看。功能
  openCV:学习
  第一次下载来自 2.3.1。安装后发现没有lib库,所以选择了2.1
  的ui
  openCV中文学习pdf:这个
  现在,我们开始详细介绍如何在QT中直播采集相机数据。温泉
  打开QTcreator(我用的是QT中文版2.3).net
  创建一个新的小部件项目指针
  
  在界面上放两个标签,显示相机拍摄的数据和照片采集。或者
  
  编辑camaraget.h文件视频
  #ifndef CAMARAGET_H
#define CAMARAGET_H

#include
#include
#include // 设置采集数据的间隔时间

#include //包含opencv库头文件
#include

namespace Ui {
class camaraGet;
}

class camaraGet : public QWidget
{
Q_OBJECT

public:
explicit camaraGet(QWidget *parent = 0);
~camaraGet();

private slots:
void openCamara(); // 打开摄像头
void readFarme(); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照

private:
Ui::camaraGet *ui;
QTimer *timer;
QImage *imag;
CvCapture *cam;// 视频获取结构, 用来做为视频获取函数的一个参数
IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
};

#endif // CAMARAGET_H
  编辑 camaraget.cpp
  #include "camaraget.h"
#include "ui_camaraget.h"

camaraGet::camaraGet(QWidget *parent) :
QWidget(parent),
ui(new Ui::camaraGet)
{
ui->setupUi(this);

cam = NULL;
timer = new QTimer(this);
imag = new QImage(); // 初始化

/*信号和槽*/
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
}

/******************************
********* 打开摄像头 ***********
*******************************/
void camaraGet::openCamara()
{
cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频

timer->start(33); // 开始计时,超时则发出timeout()信号
}

/*********************************
********* 读取摄像头信息 ***********
**********************************/
void camaraGet::readFarme()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*************************
********* 拍照 ***********
**************************/
void camaraGet::takingPictures()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧

// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);

ui->label_2->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*******************************
***关闭摄像头,释放资源,必须释放***
********************************/
void camaraGet::closeCamara()
{
timer->stop(); // 中止读取数据。

cvReleaseCapture(&cam);//释放内存;
}

camaraGet::~camaraGet()
{
delete ui;
}
  好了,所有代码都OK了(当然项目建好的时候会生成main.cpp,不用改),但是现在点击运行,还是会报错,为什么由于尚未收录 openCV 库。
  在 *.pro 文件中添加:
  INCLUDEPATH+=C:\OpenCV2.1\include\opencv
   LIBS += C:\OpenCV2.1\lib\highgui210.lib \
   C:\OpenCV2.1\lib\cxcore210.lib \
   C:\OpenCV2.1\lib\cv210.lib
  OK,大功告成,运行后,在widget中点击打开摄像头,就可以看到自己了。运行后的效果:
  
  后来发现这个效果不是很好,于是改了:改后的运行效果也贴出来:
  我改了一句:
  QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
  改成了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();
  

文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-23 02:19 • 来自相关话题

  文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)
  dedecms非常灵活,可以根据关键词、文章标题调用文章,提高内容之间的相关性,增加页面权重。要实现这个功能,主要使用likearticle标签。此标签只能在内容页面上使用。默认情况下无法调用自定义附加字段,但经常使用调用附加表字段的功能。修改方法如下:
  打开 /include/taglib/likearticle.lib.php 并找到
  
$row['templeturl'] = $GLOBALS['cfg_templeturl'];
  在下面添加代码
  
$addfile = $refObj->ChannelUnit->ChannelInfos["listfields"]; //获取文章模型的自定义字段列表
if($addfile){
$addfiles = explode(",",$addfile); //拆分成数组
$len = count($addfiles);
for($j=0;$jFields[''.$fname.''];
}
}
  调用自定义附加字段的其他修改方法
  
{dede:likeartlist row='10'}
]
<p>
[field:id runphp='yes']
$aid = @me;
$row = $GLOBALS['dsql']->GetOne("Select 字段名 From `dede_addon11` where aid='$aid' "); //根据实际需要修改附加表
@me = cn_substr(strip_tags("{$row['字段名']}"),600);
[/field:id]


{/dede:likearticle}
</p>
  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。 查看全部

  文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)
  dedecms非常灵活,可以根据关键词、文章标题调用文章,提高内容之间的相关性,增加页面权重。要实现这个功能,主要使用likearticle标签。此标签只能在内容页面上使用。默认情况下无法调用自定义附加字段,但经常使用调用附加表字段的功能。修改方法如下:
  打开 /include/taglib/likearticle.lib.php 并找到
  
$row['templeturl'] = $GLOBALS['cfg_templeturl'];
  在下面添加代码
  
$addfile = $refObj->ChannelUnit->ChannelInfos["listfields"]; //获取文章模型的自定义字段列表
if($addfile){
$addfiles = explode(",",$addfile); //拆分成数组
$len = count($addfiles);
for($j=0;$jFields[''.$fname.''];
}
}
  调用自定义附加字段的其他修改方法
  
{dede:likeartlist row='10'}
]
<p>
[field:id runphp='yes']
$aid = @me;
$row = $GLOBALS['dsql']->GetOne("Select 字段名 From `dede_addon11` where aid='$aid' "); //根据实际需要修改附加表
@me = cn_substr(strip_tags("{$row['字段名']}"),600);
[/field:id]


{/dede:likearticle}
</p>
  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。

文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar )

采集交流优采云 发表了文章 • 0 个评论 • 135 次浏览 • 2022-01-22 18:03 • 来自相关话题

  文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar
)
  在开源活动LinuxCon + ContainerCon + CloudOpen China(简称LC3))上,阿里云CDN团队分享了开源系统和应用采集软件Tsar背景、设计思路和使用方法,模块开发和未来规划。
  其实是阿里巴巴在做系统或者应用监控的时候的一个思路。队友在实际使用过程中比较舒服,软件的扩展性、稳定性、易用性也比较好,所以目前全机都可以使用。Deployment作为基础的监控代理,提供稳定的数据支持,同时也是对外开源的。
  沙皇的背景
  对于在线SA/PE/R&amp;D,他在开发和部署软件的时候,需要注意软件的运行情况。他需要去上面看看整个服务器的CPU/内存/网络/IO等基本指标是否OK。找出这些指标的一些软件瓶颈和针对性的优化。其实现在市面上有很多类似的软件,都有一定的特殊性,可能只是采集的某一个,每个软件采集都有不同的指标,这些的用法指标时间不一致。所以对用户的要求非常高,需要知道如何使用所有的监控软件,对于排查在线问题非常不方便。这也是我们最初的痛点。我们发现我们拥有所有的数据,但是如何链接和使用它很不方便。所以,我们想出了沙皇的想法。
  
  下图是现在网上很多命令的使用。整个Linux站的每一层都有一些对应的命令。运维等用户的学习成本非常高,不利于我们统一监控。
  
  需求和解决方案
  因此,我们最初的要求是有一个易于使用的采集软件,具有完整的基础数据,最好是应用程序数据。因为刚才列出的指标都是通用指标,但是我们有应用软件,所以我们想知道应用软件的一些数据,比如QPS和响应时间。目前的开源软件无法支持,业务需要编写采集工具进行数据采集和监控。
  另外,我们希望在数据之间做一些数据关联。比如当前CPU高,是否会带来其他一些数据指标的波动?需要对这些指标进行比较才能确定问题。
  同时,必须对数据进行过滤,离线实时查看,本地长期存储,远程发送,方便中心进行数据分析和挖掘。
  有了这些需求,我们的解决方案就是模仿Sar,它本身就是一个系统活动报告,实现了系统指标的采集,我们在它的基础上做了一些扩展。除了系统级的数据采集,Tsar还可以进行应用级的采集,模块化,支持扩展。例如,采集 现在有十个指标。如果还有其他应用指标和业务数据要到采集,可以很方便的在Tsar中写一个模块到采集。它还支持简单的报警和远程发送。
  设计和使用
  沙皇的原则很简单。它主要利用动态库的特性。我们每个采集模块都会实现一些功能,比如采集函数,分析处理函数,注册时提供的模块。基础字段,比如模块名,模块收录的字段,字段从哪里来采集,采集之后怎么处理和输出,这些函数都注册在Tsar框架中,每个循环到采集 调用这些指令的函数时,就可以完成采集的处理和整个数据的输出。
  整个模块的注册和执行流程如下:
  
  下图是Tsar的功能大图,底部是系统计数器和软件界面。每个具体的模块都是基于采集,参考Sar实现了很多系统指标。此外,还为应用软件提供了LVS、Nginx等对比。通用应用软件模块。
  
  在上述采集的过程中,会对模块进行一些过滤处理,并执行各个模块的采集函数来获取数据。根据格式化,框架将数据格式化并保存到/var/log/tsar.data。我们采集把所有的原创数据,以文件的形式存储起来。与Sar有区别。Tsar 中的字段是可读的,Sar 看不到含义。
  数据采集到达后,支持发送到远端,比如发送到网络接口,或者发送到MySql、Nagios等。另外,数据展示分为两部分,分别是分为实时显示和历史显示。实时显示需要每秒查看指标的样子。历史显示就是对过去每一分钟的数据做一个历史记录。回放。目前,Tsar 支持秒、分钟、天等不同维度的数据展示。
  沙皇的用法
  Tsar的用法比较简单,不管是什么模块,这个用法都是共享的。上面最常用的命令是check命令,输出系统最新的监控指标。有了这个功能,所有基础软件采集基本可以每分钟调用一次,拿到最后一分钟的监控数据,把这些数据带到我们的监控平台,在里面做一些监控配置和集中工作。这个命令是最常用的。
  
  -c 是定期执行的命令。这样,你当前打开的模块的所有采集函数都会执行一次,获取数据,并将数据保存在tsar的原创文件中。以后使用。
  -i 是指定一个间隔,多少秒或多少分钟。
  下图是一些用法的截图。实时模式下,可以指定-l或者--live,可以现场采集模块数据,实时分析结果。如果不指定,则默认为离线模式。时间间隔,如果不指定-i,默认为秒和分钟,实时每秒显示一次采集,离线每分钟显示一次。您还可以指定模块,--mod_name,指定几个模块,并显示几个指标。这样就可以将你关心的指标显示在一个屏幕上,让你看到它们之间的影响和关系,从而找到问题的症结所在。
  
  Tsar 还支持多个项目模块。有时系统指标有多个实例。这里体现了item的概念,可以更灵活的展示数据。另外,--check是看我们最后一分钟的数据,会在最后一分钟显示这一行的各个指标和字段,可以很方便的做一些监控处理。
  
  Tsar 本身是一个独立的软件,可以为其他系统提供丰富的数据源输入。
  下图是比较常见的配置,包括配置文件、指定模块、指定输出等。
  
  下图是如何输出到Mysql和Nagios的配置方法。
  
  定制开发
  Tsar 目前支持 C、bash、Lua 开发自定义模块,内部有近百个应用模块。模块组成包括模块名称、描述信息、采集函数、显示函数等,tsar本身也可以使用tsardevel的脚本自动生成一个模板,在这个模板的基础上进行修改,比较多高效的。
  
  具体模块开发内容如下:
  
  采集这个功能是具体抓取value_1/2/3,不管是到counter文件还是接口,都可以获取到value。但是得到的值并不是最终要显示的值,而是瞬时值。
  
  显示的数值需要通过数据显示功能进行处理计算。display函数中的两个输入参数会告诉你采集的最后两个数组的数据是什么。通过对这两个数组进行操作,最终得到的结果就是最终显示的数字。前几个内容做完后,最后在模块中生成注册函数。以下是一些关键信息,例如模块名称。用法、模块字段数据结构、字段数、采集 函数和表示函数。
  
  至此,一个模块基本完成。
  未来计划
  我们对沙皇的未来计划主要是三个方面。
  首先是跨平台,有些Linux版本支持的不是特别好,所以我们会在跨平台上多尝试。
  二是完善框架。目前框架比较大。如果单个模块有一些异常,整个采集都会挂掉。在本节中,我们将解耦一些模块和框架之间的强依赖关系,希望能够容灾。更好的。
  三是丰富一些模块。常用的系统模块已经很多,内部应用模块也比较丰富。也希望大家可以在开源区提供更多的模块,让我们支持的采集的类型更加丰富。一些。
  目前,在阿里巴巴整个开源代码库中,外部贡献者并不多,十几个人,内部贡献代码的有一百多人。欢迎来到主页和代码库。如有疑问,也可以联系本文分享者:再见。
   查看全部

  文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar
)
  在开源活动LinuxCon + ContainerCon + CloudOpen China(简称LC3))上,阿里云CDN团队分享了开源系统和应用采集软件Tsar背景、设计思路和使用方法,模块开发和未来规划。
  其实是阿里巴巴在做系统或者应用监控的时候的一个思路。队友在实际使用过程中比较舒服,软件的扩展性、稳定性、易用性也比较好,所以目前全机都可以使用。Deployment作为基础的监控代理,提供稳定的数据支持,同时也是对外开源的。
  沙皇的背景
  对于在线SA/PE/R&amp;D,他在开发和部署软件的时候,需要注意软件的运行情况。他需要去上面看看整个服务器的CPU/内存/网络/IO等基本指标是否OK。找出这些指标的一些软件瓶颈和针对性的优化。其实现在市面上有很多类似的软件,都有一定的特殊性,可能只是采集的某一个,每个软件采集都有不同的指标,这些的用法指标时间不一致。所以对用户的要求非常高,需要知道如何使用所有的监控软件,对于排查在线问题非常不方便。这也是我们最初的痛点。我们发现我们拥有所有的数据,但是如何链接和使用它很不方便。所以,我们想出了沙皇的想法。
  
  下图是现在网上很多命令的使用。整个Linux站的每一层都有一些对应的命令。运维等用户的学习成本非常高,不利于我们统一监控。
  
  需求和解决方案
  因此,我们最初的要求是有一个易于使用的采集软件,具有完整的基础数据,最好是应用程序数据。因为刚才列出的指标都是通用指标,但是我们有应用软件,所以我们想知道应用软件的一些数据,比如QPS和响应时间。目前的开源软件无法支持,业务需要编写采集工具进行数据采集和监控。
  另外,我们希望在数据之间做一些数据关联。比如当前CPU高,是否会带来其他一些数据指标的波动?需要对这些指标进行比较才能确定问题。
  同时,必须对数据进行过滤,离线实时查看,本地长期存储,远程发送,方便中心进行数据分析和挖掘。
  有了这些需求,我们的解决方案就是模仿Sar,它本身就是一个系统活动报告,实现了系统指标的采集,我们在它的基础上做了一些扩展。除了系统级的数据采集,Tsar还可以进行应用级的采集,模块化,支持扩展。例如,采集 现在有十个指标。如果还有其他应用指标和业务数据要到采集,可以很方便的在Tsar中写一个模块到采集。它还支持简单的报警和远程发送。
  设计和使用
  沙皇的原则很简单。它主要利用动态库的特性。我们每个采集模块都会实现一些功能,比如采集函数,分析处理函数,注册时提供的模块。基础字段,比如模块名,模块收录的字段,字段从哪里来采集,采集之后怎么处理和输出,这些函数都注册在Tsar框架中,每个循环到采集 调用这些指令的函数时,就可以完成采集的处理和整个数据的输出。
  整个模块的注册和执行流程如下:
  
  下图是Tsar的功能大图,底部是系统计数器和软件界面。每个具体的模块都是基于采集,参考Sar实现了很多系统指标。此外,还为应用软件提供了LVS、Nginx等对比。通用应用软件模块。
  
  在上述采集的过程中,会对模块进行一些过滤处理,并执行各个模块的采集函数来获取数据。根据格式化,框架将数据格式化并保存到/var/log/tsar.data。我们采集把所有的原创数据,以文件的形式存储起来。与Sar有区别。Tsar 中的字段是可读的,Sar 看不到含义。
  数据采集到达后,支持发送到远端,比如发送到网络接口,或者发送到MySql、Nagios等。另外,数据展示分为两部分,分别是分为实时显示和历史显示。实时显示需要每秒查看指标的样子。历史显示就是对过去每一分钟的数据做一个历史记录。回放。目前,Tsar 支持秒、分钟、天等不同维度的数据展示。
  沙皇的用法
  Tsar的用法比较简单,不管是什么模块,这个用法都是共享的。上面最常用的命令是check命令,输出系统最新的监控指标。有了这个功能,所有基础软件采集基本可以每分钟调用一次,拿到最后一分钟的监控数据,把这些数据带到我们的监控平台,在里面做一些监控配置和集中工作。这个命令是最常用的。
  
  -c 是定期执行的命令。这样,你当前打开的模块的所有采集函数都会执行一次,获取数据,并将数据保存在tsar的原创文件中。以后使用。
  -i 是指定一个间隔,多少秒或多少分钟。
  下图是一些用法的截图。实时模式下,可以指定-l或者--live,可以现场采集模块数据,实时分析结果。如果不指定,则默认为离线模式。时间间隔,如果不指定-i,默认为秒和分钟,实时每秒显示一次采集,离线每分钟显示一次。您还可以指定模块,--mod_name,指定几个模块,并显示几个指标。这样就可以将你关心的指标显示在一个屏幕上,让你看到它们之间的影响和关系,从而找到问题的症结所在。
  
  Tsar 还支持多个项目模块。有时系统指标有多个实例。这里体现了item的概念,可以更灵活的展示数据。另外,--check是看我们最后一分钟的数据,会在最后一分钟显示这一行的各个指标和字段,可以很方便的做一些监控处理。
  
  Tsar 本身是一个独立的软件,可以为其他系统提供丰富的数据源输入。
  下图是比较常见的配置,包括配置文件、指定模块、指定输出等。
  
  下图是如何输出到Mysql和Nagios的配置方法。
  
  定制开发
  Tsar 目前支持 C、bash、Lua 开发自定义模块,内部有近百个应用模块。模块组成包括模块名称、描述信息、采集函数、显示函数等,tsar本身也可以使用tsardevel的脚本自动生成一个模板,在这个模板的基础上进行修改,比较多高效的。
  
  具体模块开发内容如下:
  
  采集这个功能是具体抓取value_1/2/3,不管是到counter文件还是接口,都可以获取到value。但是得到的值并不是最终要显示的值,而是瞬时值。
  
  显示的数值需要通过数据显示功能进行处理计算。display函数中的两个输入参数会告诉你采集的最后两个数组的数据是什么。通过对这两个数组进行操作,最终得到的结果就是最终显示的数字。前几个内容做完后,最后在模块中生成注册函数。以下是一些关键信息,例如模块名称。用法、模块字段数据结构、字段数、采集 函数和表示函数。
  
  至此,一个模块基本完成。
  未来计划
  我们对沙皇的未来计划主要是三个方面。
  首先是跨平台,有些Linux版本支持的不是特别好,所以我们会在跨平台上多尝试。
  二是完善框架。目前框架比较大。如果单个模块有一些异常,整个采集都会挂掉。在本节中,我们将解耦一些模块和框架之间的强依赖关系,希望能够容灾。更好的。
  三是丰富一些模块。常用的系统模块已经很多,内部应用模块也比较丰富。也希望大家可以在开源区提供更多的模块,让我们支持的采集的类型更加丰富。一些。
  目前,在阿里巴巴整个开源代码库中,外部贡献者并不多,十几个人,内部贡献代码的有一百多人。欢迎来到主页和代码库。如有疑问,也可以联系本文分享者:再见。
  

文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则 )

采集交流优采云 发表了文章 • 0 个评论 • 104 次浏览 • 2022-01-22 00:14 • 来自相关话题

  文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则
)
  前言:本文章是关于如何使用Dedecms采集函数的第二篇文章。过滤规则。本次选择的目标站点为中国网管联盟网络技术频道的网络协议栏目,网址为“”。本文分为三个部分。第一部分主要介绍新添加的采集节点的第一步:设置基本信息和URL索引页面规则;第二节主要介绍新增的采集节点中的第二步:设置字段获取规则;第三节主要介绍采集如何指定节点以及如何导出采集内容。关于编写采集规则的一些基本操作,本文不做介绍或不再介绍,如有疑问,
  进入下面的第一部分。
  1.1 设置基本信息和URL索引页面规则
  新建一个普通的文章节点,输入“添加采集节点:第一步设置基本信息和URL索引页面规则”如图(图1),
  
  图1 - 新建采集节点:第一步设置基本信息和URL索引页面规则
  1.1.1 设置节点基本信息
  
  图 2 - 节点基本信息
  首先,定义节点名称为“采集Test(二)”。其次,找到目标页面代码。操作步骤为:
  (a) 打开 采集: 所针对的目标页面;
  (b) 右击选择“查看源文件”找到“charset”,如图(图3),
  
  图 3 - 查看源文件
  等号后面的代码就是想要的“编码格式”,这里是“gb2312”。“Region Matching Mode”、“Content Import Order”、“Hot Link Mode”使用默认值。
  引用 URL:您可以选择出现在 文章 列表中的任何 文章 页面的 URL。为方便起见,通常填写文章列表中第一个文章的URL,但由于第一个文章不涉及分页内容,为了展示如何采集分页文章,这里使用第二条文章作为参考网址。它的网址是:“”。设置后节点的基本信息,如图(图4),
  
  图 4 - 设置后节点的基本信息
  检查后,进入下一步。
  1.1.2 设置列表URL获取规则
  如图(图5),
  
  图 5 - 列出 URL 获取规则
  这是设置采集的文章列表页的匹配规则,也是本节的重点和难点。
  具体步骤:
  (a) 首先,回到打开的文章列表页面,然后浏览器的URL地址栏中显示的URL,如图(图6),
   查看全部

  文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则
)
  前言:本文章是关于如何使用Dedecms采集函数的第二篇文章。过滤规则。本次选择的目标站点为中国网管联盟网络技术频道的网络协议栏目,网址为“”。本文分为三个部分。第一部分主要介绍新添加的采集节点的第一步:设置基本信息和URL索引页面规则;第二节主要介绍新增的采集节点中的第二步:设置字段获取规则;第三节主要介绍采集如何指定节点以及如何导出采集内容。关于编写采集规则的一些基本操作,本文不做介绍或不再介绍,如有疑问,
  进入下面的第一部分。
  1.1 设置基本信息和URL索引页面规则
  新建一个普通的文章节点,输入“添加采集节点:第一步设置基本信息和URL索引页面规则”如图(图1),
  
  图1 - 新建采集节点:第一步设置基本信息和URL索引页面规则
  1.1.1 设置节点基本信息
  
  图 2 - 节点基本信息
  首先,定义节点名称为“采集Test(二)”。其次,找到目标页面代码。操作步骤为:
  (a) 打开 采集: 所针对的目标页面;
  (b) 右击选择“查看源文件”找到“charset”,如图(图3),
  
  图 3 - 查看源文件
  等号后面的代码就是想要的“编码格式”,这里是“gb2312”。“Region Matching Mode”、“Content Import Order”、“Hot Link Mode”使用默认值。
  引用 URL:您可以选择出现在 文章 列表中的任何 文章 页面的 URL。为方便起见,通常填写文章列表中第一个文章的URL,但由于第一个文章不涉及分页内容,为了展示如何采集分页文章,这里使用第二条文章作为参考网址。它的网址是:“”。设置后节点的基本信息,如图(图4),
  
  图 4 - 设置后节点的基本信息
  检查后,进入下一步。
  1.1.2 设置列表URL获取规则
  如图(图5),
  
  图 5 - 列出 URL 获取规则
  这是设置采集的文章列表页的匹配规则,也是本节的重点和难点。
  具体步骤:
  (a) 首先,回到打开的文章列表页面,然后浏览器的URL地址栏中显示的URL,如图(图6),
  

文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)

采集交流优采云 发表了文章 • 0 个评论 • 182 次浏览 • 2022-01-19 03:00 • 来自相关话题

  文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)
  本文主要分享使用火焰图的技巧,介绍systemtap的原理和机制,如何使用火焰图快速定位性能问题的原因,加深对systemtap的理解。
  让我们回想一下,作为编程新手,我们是如何调整程序的?通常依靠没有数据的主观假设,稍有经验的同学会分两块或一卷调试差异代码。这种定位问题的方法不仅费时费力,而且不具有普遍性。在遇到其他类似的性能问题时,需要反复踩坑填坑,那么如何避免这种情况呢?
  有句话叫:兵欲行善,必先利其器。个人认为,程序员也需要一把“利器”来定位性能问题。就像医生看病人一样,需要依靠专业的医疗工具(如X光片、听诊器等)进行诊断,最终根据患者的检测结果快速准确地定位病因。医疗工具。性能调优工具(如 perf / gprof 等)用于性能调优,就像 X 射线用于患者一样。他们可以查明程序的性能瓶颈。
  但是,常用的性能调优工具perf等只能在单个显示中列出调用堆栈或非分层时间分布,不够直观。这里推荐大家一起使用火焰图,更直观的呈现perf采集等工具的数据。
  初识火焰图
  火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的。与所有其他分析方法不同,Flame Graph 从全局角度看待时间分布。它从底部到顶部列出了所有可能的原因 性能瓶颈的调用堆栈。
  
  火焰图的整个图看起来像一个跳动的火焰,这就是它的名字的由来。
  火焰图有以下特点(这里以on-cpu火焰图为例):
  火焰图类型
  常见的火焰图类型有 On-CPU、Off-CPU 以及 Memory、Hot/Cold、Differential 等。它们适合什么样的问题?
  这里笔者主要使用了On-CPU、Off-CPU和Memory火焰图,所以这里只是对这三个火焰图进行对比,欢迎大家补充指正。
  
  火焰图分析技巧的纵轴代表调用栈的深度(栈帧数),用来表示函数之间的调用关系:下面的函数是上面函数的父函数。横轴代表调用频率。网格的宽度越大,就越有可能成为瓶颈。不同类型的火焰图适用于不同的优化场景。例如,on-cpu 火焰图适用于分析 CPU 使用率较高的问题函数,而 off-cpu 火焰图适用于解决阻塞和锁抢占问题。无意义的东西:横序是为了聚合,与函数之间的依赖或调用关系无关;火焰图的各种颜色是为了方便区分,本身并无特殊含义。更多实践:进行性能优化,自觉使用火焰图法。如何绘制火焰图以进行性能调整(如果有时间)?
  要生成火焰图,您必须有一个方便的动态跟踪工具,如果操作系统是 Linux,通常是 perf 或 systemtap 之一。其中,perf相对来说比较常用。大部分Linux系统都收录perf,可以直接使用;SystemTap 在监控方面更强大、更灵活。关于如何使用perf绘制火焰图,网上有很多文章,所以本文将以SystemTap为例。
  SystemTap 是一个动态跟踪工具。它利用探针机制来采集内核或应用程序的运行信息,使您无需修改​​内核和应用程序的代码即可获得丰富的信息,帮助您分析和定位所需的故障排除问题。SystemTap 定义了类似的 DSL 脚本语言,方便用户根据需要自由扩展。但是,与动态跟踪的鼻祖 DTrace 不同,SystemTap 没有驻留的内核运行时。它需要先将脚本编译成内核模块,然后插入内核执行。这也会导致 SystemTap 启动缓慢并依赖于完整的调试符号表。
  使用SystemTap绘制火焰图的主要流程如下:
  本文的演示步骤将基于操作系统Tlinux 2.2
  安装 SystemTap 和 OS 符号调试表
  使用 yum 工具安装 systemtap:
  yum install systemtap systemtap-runtime
  由于systemtap工具依赖于完整的调试符号表,而且生产环境中不同机器的内核版本不同(虽然都是Tlinux2.2版本,但是内核版本之后的次要版本不同,可以通过 uname -a 命令查看)) 所以我们还需要安装 kernel-debuginfo 包和 kernel-devel 包。我在这里安装了这两个依赖包。
  kernel-devel-3.10.107-1-tlinux2-0046.x86_64
kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64
  根据需要绘制的火焰图类型和工艺类型选择合适的脚本
  使用 SystemTap 统计相关数据,往往需要根据其语法编写脚本,有一定的门槛。好在github上的agentzh开源了他常用的两套SystemTap脚本:openresty-systemtap-toolkit和stapxx,这两套工具集可以覆盖C进程、nginx进程和Openresty进程的大部分性能问题场景。
  我们这里需要绘制off-cpu火焰图,所以使用sample-bt-off-cpu脚本
  生成内核模块
  现在我们已经安装了统计脚本和systemtap,可以正常使用了,但是由于systemtap是通过生成内核模块来统计相关探针的统计信息,而tlinux要求所有运行的内核模块首先到达tlinux平台签名才能运行,所以:
  所以需要先修改off-cpu脚本生成内核模块;然后签署内核模块;最后使用systemtap命令手动运行脚本统计监控数据
  systemtap执行流程如下:
  
  所以我们在这里修改off-cpu stap脚本,让它只完成第四阶段,只生成一个内核模块
  // 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段
open my $in, "|stap -p4 --skip-badvars --all-modules -x $pid -d &#39;$exec_path&#39; --ldd $d_so_args $stap_args -"
or die "Cannot run stap: $!\n";
  修改后运行脚本生成内核模块
  // -p 8682 是需要监控的进程的进程号
// -t 30 是指会采样30秒
./sample-bt-off-cpu -p 8692 -t 30
  生成的内核模块名称为stap_xxxxx.ko。由于读者无需关心内核模块的签名,本章略过。
  运行内核模块统计
  内核模块签名后,可以使用staprun命令手动运行相关内核模块
  命令:
  // 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt
  值得注意的是,被监控的进程必须有一定的systemtap负载才能采集获取相关数据,即采集时也需要有一定的请求量(通常自己构建请求,对过程进行压力测试)
  将统计数据转换为火焰图
  一旦你有了统计数据 demo.bt,你就可以使用火焰图工具来绘制火焰图
  下载FlameGraph,链接:
  命令:
  ./stackcollapse-stap.pl demo.bt > demo.folded
./flamegraph.pl demo.folded > demo.svg
  这给出了 off-cpu 火焰图:
  
  看图说话
  趁热打铁,通过几张火焰图熟悉火焰图的使用方法
  图片来自春歌微博或个人近期定位问题
  On-cpu 火焰图 Apache APISIX QPS 急剧下降问题
  
  Apache APISIX是一款开源的国产高性能API网关。在选型和压测过程中发现,当路由匹配不同场景时,QPS急剧下降。当它的CPU(48核)占用率几乎100%,QPS几千,通过绘制火焰图,发现主要时间花在了一个表插入阶段(lj_cf_table_insert)。分析代码发现表还没有释放。每次路由不匹配,就会插入数据,导致表越来越大。后续插入耗时过长,导致 QPS 下降。
  off-cpu 火焰图 nginx mutex 问题
  
  这是一个 nginx 的 off-cpu 火焰图。我们可以快速锁定到 ngx_common_set_cache_fs_size -&gt; ngx_shmtx_lock -&gt; sem_wait。这个逻辑使用了互斥锁,这使得 nginx 进程的大部分阻塞等待时间都花在了获取锁上。
  代理监控报告断点问题
  
  这是代理的非 CPU 火焰图。它是一个多线程异步事件模型。主线程处理每条消息,多个线程负责配置和传递或监控和报告的职责。目前的问题是监控上报性能差,无法在周期(一分钟)内完成监控数据上报,导致监控断点。通过off-cpu火焰图,我们可以分析出上报线程在使用curl_easy_perform接口收发http监控数据报文时花费了很多时间。 查看全部

  文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)
  本文主要分享使用火焰图的技巧,介绍systemtap的原理和机制,如何使用火焰图快速定位性能问题的原因,加深对systemtap的理解。
  让我们回想一下,作为编程新手,我们是如何调整程序的?通常依靠没有数据的主观假设,稍有经验的同学会分两块或一卷调试差异代码。这种定位问题的方法不仅费时费力,而且不具有普遍性。在遇到其他类似的性能问题时,需要反复踩坑填坑,那么如何避免这种情况呢?
  有句话叫:兵欲行善,必先利其器。个人认为,程序员也需要一把“利器”来定位性能问题。就像医生看病人一样,需要依靠专业的医疗工具(如X光片、听诊器等)进行诊断,最终根据患者的检测结果快速准确地定位病因。医疗工具。性能调优工具(如 perf / gprof 等)用于性能调优,就像 X 射线用于患者一样。他们可以查明程序的性能瓶颈。
  但是,常用的性能调优工具perf等只能在单个显示中列出调用堆栈或非分层时间分布,不够直观。这里推荐大家一起使用火焰图,更直观的呈现perf采集等工具的数据。
  初识火焰图
  火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的。与所有其他分析方法不同,Flame Graph 从全局角度看待时间分布。它从底部到顶部列出了所有可能的原因 性能瓶颈的调用堆栈。
  
  火焰图的整个图看起来像一个跳动的火焰,这就是它的名字的由来。
  火焰图有以下特点(这里以on-cpu火焰图为例):
  火焰图类型
  常见的火焰图类型有 On-CPU、Off-CPU 以及 Memory、Hot/Cold、Differential 等。它们适合什么样的问题?
  这里笔者主要使用了On-CPU、Off-CPU和Memory火焰图,所以这里只是对这三个火焰图进行对比,欢迎大家补充指正。
  
  火焰图分析技巧的纵轴代表调用栈的深度(栈帧数),用来表示函数之间的调用关系:下面的函数是上面函数的父函数。横轴代表调用频率。网格的宽度越大,就越有可能成为瓶颈。不同类型的火焰图适用于不同的优化场景。例如,on-cpu 火焰图适用于分析 CPU 使用率较高的问题函数,而 off-cpu 火焰图适用于解决阻塞和锁抢占问题。无意义的东西:横序是为了聚合,与函数之间的依赖或调用关系无关;火焰图的各种颜色是为了方便区分,本身并无特殊含义。更多实践:进行性能优化,自觉使用火焰图法。如何绘制火焰图以进行性能调整(如果有时间)?
  要生成火焰图,您必须有一个方便的动态跟踪工具,如果操作系统是 Linux,通常是 perf 或 systemtap 之一。其中,perf相对来说比较常用。大部分Linux系统都收录perf,可以直接使用;SystemTap 在监控方面更强大、更灵活。关于如何使用perf绘制火焰图,网上有很多文章,所以本文将以SystemTap为例。
  SystemTap 是一个动态跟踪工具。它利用探针机制来采集内核或应用程序的运行信息,使您无需修改​​内核和应用程序的代码即可获得丰富的信息,帮助您分析和定位所需的故障排除问题。SystemTap 定义了类似的 DSL 脚本语言,方便用户根据需要自由扩展。但是,与动态跟踪的鼻祖 DTrace 不同,SystemTap 没有驻留的内核运行时。它需要先将脚本编译成内核模块,然后插入内核执行。这也会导致 SystemTap 启动缓慢并依赖于完整的调试符号表。
  使用SystemTap绘制火焰图的主要流程如下:
  本文的演示步骤将基于操作系统Tlinux 2.2
  安装 SystemTap 和 OS 符号调试表
  使用 yum 工具安装 systemtap:
  yum install systemtap systemtap-runtime
  由于systemtap工具依赖于完整的调试符号表,而且生产环境中不同机器的内核版本不同(虽然都是Tlinux2.2版本,但是内核版本之后的次要版本不同,可以通过 uname -a 命令查看)) 所以我们还需要安装 kernel-debuginfo 包和 kernel-devel 包。我在这里安装了这两个依赖包。
  kernel-devel-3.10.107-1-tlinux2-0046.x86_64
kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64
  根据需要绘制的火焰图类型和工艺类型选择合适的脚本
  使用 SystemTap 统计相关数据,往往需要根据其语法编写脚本,有一定的门槛。好在github上的agentzh开源了他常用的两套SystemTap脚本:openresty-systemtap-toolkit和stapxx,这两套工具集可以覆盖C进程、nginx进程和Openresty进程的大部分性能问题场景。
  我们这里需要绘制off-cpu火焰图,所以使用sample-bt-off-cpu脚本
  生成内核模块
  现在我们已经安装了统计脚本和systemtap,可以正常使用了,但是由于systemtap是通过生成内核模块来统计相关探针的统计信息,而tlinux要求所有运行的内核模块首先到达tlinux平台签名才能运行,所以:
  所以需要先修改off-cpu脚本生成内核模块;然后签署内核模块;最后使用systemtap命令手动运行脚本统计监控数据
  systemtap执行流程如下:
  
  所以我们在这里修改off-cpu stap脚本,让它只完成第四阶段,只生成一个内核模块
  // 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段
open my $in, "|stap -p4 --skip-badvars --all-modules -x $pid -d &#39;$exec_path&#39; --ldd $d_so_args $stap_args -"
or die "Cannot run stap: $!\n";
  修改后运行脚本生成内核模块
  // -p 8682 是需要监控的进程的进程号
// -t 30 是指会采样30秒
./sample-bt-off-cpu -p 8692 -t 30
  生成的内核模块名称为stap_xxxxx.ko。由于读者无需关心内核模块的签名,本章略过。
  运行内核模块统计
  内核模块签名后,可以使用staprun命令手动运行相关内核模块
  命令:
  // 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt
  值得注意的是,被监控的进程必须有一定的systemtap负载才能采集获取相关数据,即采集时也需要有一定的请求量(通常自己构建请求,对过程进行压力测试)
  将统计数据转换为火焰图
  一旦你有了统计数据 demo.bt,你就可以使用火焰图工具来绘制火焰图
  下载FlameGraph,链接:
  命令:
  ./stackcollapse-stap.pl demo.bt > demo.folded
./flamegraph.pl demo.folded > demo.svg
  这给出了 off-cpu 火焰图:
  
  看图说话
  趁热打铁,通过几张火焰图熟悉火焰图的使用方法
  图片来自春歌微博或个人近期定位问题
  On-cpu 火焰图 Apache APISIX QPS 急剧下降问题
  
  Apache APISIX是一款开源的国产高性能API网关。在选型和压测过程中发现,当路由匹配不同场景时,QPS急剧下降。当它的CPU(48核)占用率几乎100%,QPS几千,通过绘制火焰图,发现主要时间花在了一个表插入阶段(lj_cf_table_insert)。分析代码发现表还没有释放。每次路由不匹配,就会插入数据,导致表越来越大。后续插入耗时过长,导致 QPS 下降。
  off-cpu 火焰图 nginx mutex 问题
  
  这是一个 nginx 的 off-cpu 火焰图。我们可以快速锁定到 ngx_common_set_cache_fs_size -&gt; ngx_shmtx_lock -&gt; sem_wait。这个逻辑使用了互斥锁,这使得 nginx 进程的大部分阻塞等待时间都花在了获取锁上。
  代理监控报告断点问题
  
  这是代理的非 CPU 火焰图。它是一个多线程异步事件模型。主线程处理每条消息,多个线程负责配置和传递或监控和报告的职责。目前的问题是监控上报性能差,无法在周期(一分钟)内完成监控数据上报,导致监控断点。通过off-cpu火焰图,我们可以分析出上报线程在使用curl_easy_perform接口收发http监控数据报文时花费了很多时间。

文章采集调用(文章采集调用node.js,可以用我前面那篇)

采集交流优采云 发表了文章 • 0 个评论 • 140 次浏览 • 2022-01-18 23:04 • 来自相关话题

  文章采集调用(文章采集调用node.js,可以用我前面那篇)
  文章采集调用node.js,可以用我前面那篇wordpress的博客包含在内。文章预览代码修改了原来dom的版本,用的beforeeach,增加了references和activex选项。
  确定不是需要加一个js::static()。用windowscript钩子进去,无论是加载老文件,还是搞个大新闻都用得上。
  我觉得上面提到的beforeeach和activex自不必说,但是我很好奇。如果你当年没有用window的话,真正要解决的应该不是这个bug。首先你要解决的问题是标题如何显示。我开始认为只有字符串,然后提交的时候,编辑器不支持那么多字符显示,于是用大小写命名,emmmm好像没太大问题。那么你接下来应该不是问beforeeach和activex的区别,而是两个命名的话,明显要出问题。
  所以你可以看看没错,window就是为此才有的。你可以用window::scriptingdefaultscheme之类的东西,改成beforeeachschemename()或者activex::staticname()之类的。
  字符串就可以但是标题编辑器用没有必要1,像这样加上拼音的tag岂不是更合适2,beforeeach的token是用js保存的时候就会创建,无需手动控制,也不需要自己传值3,beforeend不支持的tag应该很少,
  自己写ajax太麻烦了,我只看activex支持,dom文件拖个beforeeach出来就可以, 查看全部

  文章采集调用(文章采集调用node.js,可以用我前面那篇)
  文章采集调用node.js,可以用我前面那篇wordpress的博客包含在内。文章预览代码修改了原来dom的版本,用的beforeeach,增加了references和activex选项。
  确定不是需要加一个js::static()。用windowscript钩子进去,无论是加载老文件,还是搞个大新闻都用得上。
  我觉得上面提到的beforeeach和activex自不必说,但是我很好奇。如果你当年没有用window的话,真正要解决的应该不是这个bug。首先你要解决的问题是标题如何显示。我开始认为只有字符串,然后提交的时候,编辑器不支持那么多字符显示,于是用大小写命名,emmmm好像没太大问题。那么你接下来应该不是问beforeeach和activex的区别,而是两个命名的话,明显要出问题。
  所以你可以看看没错,window就是为此才有的。你可以用window::scriptingdefaultscheme之类的东西,改成beforeeachschemename()或者activex::staticname()之类的。
  字符串就可以但是标题编辑器用没有必要1,像这样加上拼音的tag岂不是更合适2,beforeeach的token是用js保存的时候就会创建,无需手动控制,也不需要自己传值3,beforeend不支持的tag应该很少,
  自己写ajax太麻烦了,我只看activex支持,dom文件拖个beforeeach出来就可以,

文章采集调用( 一段代码,是调用WordPress某段时间内评论最多的文章)

采集交流优采云 发表了文章 • 0 个评论 • 129 次浏览 • 2022-01-17 17:10 • 来自相关话题

  文章采集调用(
一段代码,是调用WordPress某段时间内评论最多的文章)
  
  很多主题都使用了wordpress流行的文章功能,但他们通常把建站以来评论最多的称为文章。说实话,这个没什么意思,可能一直显示那几篇文章文章,今天给大家推荐一段代码,是某一段时间内调用WordPress评论最多的文章的时间。方法来自zwwooooo大师的WordPress:近期最热文章.
  把下面的代码放在最后一个?>在主题的functions.php之间
  1.,注意代码中的注释文字:
  /* 某段时间内最热文章
* Reference: http://www.wprecipes.com/rarst ... -week
* Edit: zwwooooo
*/
function most_comm_posts($days=7, $nums=10) { //$days参数限制时间值,单位为‘天’,默认是7天;$nums是要显示文章数量
global $wpdb;
$today = date("Y-m-d H:i:s"); //获取今天日期时间
$daysago = date( "Y-m-d H:i:s", strtotime($today) - ($days * 24 * 60 * 60) ); //Today - $days
$result = $wpdb->get_results("SELECT comment_count, ID, post_title, post_date FROM $wpdb->posts WHERE post_date BETWEEN '$daysago' AND '$today' ORDER BY comment_count DESC LIMIT 0 , $nums");
$output = '';
if(empty($result)) {
$output = 'None data.';
} else {
foreach ($result as $topten) {
$postid = $topten->ID;
$title = $topten->post_title;
$commentcount = $topten->comment_count;
if ($commentcount != 0) {
$output .= ''.$title.' ('.$commentcount.')';
}
}
}
echo $output;
}
  2.调用的时候可以参考下面的例子:
  近期最热文章

  PS:函数参数1按天计算,30为30天;参数2为文章的显示数量,10为10篇文章的显示,可根据需要设置。具体风格看自己写css。
  免责声明:本网站上的所有 文章,除非另有说明或标记,均在本网站 原创 上发布。任何个人或组织,未经本站同意,不得复制、盗用、采集、将本站内容发布到任何网站、书籍等媒体平台。如果本站内容侵犯原作者合法权益,您可以联系我们处理。 查看全部

  文章采集调用(
一段代码,是调用WordPress某段时间内评论最多的文章)
  
  很多主题都使用了wordpress流行的文章功能,但他们通常把建站以来评论最多的称为文章。说实话,这个没什么意思,可能一直显示那几篇文章文章,今天给大家推荐一段代码,是某一段时间内调用WordPress评论最多的文章的时间。方法来自zwwooooo大师的WordPress:近期最热文章.
  把下面的代码放在最后一个?>在主题的functions.php之间
  1.,注意代码中的注释文字:
  /* 某段时间内最热文章
* Reference: http://www.wprecipes.com/rarst ... -week
* Edit: zwwooooo
*/
function most_comm_posts($days=7, $nums=10) { //$days参数限制时间值,单位为‘天’,默认是7天;$nums是要显示文章数量
global $wpdb;
$today = date("Y-m-d H:i:s"); //获取今天日期时间
$daysago = date( "Y-m-d H:i:s", strtotime($today) - ($days * 24 * 60 * 60) ); //Today - $days
$result = $wpdb->get_results("SELECT comment_count, ID, post_title, post_date FROM $wpdb->posts WHERE post_date BETWEEN '$daysago' AND '$today' ORDER BY comment_count DESC LIMIT 0 , $nums");
$output = '';
if(empty($result)) {
$output = 'None data.';
} else {
foreach ($result as $topten) {
$postid = $topten->ID;
$title = $topten->post_title;
$commentcount = $topten->comment_count;
if ($commentcount != 0) {
$output .= ''.$title.' ('.$commentcount.')';
}
}
}
echo $output;
}
  2.调用的时候可以参考下面的例子:
  近期最热文章

  PS:函数参数1按天计算,30为30天;参数2为文章的显示数量,10为10篇文章的显示,可根据需要设置。具体风格看自己写css。
  免责声明:本网站上的所有 文章,除非另有说明或标记,均在本网站 原创 上发布。任何个人或组织,未经本站同意,不得复制、盗用、采集、将本站内容发布到任何网站、书籍等媒体平台。如果本站内容侵犯原作者合法权益,您可以联系我们处理。

文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)

采集交流优采云 发表了文章 • 0 个评论 • 385 次浏览 • 2022-01-16 20:25 • 来自相关话题

  文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)
  数据栈是云原生的一站式数据中心PaaS。我们在 github 和 gitee 上有一个有趣的开源项目:FlinkX。 FlinkX 是一个基于 Flink 的批量流统一数据同步工具。可以是 采集static ,是一个集全局、异构、批处理流为一体的数据同步引擎。如果你喜欢它,请给我们一个star!星星!星星!
  github开源项目:
  gitee开源项目:
  袋鼠云云原生的一站式数据中台PaaS——数据栈,涵盖了建设数据中心过程中所需的各种工具(包括数据开发平台、数据资产平台、数据科学平台、数据服务引擎等),具有全面覆盖 离线计算和实时计算应用帮助企业大大缩短数据价值的提取过程,提高数据价值的提取能力。
  
  目前,数据栈-离线开发平台(BatchWorks)中的数据离线同步任务和数据栈-实时开发平台(StreamWorks)中的数据实时采集任务已经基于FlinkX进行了统一. 离线采集和实时数据采集的基本原理是一样的。主要区别在于源流是否有界。因此,使用 Flink 的 Stream API 来同步这两个数据。场景,实现数据同步的批量流统一。
  一、功能介绍
  1、断点续传
  断点续传是指数据同步任务在运行过程中由于各种原因而失败。它不需要重新同步数据,只需要从上次失败的位置继续同步即可。与网络原因下载文件失败类似,无需重新下载文件,继续下载即可,可大大节省时间和计算资源。断点续传是DataStack-离线开发平台(BatchWorks)中数据同步任务的功能,需要结合任务的错误重试机制来完成。当任务运行失败时,将在引擎中重试。重试时会从上次失败时读取的位置继续读取数据,直到任务运行成功。
  
  ​
  2、直播采集
  实时采集是数据栈实时开发平台(StreamWorks)中data采集任务的一个功能。数据实时同步到目标数据源。除了实时数据变化之外,实时采集和离线数据同步的另一个区别是实时采集任务不会停止,任务会一直监听数据源变化。这与 Flink 任务是一致的,所以实时 采集 任务是栈流计算应用中的任务类型,配置过程与离线计算中的同步任务基本相同。
  
  ​
  二、Flink 中的检查点机制
  断点续传和实时 采集 都依赖于 Flink 的 Checkpoint 机制,所以我们先简单看一下。
  Checkpoint 是 Fl​​ink 容错机制的核心功能。它可以根据配置,根据 Stream 中各个算子的状态,定期生成 Snapshots,从而定期持久地存储这些状态数据。当 Flink 程序意外崩溃时,会重新运行。程序可以选择性地从这些快照中恢复,从而纠正因故障引起的程序数​​据状态中断。
  
  当一个 Checkpoint 被触发时,一个屏障标记被插入到多个分布式 Stream Source 中,这些屏障与 Stream 中的数据记录一起流向下游算子。当操作员收到障碍时,它会暂停处理 Steam 中新收到的数据记录。因为一个 Operator 可能有多个输入 Stream,而每个 Stream 都会有一个对应的 Barrier,所以 Operator 必须等到输入 Stream 中的所有 Barrier 都到达。
  当流中所有的barrier都到达operator时,那么所有的barrier就出现在同一个时间点(表示已经对齐),在等待所有barrier到达的过程中,buffer的operator 可能已经缓存了一些比 Barrier 更早到达 Operator 的数据记录(Outgoing Records),那么 Operator 会发出(Emit)这些数据记录(Outgoing Records)作为下游 Operator 的输入,最后发出( Emit) Barrier 对应的 Snapshot 作为 this checkpoint 的结果数据。
  三、断点续传
  1、先决条件
  为了支持断点恢复上传,同步任务对数据源有一些强制性要求:
  1)数据源(此处为关系数据库)必须收录升序字段,例如主键或日期类型字段。同步过程中会使用检查点机制记录该字段的值,当任务恢复运行时会使用该字段。构造查询条件,过滤已同步的数据。如果该字段的值不按升序排列,则任务恢复时过滤的数据会出错,最终导致数据丢失或重复;
  2)数据源必须支持数据过滤。否则,任务将无法从断点处恢复运行,从而导致数据重复;
  3)目标数据源必须支持事务,比如关系型数据库,也可以通过临时文件支持文件类型的数据源。
  2、任务运行详细流程
  让我们以一个具体的任务来详细介绍整个过程。任务详情如下:
  
  ​
  1)读取数据
  读取数据时,首先构建数据分片。构造数据分片就是根据通道索引和检查点记录的位置构造查询sql。sql模板如下:
  select * from data_test
where id mod ${channel_num}=${channel_index}
and id > ${offset}
  
  如果是第一次运行,或者上次任务失败时checkpoint还没有触发,则offset不存在,具体查询sql可以根据offset和channel确定:
  存在偏移时
  第一个频道:
  select * from data_test
where id mod 2=0
and id > ${offset_0};
  
  第二频道:
  select * from data_test
where id mod 2=1
and id > ${offset_1};
  
  当偏移不存在时
  第一个频道:
  select * from data_test
where id mod 2=0;
  
  第二频道:
  select * from data_test
where id mod 2=1;
  
  数据分片构建完成后,每个通道根据自己的数据分片读取数据。
  2)写入数据
  在写数据之前,会先做几个操作:
  一个。检查 /data_test 目录是否存在。如果目录不存在,则创建目录。如果目录存在,则执行2个操作;
  湾。判断是否以overwrite方式写入数据,如果是,删除/data_test目录,然后创建目录,如果不是,执行3个操作;
  C。检查/data_test/.data目录是否存在。如果存在,则先删除再创建,确保没有其他任务因异常失败而留下的脏数据文件;
  数据单行写入hdfs,不支持批量写入。数据将首先写入 /data_test/.data/ 目录。数据文件的命名格式为:
  channelIndex.jobId.fileIndex
  收录三部分:通道索引、jobId、文件索引。
  3)触发检查点时
  在 FlinkX 中,“status”表示标识字段 id 的值。我们假设触发检查点时两个通道的读写情况如图所示:
  
  ​
  触发检查点后,两个读取器首先生成一个 Snapshot 来记录读取状态。通道 0 的状态为 id=12,通道 1 的状态为 id=11。Snapshot生成后,在数据流中插入一个barrier,barrier和数据一起流向Writer。以Writer_0为例,Writer_0接收Reader_0和Reader_1发送的数据。假设首先收到Reader_0 的屏障。此时Writer_0停止向HDFS写入数据,将接收到的数据先放入InputBuffer,等待Reader_1的barrier到来。之后,将Buffer中的所有数据写出,然后生成Writer的Snapshot。整个检查点结束后,记录的任务状态为:
  阅读器_0:id=12
  阅读器_1:id=11
  Writer_0:id=无法确定
  Writer_1:id=无法确定
  任务状态会记录在配置的HDFS目录/flinkx/checkpoint/abc123中。因为每个Writer会从两个Reader接收数据,而且每个通道的数据读写速率可能不同,所以Writer接收数据的顺序是不确定的,但这并不影响数据的准确性,因为数据是read 当我们只需要Reader记录的状态时,我们可以构造查询sql,我们只需要保证数据真的写入HDFS即可。在 Writer 生成 Snapshot 之前,会执行一系列操作以确保将所有接收到的数据写入 HDFS:
  一个。关闭写入HDFS文件的数据流。这时候会在/data_test/.data目录下生成两个文件:
  /data_test/.data/0.abc123.0
  /data_test/.data/1.abc123.0
  湾。将生成的两个数据文件移动到/data_test目录下;
  C。将文件名模板更新为:channelIndex.abc123.1;
  快照生成后,任务继续读写数据。如果在生成快照的过程中出现异常,任务会直接失败,这样本次就不会生成快照,任务恢复时会从上次成功的快照恢复。
  4)任务正常结束
  当任务正常结束时,它会做与生成快照时相同的操作,关闭文件流,移动临时数据文件等。
  5)任务异常终止
  如果任务异常结束,则假设任务结束时最后一条检查点记录的状态为:
  Reader_0:id=12Reader_1:id=11
  那么当任务恢复时,会将每条通道记录的状态赋值给offset,再次读取数据时构造的sql为:
  第一个频道:
  select * from data_test
where id mod 2=0
and id > 12;
  第二频道:
  select * from data_test
where id mod 2=1
and id > 11;
  这将允许您从上次失败的位置继续读取数据。
  3、一个支持续传上传的插件
  理论上,只要支持过滤数据的数据源和支持事务的数据源都可以支持断点续传功能,FlinkX目前支持的插件如下:
  
  ​
  四、直播采集
  目前 FlinkX 支持实时 采集 插件,包括 Kafka 和 binlog 插件。binlog 插件是为实时采集 mysql 数据库设计的。如果要支持其他数据源,只需要将数据发送到Kafka,然后使用FlinkX的Kafka插件消费数据,比如oracle,只需要使用oracle的ogg发送数据到Kafka即可。这里具体讲解mysql的实时采集插件binlog。
  1、二进制日志
  binlog是Mysql sever层维护的二进制日志,与innodb引擎中的redo/undo log完全不同;它主要用于记录更新或可能更新 MySQL 数据的 SQL 语句,并以“事务”格式存储在磁盘上。
  binlog的主要功能有:
  1)Replication:MySQL Replication在Master端开启binlog,Master将其binlog传递给slave,并replay,达到主从数据一致性的目的;
  2)数据恢复:通过mysqlbinlog工具恢复数据;
  3)增量备份。
  2、MySQL主从复制
  有记录数据变化的binlog日志是不够的,我们还需要用到MySQL的主备复制功能:主备复制是指一台服务器作为主库服务器,另一台或多台服务器作为从库服务器。数据自动复制到从服务器。
  
  ​
  主从复制的过程:
  1)MySQL master将数据变化写入二进制日志(binary log,这里的记录称为binary log events,可以通过show binlog events查看);
  2)MySQL slave将master的二进制日志事件复制到它的relay log中;
  3)MySQL slave 在中继日志中重放事件,反映数据变化到它自己。
  3、写入 Hive
  binlog 插件可以监控多个表的数据变化。解析后的数据收录表名信息。读取的数据可以写入目标数据库的表中,也可以根据数据中收录的表名信息写入。不同的表,目前只有 Hive 插件支持这个功能。Hive插件目前只有写插件,功能是基于HDFS写插件实现的。也就是说,从binlog读取写入hive的功能也支持故障恢复的功能。
  
  
  ​
  写入Hive的过程:
  1)从数据中解析出MySQL表名,然后根据表名映射规则转换成对应的Hive表名;
  2)检查Hive表是否存在,如果不存在,则创建Hive表;
  3)查询Hive表的相关信息,构造HdfsOutputFormat;
  4)调用 HdfsOutputFormat 将数据写入 HDFS。 查看全部

  文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)
  数据栈是云原生的一站式数据中心PaaS。我们在 github 和 gitee 上有一个有趣的开源项目:FlinkX。 FlinkX 是一个基于 Flink 的批量流统一数据同步工具。可以是 采集static ,是一个集全局、异构、批处理流为一体的数据同步引擎。如果你喜欢它,请给我们一个star!星星!星星!
  github开源项目:
  gitee开源项目:
  袋鼠云云原生的一站式数据中台PaaS——数据栈,涵盖了建设数据中心过程中所需的各种工具(包括数据开发平台、数据资产平台、数据科学平台、数据服务引擎等),具有全面覆盖 离线计算和实时计算应用帮助企业大大缩短数据价值的提取过程,提高数据价值的提取能力。
  
  目前,数据栈-离线开发平台(BatchWorks)中的数据离线同步任务和数据栈-实时开发平台(StreamWorks)中的数据实时采集任务已经基于FlinkX进行了统一. 离线采集和实时数据采集的基本原理是一样的。主要区别在于源流是否有界。因此,使用 Flink 的 Stream API 来同步这两个数据。场景,实现数据同步的批量流统一。
  一、功能介绍
  1、断点续传
  断点续传是指数据同步任务在运行过程中由于各种原因而失败。它不需要重新同步数据,只需要从上次失败的位置继续同步即可。与网络原因下载文件失败类似,无需重新下载文件,继续下载即可,可大大节省时间和计算资源。断点续传是DataStack-离线开发平台(BatchWorks)中数据同步任务的功能,需要结合任务的错误重试机制来完成。当任务运行失败时,将在引擎中重试。重试时会从上次失败时读取的位置继续读取数据,直到任务运行成功。
  
  ​
  2、直播采集
  实时采集是数据栈实时开发平台(StreamWorks)中data采集任务的一个功能。数据实时同步到目标数据源。除了实时数据变化之外,实时采集和离线数据同步的另一个区别是实时采集任务不会停止,任务会一直监听数据源变化。这与 Flink 任务是一致的,所以实时 采集 任务是栈流计算应用中的任务类型,配置过程与离线计算中的同步任务基本相同。
  
  ​
  二、Flink 中的检查点机制
  断点续传和实时 采集 都依赖于 Flink 的 Checkpoint 机制,所以我们先简单看一下。
  Checkpoint 是 Fl​​ink 容错机制的核心功能。它可以根据配置,根据 Stream 中各个算子的状态,定期生成 Snapshots,从而定期持久地存储这些状态数据。当 Flink 程序意外崩溃时,会重新运行。程序可以选择性地从这些快照中恢复,从而纠正因故障引起的程序数​​据状态中断。
  
  当一个 Checkpoint 被触发时,一个屏障标记被插入到多个分布式 Stream Source 中,这些屏障与 Stream 中的数据记录一起流向下游算子。当操作员收到障碍时,它会暂停处理 Steam 中新收到的数据记录。因为一个 Operator 可能有多个输入 Stream,而每个 Stream 都会有一个对应的 Barrier,所以 Operator 必须等到输入 Stream 中的所有 Barrier 都到达。
  当流中所有的barrier都到达operator时,那么所有的barrier就出现在同一个时间点(表示已经对齐),在等待所有barrier到达的过程中,buffer的operator 可能已经缓存了一些比 Barrier 更早到达 Operator 的数据记录(Outgoing Records),那么 Operator 会发出(Emit)这些数据记录(Outgoing Records)作为下游 Operator 的输入,最后发出( Emit) Barrier 对应的 Snapshot 作为 this checkpoint 的结果数据。
  三、断点续传
  1、先决条件
  为了支持断点恢复上传,同步任务对数据源有一些强制性要求:
  1)数据源(此处为关系数据库)必须收录升序字段,例如主键或日期类型字段。同步过程中会使用检查点机制记录该字段的值,当任务恢复运行时会使用该字段。构造查询条件,过滤已同步的数据。如果该字段的值不按升序排列,则任务恢复时过滤的数据会出错,最终导致数据丢失或重复;
  2)数据源必须支持数据过滤。否则,任务将无法从断点处恢复运行,从而导致数据重复;
  3)目标数据源必须支持事务,比如关系型数据库,也可以通过临时文件支持文件类型的数据源。
  2、任务运行详细流程
  让我们以一个具体的任务来详细介绍整个过程。任务详情如下:
  
  ​
  1)读取数据
  读取数据时,首先构建数据分片。构造数据分片就是根据通道索引和检查点记录的位置构造查询sql。sql模板如下:
  select * from data_test
where id mod ${channel_num}=${channel_index}
and id > ${offset}
  
  如果是第一次运行,或者上次任务失败时checkpoint还没有触发,则offset不存在,具体查询sql可以根据offset和channel确定:
  存在偏移时
  第一个频道:
  select * from data_test
where id mod 2=0
and id > ${offset_0};
  
  第二频道:
  select * from data_test
where id mod 2=1
and id > ${offset_1};
  
  当偏移不存在时
  第一个频道:
  select * from data_test
where id mod 2=0;
  
  第二频道:
  select * from data_test
where id mod 2=1;
  
  数据分片构建完成后,每个通道根据自己的数据分片读取数据。
  2)写入数据
  在写数据之前,会先做几个操作:
  一个。检查 /data_test 目录是否存在。如果目录不存在,则创建目录。如果目录存在,则执行2个操作;
  湾。判断是否以overwrite方式写入数据,如果是,删除/data_test目录,然后创建目录,如果不是,执行3个操作;
  C。检查/data_test/.data目录是否存在。如果存在,则先删除再创建,确保没有其他任务因异常失败而留下的脏数据文件;
  数据单行写入hdfs,不支持批量写入。数据将首先写入 /data_test/.data/ 目录。数据文件的命名格式为:
  channelIndex.jobId.fileIndex
  收录三部分:通道索引、jobId、文件索引。
  3)触发检查点时
  在 FlinkX 中,“status”表示标识字段 id 的值。我们假设触发检查点时两个通道的读写情况如图所示:
  
  ​
  触发检查点后,两个读取器首先生成一个 Snapshot 来记录读取状态。通道 0 的状态为 id=12,通道 1 的状态为 id=11。Snapshot生成后,在数据流中插入一个barrier,barrier和数据一起流向Writer。以Writer_0为例,Writer_0接收Reader_0和Reader_1发送的数据。假设首先收到Reader_0 的屏障。此时Writer_0停止向HDFS写入数据,将接收到的数据先放入InputBuffer,等待Reader_1的barrier到来。之后,将Buffer中的所有数据写出,然后生成Writer的Snapshot。整个检查点结束后,记录的任务状态为:
  阅读器_0:id=12
  阅读器_1:id=11
  Writer_0:id=无法确定
  Writer_1:id=无法确定
  任务状态会记录在配置的HDFS目录/flinkx/checkpoint/abc123中。因为每个Writer会从两个Reader接收数据,而且每个通道的数据读写速率可能不同,所以Writer接收数据的顺序是不确定的,但这并不影响数据的准确性,因为数据是read 当我们只需要Reader记录的状态时,我们可以构造查询sql,我们只需要保证数据真的写入HDFS即可。在 Writer 生成 Snapshot 之前,会执行一系列操作以确保将所有接收到的数据写入 HDFS:
  一个。关闭写入HDFS文件的数据流。这时候会在/data_test/.data目录下生成两个文件:
  /data_test/.data/0.abc123.0
  /data_test/.data/1.abc123.0
  湾。将生成的两个数据文件移动到/data_test目录下;
  C。将文件名模板更新为:channelIndex.abc123.1;
  快照生成后,任务继续读写数据。如果在生成快照的过程中出现异常,任务会直接失败,这样本次就不会生成快照,任务恢复时会从上次成功的快照恢复。
  4)任务正常结束
  当任务正常结束时,它会做与生成快照时相同的操作,关闭文件流,移动临时数据文件等。
  5)任务异常终止
  如果任务异常结束,则假设任务结束时最后一条检查点记录的状态为:
  Reader_0:id=12Reader_1:id=11
  那么当任务恢复时,会将每条通道记录的状态赋值给offset,再次读取数据时构造的sql为:
  第一个频道:
  select * from data_test
where id mod 2=0
and id > 12;
  第二频道:
  select * from data_test
where id mod 2=1
and id > 11;
  这将允许您从上次失败的位置继续读取数据。
  3、一个支持续传上传的插件
  理论上,只要支持过滤数据的数据源和支持事务的数据源都可以支持断点续传功能,FlinkX目前支持的插件如下:
  
  ​
  四、直播采集
  目前 FlinkX 支持实时 采集 插件,包括 Kafka 和 binlog 插件。binlog 插件是为实时采集 mysql 数据库设计的。如果要支持其他数据源,只需要将数据发送到Kafka,然后使用FlinkX的Kafka插件消费数据,比如oracle,只需要使用oracle的ogg发送数据到Kafka即可。这里具体讲解mysql的实时采集插件binlog。
  1、二进制日志
  binlog是Mysql sever层维护的二进制日志,与innodb引擎中的redo/undo log完全不同;它主要用于记录更新或可能更新 MySQL 数据的 SQL 语句,并以“事务”格式存储在磁盘上。
  binlog的主要功能有:
  1)Replication:MySQL Replication在Master端开启binlog,Master将其binlog传递给slave,并replay,达到主从数据一致性的目的;
  2)数据恢复:通过mysqlbinlog工具恢复数据;
  3)增量备份。
  2、MySQL主从复制
  有记录数据变化的binlog日志是不够的,我们还需要用到MySQL的主备复制功能:主备复制是指一台服务器作为主库服务器,另一台或多台服务器作为从库服务器。数据自动复制到从服务器。
  
  ​
  主从复制的过程:
  1)MySQL master将数据变化写入二进制日志(binary log,这里的记录称为binary log events,可以通过show binlog events查看);
  2)MySQL slave将master的二进制日志事件复制到它的relay log中;
  3)MySQL slave 在中继日志中重放事件,反映数据变化到它自己。
  3、写入 Hive
  binlog 插件可以监控多个表的数据变化。解析后的数据收录表名信息。读取的数据可以写入目标数据库的表中,也可以根据数据中收录的表名信息写入。不同的表,目前只有 Hive 插件支持这个功能。Hive插件目前只有写插件,功能是基于HDFS写插件实现的。也就是说,从binlog读取写入hive的功能也支持故障恢复的功能。
  
  
  ​
  写入Hive的过程:
  1)从数据中解析出MySQL表名,然后根据表名映射规则转换成对应的Hive表名;
  2)检查Hive表是否存在,如果不存在,则创建Hive表;
  3)查询Hive表的相关信息,构造HdfsOutputFormat;
  4)调用 HdfsOutputFormat 将数据写入 HDFS。

文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图) )

采集交流优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-01-16 20:24 • 来自相关话题

  文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图)
)
  前言
  在分布式链路跟踪中,为了获取服务之间的调用链信息,采集器通常需要在方法前后进行埋藏。在Java生态系统中,常见的埋点方式有两种:
  依靠SDK手动埋点;使用Java Agent技术做非侵入式埋葬。
  著名的分布式监控系统是由 Zipkin 开创的。最经典的就是了解X-B3 Ttrace协议,使用Brave SDK,手动埋点生成Trace。但是 SDK 中埋点的方式对业务代码是有侵入性的。升级埋点时,必须进行代码更改。
  那么如何将其与业务逻辑解绑呢?
  Java还提供了另一种方式:依靠Java Agent技术对目标方法的字节码进行修改,从而实现非侵入式埋葬。这种使用 Java 代理的 采集器 方式也称为探针。在应用启动时使用-javaagent参数,或者在运行时使用attach(pid)方法,可以将探针包注入到目标应用中,完成埋点的植入。以对业务代码无侵入的方式,实现不敏感的热升级。用户无需了解深层原理,即可使用完整的监控服务
  Java代理介绍
  Java Agent 是 Java 1.5 版本之后引入的一个特性。它的主要作用是在类加载之前对其进行拦截,并且已经插入到我们的监控字节码中。代理是使用 Java 的 Instrumentation 接口 (java.lang.instrument) 编写的。
  基本思路是在JVM启动时添加一个代理(Java Agent),每个代理是一个Jar包,在MANIFEST.MF文件中指定代理类,代理类收录一个premain方法。JVM在类加载的时候会先执行代理类的premain方法,然后再执行Java程序本身的main方法,这就是premain名的来源。在premain方法中,可以修改加载前的类文件。
  这种机制可以认为是虚拟机级别的AOP,无需对原创应用程序进行任何修改即可实现类的动态修改和增强。
  从 JDK 1.6 开始,支持更强大的动态 Instruments,在 JVM 启动后通过 Attach(pid) 远程加载。
  注意:
  无论 Agent 是用 Native 方式还是 Java Instrumentation 接口方式编写的,它们的工作都是在 JVMTI 的帮助下完成的。 JVMTI 是一组 Native 接口。在 Java 1.5 之前,Agent 只能通过编写 Native 代码来实现。
  Java Instrumentation 核心方法
  Instrumentation 是 java.lang.instrument 包下的一个接口。该接口的方法提供了注册类文件转换器、获取所有加载的类等功能,允许我们修改加载和卸载的类来实现AOP、性能监控等功能。
  常用方法:
  /**
* 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码
*/
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
/**
* 对JVM已经加载的类重新触发类加载
*/
void retransformClasses(Class... classes) throws UnmodifiableClassException;
/**
* 获取当前 JVM 加载的所有类对象
*/
Class[] getAllLoadedClasses()
  它的 addTransformer 为 Instrumentation 注册了一个转换器。Transformer 是 ClassFileTransformer 接口的一个实例。这个接口只有一个转换方法。调用addTransformer设置transformer后,后续JVM会在加载所有类之前被这个transform方法拦截。此方法接收原创类文件。字节数组,返回转换后的字节数组,可以在这个方法中做任何类文件的重写。
  public class MyClassTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classBytes) throws IllegalClassFormatException {
// 在这里读取、转换类文件
return classBytes;
}
}
  Java Agent 核心流程
  Java Agent加载时序图(premain):
  
  类加载时序图:
  
  Java 代理使用的 Instrumentation 取决于 JVMTI 实现。当然也可以绕过Instrumentation,直接使用JVMTI来实现Agent。JVMTI 和 JDI 构成了 Java 平台调试架构 (JPDA) 的主要功能。
  Java 代理使用
  Java Agent 实际上是一个特殊的 Jar 包。它不能单独启动,而必须附加到 JVM 进程。可以看成是JVM的寄生插件。它使用 Instrumentation API 来读取和重写当前 JVM 的类。文件,并通过 -javaagent:xxx.jar 导入目标应用程序。
  那么这个Jar和普通Jar有什么区别呢?
  
  Agent需要打包成jar包,在Maininfe.MF属性中指定“Premain-Class”或“Agent-Class”,根据需求定义Can-Redefine-Classes和Can-Retransform-Classes。
  Java Agent Jar包MANIFEST.MF配置参数:
  Manifest-Version: 1.0
#动态 agent 类
Agent-Class: com.zuozewei.javaagent01.Agent
#静态 agent 类
Premain-Class: com.zuozewei.javaagent01.Agent
是否允许重复装载
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_112
  演示预览
  1、创建POM项目Java Agent,项目结构如下:
  
  2、修改pom文件:
  

parent
com.zuozewei
1.0-SNAPSHOT

4.0.0
jar
javaagent01

agent


org.apache.maven.plugins
maven-jar-plugin
2.3.1


src/main/resources/META-INF/MANIFEST.MF




maven-assembly-plugin

${basedir}

true

true


com.zuozewei.javaagent01.Agent



jar-with-dependencies




org.apache.maven.plugins
maven-compiler-plugin

1.7
1.7




  3、创建一个AgentMain类实现控制台打印,添加Transformer为Instrumentation注册一个transformer。
  package com.zuozewei.javaagent01;
import java.lang.instrument.Instrumentation;
public class Agent {
// public static void premain(String agentArgs) {
// System.out.println("我是一个萌萌哒的 Java Agent");
// try {
// Thread.sleep(2000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
public static void premain(String agentArgs, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassFileTransformerDemo());
System.out.println("7DGroup Java Agent");
}
}
  4、创建一个ClassFileTransformerDemo类,截取并打印所有类名。
  package com.zuozewei.javaagent01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class ClassFileTransformerDemo implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
System.out.println("className: " + className);
if (!className.equalsIgnoreCase("com/zuozewei/Dog")) {
return null;
}
return getBytesFromFile("/Users/zuozewei/IdeaProjects/javaagent/example01/target/classes/com/zuozewei/Dog.class");
}
public static byte[] getBytesFromFile(String fileName) {
File file = new File(fileName);
try (InputStream is = new FileInputStream(file)) {
// precondition
long length = file.length();
byte[] bytes = new byte[(int) length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset = 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
is.close();
return bytes;
} catch (Exception e) {
System.out.println("error occurs in _ClassTransformer!"
+ e.getClass().getName());
return null;
}
}
}
  5、定义需要修改的项目example01
  6、需要修改的类的实现。
  主要的:
  package com.zuozewei;
public class Main {
public static void main(String[] args) {
System.out.println("7DGroup");
System.out.println(new Dog().hello());
// System.out.println(new Cat().hello());
}
}
  狗:
  package com.zuozewei;
public class Dog {
public int hello() {
return 0;
}
}
  7、运行example01的main方法:
  
  8、将javaagent项目打包生成jar文件,将java文件与上图example01项目的jar放在同一目录下(方便执行放在同一目录下)
  执行以下命令:
  java -jar -javaagent:agent.jar example.jar
  我们的函数实现了,执行结果如下:
  
  总结
  本文详细介绍了Java Agent启动加载实现字节码增强关键技术的实现细节。字节码增强技术为测试人员监控性能提供了新思路。目前很多开源监控产品都提供了丰富的Java探针库。作为监控服务商,开发成本进一步降低,但开发门槛较高,对测试人员的学习成本有很大的影响。
  源地址:
   查看全部

  文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图)
)
  前言
  在分布式链路跟踪中,为了获取服务之间的调用链信息,采集器通常需要在方法前后进行埋藏。在Java生态系统中,常见的埋点方式有两种:
  依靠SDK手动埋点;使用Java Agent技术做非侵入式埋葬。
  著名的分布式监控系统是由 Zipkin 开创的。最经典的就是了解X-B3 Ttrace协议,使用Brave SDK,手动埋点生成Trace。但是 SDK 中埋点的方式对业务代码是有侵入性的。升级埋点时,必须进行代码更改。
  那么如何将其与业务逻辑解绑呢?
  Java还提供了另一种方式:依靠Java Agent技术对目标方法的字节码进行修改,从而实现非侵入式埋葬。这种使用 Java 代理的 采集器 方式也称为探针。在应用启动时使用-javaagent参数,或者在运行时使用attach(pid)方法,可以将探针包注入到目标应用中,完成埋点的植入。以对业务代码无侵入的方式,实现不敏感的热升级。用户无需了解深层原理,即可使用完整的监控服务
  Java代理介绍
  Java Agent 是 Java 1.5 版本之后引入的一个特性。它的主要作用是在类加载之前对其进行拦截,并且已经插入到我们的监控字节码中。代理是使用 Java 的 Instrumentation 接口 (java.lang.instrument) 编写的。
  基本思路是在JVM启动时添加一个代理(Java Agent),每个代理是一个Jar包,在MANIFEST.MF文件中指定代理类,代理类收录一个premain方法。JVM在类加载的时候会先执行代理类的premain方法,然后再执行Java程序本身的main方法,这就是premain名的来源。在premain方法中,可以修改加载前的类文件。
  这种机制可以认为是虚拟机级别的AOP,无需对原创应用程序进行任何修改即可实现类的动态修改和增强。
  从 JDK 1.6 开始,支持更强大的动态 Instruments,在 JVM 启动后通过 Attach(pid) 远程加载。
  注意:
  无论 Agent 是用 Native 方式还是 Java Instrumentation 接口方式编写的,它们的工作都是在 JVMTI 的帮助下完成的。 JVMTI 是一组 Native 接口。在 Java 1.5 之前,Agent 只能通过编写 Native 代码来实现。
  Java Instrumentation 核心方法
  Instrumentation 是 java.lang.instrument 包下的一个接口。该接口的方法提供了注册类文件转换器、获取所有加载的类等功能,允许我们修改加载和卸载的类来实现AOP、性能监控等功能。
  常用方法:
  /**
* 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码
*/
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
/**
* 对JVM已经加载的类重新触发类加载
*/
void retransformClasses(Class... classes) throws UnmodifiableClassException;
/**
* 获取当前 JVM 加载的所有类对象
*/
Class[] getAllLoadedClasses()
  它的 addTransformer 为 Instrumentation 注册了一个转换器。Transformer 是 ClassFileTransformer 接口的一个实例。这个接口只有一个转换方法。调用addTransformer设置transformer后,后续JVM会在加载所有类之前被这个transform方法拦截。此方法接收原创类文件。字节数组,返回转换后的字节数组,可以在这个方法中做任何类文件的重写。
  public class MyClassTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classBytes) throws IllegalClassFormatException {
// 在这里读取、转换类文件
return classBytes;
}
}
  Java Agent 核心流程
  Java Agent加载时序图(premain):
  
  类加载时序图:
  
  Java 代理使用的 Instrumentation 取决于 JVMTI 实现。当然也可以绕过Instrumentation,直接使用JVMTI来实现Agent。JVMTI 和 JDI 构成了 Java 平台调试架构 (JPDA) 的主要功能。
  Java 代理使用
  Java Agent 实际上是一个特殊的 Jar 包。它不能单独启动,而必须附加到 JVM 进程。可以看成是JVM的寄生插件。它使用 Instrumentation API 来读取和重写当前 JVM 的类。文件,并通过 -javaagent:xxx.jar 导入目标应用程序。
  那么这个Jar和普通Jar有什么区别呢?
  
  Agent需要打包成jar包,在Maininfe.MF属性中指定“Premain-Class”或“Agent-Class”,根据需求定义Can-Redefine-Classes和Can-Retransform-Classes。
  Java Agent Jar包MANIFEST.MF配置参数:
  Manifest-Version: 1.0
#动态 agent 类
Agent-Class: com.zuozewei.javaagent01.Agent
#静态 agent 类
Premain-Class: com.zuozewei.javaagent01.Agent
是否允许重复装载
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_112
  演示预览
  1、创建POM项目Java Agent,项目结构如下:
  
  2、修改pom文件:
  

parent
com.zuozewei
1.0-SNAPSHOT

4.0.0
jar
javaagent01

agent


org.apache.maven.plugins
maven-jar-plugin
2.3.1


src/main/resources/META-INF/MANIFEST.MF




maven-assembly-plugin

${basedir}

true

true


com.zuozewei.javaagent01.Agent



jar-with-dependencies




org.apache.maven.plugins
maven-compiler-plugin

1.7
1.7




  3、创建一个AgentMain类实现控制台打印,添加Transformer为Instrumentation注册一个transformer。
  package com.zuozewei.javaagent01;
import java.lang.instrument.Instrumentation;
public class Agent {
// public static void premain(String agentArgs) {
// System.out.println("我是一个萌萌哒的 Java Agent");
// try {
// Thread.sleep(2000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
public static void premain(String agentArgs, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassFileTransformerDemo());
System.out.println("7DGroup Java Agent");
}
}
  4、创建一个ClassFileTransformerDemo类,截取并打印所有类名。
  package com.zuozewei.javaagent01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class ClassFileTransformerDemo implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
System.out.println("className: " + className);
if (!className.equalsIgnoreCase("com/zuozewei/Dog")) {
return null;
}
return getBytesFromFile("/Users/zuozewei/IdeaProjects/javaagent/example01/target/classes/com/zuozewei/Dog.class");
}
public static byte[] getBytesFromFile(String fileName) {
File file = new File(fileName);
try (InputStream is = new FileInputStream(file)) {
// precondition
long length = file.length();
byte[] bytes = new byte[(int) length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset = 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
is.close();
return bytes;
} catch (Exception e) {
System.out.println("error occurs in _ClassTransformer!"
+ e.getClass().getName());
return null;
}
}
}
  5、定义需要修改的项目example01
  6、需要修改的类的实现。
  主要的:
  package com.zuozewei;
public class Main {
public static void main(String[] args) {
System.out.println("7DGroup");
System.out.println(new Dog().hello());
// System.out.println(new Cat().hello());
}
}
  狗:
  package com.zuozewei;
public class Dog {
public int hello() {
return 0;
}
}
  7、运行example01的main方法:
  
  8、将javaagent项目打包生成jar文件,将java文件与上图example01项目的jar放在同一目录下(方便执行放在同一目录下)
  执行以下命令:
  java -jar -javaagent:agent.jar example.jar
  我们的函数实现了,执行结果如下:
  
  总结
  本文详细介绍了Java Agent启动加载实现字节码增强关键技术的实现细节。字节码增强技术为测试人员监控性能提供了新思路。目前很多开源监控产品都提供了丰富的Java探针库。作为监控服务商,开发成本进一步降低,但开发门槛较高,对测试人员的学习成本有很大的影响。
  源地址:
  

文章采集调用(文章采集调用方案(二):一站式采集工具)

采集交流优采云 发表了文章 • 0 个评论 • 131 次浏览 • 2022-01-13 09:00 • 来自相关话题

  文章采集调用(文章采集调用方案(二):一站式采集工具)
  文章采集调用方案主要有以下两种:1.tob采集:将我们的产品上架后,使用迅捷全程云采集系统接入成为统计入口,统计到一定的量后,向品牌商送达对应的赠品。2.toc客户采集:将产品放到竞品网站上,统计到了一定量后,向竞品送达对应的赠品,或者直接签署采购协议。
  我们学习过国外的seo监控网站管理系统,他们是按自己产品的搜索量,时间,进行收费,目前正在使用,好几个月的收费,价格的确不低。
  采集数据主要看你的用途和价值,是通过帮助自己更好的分析,还是帮助做竞品?更好分析当然最好用f12,如果是做竞品分析,可以用快照采集,慢采取,具体看你用的公司和产品吧,快采好,他更方便,
  资讯类:1。虎嗅创业快讯网;2。懂车帝平台;3。虎嗅“每日看车”专栏;4。汽车之家汽车报道类:1。汽车之家app;2。易车网“每日看车”;3。汽车之家论坛;4。易车网“我的车”;5。爱卡汽车,数据、榜单;其他:1。91training。com;2。石头数据;行业类1。中国汽车流通协会-auto-marketing/2。汽车圈3。易车网“每日销量”4。聚划算5。1918“速度车市”。
  欢迎使用禅道采集器百度搜索:禅道采集器-一站式采集工具 查看全部

  文章采集调用(文章采集调用方案(二):一站式采集工具)
  文章采集调用方案主要有以下两种:1.tob采集:将我们的产品上架后,使用迅捷全程云采集系统接入成为统计入口,统计到一定的量后,向品牌商送达对应的赠品。2.toc客户采集:将产品放到竞品网站上,统计到了一定量后,向竞品送达对应的赠品,或者直接签署采购协议。
  我们学习过国外的seo监控网站管理系统,他们是按自己产品的搜索量,时间,进行收费,目前正在使用,好几个月的收费,价格的确不低。
  采集数据主要看你的用途和价值,是通过帮助自己更好的分析,还是帮助做竞品?更好分析当然最好用f12,如果是做竞品分析,可以用快照采集,慢采取,具体看你用的公司和产品吧,快采好,他更方便,
  资讯类:1。虎嗅创业快讯网;2。懂车帝平台;3。虎嗅“每日看车”专栏;4。汽车之家汽车报道类:1。汽车之家app;2。易车网“每日看车”;3。汽车之家论坛;4。易车网“我的车”;5。爱卡汽车,数据、榜单;其他:1。91training。com;2。石头数据;行业类1。中国汽车流通协会-auto-marketing/2。汽车圈3。易车网“每日销量”4。聚划算5。1918“速度车市”。
  欢迎使用禅道采集器百度搜索:禅道采集器-一站式采集工具

文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-12 12:10 • 来自相关话题

  文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)
  用python制作优采云采集器接口,即使用优采云采集器,优采云采集器中的插件调用函数@>插件调用函数可以设置采集之前需要执行的规则。然后我们就可以做一个界面给我们设置每天需要的条件采集文章.
  
  用python做智能的原理伪原创是通过百度翻译把中文翻译成英文,再从英文翻译成中文得到伪原创的翻译句子。例如,我们将一个 seo 标题从中文翻译成英文:
  
  英文到中文
  
  这样我们就标题:网站“网站seo具体怎么做”智能伪原创”怎么做网站SEO”
  本节使用 python 为 优采云采集器 调用创建一个 伪原创 头接口。比如我们先用python模拟百度翻译过程,然后使用优采云Smart伪原创Title接口插件的源码。一、我们用python模拟百度翻译
  优采云采集器插件样例,下方区域是我们可以用python编辑的区域,那么我们就可以在这个区域编写模拟百度翻译过程
  
  输入python调用selenium浏览器,打开百度翻译窗口,使用xpath输入标题信息,然后进行汉英互译和英汉互译的过程,进行自动操作,最后得到翻译好的标题:
  
  
  完成后,我们将源代码上传到优采云采集器插件
  
  在优采云采集器
  中设置调用插件
  
  接下来让我们测试一下优采云采集器,这样我们就得到了翻译后的seo标题:
  
  有什么不懂的可以关注媒体明星软文宣传平台 查看全部

  文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)
  用python制作优采云采集器接口,即使用优采云采集器,优采云采集器中的插件调用函数@>插件调用函数可以设置采集之前需要执行的规则。然后我们就可以做一个界面给我们设置每天需要的条件采集文章.
  
  用python做智能的原理伪原创是通过百度翻译把中文翻译成英文,再从英文翻译成中文得到伪原创的翻译句子。例如,我们将一个 seo 标题从中文翻译成英文:
  
  英文到中文
  
  这样我们就标题:网站“网站seo具体怎么做”智能伪原创”怎么做网站SEO”
  本节使用 python 为 优采云采集器 调用创建一个 伪原创 头接口。比如我们先用python模拟百度翻译过程,然后使用优采云Smart伪原创Title接口插件的源码。一、我们用python模拟百度翻译
  优采云采集器插件样例,下方区域是我们可以用python编辑的区域,那么我们就可以在这个区域编写模拟百度翻译过程
  
  输入python调用selenium浏览器,打开百度翻译窗口,使用xpath输入标题信息,然后进行汉英互译和英汉互译的过程,进行自动操作,最后得到翻译好的标题:
  
  
  完成后,我们将源代码上传到优采云采集器插件
  
  在优采云采集器
  中设置调用插件
  
  接下来让我们测试一下优采云采集器,这样我们就得到了翻译后的seo标题:
  
  有什么不懂的可以关注媒体明星软文宣传平台

文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))

采集交流优采云 发表了文章 • 0 个评论 • 122 次浏览 • 2022-02-06 04:10 • 来自相关话题

  文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))
  首先,明确必须满足两个要求:
  1、调用指定的section
  2、调用文章来收录指定的关键字
  相关文档调用
  {dede:likeart titlelen='24' 行='10'}
  [字段:标题/]
  {/dede:likeart}
  注意:这是dede官方的调用模板,但是调用依据还不清楚!
  调用指定部分
  {dede:arclist typeid='??ĿID' row='10' titlelen='20'}
  [字段:文本链接/]
  {/dede:arclist}
  这是我想要实现的目标:
  指定栏目的调用(ID=4)相关新闻(关键词调用关键词或标题)
  {dede:arclist typeid='4' row='10' titlelen='20' 关键字=''}
  [字段:文本链接/]
  {/dede:arclist}
  代码 1
  
  效果一:
  
  代码 2:
  
  效果二:
  
  此时,如果你只是一个关键词,那就没问题了。以下键是我的 关键词 将要调用的:即keyword='{dede:field 或者我称之为标题
  关键字='{dede:field/}'
  但是,这很少使用,因为调用了模板。没有人希望所有 文章 都调用同一个关键字!
  博主推荐方法:
  -------------------------------------------------- ----------------------------------
  放置在 文章 模板页面中
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  表示取所有列中所有相关的文章(与当前文章的关键字相关),标题最大长度32,最大显示10,不显示缩略图.
  或者
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"Higher 3 Chinese")'/}
  你可以找到文章,其标题收录“大三中文”,或“大三”或“中文”
  例如,这一段:
  相关文章
  {dede:likeart titlelen='24' 行='10'}
  [字段:文本链接/]
  {/dede:likeart}
  只需将其更改为:
  相关文章
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  基于关键字的相关文章在用户体验和SEO方面非常好
  唯一的缺点是生成静态的时候会慢很多
  -------------------------------------------------- ------------------------------------------------
  附1:arclist中的关键字如何调用当前文档的关键字(dedecms织梦技术论坛)
  附2:{dede:arclist}的学习心得,调用文章或者软件的任意领域
  附上3、dedecms实现{dede:arclist keyword='[field:title/]'}的效果
  【Arclist标签】这个标签是Dedecms中最常用的标签,也叫free list标签,其中hotart、coolart、likeart、artlist、imglist、imginfolist、specart、autolist都是这个标签定义的别名扩展自不同属性的标签。功能说明:获取指定文档列表适用范围:封面模板、列表模板、文档模板基本语法:
  {dede:arclist typeid='' row='' col='' titlelen='' infolen=''
  imgwidth='' imgheight='' listtype='' orderby='' 关键字=''}
  底层模板(InnerText)
  {/dede:arclist} 属性说明:
  [1] typeid=''表示列ID,列表模板和文件模板中一般不需要指定。允许在封面模板中使用“,”表示多栏;
  [2] row='' 表示返回文档列表的总数;
  [3] col='' 表示显示多少列(默认为单列);
  [4] titlelen=''表示标题长度;
  [5] infolen='' 表示内容介绍的长度;
  [6] imgwidth='' 表示缩略图的宽度;
  [7] imgheight='' 表示缩略图高度;
  [8] type=''表示文件类型,为空值时为普通文件,不使用该属性,或type='all'
  § type='commend'时,表示推荐文档,相当于{dede:coolart}{/dede:coolart}
  § 当type='image'时,表示必须收录缩略图的文档,相当于{dede:imglist}{/dede:imglist}, {dede:imginfolist}{/dede:imginfolist}
  § 当type='spec'时,表示特殊主题,相当于mark {dede:specart}{/dede:specart}
  以上属性值可以组合使用,如:type='commend image'表示推荐图片文档
  [9] orderby=''表示排序方式,默认为senddate根据发布时间排列。
  § orderby='hot' 或 orderby='click' 表示按点击次数排序
  § orderby='pubdate' 按发布时间排列(即前台允许更改的时间值)
  § orderby='sortrank' 按 文章 的新排序等级排序(如果要使用顶行 文章,请使用此属性)
  § orderby='id' 排序 文章ID
  § orderby='postnum' 按 文章 评论数排序
  § orderby='rand' 随机获取指定条件的文档列表
  [10] orderway='' 取值为desc或asc,指定是降序排序还是按顺序排序,默认为降序。
  [11]keyword=''表示收录指定关键字的文档列表,多个关键字用“,”隔开
  [12] channelid='' 表示具体频道模型ID,内置频道:topic(-1), 文章(1), Atlas(2), Flash( 4),软件(3)
  [13]limit='start,end'表示记录的限制范围,row属性必须等于“end-start”,mysql的limit语句从0开始,如“limit 0,5”表示取对于前五条记录,“limit 5,5”表示从第五条记录中删除五条记录。使用该属性后,行属性将失效。
  [14] att='value' 表示自定义属性值
  [15] subday='天数' 表示文档的天数,通常用于获取指定天数的热门文档、推荐文档、热门评论文档等
  [16] partsort='列数'表示自动获取父列所有子列的列ID。该属性仅在标记为 {dede:autolist}{/dede:autolist} 时有效。
  底层模板字段:
  ID(同id),title,iscommend,color,typeid,ismake,description(同info),writer,shorttitle,memberid
  pubdate, senddate, arcrank, click, litpic (same as picname), typedir, typename,
  arcurl(与文件名相同)、typeurl、stime(发布日期的“0000-00-00”格式)、
  textlink,typelink,imglink,图像
  在:
  文本链接 = 标题
  类型链接 = 类型名称
  链接=
  
  图片 =
  
  字段调用方法:[field:varname/]
  喜欢:
  {dede:arclist infolen='100'}
  [字段:文本链接/]
  [字段:信息/]
  {/dede:arclist}
  注意:底层模板中的Field实现也是织梦标签的一种形式,所以支持使用PHP语法、Function扩展等功能
  例如:为当天发布的内容添加(新)标志
  [字段:发送日期运行php ='是']
  $ntime = 时间();
  $一天 = 3600 * 24;
  如果(($ntime-@我) 查看全部

  文章采集调用(dede官方的调用模板,至今不清楚调用依据!(一))
  首先,明确必须满足两个要求:
  1、调用指定的section
  2、调用文章来收录指定的关键字
  相关文档调用
  {dede:likeart titlelen='24' 行='10'}
  [字段:标题/]
  {/dede:likeart}
  注意:这是dede官方的调用模板,但是调用依据还不清楚!
  调用指定部分
  {dede:arclist typeid='??ĿID' row='10' titlelen='20'}
  [字段:文本链接/]
  {/dede:arclist}
  这是我想要实现的目标:
  指定栏目的调用(ID=4)相关新闻(关键词调用关键词或标题)
  {dede:arclist typeid='4' row='10' titlelen='20' 关键字=''}
  [字段:文本链接/]
  {/dede:arclist}
  代码 1
  
  效果一:
  
  代码 2:
  
  效果二:
  
  此时,如果你只是一个关键词,那就没问题了。以下键是我的 关键词 将要调用的:即keyword='{dede:field 或者我称之为标题
  关键字='{dede:field/}'
  但是,这很少使用,因为调用了模板。没有人希望所有 文章 都调用同一个关键字!
  博主推荐方法:
  -------------------------------------------------- ----------------------------------
  放置在 文章 模板页面中
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  表示取所有列中所有相关的文章(与当前文章的关键字相关),标题最大长度32,最大显示10,不显示缩略图.
  或者
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"Higher 3 Chinese")'/}
  你可以找到文章,其标题收录“大三中文”,或“大三”或“中文”
  例如,这一段:
  相关文章
  {dede:likeart titlelen='24' 行='10'}
  [字段:文本链接/]
  {/dede:likeart}
  只需将其更改为:
  相关文章
  {dede:field name='keywords' function='ShowKeyWordArc(0,32,10,0,"@me")'/}
  基于关键字的相关文章在用户体验和SEO方面非常好
  唯一的缺点是生成静态的时候会慢很多
  -------------------------------------------------- ------------------------------------------------
  附1:arclist中的关键字如何调用当前文档的关键字(dedecms织梦技术论坛)
  附2:{dede:arclist}的学习心得,调用文章或者软件的任意领域
  附上3、dedecms实现{dede:arclist keyword='[field:title/]'}的效果
  【Arclist标签】这个标签是Dedecms中最常用的标签,也叫free list标签,其中hotart、coolart、likeart、artlist、imglist、imginfolist、specart、autolist都是这个标签定义的别名扩展自不同属性的标签。功能说明:获取指定文档列表适用范围:封面模板、列表模板、文档模板基本语法:
  {dede:arclist typeid='' row='' col='' titlelen='' infolen=''
  imgwidth='' imgheight='' listtype='' orderby='' 关键字=''}
  底层模板(InnerText)
  {/dede:arclist} 属性说明:
  [1] typeid=''表示列ID,列表模板和文件模板中一般不需要指定。允许在封面模板中使用“,”表示多栏;
  [2] row='' 表示返回文档列表的总数;
  [3] col='' 表示显示多少列(默认为单列);
  [4] titlelen=''表示标题长度;
  [5] infolen='' 表示内容介绍的长度;
  [6] imgwidth='' 表示缩略图的宽度;
  [7] imgheight='' 表示缩略图高度;
  [8] type=''表示文件类型,为空值时为普通文件,不使用该属性,或type='all'
  § type='commend'时,表示推荐文档,相当于{dede:coolart}{/dede:coolart}
  § 当type='image'时,表示必须收录缩略图的文档,相当于{dede:imglist}{/dede:imglist}, {dede:imginfolist}{/dede:imginfolist}
  § 当type='spec'时,表示特殊主题,相当于mark {dede:specart}{/dede:specart}
  以上属性值可以组合使用,如:type='commend image'表示推荐图片文档
  [9] orderby=''表示排序方式,默认为senddate根据发布时间排列。
  § orderby='hot' 或 orderby='click' 表示按点击次数排序
  § orderby='pubdate' 按发布时间排列(即前台允许更改的时间值)
  § orderby='sortrank' 按 文章 的新排序等级排序(如果要使用顶行 文章,请使用此属性)
  § orderby='id' 排序 文章ID
  § orderby='postnum' 按 文章 评论数排序
  § orderby='rand' 随机获取指定条件的文档列表
  [10] orderway='' 取值为desc或asc,指定是降序排序还是按顺序排序,默认为降序。
  [11]keyword=''表示收录指定关键字的文档列表,多个关键字用“,”隔开
  [12] channelid='' 表示具体频道模型ID,内置频道:topic(-1), 文章(1), Atlas(2), Flash( 4),软件(3)
  [13]limit='start,end'表示记录的限制范围,row属性必须等于“end-start”,mysql的limit语句从0开始,如“limit 0,5”表示取对于前五条记录,“limit 5,5”表示从第五条记录中删除五条记录。使用该属性后,行属性将失效。
  [14] att='value' 表示自定义属性值
  [15] subday='天数' 表示文档的天数,通常用于获取指定天数的热门文档、推荐文档、热门评论文档等
  [16] partsort='列数'表示自动获取父列所有子列的列ID。该属性仅在标记为 {dede:autolist}{/dede:autolist} 时有效。
  底层模板字段:
  ID(同id),title,iscommend,color,typeid,ismake,description(同info),writer,shorttitle,memberid
  pubdate, senddate, arcrank, click, litpic (same as picname), typedir, typename,
  arcurl(与文件名相同)、typeurl、stime(发布日期的“0000-00-00”格式)、
  textlink,typelink,imglink,图像
  在:
  文本链接 = 标题
  类型链接 = 类型名称
  链接=
  
  图片 =
  
  字段调用方法:[field:varname/]
  喜欢:
  {dede:arclist infolen='100'}
  [字段:文本链接/]
  [字段:信息/]
  {/dede:arclist}
  注意:底层模板中的Field实现也是织梦标签的一种形式,所以支持使用PHP语法、Function扩展等功能
  例如:为当天发布的内容添加(新)标志
  [字段:发送日期运行php ='是']
  $ntime = 时间();
  $一天 = 3600 * 24;
  如果(($ntime-@我)

文章采集调用( 大型网站反而很少尤其尤其是门户网站的问题!(上))

采集交流优采云 发表了文章 • 0 个评论 • 107 次浏览 • 2022-02-03 22:20 • 来自相关话题

  文章采集调用(
大型网站反而很少尤其尤其是门户网站的问题!(上))
  
  我学习 Python 已经有一段时间了。在学习的过程中,我不断地实践所学的各种知识。我做的最多的是爬虫,也就是简单的数据采集,里面有采集图片(这个是最多的……),有的下载电影,有的和学习有关,比如爬虫ppt模板,当然我也写过诸如收发邮件、自动登录论坛发帖、验证码相关操作等等!
  这些脚本有一个共同点,它们都与网络相关,并且总是使用一些获取链接的方法。我在这里总结一下,分享给正在学习的人。
  安装相关
  其实python的各个版本差别不大,不用太担心使用3.6或者3.7.
  至于我们经常使用的库,建议大家先了解安装哪些库,安装哪些库。
  有的同学会纠结,库装不上。这个推荐大家搜索一下:python whl 是第一个。其中每个库都有不同的版本。选择对应的下载,用pip安装文件的全路径安装。!
  例如:pip install d:\requests_download-0.1.2-py2.py3-none-any.whl
  最基本的抓取站——获取源码
  导入请求#导入库
  html = requests.get(url)#获取源代码
  html.encoding='utf-8'#指定收录中文的网页源码的编码格式,具体格式一般存在于源码的meta标签中
  对于静态网页
  网站反“反爬”
  大部分网站(各种中小网站)都需要你的代码有headers信息,如果没有,会直接拒绝你的访问!大型网站很少,尤其是门户网站网站,如新浪新闻、今日头条图集、百度图片爬虫等。@>!
  对于有防爬措施的网站,大部分都可以按照添加UA信息的顺序添加到headers数据(字典格式)中——添加HOST和Referer(防盗链)信息!代码格式 requestts.get(url,headers=headers)
  UA信息就是浏览器信息,告诉对方我们是什么浏览器。通常,我们可以采集相关信息来制作一个UA池。我们可以在需要的时候调用,也可以随机调用,防止被网站发现,注意是的,如果是移动端,一定要注意移动端网页的区别和 PC 终端。例如,我们更喜欢移动端作为微博爬虫。其抗爬网能力远低于PC端。@网站 反爬很厉害,可以到手机端(手机登录复制url),说不定有惊喜!
  
  HOST信息,网站的主机信息,这个一般不变
  Referer信息,这是“防盗链”的关键信息。简单来说就是你来到当前页面的地方,破解也很简单,把url放进去就行了!
  如果上面的方法还是绕不过反爬的话,那就比较麻烦了,把所有信息都写在headers里。
  终极反“反爬”:学硒,少年!
  保存文件
  其实可以简单的分为两类:字符串内容保存和其他内容保存!简单2行代码即可解决
  
  a+是文本末尾的附加书写方式,适合字符串内容的书写。注意排版。也可以在'a+'后面加上参数encoding='utf-8'来指定保存文本的编码格式
  wb为二进制写入方式,适用于找到对象的真实下载地址后,以二进制方式下载文件
  
  待续
  篇幅有限,本来想写完的,但是有人说我写的太多了,没人看。. . 这很尴尬!那就先写到这里吧!
  也是时候重新整理一下以下内容了,大概是:自动登录(cookie池)和登录、ip代理、验证码(这是个大项目)以及scarpy框架的一些注意事项。
  有其他技能或者问题的同学也可以在评论区写,一起讨论吧!
  写在最后
  喜欢这篇文章文章或者认为这篇文章文章对你有帮助的读者可以关注或者点播转发,私信小编001获取最新python数据和0副本2018年小编整理的。基础入门教程,欢迎初学者和高级朋友 查看全部

  文章采集调用(
大型网站反而很少尤其尤其是门户网站的问题!(上))
  
  我学习 Python 已经有一段时间了。在学习的过程中,我不断地实践所学的各种知识。我做的最多的是爬虫,也就是简单的数据采集,里面有采集图片(这个是最多的……),有的下载电影,有的和学习有关,比如爬虫ppt模板,当然我也写过诸如收发邮件、自动登录论坛发帖、验证码相关操作等等!
  这些脚本有一个共同点,它们都与网络相关,并且总是使用一些获取链接的方法。我在这里总结一下,分享给正在学习的人。
  安装相关
  其实python的各个版本差别不大,不用太担心使用3.6或者3.7.
  至于我们经常使用的库,建议大家先了解安装哪些库,安装哪些库。
  有的同学会纠结,库装不上。这个推荐大家搜索一下:python whl 是第一个。其中每个库都有不同的版本。选择对应的下载,用pip安装文件的全路径安装。!
  例如:pip install d:\requests_download-0.1.2-py2.py3-none-any.whl
  最基本的抓取站——获取源码
  导入请求#导入库
  html = requests.get(url)#获取源代码
  html.encoding='utf-8'#指定收录中文的网页源码的编码格式,具体格式一般存在于源码的meta标签中
  对于静态网页
  网站反“反爬”
  大部分网站(各种中小网站)都需要你的代码有headers信息,如果没有,会直接拒绝你的访问!大型网站很少,尤其是门户网站网站,如新浪新闻、今日头条图集、百度图片爬虫等。@>!
  对于有防爬措施的网站,大部分都可以按照添加UA信息的顺序添加到headers数据(字典格式)中——添加HOST和Referer(防盗链)信息!代码格式 requestts.get(url,headers=headers)
  UA信息就是浏览器信息,告诉对方我们是什么浏览器。通常,我们可以采集相关信息来制作一个UA池。我们可以在需要的时候调用,也可以随机调用,防止被网站发现,注意是的,如果是移动端,一定要注意移动端网页的区别和 PC 终端。例如,我们更喜欢移动端作为微博爬虫。其抗爬网能力远低于PC端。@网站 反爬很厉害,可以到手机端(手机登录复制url),说不定有惊喜!
  
  HOST信息,网站的主机信息,这个一般不变
  Referer信息,这是“防盗链”的关键信息。简单来说就是你来到当前页面的地方,破解也很简单,把url放进去就行了!
  如果上面的方法还是绕不过反爬的话,那就比较麻烦了,把所有信息都写在headers里。
  终极反“反爬”:学硒,少年!
  保存文件
  其实可以简单的分为两类:字符串内容保存和其他内容保存!简单2行代码即可解决
  
  a+是文本末尾的附加书写方式,适合字符串内容的书写。注意排版。也可以在'a+'后面加上参数encoding='utf-8'来指定保存文本的编码格式
  wb为二进制写入方式,适用于找到对象的真实下载地址后,以二进制方式下载文件
  
  待续
  篇幅有限,本来想写完的,但是有人说我写的太多了,没人看。. . 这很尴尬!那就先写到这里吧!
  也是时候重新整理一下以下内容了,大概是:自动登录(cookie池)和登录、ip代理、验证码(这是个大项目)以及scarpy框架的一些注意事项。
  有其他技能或者问题的同学也可以在评论区写,一起讨论吧!
  写在最后
  喜欢这篇文章文章或者认为这篇文章文章对你有帮助的读者可以关注或者点播转发,私信小编001获取最新python数据和0副本2018年小编整理的。基础入门教程,欢迎初学者和高级朋友

文章采集调用(打开servlet-api源码可见继承和response获取方式)

采集交流优采云 发表了文章 • 0 个评论 • 140 次浏览 • 2022-02-03 22:19 • 来自相关话题

  文章采集调用(打开servlet-api源码可见继承和response获取方式)
  为了从请求中提取body和header,使代码的改动尽可能小,进入容器的请求必须被统一拦截,否则代码必须嵌入到所有的HttpServlet实现类中。在这里,我们需要再次感谢 servlet 说明符为我们提供的过滤机制。
  该规范指定过滤器是一段可重用的代码,用于转换 HTTP 请求、响应和标头信息的内容。过滤器通常不会为请求创建响应,而是修改或调整请求和响应。其中,filter主要提供四种拦截方式:
  这里我们只使用 REQUEST 模式。配置过滤器后,我们可以从过滤器的doFilter方法中获取HttpServletRequest和HttpServletResponse(简称请求和响应)。
  获取标题
  在上面,我们通过过滤机制获得了请求和响应。打开对应的源码实现,我们可以找到如下API:
  
  规范为我们提供了一个 API 来直接获取标头。通过结合 getHeaderNames() 和 getHeader(String name) 方法,我们可以轻松获取请求和响应中的标头。
  得到身体
  获取请求体和响应体的方法大致相同。这里以request为例,后面会调整差异。
  从请求API中我们可以发现body在java中是以ServletInputStream的形式存储的,而ServletInputStream是一个继承的InputStream。如果我们直接读取,用户获取到的body会是空的(因为InputStream只能读取一次),除非可以把指针放回去)。这里需要用到servlet的包装机制。
  Servlet 中的包装器
  有的人可能不会用到requestWrapper和responseWrapper,这里简单介绍一下。wrapper 是通过继承 servlet 规范中的 HttpServletResponseWrapper 和 HttpServletRequestWrapper 实现的装饰模式。相当于请求和响应的一个shell,类似于java中的代理,这样操作请求和响应的所有动作都会经过我们自定义的wrapper,使得在请求中重复获取body成为可能和回应。
  编写自己的包装器
  我们以 request 为例来说明如何编写自定义包装器。打开servlet-api源码可以看到HttpServletRequestWrapper继承了ServletRequestWrapper,实现了HttpServletRequest接口。
  
  并且大部分方法已经在 ServletRequestWrapper 中为我们实现了。
  
  我们只需要重写我们关心的几个方法,例如:getInputStream和getReader等。
  
  当用户尝试调用 getReader 或 getInputStream 时,我们将其替换为自己的流,并额外提供一个 getContent() 方法来提前读取 StringBuilder 或 byte[] 中的正文内容进行提取。
  编写好自定义包装器后,我们可以将其放入我们上面定义的过滤器中,替换原来的请求。然后把用户的请求变成我们的requestWrapper。
  优化提取逻辑
  上面提到的方法等价于预先读取收录body的inputStream,并将其存储在一个中间byte[]或StringBuilder中。当用户调用 getInputStream 时,byte[] 或 StringBuilder 被转换为 inputStream 返回给用户。如果用户根本不关心这个http请求的body,也就是用户根本不使用这个请求的body,那么我们提前把它读出来,相当于做了无用功(浪费宝贵的 CPU 时间和内存资源)。如何保证inputStream在用户使用时是只读的,当用户或后续逻辑多次获取body时,是我们的优化目标。
  对于答案,我们继续从源码中寻找。既然我们的数据在 inputStream 中,我们就跟着源码看看是怎么读取的。在servlet规范中,inputStream被封装成ServletInputStream,ServletInputStream提供了readLine方法。往里面看,可以看到它们都调用了inputStream中的read方法,如下图:
  
  既然read方法是一个统一的入口,那我们只要自定义一个ServletInputStream,重写里面的read()方法,就可以修改所有的read方法吗?答案是肯定的。只要用户调用了read方法,我们就悄悄地把我们关心的内容复制一份,这样我们只在用户使用body的时候才去采集。
  下一步是如何确保用户调用 read 多次,我们总是只读取一次。在这里,我们需要使用一个 AtomicBoolean 标志,当执行完整读取时将其设置为 true,否则设置为 false。最终效果如下:
  
  举一反三
  在这里,我们使用 servlet 规范中的过滤器和包装器机制来获取进入我们容器(tomcat)的所有 http 请求的主体和标头。这个能力在我们实际生产中可以进一步扩展,比如:我们需要在客户端加密一些敏感数据然后在服务端进行统一解密,格式化客户端发送的数据格式等等。可以限制你的是你的想象力。希望本次技术分享对您以后的工作和生活有所帮助。
  总结
  读完这篇文章,读者应该可以在不影响原代码的情况下,通过简单的代码获取所有进入容器的http请求的body和header。虽然可能需要适配一些特殊的技术栈,比如如果项目中使用了jersey,参数等信息以application/x-www-form-urlencoded的形式传递,而服务端不使用@ FormParam注解获取参数,那么我们获取body后,用户将无法获取参数;例如,如何区分媒体类型,如果是图像,则不会被提取。但我们已经验证,这条路是可行的,而且是成功的一半。 查看全部

  文章采集调用(打开servlet-api源码可见继承和response获取方式)
  为了从请求中提取body和header,使代码的改动尽可能小,进入容器的请求必须被统一拦截,否则代码必须嵌入到所有的HttpServlet实现类中。在这里,我们需要再次感谢 servlet 说明符为我们提供的过滤机制。
  该规范指定过滤器是一段可重用的代码,用于转换 HTTP 请求、响应和标头信息的内容。过滤器通常不会为请求创建响应,而是修改或调整请求和响应。其中,filter主要提供四种拦截方式:
  这里我们只使用 REQUEST 模式。配置过滤器后,我们可以从过滤器的doFilter方法中获取HttpServletRequest和HttpServletResponse(简称请求和响应)。
  获取标题
  在上面,我们通过过滤机制获得了请求和响应。打开对应的源码实现,我们可以找到如下API:
  
  规范为我们提供了一个 API 来直接获取标头。通过结合 getHeaderNames() 和 getHeader(String name) 方法,我们可以轻松获取请求和响应中的标头。
  得到身体
  获取请求体和响应体的方法大致相同。这里以request为例,后面会调整差异。
  从请求API中我们可以发现body在java中是以ServletInputStream的形式存储的,而ServletInputStream是一个继承的InputStream。如果我们直接读取,用户获取到的body会是空的(因为InputStream只能读取一次),除非可以把指针放回去)。这里需要用到servlet的包装机制。
  Servlet 中的包装器
  有的人可能不会用到requestWrapper和responseWrapper,这里简单介绍一下。wrapper 是通过继承 servlet 规范中的 HttpServletResponseWrapper 和 HttpServletRequestWrapper 实现的装饰模式。相当于请求和响应的一个shell,类似于java中的代理,这样操作请求和响应的所有动作都会经过我们自定义的wrapper,使得在请求中重复获取body成为可能和回应。
  编写自己的包装器
  我们以 request 为例来说明如何编写自定义包装器。打开servlet-api源码可以看到HttpServletRequestWrapper继承了ServletRequestWrapper,实现了HttpServletRequest接口。
  
  并且大部分方法已经在 ServletRequestWrapper 中为我们实现了。
  
  我们只需要重写我们关心的几个方法,例如:getInputStream和getReader等。
  
  当用户尝试调用 getReader 或 getInputStream 时,我们将其替换为自己的流,并额外提供一个 getContent() 方法来提前读取 StringBuilder 或 byte[] 中的正文内容进行提取。
  编写好自定义包装器后,我们可以将其放入我们上面定义的过滤器中,替换原来的请求。然后把用户的请求变成我们的requestWrapper。
  优化提取逻辑
  上面提到的方法等价于预先读取收录body的inputStream,并将其存储在一个中间byte[]或StringBuilder中。当用户调用 getInputStream 时,byte[] 或 StringBuilder 被转换为 inputStream 返回给用户。如果用户根本不关心这个http请求的body,也就是用户根本不使用这个请求的body,那么我们提前把它读出来,相当于做了无用功(浪费宝贵的 CPU 时间和内存资源)。如何保证inputStream在用户使用时是只读的,当用户或后续逻辑多次获取body时,是我们的优化目标。
  对于答案,我们继续从源码中寻找。既然我们的数据在 inputStream 中,我们就跟着源码看看是怎么读取的。在servlet规范中,inputStream被封装成ServletInputStream,ServletInputStream提供了readLine方法。往里面看,可以看到它们都调用了inputStream中的read方法,如下图:
  
  既然read方法是一个统一的入口,那我们只要自定义一个ServletInputStream,重写里面的read()方法,就可以修改所有的read方法吗?答案是肯定的。只要用户调用了read方法,我们就悄悄地把我们关心的内容复制一份,这样我们只在用户使用body的时候才去采集。
  下一步是如何确保用户调用 read 多次,我们总是只读取一次。在这里,我们需要使用一个 AtomicBoolean 标志,当执行完整读取时将其设置为 true,否则设置为 false。最终效果如下:
  
  举一反三
  在这里,我们使用 servlet 规范中的过滤器和包装器机制来获取进入我们容器(tomcat)的所有 http 请求的主体和标头。这个能力在我们实际生产中可以进一步扩展,比如:我们需要在客户端加密一些敏感数据然后在服务端进行统一解密,格式化客户端发送的数据格式等等。可以限制你的是你的想象力。希望本次技术分享对您以后的工作和生活有所帮助。
  总结
  读完这篇文章,读者应该可以在不影响原代码的情况下,通过简单的代码获取所有进入容器的http请求的body和header。虽然可能需要适配一些特殊的技术栈,比如如果项目中使用了jersey,参数等信息以application/x-www-form-urlencoded的形式传递,而服务端不使用@ FormParam注解获取参数,那么我们获取body后,用户将无法获取参数;例如,如何区分媒体类型,如果是图像,则不会被提取。但我们已经验证,这条路是可行的,而且是成功的一半。

文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)

采集交流优采云 发表了文章 • 0 个评论 • 120 次浏览 • 2022-02-01 08:04 • 来自相关话题

  文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)
  文章采集调用有:知乎api、搜狗搜索等渠道。实际上在正式回答前,我是不知道知乎api的,于是花了一个下午搞清楚了。[调用知乎api的教程(持续更新)](-union-china.html)为了照顾到国内用户的使用习惯,我只有调用苹果的api的分享特性。
  2017年6月23日,我遇到这个问题后,马上访问知乎app客户端发现并没有什么问题,于是我给知乎app做了本地代码抓包,验证没有问题,但是随后就发现知乎有多处服务异常,其中包括appstore应用信息不正确,我得去appstore问问苹果,也可能是我手机问题,然后就联系appstore客服。苹果客服说是app被review了,需要重新修改后重审,随后我就联系了反馈渠道,收到了积极响应,app客服说抓包时机是先抓取appstore信息,再抓取app本地信息,在抓取全部app和网页的信息,现在苹果就在和知乎协商这个问题,期间app客服还收到苹果漏洞的报道,苹果客服对我这个问题很负责,说过段时间苹果会给知乎反馈,顺利通过。现在一直都安心不少。附图我通过抓包问苹果客服问题。
  我来补充一下。应该是内存管理策略的问题。苹果服务器代码写入后每一个线程是只会被处理一次。这就是你看到的闪退,是因为你正在通过web服务器抓包分享。但是苹果服务器并没有review你的app是否能正常下载。会先给你分享一个无效的app然后再去扫描一次app。这样就会造成闪退。 查看全部

  文章采集调用(调用知乎api、搜狗搜索等渠道,苹果客服被review了)
  文章采集调用有:知乎api、搜狗搜索等渠道。实际上在正式回答前,我是不知道知乎api的,于是花了一个下午搞清楚了。[调用知乎api的教程(持续更新)](-union-china.html)为了照顾到国内用户的使用习惯,我只有调用苹果的api的分享特性。
  2017年6月23日,我遇到这个问题后,马上访问知乎app客户端发现并没有什么问题,于是我给知乎app做了本地代码抓包,验证没有问题,但是随后就发现知乎有多处服务异常,其中包括appstore应用信息不正确,我得去appstore问问苹果,也可能是我手机问题,然后就联系appstore客服。苹果客服说是app被review了,需要重新修改后重审,随后我就联系了反馈渠道,收到了积极响应,app客服说抓包时机是先抓取appstore信息,再抓取app本地信息,在抓取全部app和网页的信息,现在苹果就在和知乎协商这个问题,期间app客服还收到苹果漏洞的报道,苹果客服对我这个问题很负责,说过段时间苹果会给知乎反馈,顺利通过。现在一直都安心不少。附图我通过抓包问苹果客服问题。
  我来补充一下。应该是内存管理策略的问题。苹果服务器代码写入后每一个线程是只会被处理一次。这就是你看到的闪退,是因为你正在通过web服务器抓包分享。但是苹果服务器并没有review你的app是否能正常下载。会先给你分享一个无效的app然后再去扫描一次app。这样就会造成闪退。

文章采集调用(selenium爬取流程安装自动模块,代理批量采集 )

采集交流优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-02-01 07:02 • 来自相关话题

  文章采集调用(selenium爬取流程安装自动模块,代理批量采集
)
  硒爬行过程
  安装python selenium自动模块,使用selenium中的webdriver驱动浏览器获取cookies登录微信公众号后台;
  使用webdriver功能需要安装对应浏览器的驱动插件。
  注意:谷歌浏览器版本和chromedriver需要对应,否则启动时会报错。
  微信公众号登录地址:
  微信公众号文章的接口地址可以在微信公众号后台创建,可以从超链接函数中获取:
  搜索公众号名称
  获取要爬取的公众号fakeid
  选择要爬取的公众号,获取文章的接口地址
  文章列表翻页和内容获取
  
  AnyProxy 代理批量采集
  1、微信客户端:可以是安装了微信应用的手机,也可以是电脑上的安卓模拟器。
  2、微信个人账号:采集的内容,不仅需要微信客户端,采集还需要微信个人账号。
  3、本地代理服务器系统:将公众号历史消息页面中的文章列表通过Anyproxy代理服务器发送到自己的服务器。
  4、文章列表分析存储系统,分析文章列表并构建采集队列,实现批量采集内容。
  Fiddler 设置代理并抓包
  通过捕获和分析多个账户,可以确定:
  _biz:这个14位的字符串是每个公众号的“id”,可以从搜狗的微信平台获取。
  uin:与访客相关,微信ID
  key:与访问的公众号相关
  步:
  1、编写按钮向导脚本,在手机端自动点击公众号文章的列表页面,即“查看历史消息”;
  2、使用fiddler代理劫持​​手机访问,将URL转发到php编写的本地网页;
  3、将接收到的URL备份到php网页上的数据库中;
  4、使用python从数据库中检索URL,然后进行正常爬取。
  潜在问题:
  如果只是想爬文章内容,貌似没有访问频率限制,但是如果想爬读点赞数,一定频率后返回值会变空。
  付费平台
  例如,如果你只是想看数据,你可以不花钱只看每日清单。如果你需要访问自己的系统,他们也提供了一个api接口
  3 项目步骤
  3.1基本原则
  目标爬取微信平台网站收录大部分优质微信公众号文章,会定期更新。经过测试,发现对爬虫更加友好。
  1、网站页面排版和排版规则,不同公众号以链接中的账号区分
  公众号采集下的2、文章也有定时翻页:id号每翻一页+12
  所以过程思路是
  获取预查询微信公众号ID(不是直接显示的名字,而是信息名片中的ID号,一般由数字和字母组成)
  请求一个html页面判断公众号是否被更改收录
  如果没有收录,页面显示结果为:404 页面不存在,可以直接用正则表达式匹配提示信息
  正则匹配查找目标公众号的最大页数收录文章
  解析请求的页面,提取 文章 链接和标题文本
  保存信息提取结果
  调用pdfkit和wkhtmltopdf转换网页
  3.2环境
  win10(64位)
  蜘蛛(蟒蛇3.6)
  安装转换工具包 wkhtmltopdf
  要求
  pdf工具包
  3.3 公众号信息检索
  通过向目标url发起requset请求,获取页面的html信息,然后调用正则方法匹配两条信息
  1、公众号是否存在
  2、如果存在,最大文章收录页数是多少
  
  当公众号存在时,直接调用request解析目标请求链接。
  
  注意目标爬虫网站必须添加headers,否则会直接拒绝访问
  3.4 正则解析、提取链接和文章标题
  以下代码用于从 html 文本中解析链接和标题文本信息
  
  3.5 自动跳转页面
  下面的代码通过循环递增赋值来改变url中的页码参数
  
  3.6去除标题中的非法字符
  因为windows下的file命令,有些字符不能使用,所以需要使用正则剔除
  itle = re.sub('[/:*?"|]', '', info.loc[indexs]['title'])
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  
  3.8 生成的 PDF 结果
  
  4 结果显示
  
  ​
   查看全部

  文章采集调用(selenium爬取流程安装自动模块,代理批量采集
)
  硒爬行过程
  安装python selenium自动模块,使用selenium中的webdriver驱动浏览器获取cookies登录微信公众号后台;
  使用webdriver功能需要安装对应浏览器的驱动插件。
  注意:谷歌浏览器版本和chromedriver需要对应,否则启动时会报错。
  微信公众号登录地址:
  微信公众号文章的接口地址可以在微信公众号后台创建,可以从超链接函数中获取:
  搜索公众号名称
  获取要爬取的公众号fakeid
  选择要爬取的公众号,获取文章的接口地址
  文章列表翻页和内容获取
  
  AnyProxy 代理批量采集
  1、微信客户端:可以是安装了微信应用的手机,也可以是电脑上的安卓模拟器。
  2、微信个人账号:采集的内容,不仅需要微信客户端,采集还需要微信个人账号。
  3、本地代理服务器系统:将公众号历史消息页面中的文章列表通过Anyproxy代理服务器发送到自己的服务器。
  4、文章列表分析存储系统,分析文章列表并构建采集队列,实现批量采集内容。
  Fiddler 设置代理并抓包
  通过捕获和分析多个账户,可以确定:
  _biz:这个14位的字符串是每个公众号的“id”,可以从搜狗的微信平台获取。
  uin:与访客相关,微信ID
  key:与访问的公众号相关
  步:
  1、编写按钮向导脚本,在手机端自动点击公众号文章的列表页面,即“查看历史消息”;
  2、使用fiddler代理劫持​​手机访问,将URL转发到php编写的本地网页;
  3、将接收到的URL备份到php网页上的数据库中;
  4、使用python从数据库中检索URL,然后进行正常爬取。
  潜在问题:
  如果只是想爬文章内容,貌似没有访问频率限制,但是如果想爬读点赞数,一定频率后返回值会变空。
  付费平台
  例如,如果你只是想看数据,你可以不花钱只看每日清单。如果你需要访问自己的系统,他们也提供了一个api接口
  3 项目步骤
  3.1基本原则
  目标爬取微信平台网站收录大部分优质微信公众号文章,会定期更新。经过测试,发现对爬虫更加友好。
  1、网站页面排版和排版规则,不同公众号以链接中的账号区分
  公众号采集下的2、文章也有定时翻页:id号每翻一页+12
  所以过程思路是
  获取预查询微信公众号ID(不是直接显示的名字,而是信息名片中的ID号,一般由数字和字母组成)
  请求一个html页面判断公众号是否被更改收录
  如果没有收录,页面显示结果为:404 页面不存在,可以直接用正则表达式匹配提示信息
  正则匹配查找目标公众号的最大页数收录文章
  解析请求的页面,提取 文章 链接和标题文本
  保存信息提取结果
  调用pdfkit和wkhtmltopdf转换网页
  3.2环境
  win10(64位)
  蜘蛛(蟒蛇3.6)
  安装转换工具包 wkhtmltopdf
  要求
  pdf工具包
  3.3 公众号信息检索
  通过向目标url发起requset请求,获取页面的html信息,然后调用正则方法匹配两条信息
  1、公众号是否存在
  2、如果存在,最大文章收录页数是多少
  
  当公众号存在时,直接调用request解析目标请求链接。
  
  注意目标爬虫网站必须添加headers,否则会直接拒绝访问
  3.4 正则解析、提取链接和文章标题
  以下代码用于从 html 文本中解析链接和标题文本信息
  
  3.5 自动跳转页面
  下面的代码通过循环递增赋值来改变url中的页码参数
  
  3.6去除标题中的非法字符
  因为windows下的file命令,有些字符不能使用,所以需要使用正则剔除
  itle = re.sub('[/:*?"|]', '', info.loc[indexs]['title'])
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  3.7将html转换为PDF
  使用pandas的read_csv函数读取爬取的csv文件,循环遍历“link”、“title”、“date”
  然后调用pdfkit函数转换生成的PDF文件
  
  3.8 生成的 PDF 结果
  
  4 结果显示
  
  ​
  

文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])

采集交流优采云 发表了文章 • 0 个评论 • 157 次浏览 • 2022-01-31 06:05 • 来自相关话题

  文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])
  2021-06-21转载地址
  ◆◆10
  拥护萌 2013/01/30 用户互动14,482 次浏览
  
  本文内容
  [隐藏]
  常萌最近一直在思考WordPress大学的设计,特别是如何做好注册用户体验。考虑添加一个文章采集功能,让大家可以采集自己喜欢的文章,然后在页面上生成一个列表,在侧边栏显示最近采集的文章,这样,你以后可以轻松找到你需要的文章。于是我找到了 WP Favorite Posts,一个 WordPress文章 采集插件,试用了一下,感觉还不错。
  WP采集帖子简介
  WP Favorite Posts是一款不错的WordPress文章采集插件,可以在文章页面添加采集按钮,用户可以点击采集自己的文章,并可以将自己展示在一个特殊页面采集文章,还支持“最近采集文章(每个人都看到自己的)”和“全站最多采集文章”两个小工具。
  最值得一提的 WP Favorite Posts 通过浏览器 cookie 和数据库存储用户的采集数据,也就是说游客也可以采集 文章,当然游客的采集数据是通过 cookie 保存的,如果删除浏览器的cookie,采集数据会丢失,所以建议采集后注册用户,可以保存在数据库中,不会丢失。
  WP Favorite Posts 安装设置
  1.在后台插件安装页面搜索WP采集贴在线安装,或下载WP采集贴。
  2.启用后,在设置-采集帖子中,可以设置相关设置(如果不懂英文,就用翻译工具翻译)
  
  可设置各种提示
  
  设置好后就可以使用插件了。
  如何使用 WP 采集帖子
  1.如何显示“采集链接”
  您可以选择在第一张图片的界面中自动插入文章页眉或页脚,或者在single.php或page.php的主题文件中使用如下代码自定义位置:
  1
  如果您只想在某些文章 中显示采集链接,则可以在编辑文章 时将以下短代码添加到文章:
  1
  [wpfp-link]
  2.小部件调用。您可以在外观中看到两个可用的小部件 - 小部件,您可以自己设置它们。
  3.添加采集列表页面。这个页面是用来显示所有用户采集的页面文章。可以在页面中新建一个页面,然后在内容中加入如下调用代码,显示用户的采集列表(每个用户只能看到自己的采集列表)
  1
  [wp-favorite-posts]
  
  WP 最喜欢的帖子高级提示(备用)
  以下是我在论坛上看到的一些高级功能,但还没有测试过。记录它们以备将来使用。
  1.调用文章的采集夹
  最简单的方法是循环使用下面的代码,直接调用:
  1
  如果上述方法不起作用,可以考虑以下方法:
  在主题的functions.php中添加以下代码
  1
2
3
4
5
6
7
8
9
10
11
12
13
  function wpfp_get_current_count() {
global $wpdb;
$current_post = get_the_ID();
$query = "SELECT post_id, meta_value, post_status FROM $wpdb->postmeta";
$query .= " LEFT JOIN $wpdb->posts ON post_id=$wpdb->posts.ID";
$query .= " WHERE post_status='publish' AND meta_key='wpfp_favorites' AND post_id = '".$current_post."'";
$results = $wpdb->get_results($query);
if ($results) {
foreach ($results as $o):
echo $o->meta_value;
endforeach;
}else {echo( '0' );}
}
  使用下面的代码调用
  1
  2.另一种调用采集夹列表的方法
  如果想直接在主题文件中修改显示采集列表,可以使用如下调用函数
  1
  3.获取一个用户的采集数量
  该插件默认使用收录的 wpfp-page-template.php 文件来显示采集夹列表。如果想在列表上方显示采集的数量,可以参考以下代码:
  1
2
3
4
5
6
   if ($favorite_post_ids){
$user_favorite_count = count($favorite_post_ids);
echo '<p>您已收藏了 '.$user_favorite_count.' 篇文章';
}else{
echo '您目前还没有收藏任何文章!';
}</p>
  4.删除文章后统计不准确
  网站删除了一些文章,如果用户之前采集过这些文章,他们的采集数据中仍然收录这些文章的ID,导致采集的统计不准确。
  
  找到插件的wpfp-page-template.php文件,添加如下代码:
  1
2
3
4
5
6
7
8
9
10
   /*remove deleted posts cmhello*/
foreach ($favorite_post_ids as $id) {
if ( FALSE === get_post_status( $id ) ) {
$favorite_post_ids = array_diff($favorite_post_ids, array($id));
$favorite_post_ids = array_values($favorite_post_ids);
wpfp_update_user_meta($favorite_post_ids);
}
}
$favorite_post_ids = wpfp_get_user_meta();
/*//remove deleted posts cmhello*/
  
  分类:
  技术要点:
  相关文章: 查看全部

  文章采集调用(WPFavoritePosts文章收藏插件目录[隐藏篇])
  2021-06-21转载地址
  ◆◆10
  拥护萌 2013/01/30 用户互动14,482 次浏览
  
  本文内容
  [隐藏]
  常萌最近一直在思考WordPress大学的设计,特别是如何做好注册用户体验。考虑添加一个文章采集功能,让大家可以采集自己喜欢的文章,然后在页面上生成一个列表,在侧边栏显示最近采集的文章,这样,你以后可以轻松找到你需要的文章。于是我找到了 WP Favorite Posts,一个 WordPress文章 采集插件,试用了一下,感觉还不错。
  WP采集帖子简介
  WP Favorite Posts是一款不错的WordPress文章采集插件,可以在文章页面添加采集按钮,用户可以点击采集自己的文章,并可以将自己展示在一个特殊页面采集文章,还支持“最近采集文章(每个人都看到自己的)”和“全站最多采集文章”两个小工具。
  最值得一提的 WP Favorite Posts 通过浏览器 cookie 和数据库存储用户的采集数据,也就是说游客也可以采集 文章,当然游客的采集数据是通过 cookie 保存的,如果删除浏览器的cookie,采集数据会丢失,所以建议采集后注册用户,可以保存在数据库中,不会丢失。
  WP Favorite Posts 安装设置
  1.在后台插件安装页面搜索WP采集贴在线安装,或下载WP采集贴。
  2.启用后,在设置-采集帖子中,可以设置相关设置(如果不懂英文,就用翻译工具翻译)
  
  可设置各种提示
  
  设置好后就可以使用插件了。
  如何使用 WP 采集帖子
  1.如何显示“采集链接”
  您可以选择在第一张图片的界面中自动插入文章页眉或页脚,或者在single.php或page.php的主题文件中使用如下代码自定义位置:
  1
  如果您只想在某些文章 中显示采集链接,则可以在编辑文章 时将以下短代码添加到文章:
  1
  [wpfp-link]
  2.小部件调用。您可以在外观中看到两个可用的小部件 - 小部件,您可以自己设置它们。
  3.添加采集列表页面。这个页面是用来显示所有用户采集的页面文章。可以在页面中新建一个页面,然后在内容中加入如下调用代码,显示用户的采集列表(每个用户只能看到自己的采集列表)
  1
  [wp-favorite-posts]
  
  WP 最喜欢的帖子高级提示(备用)
  以下是我在论坛上看到的一些高级功能,但还没有测试过。记录它们以备将来使用。
  1.调用文章的采集夹
  最简单的方法是循环使用下面的代码,直接调用:
  1
  如果上述方法不起作用,可以考虑以下方法:
  在主题的functions.php中添加以下代码
  1
2
3
4
5
6
7
8
9
10
11
12
13
  function wpfp_get_current_count() {
global $wpdb;
$current_post = get_the_ID();
$query = "SELECT post_id, meta_value, post_status FROM $wpdb->postmeta";
$query .= " LEFT JOIN $wpdb->posts ON post_id=$wpdb->posts.ID";
$query .= " WHERE post_status='publish' AND meta_key='wpfp_favorites' AND post_id = '".$current_post."'";
$results = $wpdb->get_results($query);
if ($results) {
foreach ($results as $o):
echo $o->meta_value;
endforeach;
}else {echo( '0' );}
}
  使用下面的代码调用
  1
  2.另一种调用采集夹列表的方法
  如果想直接在主题文件中修改显示采集列表,可以使用如下调用函数
  1
  3.获取一个用户的采集数量
  该插件默认使用收录的 wpfp-page-template.php 文件来显示采集夹列表。如果想在列表上方显示采集的数量,可以参考以下代码:
  1
2
3
4
5
6
   if ($favorite_post_ids){
$user_favorite_count = count($favorite_post_ids);
echo '<p>您已收藏了 '.$user_favorite_count.' 篇文章';
}else{
echo '您目前还没有收藏任何文章!';
}</p>
  4.删除文章后统计不准确
  网站删除了一些文章,如果用户之前采集过这些文章,他们的采集数据中仍然收录这些文章的ID,导致采集的统计不准确。
  
  找到插件的wpfp-page-template.php文件,添加如下代码:
  1
2
3
4
5
6
7
8
9
10
   /*remove deleted posts cmhello*/
foreach ($favorite_post_ids as $id) {
if ( FALSE === get_post_status( $id ) ) {
$favorite_post_ids = array_diff($favorite_post_ids, array($id));
$favorite_post_ids = array_values($favorite_post_ids);
wpfp_update_user_meta($favorite_post_ids);
}
}
$favorite_post_ids = wpfp_get_user_meta();
/*//remove deleted posts cmhello*/
  
  分类:
  技术要点:
  相关文章:

文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)

采集交流优采云 发表了文章 • 0 个评论 • 99 次浏览 • 2022-01-28 15:22 • 来自相关话题

  文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)
  本文介绍如何在应用程序中使用客户端javascript脚本来提高程序的执行效率,实现更多的功能。
  一、ASP.Net 和 Javascript
  .Net是微软下一代战略的核心,ASP.Net是.Net战略在Web开发中的具体实现。它继承了 ASP 的简单易用,克服了 ASP 程序结构差,难以阅读和理解的缺点。特别是服务器端控件和事件驱动模式的引入,使得Web应用程序的开发更接近于过去桌面程序的开发。
  在介绍 ASP.Net 的各种文章 和书籍中,重点是服务器控件和 .Net Framework SDK,因为这是 ASP.Net 最新和最具革命性的改进;相反,过去在Web开发中占据重要地位的客户端脚本Javascript(包括VBScript)却很少被提及。似乎使用服务器端程序,不再需要客户端脚本。但是,服务器端程序需要浏览器和 Web 服务器之间的交互。对于ASP.Net来说,就是一个页​​面提交,需要来回发送大量的数据,输入验证或者删除确认等很多任务都是完全可以的。用 Javascript 实现。因此,在 ASP.Net 中如何使用 Javascript 还是有必要探索的。
  二、Javascript应用实例
  1.在页面上的一个服务器控件中添加一个Javascript事件
  最后生成的服务器控件还是普通的HTML,比如生成输入文本。表单中的每个 HTML 控件都有自己的 Javascript 事件,例如 Textbox 有 onchange 事件,Button 有 onclick 事件,Listbox 有 onchange 事件等。要将客户端事件添加到服务器控件,请使用 Attributes 属性。Attributes 属性是所有服务器控件都有的属性,用于在最终生成的 HTML 中添加一些自定义标签。假设Web Form上有一个保存按钮btnSave,你想在用户点击这个按钮时提示用户是否真的要保存(例如,一旦保存就不能恢复等),你应该添加Page_Load 事件的以下代码:
  如果不是 page.isPostBack() 那么
  btnSave.Attributes.Add("onclick","Javascript:return Confirm('Are you sure to save?');")
  万一
  注意,return 是不可避免的,否则即使用户点击取消,数据仍然会被保存。
  2.为Datagrid中的每一行添加Javascript事件
  假设Datagrid的每一行都有一个删除按钮,我们想在用户点击这个按钮时提示用户是否真的要删除这条记录,以防用户点击了错误的行,或者只是不小心点击了删除按钮.
  不管删除按钮的名字是什么,都不能像上例那样直接引用,因为每一行都有这样一个按钮,它是Datagrid中的一个子控件。在这种情况下,您需要使用 Datagrid 的 OnItemDataBound 事件。OnItemDataBound 事件发生在Datagrid 的每一行数据绑定到Datagrid 之后(即,一行触发一次)。首先在Datagrid的声明中加入如下代码:
  …这里的列定义
  这里说明当 OnItemDataBound 事件发生时调用 ItemDataBound 方法,并在代码隐藏文件中添加该方法的定义:
  Sub ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
  如果 e.Item.ItemType ListItemType.Header 和 e.Item.ItemType ListItemType.Footer 那么
  Dim oDeleteButton As LinkBut​​ton = e.Item.Cells(5).Controls(0)
  oDeleteButton.Attributes("onclick") = "javascript:return Confirm ('Are you sure you want to delete" &amp; DataBinder.Eval(e.Item.DataItem, "m_sName") &amp; "?')"
  万一
  结束子
  由于Datagrid的页眉行和页脚行也会触发这个事件,首先确定触发这个事件的行不是页眉行和页脚行。这里假设Delete按钮位于Datagrid的第6列(第一列是0),Datagrid的Datasource收录一个名为“m_sName”的列
  3、编辑状态下Datagrid中控件的引用
  Datagrid 的内置编辑功能使其成为记录字段较少时的一种编辑方法。用户无需进入单独的页面编辑记录,直接点击编辑按钮即可进入当前行的编辑模式。另一方面,有一些Javascript程序需要引用控件的名称。例如,很多程序在要求用户输入日期时提供了日期控件来保证日期格式的有效性。当用户单击控件图标时,将弹出一个新窗口供用户选择日期。此时需要将显示日期的文本框的 ID 提供给新窗口,以便在用户选择日期时将值回填到文本框中。
  如果是普通的服务器文本框控件,其ID与生成的HTML输入框的ID相同;但是在Datagrid的编辑状态下,两个ID不一样(原因同上例),需要使用控件的ClientID属性。
  Protected Sub ItemEdit(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
  将 sDateCtrl 调暗为字符串
  sDateCtrl = grd1. 项目(e.Item.ItemIndex)。单元格(2). FindControl("txtDate") . ClientID
  结束子
  这里假设 ItemEdit 方法是 Dategrid 的 OnItemEdit 事件处理程序,并且 Datagrid 的第三列收录一个名为 txtDate 的服务器文本框控件。
  4.参考ASP.Net自动生成的Javascript程序
  所谓“服务器端控件”是针对开发者的,在生成的HTML源程序中没有服务器端和客户端的区别,都是标准的HTML、DHTML和Javascript。它响应用户输入是因为每个控件的事件处理程序最终都会生成一个脚本,该脚本重新提交页面以使 Web 服务器有机会再次响应和处理。通常我们不必知道这个脚本是什么或者直接调用这个脚本,但是在某些情况下,适当地调用这个脚本可以简化很多工作。请看以下两个例子。
  ● 单击数据网格中的任意位置以选择一行
  Datagrid 提供了一个内置的选择按钮,当单击该按钮时选择当前行(您可以设置 SelectedItemStyle 属性以使当前行具有不同的外观)。然而,用户可能更习惯于点击任何位置来选择一行。完全自己实现这个功能是相当麻烦的。一个好主意是添加一个选择按钮,但将列隐藏,并在单击任何行时调用该按钮生成的 Javascript。
  Sub Item_Bound(ByVal sender As Object, ByVal e As DataGridItemEventArgs )
  将 itemType 调暗为 ListItemType
  itemType = CType(e.Item.ItemType, ListItemType)
  If (itemType ListItemType.Header) 和 _
  (itemType ListItemType.Footer) 和 _
  (itemType ListItemType.Separator) 然后
  Dim oSelect As LinkBut​​ton = CType(e.Item.Cells(5).Controls(0), LinkBut​​ton)
  e.Item.Attributes("onclick") = Page.GetPostBackClientHyperlink(oSelect, "")
  结束子
  这假设选择按钮在第 6 列。e.Item 代表一行,从生成的 HTML 的角度来看,每个都添加了一个 onclick 事件。Page.GetPostBackClientHyperLink方法返回页面中LinkBut​​ton控件生成的客户端脚本,其中第一个参数为Linkbutton控件,第二个参数为传递给该控件的参数,一般为空。如果不是LinkBut​​ton控件,还有一个类似的函数GetPostBackClientEvent,读者可以参考MSDN。
  ● 服务器生成的脚本与手动添加的脚本冲突
  服务器控件的服务器事件一般对应客户端控件的相应事件。例如,Dropdownlist 的 SelectedIndexChanged 事件对应 HTML 的 onchange 事件。如果要手动添加onchange事件,客户端会产生两个onchange,浏览器会忽略一个。比如,每当Dropdownlist中的某个选项发生变化时,用户都想保​​存到数据库中(虽然不是很常见,但是有这样的需求),但同时也想提醒用户是否真的有必要保存。显然,保存的代码应该放在SelectedIndexChanged事件中,提醒工作应该手动加上onchange事件。结果是只能执行两个 onchanges 中的一个。
  Page_Load 方法如下:
  将 sCmd 调暗为字符串
  sCmd=Page.GetPostBackClientHyperlink(btnUpdate, "")
  如果不是 page.isPostback 那么
  下拉列表1.Attributes.add("onchange","ConfirmUpdate(""" &amp; sCmd &amp; """)")
  万一
  ConfirmUpdate函数如下
  Javascript eval 函数在这里用于调用收录在字符串中的命令。需要注意的是,收录命令的字符串不能用单引号括起来,因为自动生成的脚本中收录单引号,所以这里用两个双引号来表示字符串本身的双引号。
  三、结束语
  以上简要讨论了在ASP.Net中插入Javascript的几种情况。在服务器程序中合理插入客户端Javascript脚本,可以提高程序的运行效率,提供更友好的用户界面。
  参考示例: 查看全部

  文章采集调用(ASP.Net中如何利用客户端的javascript脚本提高程序执行效率)
  本文介绍如何在应用程序中使用客户端javascript脚本来提高程序的执行效率,实现更多的功能。
  一、ASP.Net 和 Javascript
  .Net是微软下一代战略的核心,ASP.Net是.Net战略在Web开发中的具体实现。它继承了 ASP 的简单易用,克服了 ASP 程序结构差,难以阅读和理解的缺点。特别是服务器端控件和事件驱动模式的引入,使得Web应用程序的开发更接近于过去桌面程序的开发。
  在介绍 ASP.Net 的各种文章 和书籍中,重点是服务器控件和 .Net Framework SDK,因为这是 ASP.Net 最新和最具革命性的改进;相反,过去在Web开发中占据重要地位的客户端脚本Javascript(包括VBScript)却很少被提及。似乎使用服务器端程序,不再需要客户端脚本。但是,服务器端程序需要浏览器和 Web 服务器之间的交互。对于ASP.Net来说,就是一个页​​面提交,需要来回发送大量的数据,输入验证或者删除确认等很多任务都是完全可以的。用 Javascript 实现。因此,在 ASP.Net 中如何使用 Javascript 还是有必要探索的。
  二、Javascript应用实例
  1.在页面上的一个服务器控件中添加一个Javascript事件
  最后生成的服务器控件还是普通的HTML,比如生成输入文本。表单中的每个 HTML 控件都有自己的 Javascript 事件,例如 Textbox 有 onchange 事件,Button 有 onclick 事件,Listbox 有 onchange 事件等。要将客户端事件添加到服务器控件,请使用 Attributes 属性。Attributes 属性是所有服务器控件都有的属性,用于在最终生成的 HTML 中添加一些自定义标签。假设Web Form上有一个保存按钮btnSave,你想在用户点击这个按钮时提示用户是否真的要保存(例如,一旦保存就不能恢复等),你应该添加Page_Load 事件的以下代码:
  如果不是 page.isPostBack() 那么
  btnSave.Attributes.Add("onclick","Javascript:return Confirm('Are you sure to save?');")
  万一
  注意,return 是不可避免的,否则即使用户点击取消,数据仍然会被保存。
  2.为Datagrid中的每一行添加Javascript事件
  假设Datagrid的每一行都有一个删除按钮,我们想在用户点击这个按钮时提示用户是否真的要删除这条记录,以防用户点击了错误的行,或者只是不小心点击了删除按钮.
  不管删除按钮的名字是什么,都不能像上例那样直接引用,因为每一行都有这样一个按钮,它是Datagrid中的一个子控件。在这种情况下,您需要使用 Datagrid 的 OnItemDataBound 事件。OnItemDataBound 事件发生在Datagrid 的每一行数据绑定到Datagrid 之后(即,一行触发一次)。首先在Datagrid的声明中加入如下代码:
  …这里的列定义
  这里说明当 OnItemDataBound 事件发生时调用 ItemDataBound 方法,并在代码隐藏文件中添加该方法的定义:
  Sub ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)
  如果 e.Item.ItemType ListItemType.Header 和 e.Item.ItemType ListItemType.Footer 那么
  Dim oDeleteButton As LinkBut​​ton = e.Item.Cells(5).Controls(0)
  oDeleteButton.Attributes("onclick") = "javascript:return Confirm ('Are you sure you want to delete" &amp; DataBinder.Eval(e.Item.DataItem, "m_sName") &amp; "?')"
  万一
  结束子
  由于Datagrid的页眉行和页脚行也会触发这个事件,首先确定触发这个事件的行不是页眉行和页脚行。这里假设Delete按钮位于Datagrid的第6列(第一列是0),Datagrid的Datasource收录一个名为“m_sName”的列
  3、编辑状态下Datagrid中控件的引用
  Datagrid 的内置编辑功能使其成为记录字段较少时的一种编辑方法。用户无需进入单独的页面编辑记录,直接点击编辑按钮即可进入当前行的编辑模式。另一方面,有一些Javascript程序需要引用控件的名称。例如,很多程序在要求用户输入日期时提供了日期控件来保证日期格式的有效性。当用户单击控件图标时,将弹出一个新窗口供用户选择日期。此时需要将显示日期的文本框的 ID 提供给新窗口,以便在用户选择日期时将值回填到文本框中。
  如果是普通的服务器文本框控件,其ID与生成的HTML输入框的ID相同;但是在Datagrid的编辑状态下,两个ID不一样(原因同上例),需要使用控件的ClientID属性。
  Protected Sub ItemEdit(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)
  将 sDateCtrl 调暗为字符串
  sDateCtrl = grd1. 项目(e.Item.ItemIndex)。单元格(2). FindControl("txtDate") . ClientID
  结束子
  这里假设 ItemEdit 方法是 Dategrid 的 OnItemEdit 事件处理程序,并且 Datagrid 的第三列收录一个名为 txtDate 的服务器文本框控件。
  4.参考ASP.Net自动生成的Javascript程序
  所谓“服务器端控件”是针对开发者的,在生成的HTML源程序中没有服务器端和客户端的区别,都是标准的HTML、DHTML和Javascript。它响应用户输入是因为每个控件的事件处理程序最终都会生成一个脚本,该脚本重新提交页面以使 Web 服务器有机会再次响应和处理。通常我们不必知道这个脚本是什么或者直接调用这个脚本,但是在某些情况下,适当地调用这个脚本可以简化很多工作。请看以下两个例子。
  ● 单击数据网格中的任意位置以选择一行
  Datagrid 提供了一个内置的选择按钮,当单击该按钮时选择当前行(您可以设置 SelectedItemStyle 属性以使当前行具有不同的外观)。然而,用户可能更习惯于点击任何位置来选择一行。完全自己实现这个功能是相当麻烦的。一个好主意是添加一个选择按钮,但将列隐藏,并在单击任何行时调用该按钮生成的 Javascript。
  Sub Item_Bound(ByVal sender As Object, ByVal e As DataGridItemEventArgs )
  将 itemType 调暗为 ListItemType
  itemType = CType(e.Item.ItemType, ListItemType)
  If (itemType ListItemType.Header) 和 _
  (itemType ListItemType.Footer) 和 _
  (itemType ListItemType.Separator) 然后
  Dim oSelect As LinkBut​​ton = CType(e.Item.Cells(5).Controls(0), LinkBut​​ton)
  e.Item.Attributes("onclick") = Page.GetPostBackClientHyperlink(oSelect, "")
  结束子
  这假设选择按钮在第 6 列。e.Item 代表一行,从生成的 HTML 的角度来看,每个都添加了一个 onclick 事件。Page.GetPostBackClientHyperLink方法返回页面中LinkBut​​ton控件生成的客户端脚本,其中第一个参数为Linkbutton控件,第二个参数为传递给该控件的参数,一般为空。如果不是LinkBut​​ton控件,还有一个类似的函数GetPostBackClientEvent,读者可以参考MSDN。
  ● 服务器生成的脚本与手动添加的脚本冲突
  服务器控件的服务器事件一般对应客户端控件的相应事件。例如,Dropdownlist 的 SelectedIndexChanged 事件对应 HTML 的 onchange 事件。如果要手动添加onchange事件,客户端会产生两个onchange,浏览器会忽略一个。比如,每当Dropdownlist中的某个选项发生变化时,用户都想保​​存到数据库中(虽然不是很常见,但是有这样的需求),但同时也想提醒用户是否真的有必要保存。显然,保存的代码应该放在SelectedIndexChanged事件中,提醒工作应该手动加上onchange事件。结果是只能执行两个 onchanges 中的一个。
  Page_Load 方法如下:
  将 sCmd 调暗为字符串
  sCmd=Page.GetPostBackClientHyperlink(btnUpdate, "")
  如果不是 page.isPostback 那么
  下拉列表1.Attributes.add("onchange","ConfirmUpdate(""" &amp; sCmd &amp; """)")
  万一
  ConfirmUpdate函数如下
  Javascript eval 函数在这里用于调用收录在字符串中的命令。需要注意的是,收录命令的字符串不能用单引号括起来,因为自动生成的脚本中收录单引号,所以这里用两个双引号来表示字符串本身的双引号。
  三、结束语
  以上简要讨论了在ASP.Net中插入Javascript的几种情况。在服务器程序中合理插入客户端Javascript脚本,可以提高程序的运行效率,提供更友好的用户界面。
  参考示例:

文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))

采集交流优采云 发表了文章 • 0 个评论 • 96 次浏览 • 2022-01-25 09:01 • 来自相关话题

  文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))
  智能标签调用多表多模型调用文章
  1、调用多模型的最新文章
  [e:loop={'select * from (
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_movie where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_news where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_photo where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_flash where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_article where newstime) a order by newstime desc limit 10',10,24,1}]
  [/e:循环]
  Empire cms 从多个表中调用最新信息。演示代码为默认数据表下全站最新10张图片信息。您可以根据需要附加条件,实现全站点击、全站头条、全站推荐等。
  -------------------------------------------------- -------------------------------------------
  2、调用多模型的最新文章
  [e:循环={'
  select title,titleurl,titlepic from [!db.pre!]ecms_photo Union All
  select title,titleurl,titlepic from [!db.pre!]ecms_download Union All
  从 [!db.pre!]ecms_news',0,24,0}] 中选择标题、标题网址、标题图片
  [/e:循环]
  注:以上调用为三种模型中的文章(图片模型:photo,下载模型:download,新闻模型:news)
  三个模型通过“Union All”连接调用
  如果使用指定列: where classid in(46,47,51),
  如果调用建议附加:并且isgood=1,
  如果附加了指定的调用次数:limit 10 查看全部

  文章采集调用(灵动标签调用多表多模型(图)模型调用文章(组图))
  智能标签调用多表多模型调用文章
  1、调用多模型的最新文章
  [e:loop={'select * from (
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_movie where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_news where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_photo where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_flash where newstime union
  select id,classid,titleurl,filename,title,newstime,titlepic from phome_ecms_article where newstime) a order by newstime desc limit 10',10,24,1}]
  [/e:循环]
  Empire cms 从多个表中调用最新信息。演示代码为默认数据表下全站最新10张图片信息。您可以根据需要附加条件,实现全站点击、全站头条、全站推荐等。
  -------------------------------------------------- -------------------------------------------
  2、调用多模型的最新文章
  [e:循环={'
  select title,titleurl,titlepic from [!db.pre!]ecms_photo Union All
  select title,titleurl,titlepic from [!db.pre!]ecms_download Union All
  从 [!db.pre!]ecms_news',0,24,0}] 中选择标题、标题网址、标题图片
  [/e:循环]
  注:以上调用为三种模型中的文章(图片模型:photo,下载模型:download,新闻模型:news)
  三个模型通过“Union All”连接调用
  如果使用指定列: where classid in(46,47,51),
  如果调用建议附加:并且isgood=1,
  如果附加了指定的调用次数:limit 10

文章采集调用(文章页面内容建设的不良现状及解决办法)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-25 08:16 • 来自相关话题

  文章采集调用(文章页面内容建设的不良现状及解决办法)
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,也伤害了 网站 自己。文章 页面也可以使用随机调用,让每篇文章有文章 展示和曝光的机会
  
  图 25545-1:
  如何做好文章内容页面的SEO推广,面向营销的网站建设完成后也需要做SEO推广。@网站列表,网站详细页面也优化。面向营销的网站内容页面,文章页面也需要优化。
  内容页面建设现状不佳:在文章页面内容的创建中,很多站长经常使用的两种方法是采集和伪原创,既是投机取巧又是省时的行为. 但长此以往,无异于饮毒解渴网站。
  我们创建网站并吸引客户浏览。我们的宗旨是为客户提供能够创造价值的内容。如果存在大量的采集内容,并且所有网站都相同,如果是伪原创特别是软件实现&lt; @伪原创,由于同义词替换、格式打乱等行为,呈现的内容会产生误导,更何况不值得浏览。
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,还伤害了 网站 自己。
  内容页面是SEO推广的好方法之一。因为可以添加很多锚文本,所以被很多站长广泛使用,也是做长尾关键词的好方法。这里要提醒站长们,锚链的&lt;关键词要自然广泛,并不是所有的锚链都是一样的,容易导致过度优化。建议使用不同的关键词,指向不同的相关页面,做好长尾词的相关优化。
  1)很多网站 流量来自文章 页面。确保在标题、描述、关键词 中收录 关键词 或用户正在搜索的短语。
  SEO推广关键词密度是指搜索关键词出现的频率。举个例子:一篇文章200字的文章,你的关键词中出现的字数除以总字数的20,也就是说关键词@的密度&gt; 为 10%。在不影响用户体验的前提下,关键词密度尽量不高。关键词 的密度必须合理。文章页面关键词推荐浓度2-8%更自然。
  阅读文章的用户一般需要浏览几篇文章文章才能找到自己想要的详细答案。所以推荐相关的文章可以降低网页的跳出率。
  我们还要适当引导顾客,多做一些符合大众口味的热点文章。热点文章一般是查看相关信息后对其他新闻感兴趣的用户,这也是降低网页跳出率的一种方式。一个方法。
  5)文章页面也可以使用随机调用,让每个文章都有机会展示和曝光,不一定是最新的文章。
  SEO 随机推广一个名为 网站 的页面,并随机显示 文章。搜索引擎蜘蛛每次在爬网站的过程中都能发现不同的东西,可以知道这个页面并没有什么变化,会定期更新。建议固定页面更新频率。这将吸引更多的蜘蛛来抢我们的 网站。提供企业网站的收录量,从而为企业带来更多的免费流量。 查看全部

  文章采集调用(文章页面内容建设的不良现状及解决办法)
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,也伤害了 网站 自己。文章 页面也可以使用随机调用,让每篇文章有文章 展示和曝光的机会
  
  图 25545-1:
  如何做好文章内容页面的SEO推广,面向营销的网站建设完成后也需要做SEO推广。@网站列表,网站详细页面也优化。面向营销的网站内容页面,文章页面也需要优化。
  内容页面建设现状不佳:在文章页面内容的创建中,很多站长经常使用的两种方法是采集和伪原创,既是投机取巧又是省时的行为. 但长此以往,无异于饮毒解渴网站。
  我们创建网站并吸引客户浏览。我们的宗旨是为客户提供能够创造价值的内容。如果存在大量的采集内容,并且所有网站都相同,如果是伪原创特别是软件实现&lt; @伪原创,由于同义词替换、格式打乱等行为,呈现的内容会产生误导,更何况不值得浏览。
  文章页面内容的构造应该是原创。采集 和 伪原创 不仅伤害了访问者,还伤害了 网站 自己。
  内容页面是SEO推广的好方法之一。因为可以添加很多锚文本,所以被很多站长广泛使用,也是做长尾关键词的好方法。这里要提醒站长们,锚链的&lt;关键词要自然广泛,并不是所有的锚链都是一样的,容易导致过度优化。建议使用不同的关键词,指向不同的相关页面,做好长尾词的相关优化。
  1)很多网站 流量来自文章 页面。确保在标题、描述、关键词 中收录 关键词 或用户正在搜索的短语。
  SEO推广关键词密度是指搜索关键词出现的频率。举个例子:一篇文章200字的文章,你的关键词中出现的字数除以总字数的20,也就是说关键词@的密度&gt; 为 10%。在不影响用户体验的前提下,关键词密度尽量不高。关键词 的密度必须合理。文章页面关键词推荐浓度2-8%更自然。
  阅读文章的用户一般需要浏览几篇文章文章才能找到自己想要的详细答案。所以推荐相关的文章可以降低网页的跳出率。
  我们还要适当引导顾客,多做一些符合大众口味的热点文章。热点文章一般是查看相关信息后对其他新闻感兴趣的用户,这也是降低网页跳出率的一种方式。一个方法。
  5)文章页面也可以使用随机调用,让每个文章都有机会展示和曝光,不一定是最新的文章。
  SEO 随机推广一个名为 网站 的页面,并随机显示 文章。搜索引擎蜘蛛每次在爬网站的过程中都能发现不同的东西,可以知道这个页面并没有什么变化,会定期更新。建议固定页面更新频率。这将吸引更多的蜘蛛来抢我们的 网站。提供企业网站的收录量,从而为企业带来更多的免费流量。

文章采集调用(QT+openCV操做的这部分,其余还没时间看 )

采集交流优采云 发表了文章 • 0 个评论 • 91 次浏览 • 2022-01-24 11:16 • 来自相关话题

  文章采集调用(QT+openCV操做的这部分,其余还没时间看
)
  今天写的QT+openCV实现了拍照拍照功能。应用
  我在互联网上采集了很多信息。 QT 没有用于操作相机的特殊类。这个必须自己写。网上也有很多关于openCV和V4l的介绍。因为我的项目要在window下开发,所以选择了openCV。因为之前没用过openCV,所以只看了openCVS摄像头的操作这部分,剩下的没来得及看。功能
  openCV:学习
  第一次下载来自 2.3.1。安装后发现没有lib库,所以选择了2.1
  的ui
  openCV中文学习pdf:这个
  现在,我们开始详细介绍如何在QT中直播采集相机数据。温泉
  打开QTcreator(我用的是QT中文版2.3).net
  创建一个新的小部件项目指针
  
  在界面上放两个标签,显示相机拍摄的数据和照片采集。或者
  
  编辑camaraget.h文件视频
  #ifndef CAMARAGET_H
#define CAMARAGET_H

#include
#include
#include // 设置采集数据的间隔时间

#include //包含opencv库头文件
#include

namespace Ui {
class camaraGet;
}

class camaraGet : public QWidget
{
Q_OBJECT

public:
explicit camaraGet(QWidget *parent = 0);
~camaraGet();

private slots:
void openCamara(); // 打开摄像头
void readFarme(); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照

private:
Ui::camaraGet *ui;
QTimer *timer;
QImage *imag;
CvCapture *cam;// 视频获取结构, 用来做为视频获取函数的一个参数
IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
};

#endif // CAMARAGET_H
  编辑 camaraget.cpp
  #include "camaraget.h"
#include "ui_camaraget.h"

camaraGet::camaraGet(QWidget *parent) :
QWidget(parent),
ui(new Ui::camaraGet)
{
ui->setupUi(this);

cam = NULL;
timer = new QTimer(this);
imag = new QImage(); // 初始化

/*信号和槽*/
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
}

/******************************
********* 打开摄像头 ***********
*******************************/
void camaraGet::openCamara()
{
cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频

timer->start(33); // 开始计时,超时则发出timeout()信号
}

/*********************************
********* 读取摄像头信息 ***********
**********************************/
void camaraGet::readFarme()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*************************
********* 拍照 ***********
**************************/
void camaraGet::takingPictures()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧

// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);

ui->label_2->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*******************************
***关闭摄像头,释放资源,必须释放***
********************************/
void camaraGet::closeCamara()
{
timer->stop(); // 中止读取数据。

cvReleaseCapture(&cam);//释放内存;
}

camaraGet::~camaraGet()
{
delete ui;
}
  好了,所有代码都OK了(当然项目建好的时候会生成main.cpp,不用改),但是现在点击运行,还是会报错,为什么由于尚未收录 openCV 库。
  在 *.pro 文件中添加:
  INCLUDEPATH+=C:\OpenCV2.1\include\opencv
   LIBS += C:\OpenCV2.1\lib\highgui210.lib \
   C:\OpenCV2.1\lib\cxcore210.lib \
   C:\OpenCV2.1\lib\cv210.lib
  OK,大功告成,运行后,在widget中点击打开摄像头,就可以看到自己了。运行后的效果:
  
  后来发现这个效果不是很好,于是改了:改后的运行效果也贴出来:
  我改了一句:
  QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
  改成了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();
   查看全部

  文章采集调用(QT+openCV操做的这部分,其余还没时间看
)
  今天写的QT+openCV实现了拍照拍照功能。应用
  我在互联网上采集了很多信息。 QT 没有用于操作相机的特殊类。这个必须自己写。网上也有很多关于openCV和V4l的介绍。因为我的项目要在window下开发,所以选择了openCV。因为之前没用过openCV,所以只看了openCVS摄像头的操作这部分,剩下的没来得及看。功能
  openCV:学习
  第一次下载来自 2.3.1。安装后发现没有lib库,所以选择了2.1
  的ui
  openCV中文学习pdf:这个
  现在,我们开始详细介绍如何在QT中直播采集相机数据。温泉
  打开QTcreator(我用的是QT中文版2.3).net
  创建一个新的小部件项目指针
  
  在界面上放两个标签,显示相机拍摄的数据和照片采集。或者
  
  编辑camaraget.h文件视频
  #ifndef CAMARAGET_H
#define CAMARAGET_H

#include
#include
#include // 设置采集数据的间隔时间

#include //包含opencv库头文件
#include

namespace Ui {
class camaraGet;
}

class camaraGet : public QWidget
{
Q_OBJECT

public:
explicit camaraGet(QWidget *parent = 0);
~camaraGet();

private slots:
void openCamara(); // 打开摄像头
void readFarme(); // 读取当前帧信息
void closeCamara(); // 关闭摄像头。
void takingPictures(); // 拍照

private:
Ui::camaraGet *ui;
QTimer *timer;
QImage *imag;
CvCapture *cam;// 视频获取结构, 用来做为视频获取函数的一个参数
IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
};

#endif // CAMARAGET_H
  编辑 camaraget.cpp
  #include "camaraget.h"
#include "ui_camaraget.h"

camaraGet::camaraGet(QWidget *parent) :
QWidget(parent),
ui(new Ui::camaraGet)
{
ui->setupUi(this);

cam = NULL;
timer = new QTimer(this);
imag = new QImage(); // 初始化

/*信号和槽*/
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));
connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));
connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
}

/******************************
********* 打开摄像头 ***********
*******************************/
void camaraGet::openCamara()
{
cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频

timer->start(33); // 开始计时,超时则发出timeout()信号
}

/*********************************
********* 读取摄像头信息 ***********
**********************************/
void camaraGet::readFarme()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧
// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*************************
********* 拍照 ***********
**************************/
void camaraGet::takingPictures()
{
frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧

// 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不一样的摄像头用不一样的格式。
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);

ui->label_2->setPixmap(QPixmap::fromImage(image)); // 将图片显示到label上
}

/*******************************
***关闭摄像头,释放资源,必须释放***
********************************/
void camaraGet::closeCamara()
{
timer->stop(); // 中止读取数据。

cvReleaseCapture(&cam);//释放内存;
}

camaraGet::~camaraGet()
{
delete ui;
}
  好了,所有代码都OK了(当然项目建好的时候会生成main.cpp,不用改),但是现在点击运行,还是会报错,为什么由于尚未收录 openCV 库。
  在 *.pro 文件中添加:
  INCLUDEPATH+=C:\OpenCV2.1\include\opencv
   LIBS += C:\OpenCV2.1\lib\highgui210.lib \
   C:\OpenCV2.1\lib\cxcore210.lib \
   C:\OpenCV2.1\lib\cv210.lib
  OK,大功告成,运行后,在widget中点击打开摄像头,就可以看到自己了。运行后的效果:
  
  后来发现这个效果不是很好,于是改了:改后的运行效果也贴出来:
  我改了一句:
  QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
  改成了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();
  

文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-23 02:19 • 来自相关话题

  文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)
  dedecms非常灵活,可以根据关键词、文章标题调用文章,提高内容之间的相关性,增加页面权重。要实现这个功能,主要使用likearticle标签。此标签只能在内容页面上使用。默认情况下无法调用自定义附加字段,但经常使用调用附加表字段的功能。修改方法如下:
  打开 /include/taglib/likearticle.lib.php 并找到
  
$row['templeturl'] = $GLOBALS['cfg_templeturl'];
  在下面添加代码
  
$addfile = $refObj->ChannelUnit->ChannelInfos["listfields"]; //获取文章模型的自定义字段列表
if($addfile){
$addfiles = explode(",",$addfile); //拆分成数组
$len = count($addfiles);
for($j=0;$jFields[''.$fname.''];
}
}
  调用自定义附加字段的其他修改方法
  
{dede:likeartlist row='10'}
]
<p>
[field:id runphp='yes']
$aid = @me;
$row = $GLOBALS['dsql']->GetOne("Select 字段名 From `dede_addon11` where aid='$aid' "); //根据实际需要修改附加表
@me = cn_substr(strip_tags("{$row['字段名']}"),600);
[/field:id]


{/dede:likearticle}
</p>
  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。 查看全部

  文章采集调用(非常灵活提高内容之间的调用自定义附加字段的其他修改方法)
  dedecms非常灵活,可以根据关键词、文章标题调用文章,提高内容之间的相关性,增加页面权重。要实现这个功能,主要使用likearticle标签。此标签只能在内容页面上使用。默认情况下无法调用自定义附加字段,但经常使用调用附加表字段的功能。修改方法如下:
  打开 /include/taglib/likearticle.lib.php 并找到
  
$row['templeturl'] = $GLOBALS['cfg_templeturl'];
  在下面添加代码
  
$addfile = $refObj->ChannelUnit->ChannelInfos["listfields"]; //获取文章模型的自定义字段列表
if($addfile){
$addfiles = explode(",",$addfile); //拆分成数组
$len = count($addfiles);
for($j=0;$jFields[''.$fname.''];
}
}
  调用自定义附加字段的其他修改方法
  
{dede:likeartlist row='10'}
]
<p>
[field:id runphp='yes']
$aid = @me;
$row = $GLOBALS['dsql']->GetOne("Select 字段名 From `dede_addon11` where aid='$aid' "); //根据实际需要修改附加表
@me = cn_substr(strip_tags("{$row['字段名']}"),600);
[/field:id]


{/dede:likearticle}
</p>
  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。

文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar )

采集交流优采云 发表了文章 • 0 个评论 • 135 次浏览 • 2022-01-22 18:03 • 来自相关话题

  文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar
)
  在开源活动LinuxCon + ContainerCon + CloudOpen China(简称LC3))上,阿里云CDN团队分享了开源系统和应用采集软件Tsar背景、设计思路和使用方法,模块开发和未来规划。
  其实是阿里巴巴在做系统或者应用监控的时候的一个思路。队友在实际使用过程中比较舒服,软件的扩展性、稳定性、易用性也比较好,所以目前全机都可以使用。Deployment作为基础的监控代理,提供稳定的数据支持,同时也是对外开源的。
  沙皇的背景
  对于在线SA/PE/R&amp;D,他在开发和部署软件的时候,需要注意软件的运行情况。他需要去上面看看整个服务器的CPU/内存/网络/IO等基本指标是否OK。找出这些指标的一些软件瓶颈和针对性的优化。其实现在市面上有很多类似的软件,都有一定的特殊性,可能只是采集的某一个,每个软件采集都有不同的指标,这些的用法指标时间不一致。所以对用户的要求非常高,需要知道如何使用所有的监控软件,对于排查在线问题非常不方便。这也是我们最初的痛点。我们发现我们拥有所有的数据,但是如何链接和使用它很不方便。所以,我们想出了沙皇的想法。
  
  下图是现在网上很多命令的使用。整个Linux站的每一层都有一些对应的命令。运维等用户的学习成本非常高,不利于我们统一监控。
  
  需求和解决方案
  因此,我们最初的要求是有一个易于使用的采集软件,具有完整的基础数据,最好是应用程序数据。因为刚才列出的指标都是通用指标,但是我们有应用软件,所以我们想知道应用软件的一些数据,比如QPS和响应时间。目前的开源软件无法支持,业务需要编写采集工具进行数据采集和监控。
  另外,我们希望在数据之间做一些数据关联。比如当前CPU高,是否会带来其他一些数据指标的波动?需要对这些指标进行比较才能确定问题。
  同时,必须对数据进行过滤,离线实时查看,本地长期存储,远程发送,方便中心进行数据分析和挖掘。
  有了这些需求,我们的解决方案就是模仿Sar,它本身就是一个系统活动报告,实现了系统指标的采集,我们在它的基础上做了一些扩展。除了系统级的数据采集,Tsar还可以进行应用级的采集,模块化,支持扩展。例如,采集 现在有十个指标。如果还有其他应用指标和业务数据要到采集,可以很方便的在Tsar中写一个模块到采集。它还支持简单的报警和远程发送。
  设计和使用
  沙皇的原则很简单。它主要利用动态库的特性。我们每个采集模块都会实现一些功能,比如采集函数,分析处理函数,注册时提供的模块。基础字段,比如模块名,模块收录的字段,字段从哪里来采集,采集之后怎么处理和输出,这些函数都注册在Tsar框架中,每个循环到采集 调用这些指令的函数时,就可以完成采集的处理和整个数据的输出。
  整个模块的注册和执行流程如下:
  
  下图是Tsar的功能大图,底部是系统计数器和软件界面。每个具体的模块都是基于采集,参考Sar实现了很多系统指标。此外,还为应用软件提供了LVS、Nginx等对比。通用应用软件模块。
  
  在上述采集的过程中,会对模块进行一些过滤处理,并执行各个模块的采集函数来获取数据。根据格式化,框架将数据格式化并保存到/var/log/tsar.data。我们采集把所有的原创数据,以文件的形式存储起来。与Sar有区别。Tsar 中的字段是可读的,Sar 看不到含义。
  数据采集到达后,支持发送到远端,比如发送到网络接口,或者发送到MySql、Nagios等。另外,数据展示分为两部分,分别是分为实时显示和历史显示。实时显示需要每秒查看指标的样子。历史显示就是对过去每一分钟的数据做一个历史记录。回放。目前,Tsar 支持秒、分钟、天等不同维度的数据展示。
  沙皇的用法
  Tsar的用法比较简单,不管是什么模块,这个用法都是共享的。上面最常用的命令是check命令,输出系统最新的监控指标。有了这个功能,所有基础软件采集基本可以每分钟调用一次,拿到最后一分钟的监控数据,把这些数据带到我们的监控平台,在里面做一些监控配置和集中工作。这个命令是最常用的。
  
  -c 是定期执行的命令。这样,你当前打开的模块的所有采集函数都会执行一次,获取数据,并将数据保存在tsar的原创文件中。以后使用。
  -i 是指定一个间隔,多少秒或多少分钟。
  下图是一些用法的截图。实时模式下,可以指定-l或者--live,可以现场采集模块数据,实时分析结果。如果不指定,则默认为离线模式。时间间隔,如果不指定-i,默认为秒和分钟,实时每秒显示一次采集,离线每分钟显示一次。您还可以指定模块,--mod_name,指定几个模块,并显示几个指标。这样就可以将你关心的指标显示在一个屏幕上,让你看到它们之间的影响和关系,从而找到问题的症结所在。
  
  Tsar 还支持多个项目模块。有时系统指标有多个实例。这里体现了item的概念,可以更灵活的展示数据。另外,--check是看我们最后一分钟的数据,会在最后一分钟显示这一行的各个指标和字段,可以很方便的做一些监控处理。
  
  Tsar 本身是一个独立的软件,可以为其他系统提供丰富的数据源输入。
  下图是比较常见的配置,包括配置文件、指定模块、指定输出等。
  
  下图是如何输出到Mysql和Nagios的配置方法。
  
  定制开发
  Tsar 目前支持 C、bash、Lua 开发自定义模块,内部有近百个应用模块。模块组成包括模块名称、描述信息、采集函数、显示函数等,tsar本身也可以使用tsardevel的脚本自动生成一个模板,在这个模板的基础上进行修改,比较多高效的。
  
  具体模块开发内容如下:
  
  采集这个功能是具体抓取value_1/2/3,不管是到counter文件还是接口,都可以获取到value。但是得到的值并不是最终要显示的值,而是瞬时值。
  
  显示的数值需要通过数据显示功能进行处理计算。display函数中的两个输入参数会告诉你采集的最后两个数组的数据是什么。通过对这两个数组进行操作,最终得到的结果就是最终显示的数字。前几个内容做完后,最后在模块中生成注册函数。以下是一些关键信息,例如模块名称。用法、模块字段数据结构、字段数、采集 函数和表示函数。
  
  至此,一个模块基本完成。
  未来计划
  我们对沙皇的未来计划主要是三个方面。
  首先是跨平台,有些Linux版本支持的不是特别好,所以我们会在跨平台上多尝试。
  二是完善框架。目前框架比较大。如果单个模块有一些异常,整个采集都会挂掉。在本节中,我们将解耦一些模块和框架之间的强依赖关系,希望能够容灾。更好的。
  三是丰富一些模块。常用的系统模块已经很多,内部应用模块也比较丰富。也希望大家可以在开源区提供更多的模块,让我们支持的采集的类型更加丰富。一些。
  目前,在阿里巴巴整个开源代码库中,外部贡献者并不多,十几个人,内部贡献代码的有一百多人。欢迎来到主页和代码库。如有疑问,也可以联系本文分享者:再见。
   查看全部

  文章采集调用(阿里云CDN团队空见:开源的系统和应用采集软件Tsar
)
  在开源活动LinuxCon + ContainerCon + CloudOpen China(简称LC3))上,阿里云CDN团队分享了开源系统和应用采集软件Tsar背景、设计思路和使用方法,模块开发和未来规划。
  其实是阿里巴巴在做系统或者应用监控的时候的一个思路。队友在实际使用过程中比较舒服,软件的扩展性、稳定性、易用性也比较好,所以目前全机都可以使用。Deployment作为基础的监控代理,提供稳定的数据支持,同时也是对外开源的。
  沙皇的背景
  对于在线SA/PE/R&amp;D,他在开发和部署软件的时候,需要注意软件的运行情况。他需要去上面看看整个服务器的CPU/内存/网络/IO等基本指标是否OK。找出这些指标的一些软件瓶颈和针对性的优化。其实现在市面上有很多类似的软件,都有一定的特殊性,可能只是采集的某一个,每个软件采集都有不同的指标,这些的用法指标时间不一致。所以对用户的要求非常高,需要知道如何使用所有的监控软件,对于排查在线问题非常不方便。这也是我们最初的痛点。我们发现我们拥有所有的数据,但是如何链接和使用它很不方便。所以,我们想出了沙皇的想法。
  
  下图是现在网上很多命令的使用。整个Linux站的每一层都有一些对应的命令。运维等用户的学习成本非常高,不利于我们统一监控。
  
  需求和解决方案
  因此,我们最初的要求是有一个易于使用的采集软件,具有完整的基础数据,最好是应用程序数据。因为刚才列出的指标都是通用指标,但是我们有应用软件,所以我们想知道应用软件的一些数据,比如QPS和响应时间。目前的开源软件无法支持,业务需要编写采集工具进行数据采集和监控。
  另外,我们希望在数据之间做一些数据关联。比如当前CPU高,是否会带来其他一些数据指标的波动?需要对这些指标进行比较才能确定问题。
  同时,必须对数据进行过滤,离线实时查看,本地长期存储,远程发送,方便中心进行数据分析和挖掘。
  有了这些需求,我们的解决方案就是模仿Sar,它本身就是一个系统活动报告,实现了系统指标的采集,我们在它的基础上做了一些扩展。除了系统级的数据采集,Tsar还可以进行应用级的采集,模块化,支持扩展。例如,采集 现在有十个指标。如果还有其他应用指标和业务数据要到采集,可以很方便的在Tsar中写一个模块到采集。它还支持简单的报警和远程发送。
  设计和使用
  沙皇的原则很简单。它主要利用动态库的特性。我们每个采集模块都会实现一些功能,比如采集函数,分析处理函数,注册时提供的模块。基础字段,比如模块名,模块收录的字段,字段从哪里来采集,采集之后怎么处理和输出,这些函数都注册在Tsar框架中,每个循环到采集 调用这些指令的函数时,就可以完成采集的处理和整个数据的输出。
  整个模块的注册和执行流程如下:
  
  下图是Tsar的功能大图,底部是系统计数器和软件界面。每个具体的模块都是基于采集,参考Sar实现了很多系统指标。此外,还为应用软件提供了LVS、Nginx等对比。通用应用软件模块。
  
  在上述采集的过程中,会对模块进行一些过滤处理,并执行各个模块的采集函数来获取数据。根据格式化,框架将数据格式化并保存到/var/log/tsar.data。我们采集把所有的原创数据,以文件的形式存储起来。与Sar有区别。Tsar 中的字段是可读的,Sar 看不到含义。
  数据采集到达后,支持发送到远端,比如发送到网络接口,或者发送到MySql、Nagios等。另外,数据展示分为两部分,分别是分为实时显示和历史显示。实时显示需要每秒查看指标的样子。历史显示就是对过去每一分钟的数据做一个历史记录。回放。目前,Tsar 支持秒、分钟、天等不同维度的数据展示。
  沙皇的用法
  Tsar的用法比较简单,不管是什么模块,这个用法都是共享的。上面最常用的命令是check命令,输出系统最新的监控指标。有了这个功能,所有基础软件采集基本可以每分钟调用一次,拿到最后一分钟的监控数据,把这些数据带到我们的监控平台,在里面做一些监控配置和集中工作。这个命令是最常用的。
  
  -c 是定期执行的命令。这样,你当前打开的模块的所有采集函数都会执行一次,获取数据,并将数据保存在tsar的原创文件中。以后使用。
  -i 是指定一个间隔,多少秒或多少分钟。
  下图是一些用法的截图。实时模式下,可以指定-l或者--live,可以现场采集模块数据,实时分析结果。如果不指定,则默认为离线模式。时间间隔,如果不指定-i,默认为秒和分钟,实时每秒显示一次采集,离线每分钟显示一次。您还可以指定模块,--mod_name,指定几个模块,并显示几个指标。这样就可以将你关心的指标显示在一个屏幕上,让你看到它们之间的影响和关系,从而找到问题的症结所在。
  
  Tsar 还支持多个项目模块。有时系统指标有多个实例。这里体现了item的概念,可以更灵活的展示数据。另外,--check是看我们最后一分钟的数据,会在最后一分钟显示这一行的各个指标和字段,可以很方便的做一些监控处理。
  
  Tsar 本身是一个独立的软件,可以为其他系统提供丰富的数据源输入。
  下图是比较常见的配置,包括配置文件、指定模块、指定输出等。
  
  下图是如何输出到Mysql和Nagios的配置方法。
  
  定制开发
  Tsar 目前支持 C、bash、Lua 开发自定义模块,内部有近百个应用模块。模块组成包括模块名称、描述信息、采集函数、显示函数等,tsar本身也可以使用tsardevel的脚本自动生成一个模板,在这个模板的基础上进行修改,比较多高效的。
  
  具体模块开发内容如下:
  
  采集这个功能是具体抓取value_1/2/3,不管是到counter文件还是接口,都可以获取到value。但是得到的值并不是最终要显示的值,而是瞬时值。
  
  显示的数值需要通过数据显示功能进行处理计算。display函数中的两个输入参数会告诉你采集的最后两个数组的数据是什么。通过对这两个数组进行操作,最终得到的结果就是最终显示的数字。前几个内容做完后,最后在模块中生成注册函数。以下是一些关键信息,例如模块名称。用法、模块字段数据结构、字段数、采集 函数和表示函数。
  
  至此,一个模块基本完成。
  未来计划
  我们对沙皇的未来计划主要是三个方面。
  首先是跨平台,有些Linux版本支持的不是特别好,所以我们会在跨平台上多尝试。
  二是完善框架。目前框架比较大。如果单个模块有一些异常,整个采集都会挂掉。在本节中,我们将解耦一些模块和框架之间的强依赖关系,希望能够容灾。更好的。
  三是丰富一些模块。常用的系统模块已经很多,内部应用模块也比较丰富。也希望大家可以在开源区提供更多的模块,让我们支持的采集的类型更加丰富。一些。
  目前,在阿里巴巴整个开源代码库中,外部贡献者并不多,十几个人,内部贡献代码的有一百多人。欢迎来到主页和代码库。如有疑问,也可以联系本文分享者:再见。
  

文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则 )

采集交流优采云 发表了文章 • 0 个评论 • 104 次浏览 • 2022-01-22 00:14 • 来自相关话题

  文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则
)
  前言:本文章是关于如何使用Dedecms采集函数的第二篇文章。过滤规则。本次选择的目标站点为中国网管联盟网络技术频道的网络协议栏目,网址为“”。本文分为三个部分。第一部分主要介绍新添加的采集节点的第一步:设置基本信息和URL索引页面规则;第二节主要介绍新增的采集节点中的第二步:设置字段获取规则;第三节主要介绍采集如何指定节点以及如何导出采集内容。关于编写采集规则的一些基本操作,本文不做介绍或不再介绍,如有疑问,
  进入下面的第一部分。
  1.1 设置基本信息和URL索引页面规则
  新建一个普通的文章节点,输入“添加采集节点:第一步设置基本信息和URL索引页面规则”如图(图1),
  
  图1 - 新建采集节点:第一步设置基本信息和URL索引页面规则
  1.1.1 设置节点基本信息
  
  图 2 - 节点基本信息
  首先,定义节点名称为“采集Test(二)”。其次,找到目标页面代码。操作步骤为:
  (a) 打开 采集: 所针对的目标页面;
  (b) 右击选择“查看源文件”找到“charset”,如图(图3),
  
  图 3 - 查看源文件
  等号后面的代码就是想要的“编码格式”,这里是“gb2312”。“Region Matching Mode”、“Content Import Order”、“Hot Link Mode”使用默认值。
  引用 URL:您可以选择出现在 文章 列表中的任何 文章 页面的 URL。为方便起见,通常填写文章列表中第一个文章的URL,但由于第一个文章不涉及分页内容,为了展示如何采集分页文章,这里使用第二条文章作为参考网址。它的网址是:“”。设置后节点的基本信息,如图(图4),
  
  图 4 - 设置后节点的基本信息
  检查后,进入下一步。
  1.1.2 设置列表URL获取规则
  如图(图5),
  
  图 5 - 列出 URL 获取规则
  这是设置采集的文章列表页的匹配规则,也是本节的重点和难点。
  具体步骤:
  (a) 首先,回到打开的文章列表页面,然后浏览器的URL地址栏中显示的URL,如图(图6),
   查看全部

  文章采集调用(Dedecms采集功能使用方法的第二篇设置基本信息及网址索引页规则
)
  前言:本文章是关于如何使用Dedecms采集函数的第二篇文章。过滤规则。本次选择的目标站点为中国网管联盟网络技术频道的网络协议栏目,网址为“”。本文分为三个部分。第一部分主要介绍新添加的采集节点的第一步:设置基本信息和URL索引页面规则;第二节主要介绍新增的采集节点中的第二步:设置字段获取规则;第三节主要介绍采集如何指定节点以及如何导出采集内容。关于编写采集规则的一些基本操作,本文不做介绍或不再介绍,如有疑问,
  进入下面的第一部分。
  1.1 设置基本信息和URL索引页面规则
  新建一个普通的文章节点,输入“添加采集节点:第一步设置基本信息和URL索引页面规则”如图(图1),
  
  图1 - 新建采集节点:第一步设置基本信息和URL索引页面规则
  1.1.1 设置节点基本信息
  
  图 2 - 节点基本信息
  首先,定义节点名称为“采集Test(二)”。其次,找到目标页面代码。操作步骤为:
  (a) 打开 采集: 所针对的目标页面;
  (b) 右击选择“查看源文件”找到“charset”,如图(图3),
  
  图 3 - 查看源文件
  等号后面的代码就是想要的“编码格式”,这里是“gb2312”。“Region Matching Mode”、“Content Import Order”、“Hot Link Mode”使用默认值。
  引用 URL:您可以选择出现在 文章 列表中的任何 文章 页面的 URL。为方便起见,通常填写文章列表中第一个文章的URL,但由于第一个文章不涉及分页内容,为了展示如何采集分页文章,这里使用第二条文章作为参考网址。它的网址是:“”。设置后节点的基本信息,如图(图4),
  
  图 4 - 设置后节点的基本信息
  检查后,进入下一步。
  1.1.2 设置列表URL获取规则
  如图(图5),
  
  图 5 - 列出 URL 获取规则
  这是设置采集的文章列表页的匹配规则,也是本节的重点和难点。
  具体步骤:
  (a) 首先,回到打开的文章列表页面,然后浏览器的URL地址栏中显示的URL,如图(图6),
  

文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)

采集交流优采云 发表了文章 • 0 个评论 • 182 次浏览 • 2022-01-19 03:00 • 来自相关话题

  文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)
  本文主要分享使用火焰图的技巧,介绍systemtap的原理和机制,如何使用火焰图快速定位性能问题的原因,加深对systemtap的理解。
  让我们回想一下,作为编程新手,我们是如何调整程序的?通常依靠没有数据的主观假设,稍有经验的同学会分两块或一卷调试差异代码。这种定位问题的方法不仅费时费力,而且不具有普遍性。在遇到其他类似的性能问题时,需要反复踩坑填坑,那么如何避免这种情况呢?
  有句话叫:兵欲行善,必先利其器。个人认为,程序员也需要一把“利器”来定位性能问题。就像医生看病人一样,需要依靠专业的医疗工具(如X光片、听诊器等)进行诊断,最终根据患者的检测结果快速准确地定位病因。医疗工具。性能调优工具(如 perf / gprof 等)用于性能调优,就像 X 射线用于患者一样。他们可以查明程序的性能瓶颈。
  但是,常用的性能调优工具perf等只能在单个显示中列出调用堆栈或非分层时间分布,不够直观。这里推荐大家一起使用火焰图,更直观的呈现perf采集等工具的数据。
  初识火焰图
  火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的。与所有其他分析方法不同,Flame Graph 从全局角度看待时间分布。它从底部到顶部列出了所有可能的原因 性能瓶颈的调用堆栈。
  
  火焰图的整个图看起来像一个跳动的火焰,这就是它的名字的由来。
  火焰图有以下特点(这里以on-cpu火焰图为例):
  火焰图类型
  常见的火焰图类型有 On-CPU、Off-CPU 以及 Memory、Hot/Cold、Differential 等。它们适合什么样的问题?
  这里笔者主要使用了On-CPU、Off-CPU和Memory火焰图,所以这里只是对这三个火焰图进行对比,欢迎大家补充指正。
  
  火焰图分析技巧的纵轴代表调用栈的深度(栈帧数),用来表示函数之间的调用关系:下面的函数是上面函数的父函数。横轴代表调用频率。网格的宽度越大,就越有可能成为瓶颈。不同类型的火焰图适用于不同的优化场景。例如,on-cpu 火焰图适用于分析 CPU 使用率较高的问题函数,而 off-cpu 火焰图适用于解决阻塞和锁抢占问题。无意义的东西:横序是为了聚合,与函数之间的依赖或调用关系无关;火焰图的各种颜色是为了方便区分,本身并无特殊含义。更多实践:进行性能优化,自觉使用火焰图法。如何绘制火焰图以进行性能调整(如果有时间)?
  要生成火焰图,您必须有一个方便的动态跟踪工具,如果操作系统是 Linux,通常是 perf 或 systemtap 之一。其中,perf相对来说比较常用。大部分Linux系统都收录perf,可以直接使用;SystemTap 在监控方面更强大、更灵活。关于如何使用perf绘制火焰图,网上有很多文章,所以本文将以SystemTap为例。
  SystemTap 是一个动态跟踪工具。它利用探针机制来采集内核或应用程序的运行信息,使您无需修改​​内核和应用程序的代码即可获得丰富的信息,帮助您分析和定位所需的故障排除问题。SystemTap 定义了类似的 DSL 脚本语言,方便用户根据需要自由扩展。但是,与动态跟踪的鼻祖 DTrace 不同,SystemTap 没有驻留的内核运行时。它需要先将脚本编译成内核模块,然后插入内核执行。这也会导致 SystemTap 启动缓慢并依赖于完整的调试符号表。
  使用SystemTap绘制火焰图的主要流程如下:
  本文的演示步骤将基于操作系统Tlinux 2.2
  安装 SystemTap 和 OS 符号调试表
  使用 yum 工具安装 systemtap:
  yum install systemtap systemtap-runtime
  由于systemtap工具依赖于完整的调试符号表,而且生产环境中不同机器的内核版本不同(虽然都是Tlinux2.2版本,但是内核版本之后的次要版本不同,可以通过 uname -a 命令查看)) 所以我们还需要安装 kernel-debuginfo 包和 kernel-devel 包。我在这里安装了这两个依赖包。
  kernel-devel-3.10.107-1-tlinux2-0046.x86_64
kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64
  根据需要绘制的火焰图类型和工艺类型选择合适的脚本
  使用 SystemTap 统计相关数据,往往需要根据其语法编写脚本,有一定的门槛。好在github上的agentzh开源了他常用的两套SystemTap脚本:openresty-systemtap-toolkit和stapxx,这两套工具集可以覆盖C进程、nginx进程和Openresty进程的大部分性能问题场景。
  我们这里需要绘制off-cpu火焰图,所以使用sample-bt-off-cpu脚本
  生成内核模块
  现在我们已经安装了统计脚本和systemtap,可以正常使用了,但是由于systemtap是通过生成内核模块来统计相关探针的统计信息,而tlinux要求所有运行的内核模块首先到达tlinux平台签名才能运行,所以:
  所以需要先修改off-cpu脚本生成内核模块;然后签署内核模块;最后使用systemtap命令手动运行脚本统计监控数据
  systemtap执行流程如下:
  
  所以我们在这里修改off-cpu stap脚本,让它只完成第四阶段,只生成一个内核模块
  // 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段
open my $in, "|stap -p4 --skip-badvars --all-modules -x $pid -d &#39;$exec_path&#39; --ldd $d_so_args $stap_args -"
or die "Cannot run stap: $!\n";
  修改后运行脚本生成内核模块
  // -p 8682 是需要监控的进程的进程号
// -t 30 是指会采样30秒
./sample-bt-off-cpu -p 8692 -t 30
  生成的内核模块名称为stap_xxxxx.ko。由于读者无需关心内核模块的签名,本章略过。
  运行内核模块统计
  内核模块签名后,可以使用staprun命令手动运行相关内核模块
  命令:
  // 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt
  值得注意的是,被监控的进程必须有一定的systemtap负载才能采集获取相关数据,即采集时也需要有一定的请求量(通常自己构建请求,对过程进行压力测试)
  将统计数据转换为火焰图
  一旦你有了统计数据 demo.bt,你就可以使用火焰图工具来绘制火焰图
  下载FlameGraph,链接:
  命令:
  ./stackcollapse-stap.pl demo.bt > demo.folded
./flamegraph.pl demo.folded > demo.svg
  这给出了 off-cpu 火焰图:
  
  看图说话
  趁热打铁,通过几张火焰图熟悉火焰图的使用方法
  图片来自春歌微博或个人近期定位问题
  On-cpu 火焰图 Apache APISIX QPS 急剧下降问题
  
  Apache APISIX是一款开源的国产高性能API网关。在选型和压测过程中发现,当路由匹配不同场景时,QPS急剧下降。当它的CPU(48核)占用率几乎100%,QPS几千,通过绘制火焰图,发现主要时间花在了一个表插入阶段(lj_cf_table_insert)。分析代码发现表还没有释放。每次路由不匹配,就会插入数据,导致表越来越大。后续插入耗时过长,导致 QPS 下降。
  off-cpu 火焰图 nginx mutex 问题
  
  这是一个 nginx 的 off-cpu 火焰图。我们可以快速锁定到 ngx_common_set_cache_fs_size -&gt; ngx_shmtx_lock -&gt; sem_wait。这个逻辑使用了互斥锁,这使得 nginx 进程的大部分阻塞等待时间都花在了获取锁上。
  代理监控报告断点问题
  
  这是代理的非 CPU 火焰图。它是一个多线程异步事件模型。主线程处理每条消息,多个线程负责配置和传递或监控和报告的职责。目前的问题是监控上报性能差,无法在周期(一分钟)内完成监控数据上报,导致监控断点。通过off-cpu火焰图,我们可以分析出上报线程在使用curl_easy_perform接口收发http监控数据报文时花费了很多时间。 查看全部

  文章采集调用(本文的原理机制,如何使用火焰图快速定位性能问题)
  本文主要分享使用火焰图的技巧,介绍systemtap的原理和机制,如何使用火焰图快速定位性能问题的原因,加深对systemtap的理解。
  让我们回想一下,作为编程新手,我们是如何调整程序的?通常依靠没有数据的主观假设,稍有经验的同学会分两块或一卷调试差异代码。这种定位问题的方法不仅费时费力,而且不具有普遍性。在遇到其他类似的性能问题时,需要反复踩坑填坑,那么如何避免这种情况呢?
  有句话叫:兵欲行善,必先利其器。个人认为,程序员也需要一把“利器”来定位性能问题。就像医生看病人一样,需要依靠专业的医疗工具(如X光片、听诊器等)进行诊断,最终根据患者的检测结果快速准确地定位病因。医疗工具。性能调优工具(如 perf / gprof 等)用于性能调优,就像 X 射线用于患者一样。他们可以查明程序的性能瓶颈。
  但是,常用的性能调优工具perf等只能在单个显示中列出调用堆栈或非分层时间分布,不够直观。这里推荐大家一起使用火焰图,更直观的呈现perf采集等工具的数据。
  初识火焰图
  火焰图(Flame Graph)是由 Linux 性能优化大师 Brendan Gregg 发明的。与所有其他分析方法不同,Flame Graph 从全局角度看待时间分布。它从底部到顶部列出了所有可能的原因 性能瓶颈的调用堆栈。
  
  火焰图的整个图看起来像一个跳动的火焰,这就是它的名字的由来。
  火焰图有以下特点(这里以on-cpu火焰图为例):
  火焰图类型
  常见的火焰图类型有 On-CPU、Off-CPU 以及 Memory、Hot/Cold、Differential 等。它们适合什么样的问题?
  这里笔者主要使用了On-CPU、Off-CPU和Memory火焰图,所以这里只是对这三个火焰图进行对比,欢迎大家补充指正。
  
  火焰图分析技巧的纵轴代表调用栈的深度(栈帧数),用来表示函数之间的调用关系:下面的函数是上面函数的父函数。横轴代表调用频率。网格的宽度越大,就越有可能成为瓶颈。不同类型的火焰图适用于不同的优化场景。例如,on-cpu 火焰图适用于分析 CPU 使用率较高的问题函数,而 off-cpu 火焰图适用于解决阻塞和锁抢占问题。无意义的东西:横序是为了聚合,与函数之间的依赖或调用关系无关;火焰图的各种颜色是为了方便区分,本身并无特殊含义。更多实践:进行性能优化,自觉使用火焰图法。如何绘制火焰图以进行性能调整(如果有时间)?
  要生成火焰图,您必须有一个方便的动态跟踪工具,如果操作系统是 Linux,通常是 perf 或 systemtap 之一。其中,perf相对来说比较常用。大部分Linux系统都收录perf,可以直接使用;SystemTap 在监控方面更强大、更灵活。关于如何使用perf绘制火焰图,网上有很多文章,所以本文将以SystemTap为例。
  SystemTap 是一个动态跟踪工具。它利用探针机制来采集内核或应用程序的运行信息,使您无需修改​​内核和应用程序的代码即可获得丰富的信息,帮助您分析和定位所需的故障排除问题。SystemTap 定义了类似的 DSL 脚本语言,方便用户根据需要自由扩展。但是,与动态跟踪的鼻祖 DTrace 不同,SystemTap 没有驻留的内核运行时。它需要先将脚本编译成内核模块,然后插入内核执行。这也会导致 SystemTap 启动缓慢并依赖于完整的调试符号表。
  使用SystemTap绘制火焰图的主要流程如下:
  本文的演示步骤将基于操作系统Tlinux 2.2
  安装 SystemTap 和 OS 符号调试表
  使用 yum 工具安装 systemtap:
  yum install systemtap systemtap-runtime
  由于systemtap工具依赖于完整的调试符号表,而且生产环境中不同机器的内核版本不同(虽然都是Tlinux2.2版本,但是内核版本之后的次要版本不同,可以通过 uname -a 命令查看)) 所以我们还需要安装 kernel-debuginfo 包和 kernel-devel 包。我在这里安装了这两个依赖包。
  kernel-devel-3.10.107-1-tlinux2-0046.x86_64
kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64
  根据需要绘制的火焰图类型和工艺类型选择合适的脚本
  使用 SystemTap 统计相关数据,往往需要根据其语法编写脚本,有一定的门槛。好在github上的agentzh开源了他常用的两套SystemTap脚本:openresty-systemtap-toolkit和stapxx,这两套工具集可以覆盖C进程、nginx进程和Openresty进程的大部分性能问题场景。
  我们这里需要绘制off-cpu火焰图,所以使用sample-bt-off-cpu脚本
  生成内核模块
  现在我们已经安装了统计脚本和systemtap,可以正常使用了,但是由于systemtap是通过生成内核模块来统计相关探针的统计信息,而tlinux要求所有运行的内核模块首先到达tlinux平台签名才能运行,所以:
  所以需要先修改off-cpu脚本生成内核模块;然后签署内核模块;最后使用systemtap命令手动运行脚本统计监控数据
  systemtap执行流程如下:
  
  所以我们在这里修改off-cpu stap脚本,让它只完成第四阶段,只生成一个内核模块
  // 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段
open my $in, "|stap -p4 --skip-badvars --all-modules -x $pid -d &#39;$exec_path&#39; --ldd $d_so_args $stap_args -"
or die "Cannot run stap: $!\n";
  修改后运行脚本生成内核模块
  // -p 8682 是需要监控的进程的进程号
// -t 30 是指会采样30秒
./sample-bt-off-cpu -p 8692 -t 30
  生成的内核模块名称为stap_xxxxx.ko。由于读者无需关心内核模块的签名,本章略过。
  运行内核模块统计
  内核模块签名后,可以使用staprun命令手动运行相关内核模块
  命令:
  // 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt
  值得注意的是,被监控的进程必须有一定的systemtap负载才能采集获取相关数据,即采集时也需要有一定的请求量(通常自己构建请求,对过程进行压力测试)
  将统计数据转换为火焰图
  一旦你有了统计数据 demo.bt,你就可以使用火焰图工具来绘制火焰图
  下载FlameGraph,链接:
  命令:
  ./stackcollapse-stap.pl demo.bt > demo.folded
./flamegraph.pl demo.folded > demo.svg
  这给出了 off-cpu 火焰图:
  
  看图说话
  趁热打铁,通过几张火焰图熟悉火焰图的使用方法
  图片来自春歌微博或个人近期定位问题
  On-cpu 火焰图 Apache APISIX QPS 急剧下降问题
  
  Apache APISIX是一款开源的国产高性能API网关。在选型和压测过程中发现,当路由匹配不同场景时,QPS急剧下降。当它的CPU(48核)占用率几乎100%,QPS几千,通过绘制火焰图,发现主要时间花在了一个表插入阶段(lj_cf_table_insert)。分析代码发现表还没有释放。每次路由不匹配,就会插入数据,导致表越来越大。后续插入耗时过长,导致 QPS 下降。
  off-cpu 火焰图 nginx mutex 问题
  
  这是一个 nginx 的 off-cpu 火焰图。我们可以快速锁定到 ngx_common_set_cache_fs_size -&gt; ngx_shmtx_lock -&gt; sem_wait。这个逻辑使用了互斥锁,这使得 nginx 进程的大部分阻塞等待时间都花在了获取锁上。
  代理监控报告断点问题
  
  这是代理的非 CPU 火焰图。它是一个多线程异步事件模型。主线程处理每条消息,多个线程负责配置和传递或监控和报告的职责。目前的问题是监控上报性能差,无法在周期(一分钟)内完成监控数据上报,导致监控断点。通过off-cpu火焰图,我们可以分析出上报线程在使用curl_easy_perform接口收发http监控数据报文时花费了很多时间。

文章采集调用(文章采集调用node.js,可以用我前面那篇)

采集交流优采云 发表了文章 • 0 个评论 • 140 次浏览 • 2022-01-18 23:04 • 来自相关话题

  文章采集调用(文章采集调用node.js,可以用我前面那篇)
  文章采集调用node.js,可以用我前面那篇wordpress的博客包含在内。文章预览代码修改了原来dom的版本,用的beforeeach,增加了references和activex选项。
  确定不是需要加一个js::static()。用windowscript钩子进去,无论是加载老文件,还是搞个大新闻都用得上。
  我觉得上面提到的beforeeach和activex自不必说,但是我很好奇。如果你当年没有用window的话,真正要解决的应该不是这个bug。首先你要解决的问题是标题如何显示。我开始认为只有字符串,然后提交的时候,编辑器不支持那么多字符显示,于是用大小写命名,emmmm好像没太大问题。那么你接下来应该不是问beforeeach和activex的区别,而是两个命名的话,明显要出问题。
  所以你可以看看没错,window就是为此才有的。你可以用window::scriptingdefaultscheme之类的东西,改成beforeeachschemename()或者activex::staticname()之类的。
  字符串就可以但是标题编辑器用没有必要1,像这样加上拼音的tag岂不是更合适2,beforeeach的token是用js保存的时候就会创建,无需手动控制,也不需要自己传值3,beforeend不支持的tag应该很少,
  自己写ajax太麻烦了,我只看activex支持,dom文件拖个beforeeach出来就可以, 查看全部

  文章采集调用(文章采集调用node.js,可以用我前面那篇)
  文章采集调用node.js,可以用我前面那篇wordpress的博客包含在内。文章预览代码修改了原来dom的版本,用的beforeeach,增加了references和activex选项。
  确定不是需要加一个js::static()。用windowscript钩子进去,无论是加载老文件,还是搞个大新闻都用得上。
  我觉得上面提到的beforeeach和activex自不必说,但是我很好奇。如果你当年没有用window的话,真正要解决的应该不是这个bug。首先你要解决的问题是标题如何显示。我开始认为只有字符串,然后提交的时候,编辑器不支持那么多字符显示,于是用大小写命名,emmmm好像没太大问题。那么你接下来应该不是问beforeeach和activex的区别,而是两个命名的话,明显要出问题。
  所以你可以看看没错,window就是为此才有的。你可以用window::scriptingdefaultscheme之类的东西,改成beforeeachschemename()或者activex::staticname()之类的。
  字符串就可以但是标题编辑器用没有必要1,像这样加上拼音的tag岂不是更合适2,beforeeach的token是用js保存的时候就会创建,无需手动控制,也不需要自己传值3,beforeend不支持的tag应该很少,
  自己写ajax太麻烦了,我只看activex支持,dom文件拖个beforeeach出来就可以,

文章采集调用( 一段代码,是调用WordPress某段时间内评论最多的文章)

采集交流优采云 发表了文章 • 0 个评论 • 129 次浏览 • 2022-01-17 17:10 • 来自相关话题

  文章采集调用(
一段代码,是调用WordPress某段时间内评论最多的文章)
  
  很多主题都使用了wordpress流行的文章功能,但他们通常把建站以来评论最多的称为文章。说实话,这个没什么意思,可能一直显示那几篇文章文章,今天给大家推荐一段代码,是某一段时间内调用WordPress评论最多的文章的时间。方法来自zwwooooo大师的WordPress:近期最热文章.
  把下面的代码放在最后一个?>在主题的functions.php之间
  1.,注意代码中的注释文字:
  /* 某段时间内最热文章
* Reference: http://www.wprecipes.com/rarst ... -week
* Edit: zwwooooo
*/
function most_comm_posts($days=7, $nums=10) { //$days参数限制时间值,单位为‘天’,默认是7天;$nums是要显示文章数量
global $wpdb;
$today = date("Y-m-d H:i:s"); //获取今天日期时间
$daysago = date( "Y-m-d H:i:s", strtotime($today) - ($days * 24 * 60 * 60) ); //Today - $days
$result = $wpdb->get_results("SELECT comment_count, ID, post_title, post_date FROM $wpdb->posts WHERE post_date BETWEEN '$daysago' AND '$today' ORDER BY comment_count DESC LIMIT 0 , $nums");
$output = '';
if(empty($result)) {
$output = 'None data.';
} else {
foreach ($result as $topten) {
$postid = $topten->ID;
$title = $topten->post_title;
$commentcount = $topten->comment_count;
if ($commentcount != 0) {
$output .= ''.$title.' ('.$commentcount.')';
}
}
}
echo $output;
}
  2.调用的时候可以参考下面的例子:
  近期最热文章

  PS:函数参数1按天计算,30为30天;参数2为文章的显示数量,10为10篇文章的显示,可根据需要设置。具体风格看自己写css。
  免责声明:本网站上的所有 文章,除非另有说明或标记,均在本网站 原创 上发布。任何个人或组织,未经本站同意,不得复制、盗用、采集、将本站内容发布到任何网站、书籍等媒体平台。如果本站内容侵犯原作者合法权益,您可以联系我们处理。 查看全部

  文章采集调用(
一段代码,是调用WordPress某段时间内评论最多的文章)
  
  很多主题都使用了wordpress流行的文章功能,但他们通常把建站以来评论最多的称为文章。说实话,这个没什么意思,可能一直显示那几篇文章文章,今天给大家推荐一段代码,是某一段时间内调用WordPress评论最多的文章的时间。方法来自zwwooooo大师的WordPress:近期最热文章.
  把下面的代码放在最后一个?>在主题的functions.php之间
  1.,注意代码中的注释文字:
  /* 某段时间内最热文章
* Reference: http://www.wprecipes.com/rarst ... -week
* Edit: zwwooooo
*/
function most_comm_posts($days=7, $nums=10) { //$days参数限制时间值,单位为‘天’,默认是7天;$nums是要显示文章数量
global $wpdb;
$today = date("Y-m-d H:i:s"); //获取今天日期时间
$daysago = date( "Y-m-d H:i:s", strtotime($today) - ($days * 24 * 60 * 60) ); //Today - $days
$result = $wpdb->get_results("SELECT comment_count, ID, post_title, post_date FROM $wpdb->posts WHERE post_date BETWEEN '$daysago' AND '$today' ORDER BY comment_count DESC LIMIT 0 , $nums");
$output = '';
if(empty($result)) {
$output = 'None data.';
} else {
foreach ($result as $topten) {
$postid = $topten->ID;
$title = $topten->post_title;
$commentcount = $topten->comment_count;
if ($commentcount != 0) {
$output .= ''.$title.' ('.$commentcount.')';
}
}
}
echo $output;
}
  2.调用的时候可以参考下面的例子:
  近期最热文章

  PS:函数参数1按天计算,30为30天;参数2为文章的显示数量,10为10篇文章的显示,可根据需要设置。具体风格看自己写css。
  免责声明:本网站上的所有 文章,除非另有说明或标记,均在本网站 原创 上发布。任何个人或组织,未经本站同意,不得复制、盗用、采集、将本站内容发布到任何网站、书籍等媒体平台。如果本站内容侵犯原作者合法权益,您可以联系我们处理。

文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)

采集交流优采云 发表了文章 • 0 个评论 • 385 次浏览 • 2022-01-16 20:25 • 来自相关话题

  文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)
  数据栈是云原生的一站式数据中心PaaS。我们在 github 和 gitee 上有一个有趣的开源项目:FlinkX。 FlinkX 是一个基于 Flink 的批量流统一数据同步工具。可以是 采集static ,是一个集全局、异构、批处理流为一体的数据同步引擎。如果你喜欢它,请给我们一个star!星星!星星!
  github开源项目:
  gitee开源项目:
  袋鼠云云原生的一站式数据中台PaaS——数据栈,涵盖了建设数据中心过程中所需的各种工具(包括数据开发平台、数据资产平台、数据科学平台、数据服务引擎等),具有全面覆盖 离线计算和实时计算应用帮助企业大大缩短数据价值的提取过程,提高数据价值的提取能力。
  
  目前,数据栈-离线开发平台(BatchWorks)中的数据离线同步任务和数据栈-实时开发平台(StreamWorks)中的数据实时采集任务已经基于FlinkX进行了统一. 离线采集和实时数据采集的基本原理是一样的。主要区别在于源流是否有界。因此,使用 Flink 的 Stream API 来同步这两个数据。场景,实现数据同步的批量流统一。
  一、功能介绍
  1、断点续传
  断点续传是指数据同步任务在运行过程中由于各种原因而失败。它不需要重新同步数据,只需要从上次失败的位置继续同步即可。与网络原因下载文件失败类似,无需重新下载文件,继续下载即可,可大大节省时间和计算资源。断点续传是DataStack-离线开发平台(BatchWorks)中数据同步任务的功能,需要结合任务的错误重试机制来完成。当任务运行失败时,将在引擎中重试。重试时会从上次失败时读取的位置继续读取数据,直到任务运行成功。
  
  ​
  2、直播采集
  实时采集是数据栈实时开发平台(StreamWorks)中data采集任务的一个功能。数据实时同步到目标数据源。除了实时数据变化之外,实时采集和离线数据同步的另一个区别是实时采集任务不会停止,任务会一直监听数据源变化。这与 Flink 任务是一致的,所以实时 采集 任务是栈流计算应用中的任务类型,配置过程与离线计算中的同步任务基本相同。
  
  ​
  二、Flink 中的检查点机制
  断点续传和实时 采集 都依赖于 Flink 的 Checkpoint 机制,所以我们先简单看一下。
  Checkpoint 是 Fl​​ink 容错机制的核心功能。它可以根据配置,根据 Stream 中各个算子的状态,定期生成 Snapshots,从而定期持久地存储这些状态数据。当 Flink 程序意外崩溃时,会重新运行。程序可以选择性地从这些快照中恢复,从而纠正因故障引起的程序数​​据状态中断。
  
  当一个 Checkpoint 被触发时,一个屏障标记被插入到多个分布式 Stream Source 中,这些屏障与 Stream 中的数据记录一起流向下游算子。当操作员收到障碍时,它会暂停处理 Steam 中新收到的数据记录。因为一个 Operator 可能有多个输入 Stream,而每个 Stream 都会有一个对应的 Barrier,所以 Operator 必须等到输入 Stream 中的所有 Barrier 都到达。
  当流中所有的barrier都到达operator时,那么所有的barrier就出现在同一个时间点(表示已经对齐),在等待所有barrier到达的过程中,buffer的operator 可能已经缓存了一些比 Barrier 更早到达 Operator 的数据记录(Outgoing Records),那么 Operator 会发出(Emit)这些数据记录(Outgoing Records)作为下游 Operator 的输入,最后发出( Emit) Barrier 对应的 Snapshot 作为 this checkpoint 的结果数据。
  三、断点续传
  1、先决条件
  为了支持断点恢复上传,同步任务对数据源有一些强制性要求:
  1)数据源(此处为关系数据库)必须收录升序字段,例如主键或日期类型字段。同步过程中会使用检查点机制记录该字段的值,当任务恢复运行时会使用该字段。构造查询条件,过滤已同步的数据。如果该字段的值不按升序排列,则任务恢复时过滤的数据会出错,最终导致数据丢失或重复;
  2)数据源必须支持数据过滤。否则,任务将无法从断点处恢复运行,从而导致数据重复;
  3)目标数据源必须支持事务,比如关系型数据库,也可以通过临时文件支持文件类型的数据源。
  2、任务运行详细流程
  让我们以一个具体的任务来详细介绍整个过程。任务详情如下:
  
  ​
  1)读取数据
  读取数据时,首先构建数据分片。构造数据分片就是根据通道索引和检查点记录的位置构造查询sql。sql模板如下:
  select * from data_test
where id mod ${channel_num}=${channel_index}
and id > ${offset}
  
  如果是第一次运行,或者上次任务失败时checkpoint还没有触发,则offset不存在,具体查询sql可以根据offset和channel确定:
  存在偏移时
  第一个频道:
  select * from data_test
where id mod 2=0
and id > ${offset_0};
  
  第二频道:
  select * from data_test
where id mod 2=1
and id > ${offset_1};
  
  当偏移不存在时
  第一个频道:
  select * from data_test
where id mod 2=0;
  
  第二频道:
  select * from data_test
where id mod 2=1;
  
  数据分片构建完成后,每个通道根据自己的数据分片读取数据。
  2)写入数据
  在写数据之前,会先做几个操作:
  一个。检查 /data_test 目录是否存在。如果目录不存在,则创建目录。如果目录存在,则执行2个操作;
  湾。判断是否以overwrite方式写入数据,如果是,删除/data_test目录,然后创建目录,如果不是,执行3个操作;
  C。检查/data_test/.data目录是否存在。如果存在,则先删除再创建,确保没有其他任务因异常失败而留下的脏数据文件;
  数据单行写入hdfs,不支持批量写入。数据将首先写入 /data_test/.data/ 目录。数据文件的命名格式为:
  channelIndex.jobId.fileIndex
  收录三部分:通道索引、jobId、文件索引。
  3)触发检查点时
  在 FlinkX 中,“status”表示标识字段 id 的值。我们假设触发检查点时两个通道的读写情况如图所示:
  
  ​
  触发检查点后,两个读取器首先生成一个 Snapshot 来记录读取状态。通道 0 的状态为 id=12,通道 1 的状态为 id=11。Snapshot生成后,在数据流中插入一个barrier,barrier和数据一起流向Writer。以Writer_0为例,Writer_0接收Reader_0和Reader_1发送的数据。假设首先收到Reader_0 的屏障。此时Writer_0停止向HDFS写入数据,将接收到的数据先放入InputBuffer,等待Reader_1的barrier到来。之后,将Buffer中的所有数据写出,然后生成Writer的Snapshot。整个检查点结束后,记录的任务状态为:
  阅读器_0:id=12
  阅读器_1:id=11
  Writer_0:id=无法确定
  Writer_1:id=无法确定
  任务状态会记录在配置的HDFS目录/flinkx/checkpoint/abc123中。因为每个Writer会从两个Reader接收数据,而且每个通道的数据读写速率可能不同,所以Writer接收数据的顺序是不确定的,但这并不影响数据的准确性,因为数据是read 当我们只需要Reader记录的状态时,我们可以构造查询sql,我们只需要保证数据真的写入HDFS即可。在 Writer 生成 Snapshot 之前,会执行一系列操作以确保将所有接收到的数据写入 HDFS:
  一个。关闭写入HDFS文件的数据流。这时候会在/data_test/.data目录下生成两个文件:
  /data_test/.data/0.abc123.0
  /data_test/.data/1.abc123.0
  湾。将生成的两个数据文件移动到/data_test目录下;
  C。将文件名模板更新为:channelIndex.abc123.1;
  快照生成后,任务继续读写数据。如果在生成快照的过程中出现异常,任务会直接失败,这样本次就不会生成快照,任务恢复时会从上次成功的快照恢复。
  4)任务正常结束
  当任务正常结束时,它会做与生成快照时相同的操作,关闭文件流,移动临时数据文件等。
  5)任务异常终止
  如果任务异常结束,则假设任务结束时最后一条检查点记录的状态为:
  Reader_0:id=12Reader_1:id=11
  那么当任务恢复时,会将每条通道记录的状态赋值给offset,再次读取数据时构造的sql为:
  第一个频道:
  select * from data_test
where id mod 2=0
and id > 12;
  第二频道:
  select * from data_test
where id mod 2=1
and id > 11;
  这将允许您从上次失败的位置继续读取数据。
  3、一个支持续传上传的插件
  理论上,只要支持过滤数据的数据源和支持事务的数据源都可以支持断点续传功能,FlinkX目前支持的插件如下:
  
  ​
  四、直播采集
  目前 FlinkX 支持实时 采集 插件,包括 Kafka 和 binlog 插件。binlog 插件是为实时采集 mysql 数据库设计的。如果要支持其他数据源,只需要将数据发送到Kafka,然后使用FlinkX的Kafka插件消费数据,比如oracle,只需要使用oracle的ogg发送数据到Kafka即可。这里具体讲解mysql的实时采集插件binlog。
  1、二进制日志
  binlog是Mysql sever层维护的二进制日志,与innodb引擎中的redo/undo log完全不同;它主要用于记录更新或可能更新 MySQL 数据的 SQL 语句,并以“事务”格式存储在磁盘上。
  binlog的主要功能有:
  1)Replication:MySQL Replication在Master端开启binlog,Master将其binlog传递给slave,并replay,达到主从数据一致性的目的;
  2)数据恢复:通过mysqlbinlog工具恢复数据;
  3)增量备份。
  2、MySQL主从复制
  有记录数据变化的binlog日志是不够的,我们还需要用到MySQL的主备复制功能:主备复制是指一台服务器作为主库服务器,另一台或多台服务器作为从库服务器。数据自动复制到从服务器。
  
  ​
  主从复制的过程:
  1)MySQL master将数据变化写入二进制日志(binary log,这里的记录称为binary log events,可以通过show binlog events查看);
  2)MySQL slave将master的二进制日志事件复制到它的relay log中;
  3)MySQL slave 在中继日志中重放事件,反映数据变化到它自己。
  3、写入 Hive
  binlog 插件可以监控多个表的数据变化。解析后的数据收录表名信息。读取的数据可以写入目标数据库的表中,也可以根据数据中收录的表名信息写入。不同的表,目前只有 Hive 插件支持这个功能。Hive插件目前只有写插件,功能是基于HDFS写插件实现的。也就是说,从binlog读取写入hive的功能也支持故障恢复的功能。
  
  
  ​
  写入Hive的过程:
  1)从数据中解析出MySQL表名,然后根据表名映射规则转换成对应的Hive表名;
  2)检查Hive表是否存在,如果不存在,则创建Hive表;
  3)查询Hive表的相关信息,构造HdfsOutputFormat;
  4)调用 HdfsOutputFormat 将数据写入 HDFS。 查看全部

  文章采集调用(【开源项目】袋鼠云云原生一站式数据中台PaaS)
  数据栈是云原生的一站式数据中心PaaS。我们在 github 和 gitee 上有一个有趣的开源项目:FlinkX。 FlinkX 是一个基于 Flink 的批量流统一数据同步工具。可以是 采集static ,是一个集全局、异构、批处理流为一体的数据同步引擎。如果你喜欢它,请给我们一个star!星星!星星!
  github开源项目:
  gitee开源项目:
  袋鼠云云原生的一站式数据中台PaaS——数据栈,涵盖了建设数据中心过程中所需的各种工具(包括数据开发平台、数据资产平台、数据科学平台、数据服务引擎等),具有全面覆盖 离线计算和实时计算应用帮助企业大大缩短数据价值的提取过程,提高数据价值的提取能力。
  
  目前,数据栈-离线开发平台(BatchWorks)中的数据离线同步任务和数据栈-实时开发平台(StreamWorks)中的数据实时采集任务已经基于FlinkX进行了统一. 离线采集和实时数据采集的基本原理是一样的。主要区别在于源流是否有界。因此,使用 Flink 的 Stream API 来同步这两个数据。场景,实现数据同步的批量流统一。
  一、功能介绍
  1、断点续传
  断点续传是指数据同步任务在运行过程中由于各种原因而失败。它不需要重新同步数据,只需要从上次失败的位置继续同步即可。与网络原因下载文件失败类似,无需重新下载文件,继续下载即可,可大大节省时间和计算资源。断点续传是DataStack-离线开发平台(BatchWorks)中数据同步任务的功能,需要结合任务的错误重试机制来完成。当任务运行失败时,将在引擎中重试。重试时会从上次失败时读取的位置继续读取数据,直到任务运行成功。
  
  ​
  2、直播采集
  实时采集是数据栈实时开发平台(StreamWorks)中data采集任务的一个功能。数据实时同步到目标数据源。除了实时数据变化之外,实时采集和离线数据同步的另一个区别是实时采集任务不会停止,任务会一直监听数据源变化。这与 Flink 任务是一致的,所以实时 采集 任务是栈流计算应用中的任务类型,配置过程与离线计算中的同步任务基本相同。
  
  ​
  二、Flink 中的检查点机制
  断点续传和实时 采集 都依赖于 Flink 的 Checkpoint 机制,所以我们先简单看一下。
  Checkpoint 是 Fl​​ink 容错机制的核心功能。它可以根据配置,根据 Stream 中各个算子的状态,定期生成 Snapshots,从而定期持久地存储这些状态数据。当 Flink 程序意外崩溃时,会重新运行。程序可以选择性地从这些快照中恢复,从而纠正因故障引起的程序数​​据状态中断。
  
  当一个 Checkpoint 被触发时,一个屏障标记被插入到多个分布式 Stream Source 中,这些屏障与 Stream 中的数据记录一起流向下游算子。当操作员收到障碍时,它会暂停处理 Steam 中新收到的数据记录。因为一个 Operator 可能有多个输入 Stream,而每个 Stream 都会有一个对应的 Barrier,所以 Operator 必须等到输入 Stream 中的所有 Barrier 都到达。
  当流中所有的barrier都到达operator时,那么所有的barrier就出现在同一个时间点(表示已经对齐),在等待所有barrier到达的过程中,buffer的operator 可能已经缓存了一些比 Barrier 更早到达 Operator 的数据记录(Outgoing Records),那么 Operator 会发出(Emit)这些数据记录(Outgoing Records)作为下游 Operator 的输入,最后发出( Emit) Barrier 对应的 Snapshot 作为 this checkpoint 的结果数据。
  三、断点续传
  1、先决条件
  为了支持断点恢复上传,同步任务对数据源有一些强制性要求:
  1)数据源(此处为关系数据库)必须收录升序字段,例如主键或日期类型字段。同步过程中会使用检查点机制记录该字段的值,当任务恢复运行时会使用该字段。构造查询条件,过滤已同步的数据。如果该字段的值不按升序排列,则任务恢复时过滤的数据会出错,最终导致数据丢失或重复;
  2)数据源必须支持数据过滤。否则,任务将无法从断点处恢复运行,从而导致数据重复;
  3)目标数据源必须支持事务,比如关系型数据库,也可以通过临时文件支持文件类型的数据源。
  2、任务运行详细流程
  让我们以一个具体的任务来详细介绍整个过程。任务详情如下:
  
  ​
  1)读取数据
  读取数据时,首先构建数据分片。构造数据分片就是根据通道索引和检查点记录的位置构造查询sql。sql模板如下:
  select * from data_test
where id mod ${channel_num}=${channel_index}
and id > ${offset}
  
  如果是第一次运行,或者上次任务失败时checkpoint还没有触发,则offset不存在,具体查询sql可以根据offset和channel确定:
  存在偏移时
  第一个频道:
  select * from data_test
where id mod 2=0
and id > ${offset_0};
  
  第二频道:
  select * from data_test
where id mod 2=1
and id > ${offset_1};
  
  当偏移不存在时
  第一个频道:
  select * from data_test
where id mod 2=0;
  
  第二频道:
  select * from data_test
where id mod 2=1;
  
  数据分片构建完成后,每个通道根据自己的数据分片读取数据。
  2)写入数据
  在写数据之前,会先做几个操作:
  一个。检查 /data_test 目录是否存在。如果目录不存在,则创建目录。如果目录存在,则执行2个操作;
  湾。判断是否以overwrite方式写入数据,如果是,删除/data_test目录,然后创建目录,如果不是,执行3个操作;
  C。检查/data_test/.data目录是否存在。如果存在,则先删除再创建,确保没有其他任务因异常失败而留下的脏数据文件;
  数据单行写入hdfs,不支持批量写入。数据将首先写入 /data_test/.data/ 目录。数据文件的命名格式为:
  channelIndex.jobId.fileIndex
  收录三部分:通道索引、jobId、文件索引。
  3)触发检查点时
  在 FlinkX 中,“status”表示标识字段 id 的值。我们假设触发检查点时两个通道的读写情况如图所示:
  
  ​
  触发检查点后,两个读取器首先生成一个 Snapshot 来记录读取状态。通道 0 的状态为 id=12,通道 1 的状态为 id=11。Snapshot生成后,在数据流中插入一个barrier,barrier和数据一起流向Writer。以Writer_0为例,Writer_0接收Reader_0和Reader_1发送的数据。假设首先收到Reader_0 的屏障。此时Writer_0停止向HDFS写入数据,将接收到的数据先放入InputBuffer,等待Reader_1的barrier到来。之后,将Buffer中的所有数据写出,然后生成Writer的Snapshot。整个检查点结束后,记录的任务状态为:
  阅读器_0:id=12
  阅读器_1:id=11
  Writer_0:id=无法确定
  Writer_1:id=无法确定
  任务状态会记录在配置的HDFS目录/flinkx/checkpoint/abc123中。因为每个Writer会从两个Reader接收数据,而且每个通道的数据读写速率可能不同,所以Writer接收数据的顺序是不确定的,但这并不影响数据的准确性,因为数据是read 当我们只需要Reader记录的状态时,我们可以构造查询sql,我们只需要保证数据真的写入HDFS即可。在 Writer 生成 Snapshot 之前,会执行一系列操作以确保将所有接收到的数据写入 HDFS:
  一个。关闭写入HDFS文件的数据流。这时候会在/data_test/.data目录下生成两个文件:
  /data_test/.data/0.abc123.0
  /data_test/.data/1.abc123.0
  湾。将生成的两个数据文件移动到/data_test目录下;
  C。将文件名模板更新为:channelIndex.abc123.1;
  快照生成后,任务继续读写数据。如果在生成快照的过程中出现异常,任务会直接失败,这样本次就不会生成快照,任务恢复时会从上次成功的快照恢复。
  4)任务正常结束
  当任务正常结束时,它会做与生成快照时相同的操作,关闭文件流,移动临时数据文件等。
  5)任务异常终止
  如果任务异常结束,则假设任务结束时最后一条检查点记录的状态为:
  Reader_0:id=12Reader_1:id=11
  那么当任务恢复时,会将每条通道记录的状态赋值给offset,再次读取数据时构造的sql为:
  第一个频道:
  select * from data_test
where id mod 2=0
and id > 12;
  第二频道:
  select * from data_test
where id mod 2=1
and id > 11;
  这将允许您从上次失败的位置继续读取数据。
  3、一个支持续传上传的插件
  理论上,只要支持过滤数据的数据源和支持事务的数据源都可以支持断点续传功能,FlinkX目前支持的插件如下:
  
  ​
  四、直播采集
  目前 FlinkX 支持实时 采集 插件,包括 Kafka 和 binlog 插件。binlog 插件是为实时采集 mysql 数据库设计的。如果要支持其他数据源,只需要将数据发送到Kafka,然后使用FlinkX的Kafka插件消费数据,比如oracle,只需要使用oracle的ogg发送数据到Kafka即可。这里具体讲解mysql的实时采集插件binlog。
  1、二进制日志
  binlog是Mysql sever层维护的二进制日志,与innodb引擎中的redo/undo log完全不同;它主要用于记录更新或可能更新 MySQL 数据的 SQL 语句,并以“事务”格式存储在磁盘上。
  binlog的主要功能有:
  1)Replication:MySQL Replication在Master端开启binlog,Master将其binlog传递给slave,并replay,达到主从数据一致性的目的;
  2)数据恢复:通过mysqlbinlog工具恢复数据;
  3)增量备份。
  2、MySQL主从复制
  有记录数据变化的binlog日志是不够的,我们还需要用到MySQL的主备复制功能:主备复制是指一台服务器作为主库服务器,另一台或多台服务器作为从库服务器。数据自动复制到从服务器。
  
  ​
  主从复制的过程:
  1)MySQL master将数据变化写入二进制日志(binary log,这里的记录称为binary log events,可以通过show binlog events查看);
  2)MySQL slave将master的二进制日志事件复制到它的relay log中;
  3)MySQL slave 在中继日志中重放事件,反映数据变化到它自己。
  3、写入 Hive
  binlog 插件可以监控多个表的数据变化。解析后的数据收录表名信息。读取的数据可以写入目标数据库的表中,也可以根据数据中收录的表名信息写入。不同的表,目前只有 Hive 插件支持这个功能。Hive插件目前只有写插件,功能是基于HDFS写插件实现的。也就是说,从binlog读取写入hive的功能也支持故障恢复的功能。
  
  
  ​
  写入Hive的过程:
  1)从数据中解析出MySQL表名,然后根据表名映射规则转换成对应的Hive表名;
  2)检查Hive表是否存在,如果不存在,则创建Hive表;
  3)查询Hive表的相关信息,构造HdfsOutputFormat;
  4)调用 HdfsOutputFormat 将数据写入 HDFS。

文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图) )

采集交流优采云 发表了文章 • 0 个评论 • 148 次浏览 • 2022-01-16 20:24 • 来自相关话题

  文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图)
)
  前言
  在分布式链路跟踪中,为了获取服务之间的调用链信息,采集器通常需要在方法前后进行埋藏。在Java生态系统中,常见的埋点方式有两种:
  依靠SDK手动埋点;使用Java Agent技术做非侵入式埋葬。
  著名的分布式监控系统是由 Zipkin 开创的。最经典的就是了解X-B3 Ttrace协议,使用Brave SDK,手动埋点生成Trace。但是 SDK 中埋点的方式对业务代码是有侵入性的。升级埋点时,必须进行代码更改。
  那么如何将其与业务逻辑解绑呢?
  Java还提供了另一种方式:依靠Java Agent技术对目标方法的字节码进行修改,从而实现非侵入式埋葬。这种使用 Java 代理的 采集器 方式也称为探针。在应用启动时使用-javaagent参数,或者在运行时使用attach(pid)方法,可以将探针包注入到目标应用中,完成埋点的植入。以对业务代码无侵入的方式,实现不敏感的热升级。用户无需了解深层原理,即可使用完整的监控服务
  Java代理介绍
  Java Agent 是 Java 1.5 版本之后引入的一个特性。它的主要作用是在类加载之前对其进行拦截,并且已经插入到我们的监控字节码中。代理是使用 Java 的 Instrumentation 接口 (java.lang.instrument) 编写的。
  基本思路是在JVM启动时添加一个代理(Java Agent),每个代理是一个Jar包,在MANIFEST.MF文件中指定代理类,代理类收录一个premain方法。JVM在类加载的时候会先执行代理类的premain方法,然后再执行Java程序本身的main方法,这就是premain名的来源。在premain方法中,可以修改加载前的类文件。
  这种机制可以认为是虚拟机级别的AOP,无需对原创应用程序进行任何修改即可实现类的动态修改和增强。
  从 JDK 1.6 开始,支持更强大的动态 Instruments,在 JVM 启动后通过 Attach(pid) 远程加载。
  注意:
  无论 Agent 是用 Native 方式还是 Java Instrumentation 接口方式编写的,它们的工作都是在 JVMTI 的帮助下完成的。 JVMTI 是一组 Native 接口。在 Java 1.5 之前,Agent 只能通过编写 Native 代码来实现。
  Java Instrumentation 核心方法
  Instrumentation 是 java.lang.instrument 包下的一个接口。该接口的方法提供了注册类文件转换器、获取所有加载的类等功能,允许我们修改加载和卸载的类来实现AOP、性能监控等功能。
  常用方法:
  /**
* 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码
*/
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
/**
* 对JVM已经加载的类重新触发类加载
*/
void retransformClasses(Class... classes) throws UnmodifiableClassException;
/**
* 获取当前 JVM 加载的所有类对象
*/
Class[] getAllLoadedClasses()
  它的 addTransformer 为 Instrumentation 注册了一个转换器。Transformer 是 ClassFileTransformer 接口的一个实例。这个接口只有一个转换方法。调用addTransformer设置transformer后,后续JVM会在加载所有类之前被这个transform方法拦截。此方法接收原创类文件。字节数组,返回转换后的字节数组,可以在这个方法中做任何类文件的重写。
  public class MyClassTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classBytes) throws IllegalClassFormatException {
// 在这里读取、转换类文件
return classBytes;
}
}
  Java Agent 核心流程
  Java Agent加载时序图(premain):
  
  类加载时序图:
  
  Java 代理使用的 Instrumentation 取决于 JVMTI 实现。当然也可以绕过Instrumentation,直接使用JVMTI来实现Agent。JVMTI 和 JDI 构成了 Java 平台调试架构 (JPDA) 的主要功能。
  Java 代理使用
  Java Agent 实际上是一个特殊的 Jar 包。它不能单独启动,而必须附加到 JVM 进程。可以看成是JVM的寄生插件。它使用 Instrumentation API 来读取和重写当前 JVM 的类。文件,并通过 -javaagent:xxx.jar 导入目标应用程序。
  那么这个Jar和普通Jar有什么区别呢?
  
  Agent需要打包成jar包,在Maininfe.MF属性中指定“Premain-Class”或“Agent-Class”,根据需求定义Can-Redefine-Classes和Can-Retransform-Classes。
  Java Agent Jar包MANIFEST.MF配置参数:
  Manifest-Version: 1.0
#动态 agent 类
Agent-Class: com.zuozewei.javaagent01.Agent
#静态 agent 类
Premain-Class: com.zuozewei.javaagent01.Agent
是否允许重复装载
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_112
  演示预览
  1、创建POM项目Java Agent,项目结构如下:
  
  2、修改pom文件:
  

parent
com.zuozewei
1.0-SNAPSHOT

4.0.0
jar
javaagent01

agent


org.apache.maven.plugins
maven-jar-plugin
2.3.1


src/main/resources/META-INF/MANIFEST.MF




maven-assembly-plugin

${basedir}

true

true


com.zuozewei.javaagent01.Agent



jar-with-dependencies




org.apache.maven.plugins
maven-compiler-plugin

1.7
1.7




  3、创建一个AgentMain类实现控制台打印,添加Transformer为Instrumentation注册一个transformer。
  package com.zuozewei.javaagent01;
import java.lang.instrument.Instrumentation;
public class Agent {
// public static void premain(String agentArgs) {
// System.out.println("我是一个萌萌哒的 Java Agent");
// try {
// Thread.sleep(2000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
public static void premain(String agentArgs, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassFileTransformerDemo());
System.out.println("7DGroup Java Agent");
}
}
  4、创建一个ClassFileTransformerDemo类,截取并打印所有类名。
  package com.zuozewei.javaagent01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class ClassFileTransformerDemo implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
System.out.println("className: " + className);
if (!className.equalsIgnoreCase("com/zuozewei/Dog")) {
return null;
}
return getBytesFromFile("/Users/zuozewei/IdeaProjects/javaagent/example01/target/classes/com/zuozewei/Dog.class");
}
public static byte[] getBytesFromFile(String fileName) {
File file = new File(fileName);
try (InputStream is = new FileInputStream(file)) {
// precondition
long length = file.length();
byte[] bytes = new byte[(int) length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset = 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
is.close();
return bytes;
} catch (Exception e) {
System.out.println("error occurs in _ClassTransformer!"
+ e.getClass().getName());
return null;
}
}
}
  5、定义需要修改的项目example01
  6、需要修改的类的实现。
  主要的:
  package com.zuozewei;
public class Main {
public static void main(String[] args) {
System.out.println("7DGroup");
System.out.println(new Dog().hello());
// System.out.println(new Cat().hello());
}
}
  狗:
  package com.zuozewei;
public class Dog {
public int hello() {
return 0;
}
}
  7、运行example01的main方法:
  
  8、将javaagent项目打包生成jar文件,将java文件与上图example01项目的jar放在同一目录下(方便执行放在同一目录下)
  执行以下命令:
  java -jar -javaagent:agent.jar example.jar
  我们的函数实现了,执行结果如下:
  
  总结
  本文详细介绍了Java Agent启动加载实现字节码增强关键技术的实现细节。字节码增强技术为测试人员监控性能提供了新思路。目前很多开源监控产品都提供了丰富的Java探针库。作为监控服务商,开发成本进一步降低,但开发门槛较高,对测试人员的学习成本有很大的影响。
  源地址:
   查看全部

  文章采集调用(使用Java的Instrumentation接口(java.lang.instrument)(组图)
)
  前言
  在分布式链路跟踪中,为了获取服务之间的调用链信息,采集器通常需要在方法前后进行埋藏。在Java生态系统中,常见的埋点方式有两种:
  依靠SDK手动埋点;使用Java Agent技术做非侵入式埋葬。
  著名的分布式监控系统是由 Zipkin 开创的。最经典的就是了解X-B3 Ttrace协议,使用Brave SDK,手动埋点生成Trace。但是 SDK 中埋点的方式对业务代码是有侵入性的。升级埋点时,必须进行代码更改。
  那么如何将其与业务逻辑解绑呢?
  Java还提供了另一种方式:依靠Java Agent技术对目标方法的字节码进行修改,从而实现非侵入式埋葬。这种使用 Java 代理的 采集器 方式也称为探针。在应用启动时使用-javaagent参数,或者在运行时使用attach(pid)方法,可以将探针包注入到目标应用中,完成埋点的植入。以对业务代码无侵入的方式,实现不敏感的热升级。用户无需了解深层原理,即可使用完整的监控服务
  Java代理介绍
  Java Agent 是 Java 1.5 版本之后引入的一个特性。它的主要作用是在类加载之前对其进行拦截,并且已经插入到我们的监控字节码中。代理是使用 Java 的 Instrumentation 接口 (java.lang.instrument) 编写的。
  基本思路是在JVM启动时添加一个代理(Java Agent),每个代理是一个Jar包,在MANIFEST.MF文件中指定代理类,代理类收录一个premain方法。JVM在类加载的时候会先执行代理类的premain方法,然后再执行Java程序本身的main方法,这就是premain名的来源。在premain方法中,可以修改加载前的类文件。
  这种机制可以认为是虚拟机级别的AOP,无需对原创应用程序进行任何修改即可实现类的动态修改和增强。
  从 JDK 1.6 开始,支持更强大的动态 Instruments,在 JVM 启动后通过 Attach(pid) 远程加载。
  注意:
  无论 Agent 是用 Native 方式还是 Java Instrumentation 接口方式编写的,它们的工作都是在 JVMTI 的帮助下完成的。 JVMTI 是一组 Native 接口。在 Java 1.5 之前,Agent 只能通过编写 Native 代码来实现。
  Java Instrumentation 核心方法
  Instrumentation 是 java.lang.instrument 包下的一个接口。该接口的方法提供了注册类文件转换器、获取所有加载的类等功能,允许我们修改加载和卸载的类来实现AOP、性能监控等功能。
  常用方法:
  /**
* 为 Instrumentation 注册一个类文件转换器,可以修改读取类文件字节码
*/
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
/**
* 对JVM已经加载的类重新触发类加载
*/
void retransformClasses(Class... classes) throws UnmodifiableClassException;
/**
* 获取当前 JVM 加载的所有类对象
*/
Class[] getAllLoadedClasses()
  它的 addTransformer 为 Instrumentation 注册了一个转换器。Transformer 是 ClassFileTransformer 接口的一个实例。这个接口只有一个转换方法。调用addTransformer设置transformer后,后续JVM会在加载所有类之前被这个transform方法拦截。此方法接收原创类文件。字节数组,返回转换后的字节数组,可以在这个方法中做任何类文件的重写。
  public class MyClassTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classBytes) throws IllegalClassFormatException {
// 在这里读取、转换类文件
return classBytes;
}
}
  Java Agent 核心流程
  Java Agent加载时序图(premain):
  
  类加载时序图:
  
  Java 代理使用的 Instrumentation 取决于 JVMTI 实现。当然也可以绕过Instrumentation,直接使用JVMTI来实现Agent。JVMTI 和 JDI 构成了 Java 平台调试架构 (JPDA) 的主要功能。
  Java 代理使用
  Java Agent 实际上是一个特殊的 Jar 包。它不能单独启动,而必须附加到 JVM 进程。可以看成是JVM的寄生插件。它使用 Instrumentation API 来读取和重写当前 JVM 的类。文件,并通过 -javaagent:xxx.jar 导入目标应用程序。
  那么这个Jar和普通Jar有什么区别呢?
  
  Agent需要打包成jar包,在Maininfe.MF属性中指定“Premain-Class”或“Agent-Class”,根据需求定义Can-Redefine-Classes和Can-Retransform-Classes。
  Java Agent Jar包MANIFEST.MF配置参数:
  Manifest-Version: 1.0
#动态 agent 类
Agent-Class: com.zuozewei.javaagent01.Agent
#静态 agent 类
Premain-Class: com.zuozewei.javaagent01.Agent
是否允许重复装载
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_112
  演示预览
  1、创建POM项目Java Agent,项目结构如下:
  
  2、修改pom文件:
  

parent
com.zuozewei
1.0-SNAPSHOT

4.0.0
jar
javaagent01

agent


org.apache.maven.plugins
maven-jar-plugin
2.3.1


src/main/resources/META-INF/MANIFEST.MF




maven-assembly-plugin

${basedir}

true

true


com.zuozewei.javaagent01.Agent



jar-with-dependencies




org.apache.maven.plugins
maven-compiler-plugin

1.7
1.7




  3、创建一个AgentMain类实现控制台打印,添加Transformer为Instrumentation注册一个transformer。
  package com.zuozewei.javaagent01;
import java.lang.instrument.Instrumentation;
public class Agent {
// public static void premain(String agentArgs) {
// System.out.println("我是一个萌萌哒的 Java Agent");
// try {
// Thread.sleep(2000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
public static void premain(String agentArgs, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassFileTransformerDemo());
System.out.println("7DGroup Java Agent");
}
}
  4、创建一个ClassFileTransformerDemo类,截取并打印所有类名。
  package com.zuozewei.javaagent01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class ClassFileTransformerDemo implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
System.out.println("className: " + className);
if (!className.equalsIgnoreCase("com/zuozewei/Dog")) {
return null;
}
return getBytesFromFile("/Users/zuozewei/IdeaProjects/javaagent/example01/target/classes/com/zuozewei/Dog.class");
}
public static byte[] getBytesFromFile(String fileName) {
File file = new File(fileName);
try (InputStream is = new FileInputStream(file)) {
// precondition
long length = file.length();
byte[] bytes = new byte[(int) length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset = 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
is.close();
return bytes;
} catch (Exception e) {
System.out.println("error occurs in _ClassTransformer!"
+ e.getClass().getName());
return null;
}
}
}
  5、定义需要修改的项目example01
  6、需要修改的类的实现。
  主要的:
  package com.zuozewei;
public class Main {
public static void main(String[] args) {
System.out.println("7DGroup");
System.out.println(new Dog().hello());
// System.out.println(new Cat().hello());
}
}
  狗:
  package com.zuozewei;
public class Dog {
public int hello() {
return 0;
}
}
  7、运行example01的main方法:
  
  8、将javaagent项目打包生成jar文件,将java文件与上图example01项目的jar放在同一目录下(方便执行放在同一目录下)
  执行以下命令:
  java -jar -javaagent:agent.jar example.jar
  我们的函数实现了,执行结果如下:
  
  总结
  本文详细介绍了Java Agent启动加载实现字节码增强关键技术的实现细节。字节码增强技术为测试人员监控性能提供了新思路。目前很多开源监控产品都提供了丰富的Java探针库。作为监控服务商,开发成本进一步降低,但开发门槛较高,对测试人员的学习成本有很大的影响。
  源地址:
  

文章采集调用(文章采集调用方案(二):一站式采集工具)

采集交流优采云 发表了文章 • 0 个评论 • 131 次浏览 • 2022-01-13 09:00 • 来自相关话题

  文章采集调用(文章采集调用方案(二):一站式采集工具)
  文章采集调用方案主要有以下两种:1.tob采集:将我们的产品上架后,使用迅捷全程云采集系统接入成为统计入口,统计到一定的量后,向品牌商送达对应的赠品。2.toc客户采集:将产品放到竞品网站上,统计到了一定量后,向竞品送达对应的赠品,或者直接签署采购协议。
  我们学习过国外的seo监控网站管理系统,他们是按自己产品的搜索量,时间,进行收费,目前正在使用,好几个月的收费,价格的确不低。
  采集数据主要看你的用途和价值,是通过帮助自己更好的分析,还是帮助做竞品?更好分析当然最好用f12,如果是做竞品分析,可以用快照采集,慢采取,具体看你用的公司和产品吧,快采好,他更方便,
  资讯类:1。虎嗅创业快讯网;2。懂车帝平台;3。虎嗅“每日看车”专栏;4。汽车之家汽车报道类:1。汽车之家app;2。易车网“每日看车”;3。汽车之家论坛;4。易车网“我的车”;5。爱卡汽车,数据、榜单;其他:1。91training。com;2。石头数据;行业类1。中国汽车流通协会-auto-marketing/2。汽车圈3。易车网“每日销量”4。聚划算5。1918“速度车市”。
  欢迎使用禅道采集器百度搜索:禅道采集器-一站式采集工具 查看全部

  文章采集调用(文章采集调用方案(二):一站式采集工具)
  文章采集调用方案主要有以下两种:1.tob采集:将我们的产品上架后,使用迅捷全程云采集系统接入成为统计入口,统计到一定的量后,向品牌商送达对应的赠品。2.toc客户采集:将产品放到竞品网站上,统计到了一定量后,向竞品送达对应的赠品,或者直接签署采购协议。
  我们学习过国外的seo监控网站管理系统,他们是按自己产品的搜索量,时间,进行收费,目前正在使用,好几个月的收费,价格的确不低。
  采集数据主要看你的用途和价值,是通过帮助自己更好的分析,还是帮助做竞品?更好分析当然最好用f12,如果是做竞品分析,可以用快照采集,慢采取,具体看你用的公司和产品吧,快采好,他更方便,
  资讯类:1。虎嗅创业快讯网;2。懂车帝平台;3。虎嗅“每日看车”专栏;4。汽车之家汽车报道类:1。汽车之家app;2。易车网“每日看车”;3。汽车之家论坛;4。易车网“我的车”;5。爱卡汽车,数据、榜单;其他:1。91training。com;2。石头数据;行业类1。中国汽车流通协会-auto-marketing/2。汽车圈3。易车网“每日销量”4。聚划算5。1918“速度车市”。
  欢迎使用禅道采集器百度搜索:禅道采集器-一站式采集工具

文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)

采集交流优采云 发表了文章 • 0 个评论 • 123 次浏览 • 2022-01-12 12:10 • 来自相关话题

  文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)
  用python制作优采云采集器接口,即使用优采云采集器,优采云采集器中的插件调用函数@>插件调用函数可以设置采集之前需要执行的规则。然后我们就可以做一个界面给我们设置每天需要的条件采集文章.
  
  用python做智能的原理伪原创是通过百度翻译把中文翻译成英文,再从英文翻译成中文得到伪原创的翻译句子。例如,我们将一个 seo 标题从中文翻译成英文:
  
  英文到中文
  
  这样我们就标题:网站“网站seo具体怎么做”智能伪原创”怎么做网站SEO”
  本节使用 python 为 优采云采集器 调用创建一个 伪原创 头接口。比如我们先用python模拟百度翻译过程,然后使用优采云Smart伪原创Title接口插件的源码。一、我们用python模拟百度翻译
  优采云采集器插件样例,下方区域是我们可以用python编辑的区域,那么我们就可以在这个区域编写模拟百度翻译过程
  
  输入python调用selenium浏览器,打开百度翻译窗口,使用xpath输入标题信息,然后进行汉英互译和英汉互译的过程,进行自动操作,最后得到翻译好的标题:
  
  
  完成后,我们将源代码上传到优采云采集器插件
  
  在优采云采集器
  中设置调用插件
  
  接下来让我们测试一下优采云采集器,这样我们就得到了翻译后的seo标题:
  
  有什么不懂的可以关注媒体明星软文宣传平台 查看全部

  文章采集调用(网站“网站seo具体怎么做”智能伪原创”如何做网站SEO)
  用python制作优采云采集器接口,即使用优采云采集器,优采云采集器中的插件调用函数@>插件调用函数可以设置采集之前需要执行的规则。然后我们就可以做一个界面给我们设置每天需要的条件采集文章.
  
  用python做智能的原理伪原创是通过百度翻译把中文翻译成英文,再从英文翻译成中文得到伪原创的翻译句子。例如,我们将一个 seo 标题从中文翻译成英文:
  
  英文到中文
  
  这样我们就标题:网站“网站seo具体怎么做”智能伪原创”怎么做网站SEO”
  本节使用 python 为 优采云采集器 调用创建一个 伪原创 头接口。比如我们先用python模拟百度翻译过程,然后使用优采云Smart伪原创Title接口插件的源码。一、我们用python模拟百度翻译
  优采云采集器插件样例,下方区域是我们可以用python编辑的区域,那么我们就可以在这个区域编写模拟百度翻译过程
  
  输入python调用selenium浏览器,打开百度翻译窗口,使用xpath输入标题信息,然后进行汉英互译和英汉互译的过程,进行自动操作,最后得到翻译好的标题:
  
  
  完成后,我们将源代码上传到优采云采集器插件
  
  在优采云采集器
  中设置调用插件
  
  接下来让我们测试一下优采云采集器,这样我们就得到了翻译后的seo标题:
  
  有什么不懂的可以关注媒体明星软文宣传平台

官方客服QQ群

微信人工客服

QQ人工客服


线