搜索
首页后端开发php教程大家有什么好方法,防止页面被机器人curl抓取?

以前一直研究抓取别人的页面内容,现在想请教一下各位前辈,根据大家的经验,有什么好方法防止页面被抓取吗?

我以前遇到2种情况,比较难抓取(指的是自动程序批量获取).
第一种:生成复杂的cookie验证,每几分钟过期一次,要curl抓取的话,每次都要手动粘贴cookie到CURLOPT_HEADER里。

第二种:如果一个IP在一段时间内频繁的抓取(指的是类似GOOGLE的搜索结果页面),那么隔一段会跳出一个验证码,需要人工验证。

别的,像内容写进js里,再打印到页面里之类的都可以破解以后批量获取。

各位前辈,请教你们的高见,最好能秀一下大家的代码,供大家切磋、破解。


回复讨论(解决方案)

图片....

我知道一个貌似是reboot.txt的文件放在网站中可以设置搜索引擎抓取页面。

期待牛人来回答一下,我就学习一下。

curl好像可以跟浏览者搞的一模一样啊,可以用其他思路搞,比如加很多垃圾代码,里面有你域名的连接,无规则的加入,像织梦防采集那样,这样采集你的人,他很难通过正则匹配到你的内容,就算匹配的差不多,每个页面都会有几个你的链接,如果他愿意采集,呵呵,免费外链也可以啊。

只要是浏览器能看到的,curl就能抓到
可灵活使用 CURLOPT_COOKIESESSION、CURLOPT_COOKIE、CURLOPT_COOKIEFILE、CURLOPT_COOKIEJAR 来处理 cookie,并不存在楼主的“每次都要手动粘贴cookie到CURLOPT_HEADER里”
虽然可以用js代码验证并跳转来阻止curl的动作,但下载 linux 下执行js代码的php扩展业已存在了

唯一可行的方案就是检测访问的频率
目前很多网站都是用此法,不过不是弹出对话框。而是输出无效的页面内容,让你白干一场

唯一可行的方案就是检测访问的频率
目前很多网站都是用此法,不过不是弹出对话框。而是输出无效的页面内容,让你白干一场

伟大的斑竹大人,有没有实例代码供小弟学习一下?谢谢。

我也来这里学习一下啊 

应该无法防止机器人抓取网页吧,唯一可行的方案就是检测访问的频率~~~

如何最经济的检测访问的频率呢?建立临时数据表?session?

我大概几年前遇到过一个机票网站,它们采用了一种方法,令我当时束手无策。

刚才又回忆了一下,现在发出来,大家一起探讨下。
当然我不能完全获悉它的所有细节,只是根据当时的研究自己做了一些推测,他使用的方法大概如下:

页面第一次加载后,只是将一些基本的html加载出来,js会通过ajax将关键性的数据通过ajax请求回来,返回的可以是json,然后在通过页面js讲json解析,绘制到页面上。问题的关键是做那次ajax请求时,需要带一个特殊的参数过去才能正确获得数据。并且这个通过这个参数获得数据后,这个参数就失效了。而这个参数应该是有一定算法的,并且由这个动态页面在加载的同时生成。


做法大概可以这样:
1 请求页面a.php,a.php页面在生成需要返回浏览器的html的同时,根据特定算法生成一个验证串abc123(并且每次请求都生成的串都不一样),并写入数据库或第三方存储媒介。

2 a.php的html返回浏览器后,拼接出需要ajax请求的url,并且最后附加一个参数,就是刚才生成的验证串abc123。然后执行ajax的请求。接收ajax请求的页面,去数据库中查询一下这个abc123是否存在。如果存在,则返回正确的json数据,否则不返回或返回异常。


这样做,对于采集的一方来说。当你去抓那个a.php时,抓到之后ajax会自动执行一次。这个时候,你抓回来的页面虽然可以看到a.php中ajax请求得到的数据,你会发现源代码中没有它。而你想再用a.php的html源代码中的ajax url去请求一次,发现生成的那个abc123验证串已经失效了。


做个实验吧,先不考虑验ajax证串的问题:
1.php(也就是我们抓取方的脚本)

