Antispam,反垃圾,反作弊

关键词: 搜索引擎优化 反作弊 antispam

Antispam 就是反垃圾、反作弊的意思,spam的意思是:兜售信息[邮件,广告,新闻,文章],非索要信息。与垃圾邮件(junk mail)同义。Anti就是反对、去除的意思。这个词汇多用于反垃圾邮件。也用于形容搜索引擎反垃圾信息。Spam和antispam在搜索引擎诞生之 日起就开始了无休止的搏杀。因为有巨大的商业利益掺杂其中。

2003年上半年之前中文搜索引擎基本上没有大规模的搜索引擎作弊。2002年的时候百度的讨论区有搜索引擎爱好者讨论搜索技巧、搜索引擎相关知识会讨论到优化、友好,但是范围非常小,气氛主体是搜索技巧。也有部分人和公司做搜索引擎优化的,但是仅仅是针对某几个词汇做链接以获取在google的排名收取企业费用。当时我们还讨论过作弊和友好的界限定义很难区分的问题,现在想想,当时这种问题对中国人来说根本没有必要讨论。

2003下半年中文搜索引擎作弊大面积泛滥,一时间“google、百度被爆奸了”甚至有人可以包揽某类关键词前几十页的所有条目,有人声称可以将任何词汇做到百度的前几名……,到2005年已经是全民作弊了。

这时候,antispam成为中文搜索引擎的重点工作之一了。搜索引擎反作弊从开始以来一直都是处于被动防守状态,这是因为必须有人作弊,才能反作弊,几乎不可能预知作弊的新方式来预先antispam。而且也不存在破窗理论,因为一个网站作弊在某搜索引擎无效,但是会在其它搜索引擎有效。长期无效,但是短期有效。

Antispam的目的是为了改善用户体验,丢弃垃圾信息。垃圾信息包括重复无穷次的信息和没有任何价值的信息,internet本来就存在很多的垃圾页面和垃圾信息和重复信息,再加上有很多人为的制作垃圾信息,那搜索引擎反垃圾就凸现出重要性了。

反作弊其实不难,搜索引擎能管理数十亿的信息,那管理这么点垃圾信息还不是很轻松的事情?因为作弊具有共性,抓住这些共性就可以解决一类问题,一类问题一类问题的解决,作弊的影响就可以降到最低。极大程度的增加作弊的成本和风险。

方法大致可以如下:建立每个网页和网站的spam系数,这个系数和这些参数相关:
1.建立常用spam词表,分级别,分类。
2.通过常用spam词表分析相关词汇重复频率、密度、位置、分布情况。设定多个阀值,每个阀值进行处理不同的处理。
3.链接数量、质量、锚文本分析、spam链接工厂分析,进行spam判断。
4.桥页,跳转页面、鬼文等各种常用作弊手法分析。
5.搜索结果页面判断
6.重复信息判断……
当spam系数超过某个阀值的时候这个网页就被删除或者降权、当网站spam系数(网站spam系数来源于网站的页面spam系数加权)达到某个阀值的时 候这个网站就进入spam管理人员的待处理信息列表中,spam管理人员进行人工判断,如果确实作弊那就把权值降到0%,或者直接删除。
如果更深入一些可以再做:
1.更深入的重复信息判断(重复信息的识别,可以识别到段,甚至句。对互联网上重复了1000次的spam的信息降低权值索引或不索引)
2.基于视觉的网页块分析,对网页视觉中心的内容进行加权,非视觉中心的内容降权或者根据spam系数非视觉中心的内容不索引入库,
3.简单的语法分析网页的正文内容是否符合正常的自然语言描述
4.统计用户的点击行为、浏览行为进行分析。统计网站各类词汇的排名情况,找出不正常的网站……
5.结构化信息抽取,针对链接的描述语言作为锚文本,同时降低锚文本的权值。(在垂直搜索引擎中更有效)
6.其它一些技术来凸出优质信息。


