Python爬蟲防封的6個小訣竅
方法1:設置等待時間
有一些網站的防範措施可能會因為你快速提交表單而把你當做機器人爬蟲,比如說以非常人的速度下載圖片,登錄網站,爬取信息。
常見的設置等待時間有兩種,一種是顯性等待時間(強制停幾秒),一種是隱性等待時間(看具體情況,比如根據元素載入完成需要時間而等待)
1.顯性等待時間
import time#導入包time.sleep(3)#設置時間間隔為3秒
而且盡量在夜深人靜的時候進行數據的採集,切記採集不要太快,不然容易讓網站識別出你個非人類
2.隱式等待這裡用到的主要語句,以wait.until()為例比如說形式如下
wait1.until(lambda driver: driver.find_element_by_xpath("//p[@id="link-report"]/span"))
上面的語句就是在等待頁面元素載入全部完成後才進行下一步操作,因為爬蟲速度太快,導致一些元素沒有被載入完全就進行下一步操作而導致沒有查找到元素或者被網站認為是機器人在進行瀏覽。
具體的案例可以在我以前的文章中詳細應用Python自定義豆瓣電影種類,排行,點評的爬取與存儲(進階下)
方法2:修改請求頭
識別你是機器人還是人類瀏覽器瀏覽的重要依據就是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,所以要進行修改。
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)
方法3:採用代理ip
當自己的ip被網站封了之後,只能採取換代理ip的方式進行爬取,所以,我建議,每次爬取的時候盡量用代理來爬,封了代理,還有代理,無窮無盡啊,可別拿代理去黑學校網站啊,你懂得0.0廢話不多說,扔上代理的實現程序
# -*- coding: utf-8 -*-
import urllib2
#參數是一個字典{"類型":"代理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池的方法~舉個栗子
# -*- coding: utf-8 -*-
import urllib2
import random
ip_list=["119.6.136.122","114.106.77.14"]
#使用一組ip調用random函數來隨機使用其中一個ip
#參數是一個字典{"類型":"代理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池呢,也很簡單,用BS4隨便找個匿名ip的網站進行代理ip爬取,然後清洗一下ip,把能用的留下來寫到列表裡,然後就可以形成ip池啦,最後當某個ip不能用了,那就從池中剔除!ip池製作
方法4:避開不可見元素陷阱
自己爬著爬著就把隱藏元素都爬出來了,你說你自己是不是爬蟲吧,這是網站給爬蟲的陷阱,只要發現,立馬封IP,所以請查看一下元素再進行爬取!比如說這個網址,一個簡單的登錄頁面,從審查元素中我們可以看到有一些元素是不可見的!
上述中可以看到隱藏的value和不顯示的url
查找出陷阱url和不可見的value代碼
from selenium import webdriver#from selenium.webdriver.remote.webelement import WebElementurl = "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 trapdo not change value of phonedo not change value of email
方法5:採用分散式爬取
基於Python,scrapy,redis的分散式爬蟲實現框架
分散式爬取,針對比較大型爬蟲系統,實現步驟如下所示1.基本的http抓取工具,如scrapy2.避免重複抓取網頁,如Bloom Filter3.維護一個所有集群機器能夠有效分享的分散式隊列4.將分散式隊列和Scrapy結合5.後續處理,網頁析取(python-goose),存儲(Mongodb)(知乎上看到的補充一下)
採用Scrapy的例子,請參考這裡基於Scrapy對Dmoz進行抓取
方法6:進行模擬登陸
這個就太多了,一般用Selenium,可以結合Firefox或者是無頭瀏覽器PhantomJS,這個做的東西比較多了,如果感興趣,可以點擊這些,進行查看,方法,代碼,解析,一應俱全
Selenium+PhantomJS自動續借圖書館書籍(下)
Python自定義豆瓣電影種類,排行,點評的爬取與存儲(進階下)
基於Selenium一鍵寫CSDN博客
Pay Attention
1.上述實驗的代理ip只對當前數據有效,如果你自己想實驗,請自己選擇比較新的代理ip,這個ip可能過一段時間就廢了
2.目前主要採用的方法就是採用加請求頭掛上代理ip的方法,對用JS寫的網站,requests抓不全數據,所以採用Selenium+PhantomJS/Firefox的方法
※Python 從Zero到Hero(一)
※練習 16-18 Learn Python 3 The Hard Way
TAG:Python |