<?phpfunction request( $url, $header = '', $postfields = '' ){		$ch = curl_init();		$options = array(			CURLOPT_URL => $url,			CURLOPT_HEADER => 0,			//CURLOPT_HTTPHEADER => $header,			CURLOPT_NOBODY => 0,			CURLOPT_PORT => 80,			CURLOPT_POST => 1,			CURLOPT_POSTFIELDS => $postfields,			CURLOPT_RETURNTRANSFER => 1,			CURLOPT_FOLLOWLOCATION => 1,			//CURLOPT_COOKIEJAR => $cookie_jar,			//CURLOPT_COOKIEFILE => $cookie_jar,			//CURLOPT_SSL_VERIFYPEER => 0,			//CURLOPT_SSL_VERIFYHOST => 1,			CURLOPT_TIMEOUT => 30		);		curl_setopt_array($ch, $options);		$code = curl_exec($ch);		curl_close($ch);		return $code;}$url = 'http://www.angryfrog.com/2.php';echo request($url);



2.php(被抓取方的页面)
<script src="./js/jquery-1.7.1.min.js"></script><script>	$(document).ready(function(){		$.get('http://www.angryfrog.com/3.php', '', function(data){ d=$.parseJSON(data);$('#tmp').html(d.node1);});	});</script><a id="tmp"></a>



3.php(被抓取方的ajax接口)
<?php$a = array(	'node1' => 'data1',	'node2' => 'data2');echo json_encode($a);



当我执行1.php后,页面显示的结果如下:


但我查看1.php的源代码,发现:


请问,1.php页面上显示的那个data1在哪?

修改一下我的1.php,将抓取后的结果写入一个临时文件。也就是将
echo request($url);
改为
file_put_contents('./tmp', request($url););

再次执行1.php后,查看文件tmp:


发现结果还是一样,无法得到那个data1



上面的例子证明通过一次请求对方的脚本页面,虽然浏览器上可以看到我们想要的数据,但源代码里是没有的。因为那数据是通过第二次ajax请求得到的。

那么我们也模拟下它的ajax,再做一次请求如何?

假如按我开头的思路,ajax请求地址中有个参数是验证串的话,通过查看2.php的源代码,ajax模拟请求的url为
http://www.angryfrog.com/3.php?vcode=123abc

想再模拟ajax做一次请求时,3.php去数据库中检查这个123abc的验证串,发现那个123abc已经过期了(在数据库中不存在了),因为第一次请求成功后,3.php会将它从数据库中删除。那么既然过期了,3.php可以选择不返回正确数据了。


这就造成了个矛盾,我不请求2.php,就没法生成那个验证串。但我请求了2.php,它又会自动去请求下3.php,把生成的验证串给废掉。

所以我当时没有成功,不知这种情况如何破。大家有没有啥好办法?能否成功请求2.php,让他生成出验证串,但又不自动去做ajax请求以至于不废掉生成出来的串,被我们得到后自己拿着去做ajax请求?

sorry,突然想到,我那个想法是有bug的。

我只测试了同域的情况下,如果是真实情况的话,ajax请求是不可能被自动执行成功的。因为跨域了。

当我们从自己的服务器去请求对方页面,得到html和js,包括那些ajax。回到我们的浏览器后。域就变成我们自己服务器的了,这时页面上的ajax不可能跨域请求成功对方的ajax接口。也就谈不上那个生成的验证码被自动销毁的情况了。看来这种方法不行。

又仔细回忆了一下(时间实在太久远了)。当时我确实是看到对方页面上的ajax,并且包含了一个可疑的参数,每次请求得到后的都不同(而且确认不是为了防止cache用的),但当我自己尝试带着这个参数去请求这个url时,什么结果也得不到。而通过它的页面,请求这个地址却可以返回数据。不知是什么原因,referer、user-agent我也都模拟了。

可不可以这样?a.php页面生成验证串写入数据库后,这个串在很短的时间内就会失效。比如1秒。这点用redis或memcached就很容易做到,给那个key做一个失效时间。

当我们通过脚本抓取a.php后,需要分析它的源代码,找出ajax请求的地址,再去请求,时间会比较长,这个过程可能会超过1秒,那个验证串已经失效了,ajax接口则不会成功返回数据。而正常访问它的页面,页面执行ajax,速度会比较快不会超过1秒,因此能成功得到数据。


明天有时间,我把完整的代码写下试试看。

php_v8js 的作用是在 php 中执行 js 代码
而楼上的描述使用 php 去模拟 js 的动作

这显然不是一回事

这个问题其实说到底是看哪一方不惜工本
防的一方不惜工本,迫使抓的一方在考虑成本效益后放弃
抓的一方不惜工本,防的一方在考虑用户流失后放弃

你们还没见过那些疯狂的人而已

总的来说,在open web时代,抓的一方所花费成本要低很多

刘明,等看

采用加密算法生成相对复杂的认证标志,只有带这个标志才可访问,同时入口处提供验证码识别。
而验证码识别会降低用户体验。
而只是使用复杂的认证标志,一旦生成算法破解,一样可以批量发起请求。
总的来说,人能通过浏览器访问无非就是发送http请求,那么机器同样可以做到,无非是机器要先采集数据,分析清楚访问流程而已。

@ShadowSniper, 很好的实例哦,开阔思路了。
这就想到于:
浏览器访问A页面时,生成一个随机码,该随机码作为ajax参数传递到B页面,B页面需要验证这个随机码的合法性,然后返回数据到A页面。
所以直接curl A页面的话,什么也得不到。
直接curl B页面(ajax页面的话),由于没有合法的随机码,所以还是什么也得不到。

@ShadowSniper, 很好的实例哦,开阔思路了。
这就想到于:
浏览器访问A页面时,生成一个随机码,该随机码作为ajax参数传递到B页面,B页面需要验证这个随机码的合法性,然后返回数据到A页面。
所以直接curl A页面的话,什么也得不到。
直接curl B页面(ajax页面的话),由于没有合法的随机码,所以还是什么也得不到。

错了吧?
直接curlA,得到了一个随机码,然后模拟curlB并带着刚才那个随机码,不就获取最终想要的数据了么。
同时,你说的“B页面需要验证这个随机码的合法性,然后返回数据到A页面”,这个数据就是最终想要的数据,而这个数据只需要带上随机码就可以了。

@ShadowSniper, 很好的实例哦,开阔思路了。
这就想到于:
浏览器访问A页面时,生成一个随机码,该随机码作为ajax参数传递到B页面,B页面需要验证这个随机码的合法性,然后返回数据到A页面。
所以直接curl A页面的话,什么也得不到。
直接curl B页面(ajax页面的话),由于没有合法的随机码,所以还是什么也得不到。

难道你防的仅仅是curl?那整个造盾思路就错了
要防的是这个   点击看维基-webkit
现在基于webkit的矛(非GUI浏览器)多的是,远超curl了


csdn 
都被抓取 
http://s.yanghao.org/program/viewdetail.php?i=393421

引用 18 楼 changjay 的回复:@ShadowSniper, 很好的实例哦,开阔思路了。
这就想到于:
浏览器访问A页面时,生成一个随机码,该随机码作为ajax参数传递到B页面,B页面需要验证这个随机码的合法性,然后返回数据到A页面。
所以直接curl A页面的话,什么也得不到。
直接curl B页面(ajax页面的话),由于没有合法的随机码,所以还是什……


我说的那个方法,大概思路是对的。但我一开始没考虑跨域的问题。

a页面生成验证码,写入db。a带着这个验证码去请求b接口,b接口拿到a传过来的验证码,去db里查询是否存在,如果存在,就返回正确数据,并且从db中清除掉这个验证码。

所以由a页面生成的验证码,只能使用一次。

当你模拟请求a页面,a不光会生成一个验证码,同时会把这个流程走完,并且销毁掉这个验证码。也会返回数据,但这一次你无法得到a页面返回的数据(只能看到,但得不到。不信拿我的那几个例子去试验下)

而一般来说,页面中含有ajax的二次请求,我们应该在第一次请求得到页面中ajax请求的地址后,用正则分析出a页面生成的验证码和他ajax请求的地址,再用php带着这个验证码去请求一次。希望通过这样,来得到正确的数据。但可惜的是,在你第一次模拟请求a页面时,他已经把整个流程走完了,包括页面中的ajax会自动执行。那个生成验证码也被销毁了。所以这里就造成了个矛盾的问题。
这种情况,抓取方和被抓取方处于同域的情况下,是可以实现的。

但实际情况中,抓取方不可能和被抓取方处于同域,所以请求a页面后,可以得到生成的验证码,但是ajax请求不会成功,因为跨域。所以那个生成的验证码也不会被销毁。那么我们就可以拿到验证码后,再用php去请求一下那个ajax地址来获得正确的数据。

引用 18 楼 changjay 的回复:@ShadowSniper, 很好的实例哦,开阔思路了。
这就想到于:
浏览器访问A页面时,生成一个随机码,该随机码作为ajax参数传递到B页面,B页面需要验证这个随机码的合法性,然后返回数据到A页面。
所以直接curl A页面的话,什么也得不到。
直接curl B页面(ajax页面的话),由于没有合法的随机码,所以还是什……


a.php

function request( $url, $header = '', $postfields = '' ){		$ch = curl_init();		$options = array(			CURLOPT_URL => $url,			CURLOPT_HEADER => 0,			//CURLOPT_HTTPHEADER => $header,			CURLOPT_NOBODY => 0,			CURLOPT_PORT => 80,			CURLOPT_POST => 1,			CURLOPT_POSTFIELDS => $postfields,			CURLOPT_RETURNTRANSFER => 1,			CURLOPT_FOLLOWLOCATION => 1,			//CURLOPT_COOKIEJAR => $cookie_jar,			//CURLOPT_COOKIEFILE => $cookie_jar,			//CURLOPT_SSL_VERIFYPEER => 0,			//CURLOPT_SSL_VERIFYHOST => 1,			CURLOPT_TIMEOUT => 30		);		curl_setopt_array($ch, $options);		$code = curl_exec($ch);		curl_close($ch);		return $code;}$url = 'http://www.angryfrog.com/b.php';echo request($url);


b.php
<script>alert(123);</script>



执行一下a.php,b.php中的js返回后会被自动执行。

ShadowSniper研究的比较深,谢谢。好好再琢磨一下。

抓数据,一般只抓页面,页面里的图片,CSS,JS等等都是不会继续向服务器请求的。所以很容易判断哪些用户的请求是爬虫,哪些不是:)

访问频率检查方案方面,请问大家有什么经验指点?

//第一步:入口文件检测IP黑名单实现禁止访问

//第二步:访问频率检测
$ip = get_client_ip();    //获取访问者IP
$ipCode = md5($ip);
$次数 = intval($cache->get($ipCode));  //把null转成0
if($次数 set($ipCode, ++$次数, 3000);  //缓存过期时间为3000毫秒=3秒
else{
    //将该IP加入黑名单,N天/N个小时后解除黑名单
}

建议在 .htaccess直接屏蔽对方的 IP地址段。
当然,也可以考虑iptables;

用js joson可以增加难度

抓数据,一般只抓页面,页面里的图片,CSS,JS等等都是不会继续向服务器请求的。所以很容易判断哪些用户的请求是爬虫,哪些不是:)
怎么理解,分析客户端是否下载了CSS,JS文件?这个怎么判断?还有怎么可以分辨出是搜索引擎爬虫还是不良爬虫?

引用 25 楼 LuciferStar 的回复:抓数据,一般只抓页面,页面里的图片,CSS,JS等等都是不会继续向服务器请求的。所以很容易判断哪些用户的请求是爬虫,哪些不是:)
怎么理解,分析客户端是否下载了CSS,JS文件?这个怎么判断?还有怎么可以分辨出是搜索引擎爬虫还是不良爬虫? 这个应该是服务器上防止采集的一个策略吧。
估计得服务器软件进行行为控制了。

mark  我也碰到过这样的问题 好像大多防这个都是服务器去处理了

sorry,突然想到,我那个想法是有bug的。

我只测试了同域的情况下,如果是真实情况的话,ajax请求是不可能被自动执行成功的。因为跨域了。

当我们从自己的服务器去请求对方页面,得到html和js,包括那些ajax。回到我们的浏览器后。域就变成我们自己服务器的了,这时页面上的ajax不可能跨域请求成功对方的ajax接口。也就谈不上那个生成的验证码被自动销毁……
大牛,腾讯新闻的好像也是这种高法,内容关键性的js全部是动态的 还各种包含,呵呵,头大

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP的当前状态:查看网络开发趋势PHP的当前状态:查看网络开发趋势Apr 13, 2025 am 12:20 AM

PHP在现代Web开发中仍然重要,尤其在内容管理和电子商务平台。1)PHP拥有丰富的生态系统和强大框架支持,如Laravel和Symfony。2)性能优化可通过OPcache和Nginx实现。3)PHP8.0引入JIT编译器,提升性能。4)云原生应用通过Docker和Kubernetes部署,提高灵活性和可扩展性。