还存在一些问题:
1.比如我的文章在我的小站发布了,搜索引擎去重后留下的是其它网站转载的信息……(百度把我这个页面去重掉了20060121)
2.反作弊后有很多域名不存在了,但是有用户会需要这些网站?如何解决这个用户体验?建一个spam网页索引?
3.最大的问题是误判很正常,也很多,那误判怎么办?作弊网站的恢复机制?
还有就是spam的标准问题可能在不久的将来会成为一个焦点。
4.本文是随笔,会不断更新,如转载请保留原文链接,谢谢!
5.这篇文章我写了两次,感觉现在这个版本没有第一个版本的好。写两次是因为我在表单直接填写,结果session过期了,导致数据丢失,浪费了我一个小时。
6.按照spam的定义,百度的竞价排名也是spam。广告在恰当的时候是搜索引擎内容的补充,那有没有可能利用垃圾页面?

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当然可以,下面是一个使用 Spring AOP 实现防刷接口的示例: 1. 创建一个注解,用于标识要进行防刷的接口: ``` import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AccessLimit { int seconds(); int maxCount(); boolean needLogin() default true; } ``` 2. 创建一个切面,在切点中使用上述注解,并在通知中进行防刷的逻辑处理: ``` import java.util.concurrent.TimeUnit; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.RedisScript; @Aspect @Configuration public class AccessLimitAspect { private final RedisTemplate<String, Object> redisTemplate; public AccessLimitAspect(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } @Pointcut("@annotation(com.example.demo.annotation.AccessLimit)") public void accessLimitPointcut() { } @Around("accessLimitPointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); AccessLimit accessLimit = signature.getMethod().getAnnotation(AccessLimit.class); int seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); boolean needLogin = accessLimit.needLogin(); StringBuilder keyBuilder = new StringBuilder(); keyBuilder.append(signature.getDeclaringTypeName()).append(".").append(signature.getName()); if (needLogin) { // 如果需要登录,则将用户的登录信息作为 key 的一部分 keyBuilder.append( ### 回答2: Spring Boot提供了AOP(面向切面编程)的支持,可以通过切面来实现接口的防刷功能。 首先,需要引入`spring-boot-starter-aop`依赖包。 接下来,创建一个切面类(如`RateLimitAspect`),并加上`@Aspect`和`@Component`注解,表示该类是一个切面并且会被Spring Boot自动扫描。 在切面类中定义一个切点,用于指定哪些方法需要进行防刷操作。可以使用`@Pointcut`注解来定义切点表达式,如下所示: ```java @Pointcut("execution(public * com.example.demo.controller.*.*(..))") public void rateLimit() {} ``` 上面的切点表达式表示拦截`com.example.demo.controller`包下的所有公共方法。 然后,在切面类中定义一个环绕通知方法,用来实现具体的防刷逻辑。可以使用`@Around`注解来声明环绕通知,并在方法中编写相应的逻辑,如下所示: ```java @Around("rateLimit()") public Object doRateLimit(ProceedingJoinPoint joinPoint) throws Throwable { // 实现防刷逻辑 // 获取方法参数 Object[] args = joinPoint.getArgs(); // 根据方法参数进行限流 // 如果达到限流条件,可以抛出异常或者返回一个自定义的错误信息 // 没有达到限流条件,则继续执行原方法 Object result = joinPoint.proceed(args); return result; } ``` 上面的代码中,`ProceedingJoinPoint`对象表示连接点(被拦截的方法),通过调用`getArgs()`方法可以获取方法的参数。 在`doRateLimit()`方法中,我们可以根据具体的业务需求实现防刷逻辑,比如进行计数、限制访问频率等操作。 最后,需要在`application.properties`文件中配置AOP的开关,添加如下配置: ``` spring.aop.auto=true ``` 这样,通过切面和环绕通知的配合,就可以实现接口的防刷功能了。当有请求访问被切点定义的方法时,会先经过切面的处理,然后再执行原方法。 ### 回答3: Spring Boot提供了AOP(Aspect Oriented Programming)的功能,可以很方便地实现接口防刷的切面。 首先,在Spring Boot项目中引入相关的依赖,包括`spring-boot-starter-aop`和`javax.annotation-api`。 接着,在项目的配置类上添加`@EnableAspectJAutoProxy`注解,开启AOP的自动代理功能。 然后,定义一个自定义注解`@AntiSpam`,用于标记需要进行接口防刷处理的方法: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AntiSpam { int limit() default 5; // 指定限制的次数,默认5次 int interval() default 60; // 指定限制的时间间隔,默认60秒 } ``` 接下来,编写切面类`AntiSpamAspect`,实现接口防刷的逻辑: ```java import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Aspect @Component public class AntiSpamAspect { private Map<String, Integer> countMap = new ConcurrentHashMap<>(); @Pointcut("@annotation(antiSpam)") public void limitPointcut(AntiSpam antiSpam) {} @Before("limitPointcut(antiSpam)") public void doBefore(JoinPoint joinPoint, AntiSpam antiSpam) { String methodName = joinPoint.getSignature().toLongString(); int limit = antiSpam.limit(); int interval = antiSpam.interval(); long currentTime = System.currentTimeMillis() / 1000; // 获取当前时间,单位为秒 synchronized (countMap) { int count = countMap.getOrDefault(methodName, 0); long lastTime = countMap.getOrDefault(methodName + "_time", 0L); if (currentTime - lastTime < interval) { if (count >= limit) { throw new RuntimeException("接口调用频率过高,请稍后再试!"); } else { countMap.put(methodName, count + 1); } } else { countMap.put(methodName, 1); } countMap.put(methodName + "_time", currentTime); } } } ``` 最后,在需要进行接口防刷处理的方法上添加`@AntiSpam`注解,即可实现接口防刷的功能: ```java @RestController public class MyController { @AntiSpam(limit = 3, interval = 30) // 每30秒内最多只能调用3次 @GetMapping("/api/test") public String testApi() { // 执行业务逻辑 return "success"; } } ``` 以上就是一个基本的Spring Boot接口防刷的切面的实现方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值