什麼是反爬蟲?
- 人家的服務器, 是給用戶服務的, 而爬蟲會佔用服務器資源
- 服務器能夠獲取向服務器發送請求的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代理, 修改以前的電子書城代碼
下一節