什么是反爬虫?
- 人家的服务器, 是给用户服务的, 而爬虫会占用服务器资源
- 服务器能够获取向服务器发送请求的IP
- 若是某个IP, 短期高频访问, 服务器就会禁掉该IP
爬虫伦理
- 一般状况下,服务器不太会在乎小爬虫,
- 可是,服务器会拒绝频率很高的大型爬虫和恶意爬虫,由于这会给服务器带来极大的压力或伤害
- 服务器在一般状况下,对搜索引擎是欢迎的态度(谷歌和百度的核心技术之一就是爬虫)。
- 固然,这是有条件的,而这些条件会写在Robots协议。
- Robots协议是互联网爬虫的一项公认的道德规范,
- 全称是“网络爬虫排除标准”(Robots exclusion protocol),
- 这个协议用来告诉爬虫,哪些页面是能够抓取的,哪些不能够。
- 如何查看网站的robots协议呢,很简单,在网站的域名后加上/robots.txt就能够了。
- 淘宝的robots协议 ( www.taobao.com/robots.txt)。
- 在截取的部分,能够看到淘宝对百度和谷歌这两个爬虫的访问规定,以及对其它爬虫的规定。
User-agent: Baiduspider
Allow: /article
Allow: /oshtml
Allow: /ershou
Allow: /$
Disallow: /product/
Disallow: /
User-Agent: Googlebot
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /oversea
Allow: /list
Allow: /ershou
Allow: /$
Disallow: /
……
User-Agent: *
Disallow: /
复制代码
- 网站的服务器被爬虫爬得多了,也会受到较大的压力,所以,各大网站也会作一些反爬虫的措施。
- 不过呢,有反爬虫,也就有相应的反反爬虫
- 限制好爬虫的速度,对提供数据的服务器心存感谢,避免给它形成太大压力,维持良好的互联网秩序
若是反反爬虫?
- 有反爬虫, 就有反反爬虫
- 既然是高频访问会受限制, 那么解决方案有两个
- 第一, 设置sleep, 下降同一IP的访问频率
- 第二, 使用IP代理池, 每次都用不一样的IP
选择一个靠谱的IP代理商
PHP使用阿布云建立IP代理池
须要打开curl扩展
测试是否成功, 示例代码, 输出当前IP
<?php
$targetUrl = "http://test.abuyun.com";
$proxyServer = "http://http-dyn.abuyun.com:9020";
$proxyUser = "H19D75L76VK89Q8D";
$proxyPass = "8C17B0A80F475BD8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $targetUrl);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
curl_setopt($ch, CURLOPT_PROXY, $proxyServer);
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$proxyUser}:{$proxyPass}");
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727;)");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
var_dump($result);
复制代码
和querylist结合, 每次请求获取请求IP
<?php
require 'vendor/autoload.php';
use QL\QueryList;
$ql = new QueryList();
$data = $ql->html(get_html_source('http://ip.tool.chinaz.com/'))->rules([
'ip'=>['#rightinfo > dl > dd.fz24','text'],
'address'=>['#rightinfo > dl > dd:nth-child(4)','text']
])->queryData();
var_dump($data);
function get_html_source($url) {
$result = false;
while (!$result) {
$targetUrl = $url;
$proxyServer = "http://http-dyn.abuyun.com:9020";
$proxyUser = "H19D75L76VK89Q8D";
$proxyPass = "8C17B0A80F475BD8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $targetUrl);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
curl_setopt($ch, CURLOPT_PROXY, $proxyServer);
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$proxyUser}:{$proxyPass}");
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727;)");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if(!$result){
sleep(2);
}
curl_close($ch);
}
return $result;
}
复制代码
舒适提示: 动态版的一个问题...
- 动态版是每次请求都会换一个ip
- 可是并非每一个IP都能用
- 因此须要写一个循环, 若是获取不到数据, 就一直换着ip访问
- 可是还有一个细节, 若是你是每秒只能有一次请求, 那么频繁的换ip就会一直false, 死循环
- 还须要加上
sleep(2)
- 因此仔细观察上一个代码, 咱们的函数里有while(), 也有sleep
做业, 使用ip代理, 修改以前的电子书城代码
下一节