在爬取的過程當中不免發生ip被封和403錯誤等等,這都是網站檢測出你是爬蟲而進行反爬措施,這裏本身總結下如何避免
有一些網站的防範措施可能會由於你快速提交表單而把你當作機器人爬蟲,好比說以很是人的速度下載圖片,登陸網站,爬取信息。html
常見的設置等待時間有兩種,一種是顯性等待時間(強制停幾秒),一種是隱性等待時間(看具體狀況,好比根據元素加載完成須要時間而等待)python
1.顯性等待時間web
import time#導入包 time.sleep(3)#設置時間間隔爲3秒
並且儘可能在夜深人靜的時候進行數據的採集,切記採集不要太快,否則容易讓網站識別出你個非人類redis
2.隱式等待
這裏用到的主要語句,以wait.until()爲例
好比說形式以下api
wait1.until(lambda driver: driver.find_element_by_xpath("//div[@id='link-report']/span"))
上面的語句就是在等待頁面元素加載所有完成後才進行下一步操做,由於爬蟲速度太快,致使一些元素沒有被加載徹底就進行下一步操做而致使沒有查找到元素或者被網站認爲是機器人在進行瀏覽。瀏覽器
具體的案例能夠在我之前的文章中詳細應用Python自定義豆瓣電影種類,排行,點評的爬取與存儲(進階下)網絡
識別你是機器人仍是人類瀏覽器瀏覽的重要依據就是User-Agent,好比人類用瀏覽器瀏覽就會使這個樣子的User-Agent:'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'框架
這裏拿urllib2來講,默認的User-Agent是Python-urllib2/2.7,因此要進行修改。less
import urllib2
req = urllib2.Request(url)
#多瞭如下一這一步而已
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36') response = urllib2.urlopen(req)
當本身的ip被網站封了以後,只能採起換代理ip的方式進行爬取,因此,我建議,每次爬取的時候儘可能用代理來爬,封了代理,還有代理,無窮無盡啊,可別拿代理去黑學校網站啊,你懂得0.0
廢話很少說,扔上代理的實現程序dom
# -*- coding: utf-8 -*- import urllib2 url = "http://www.ip181.com/" proxy_support = urllib2.ProxyHandler({'http':'121.40.108.76'}) #參數是一個字典{'類型':'代理ip:端口號'} opener = urllib2.build_opener(proxy_support) #定製opener opener.add_handler=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')] #add_handler給加上假裝 urllib2.install_opener(opener) response = urllib2.urlopen(url) print response.read().decode('gbk')
這裏採用的測試網站是http://www.ip181.com, 它能夠檢測出你使用的ip是什麼,正好來檢驗本身是否用代理ip成功
從結果中能夠看出,檢測出了代理ip,正是我本身加上的ip值,此乃最後一招,當本身ip被封后,採用代理ip進行訪問。
要是一個代理ip掛了怎麼辦,那你能夠作個ip池啊,就是把一堆代理ip放在一塊兒,每次運行時從ip池挑一個代理ip當作訪問ip就能夠了!
採用ip池的方法~舉個栗子
# -*- coding: utf-8 -*- import urllib2 import random ip_list=['119.6.136.122','114.106.77.14'] #使用一組ip調用random函數來隨機使用其中一個ip url = "http://www.ip181.com/" proxy_support = urllib2.ProxyHandler({'http':random.choice(ip_list)}) #參數是一個字典{'類型':'代理ip:端口號'} opener = urllib2.build_opener(proxy_support) #定製opener opener.add_handler=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')] #add_handler給加上假裝 urllib2.install_opener(opener) response = urllib2.urlopen(url) print response.read().decode('gbk')
採用代理ip池的方法,能夠看出,檢測出的ip是ip池中的一個,對吧,很簡單對不對,那麼怎麼來建立ip池呢,也很簡單,用動態或者靜態方法隨便找個匿名ip的網站進行代理ip爬取,而後清洗一下ip,把能用的(測試一個簡單的返回狀態網頁)留下來寫到列表裏,而後就能夠造成ip池啦,最後當某個ip不能用了,那就從池中剔除!ip池製做,建議參考@七夜的故事--代理ip池
本身爬着爬着就把隱藏元素都爬出來了,你說你本身是否是爬蟲吧,這是網站給爬蟲的陷阱,只要發現,立馬封IP,因此請查看一下元素再進行爬取!
好比說這個網址,一個簡單的登陸頁面,從審查元素中咱們能夠看到有一些元素是不可見的!(例子抄自python網絡數據採集第12章)
查找出陷阱url和不可見的value代碼
from selenium import webdriver #from selenium.webdriver.remote.webelement import WebElement url = 'http://pythonscraping.com/pages/itsatrap.html' driver = webdriver.PhantomJS(executable_path="phantomjs.exe") driver.get(url) links = driver.find_elements_by_tag_name("a") for link in links: if not link.is_displayed(): print "the link "+link.get_attribute("href")+"is a trap" fields = driver.find_elements_by_tag_name("input") for field in fields: if not field.is_displayed(): print "do not change value of "+field.get_attribute("name")
結果就是
the link http://pythonscraping.com/dontgohereis a trap do not change value of phone do not change value of email
基於Python,scrapy,redis的分佈式爬蟲實現框架
分佈式爬取,針對比較大型爬蟲系統,實現步驟以下所示
1.基本的http抓取工具,如scrapy
2.避免重複抓取網頁,如Bloom Filter
3.維護一個全部集羣機器可以有效分享的分佈式隊列
4.將分佈式隊列和Scrapy結合
5.後續處理,網頁析取(python-goose),存儲(Mongodb)
(知乎上看到的補充一下)
採用Scrapy的例子,請參考這裏基於Scrapy對Dmoz進行抓取
這個就太多了,通常用Selenium,能夠結合Firefox或者是無頭瀏覽器PhantomJS,這個作的東西比較多了,若是感興趣,能夠點擊這些,進行查看,方法,代碼,解析,包羅萬象