站在網站管理的角度,如果在同一時間段,大家全部利用爬蟲程序對自己的網站進行爬取操作,那么這網站服務器能不能承受這種負荷?肯定不能啊,如果嚴重超負荷則會時服務器宕機(死機)的,對於一些商業型的網站,宕機一秒鍾的損失都是不得了的,這不是一個管理員能承擔的,對吧?那管理員會網站服務器做什么來優化呢?我想到的是,寫一個腳本,當檢測到一個IP訪問的速度過快,報文頭部並不是瀏覽器的話,那么就拒絕服務,或者屏蔽IP等,這樣就可以減少服務器的負擔並讓服務器正常進行。
那么既然服務器做好了優化,但你知道這是對爬蟲程序的優化,如果你是用瀏覽器來作為一個用戶訪問的話,服務器是不會攔截或者屏蔽你的,它也不敢攔你,為什么,你現在是客戶,它敢攔客戶,不想繼續經營了是吧?所以對於如果是一個瀏覽器用戶的話,是可以正常訪問的。
所以想到方法了嗎?是的,把程序偽造成一個瀏覽器啊,前面說過服務器會檢測報文頭部信息,如果是瀏覽器就不正常通行,如果是程序就拒絕服務。
那么報文是什么?頭部信息又是什么?詳細的就不解釋了,這涉及到http協議和tcp/ip三次握手等等的網絡基礎知識,感興趣的自己百度或者谷歌吧。
本篇博文不扯遠了,只說相關的重點——怎么查看頭部信息。
User-Agent
其實我想有些朋友可能有疑惑,服務器是怎么知道我們使用的是程序或者瀏覽器呢?它用什么來判斷的?
我使用的是火狐瀏覽器,鼠標右鍵-查看元素(有的瀏覽器是審查元素或者檢查)
網絡(有的是network):
出現報文:
雙擊它, 右邊則會出現詳細的信息,選擇消息頭(有的是headers)
找到請求頭(request headers),其中的User-Agent就是我們頭部信息:
看到是顯示的
# -*- coding:utf-8 -*- import urllib url='http://www.baidu.com' #百度網址 html=urllib.urlopen(url)#利用模塊urllib里的urlopen方法打開網頁 print(dir(html)) #查看對象html的方法 print(urllib.urlopen) #查看對象urllib.urlopen的方法 print(urllib.urlopen()) #查看對象urllib.urlopen實例化后的方法
Traceback (most recent call last): File "D:\programme\PyCharm 5.0.3\helpers\pycharm\utrunner.py", line 121, in <module> modules = [loadSource(a[0])] File "D:\programme\PyCharm 5.0.3\helpers\pycharm\utrunner.py", line 41, in loadSource module = imp.load_source(moduleName, fileName) File "G:\programme\Python\python project\test.py", line 8, in <module> print(urllib.urlopen()) TypeError: urlopen() takes at least 1 argument (0 given) ['__doc__', '__init__', '__iter__', '__module__', '__repr__', 'close', 'code', 'fileno', 'fp', 'getcode', 'geturl', 'headers', 'info', 'next', 'read', 'readline', 'readlines', 'url'] <function urlopen at 0x0297FD30>
urlopen提供了如下方法:
- read() , readline() , readlines() , fileno() , close() :這些方法的使用方式與文件對象完全一樣
- info():返回一個httplib.HTTPMessage 對象,表示遠程服務器返回的頭信息
- getcode():返回Http狀態碼。如果是http請求,200表示請求成功完成;404表示網址未找到
- geturl():返回請求的url
- headers:返回請求頭部信息
- code:返回狀態碼
- url:返回請求的url
好的,詳細的自己去研究了,本篇博文的重點終於來了,偽裝一個頭部信息
偽造頭部信息
由於urllib沒有偽造頭部信息的方法,所以這里得使用一個新的模塊,urllib2
# -*- coding:utf-8 -*- import urllib2 url='http://www.baidu.com' head={ 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0' } #頭部信息,必須是一個字典 html=urllib2.Request(url,headers=head) result=urllib2.urlopen(html) print result.read()
或者你也可以這樣:
# -*- coding:utf-8 -*- import urllib2 url='http://www.baidu.com' html=urllib2.Request(url) html.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0') #此時注意區別格式 result=urllib2.urlopen(html) print result.read()
結果都一樣的,我也就不展示了。
按照上面的方法就可以偽造請求頭部信息。
那么你說,我怎么知道偽造成功了?還有不偽造頭部信息時,顯示的到底是什么呢?介紹一個抓包工具——fidder,用這個工具就可以查看到底報文頭部是什么了。這里就不展示了,自己下去常識了。並且我可以確切的保證,確實偽造成功了。
這樣,我們就把爬蟲代碼升級了一下,可以搞定普通的反爬蟲限制