PHP与其他语言:比较PHP与其他语言:比较Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP与Python:核心功能PHP与Python:核心功能Apr 13, 2025 am 12:16 AM

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHP:网络开发的关键语言PHP:网络开发的关键语言Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP:许多网站的基础PHP:许多网站的基础Apr 13, 2025 am 12:07 AM

PHP成为许多网站首选技术栈的原因包括其易用性、强大社区支持和广泛应用。1)易于学习和使用,适合初学者。2)拥有庞大的开发者社区,资源丰富。3)广泛应用于WordPress、Drupal等平台。4)与Web服务器紧密集成,简化开发部署。

超越炒作:评估当今PHP的角色超越炒作:评估当今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在现代编程中仍然是一个强大且广泛使用的工具,尤其在web开发领域。1)PHP易用且与数据库集成无缝,是许多开发者的首选。2)它支持动态内容生成和面向对象编程,适合快速创建和维护网站。3)PHP的性能可以通过缓存和优化数据库查询来提升,其广泛的社区和丰富生态系统使其在当今技术栈中仍具重要地位。

PHP中的弱参考是什么?什么时候有用?PHP中的弱参考是什么?什么时候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通过WeakReference类实现的,不会阻止垃圾回收器回收对象。弱引用适用于缓存系统和事件监听器等场景,需注意其不能保证对象存活,且垃圾回收可能延迟。

解释PHP中的__ Invoke Magic方法。解释PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允许对象像函数一样被调用。1.定义\_\_invoke方法使对象可被调用。2.使用$obj(...)语法时,PHP会执行\_\_invoke方法。3.适用于日志记录和计算器等场景,提高代码灵活性和可读性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具