關於urllib、urllib2爬蟲假裝的總結

站在網站管理的角度,若是在同一時間段,你們所有利用爬蟲程序對本身的網站進行爬取操做,那麼這網站服務器能不能承受這種負荷?確定不能啊,若是嚴重超負荷則會時服務器宕機(死機)的,對於一些商業型的網站,宕機一秒鐘的損失都是不得了的,這不是一個管理員能承擔的,對吧?那管理員會網站服務器作什麼來優化呢?我想到的是,寫一個腳本,當檢測到一個IP訪問的速度過快,報文頭部並非瀏覽器的話,那麼就拒絕服務,或者屏蔽IP等,這樣就能夠減小服務器的負擔並讓服務器正常進行。html

那麼既然服務器作好了優化,但你知道這是對爬蟲程序的優化,若是你是用瀏覽器來做爲一個用戶訪問的話,服務器是不會攔截或者屏蔽你的,它也不敢攔你,爲何,你如今是客戶,它敢攔客戶,不想繼續經營了是吧?因此對於若是是一個瀏覽器用戶的話,是能夠正常訪問的。python

因此想到方法了嗎?是的,把程序僞形成一個瀏覽器啊,前面說過服務器會檢測報文頭部信息,若是是瀏覽器就不正常通行,若是是程序就拒絕服務。瀏覽器

那麼報文是什麼?頭部信息又是什麼?詳細的就不解釋了,這涉及到http協議和tcp/ip三次握手等等的網絡基礎知識,感興趣的本身百度或者谷歌吧。服務器

本篇博文不扯遠了,只說相關的重點——怎麼查看頭部信息。網絡

 

User-Agent

其實我想有些朋友可能有疑惑,服務器是怎麼知道咱們使用的是程序或者瀏覽器呢?它用什麼來判斷的?tcp

我使用的是火狐瀏覽器,鼠標右鍵-查看元素(有的瀏覽器是審查元素或者檢查)工具

 

網絡(有的是network):優化

 

出現報文:網站

雙擊它, 右邊則會出現詳細的信息,選擇消息頭(有的是headers)url

找到請求頭(request headers),其中的User-Agent就是咱們頭部信息:

看到是顯示的

User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0。
這就是咱們的頭部信息。看到沒,顯示的信息,使用的操做系統內核是6.1,對應win7的64位,用的firefox56,就是火狐瀏覽器版本56
 
那麼瀏覽器訪問的都能察覺,天然咱們用的程序訪問同樣能夠察覺,無論他是怎麼識別的。其實若是我是管理員(若是我幹了我學的專業的話,還就真的是管理員了),按個人想法的話,我直接定義個合法報文頭都得是【Mozilla/5.0……】之類的就行,除了這些其餘所有拒絕是否是就能夠了?
 
前面只用了urllib模塊的urlopen方法打開網頁,其下還有個功能就能夠查看頭部信息,但和瀏覽器查看的有些差異。
 
注意:如下代碼都是在python2中,python3中不存在urllib和urllib2模塊,在python3中,把相關的urllib模塊組合成了一個包,都在urllib包下
複製代碼
# -*- 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>
複製代碼
由此,這裏就必須注意,只有當urllib.urlopen()實例化後纔有其後面的方法,urlopen會返回一個類文件對象,urllib.urlopen只是一個對象,而urllib.urlopen()必須傳入一個參數,否則則報錯。
在前一章已經用過有效實例化後的read()方法,能夠讀取獲得的網站信息。

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,用這個工具就能夠查看到底報文頭部是什麼了。這裏就不展現了,本身下去常識了。而且我能夠確切的保證,確實僞形成功了。

這樣,咱們就把爬蟲代碼升級了一下,能夠搞定普通的反爬蟲限制

相關文章
相關標籤/搜索