Robots協議也稱爲爬蟲協議,是網絡爬蟲排除標準(Robots Exclusion Protocol),用來告訴爬蟲和搜索引擎哪些頁面能夠抓取,哪些不能夠抓取。由於咱們若是無限制的使用爬蟲爬取信息的話,且不說技術上可否突破某些網站上的發爬蟲措施,若是毫無限制的進行爬取,再加上個分佈式和多線程,則有可能致使把訪問網站跑崩掉(雖然這種機率很小);可是這也說明了咱們須要對咱們的爬蟲進行規範化處理,只能爬取咱們須要的別人願意給的數據,這樣就不會違反一些法律。
咱們能夠在任何一個網站上加上/robots.txt
查看這個網站對於爬蟲是否有限制,在這裏舉一個知乎的例子:https://www.zhihu.com/robots.txt
,出現的爲下圖:python
知乎裏有User-agent與Disallow,Disallow 指定了不容許抓取的目錄,而知乎裏的意思就是禁止全部爬蟲訪問下面所列舉的目錄。git
咱們能夠利用robotparser模塊來解析robots.txt,robotparser 模塊提供了一個類,叫作 RobotFileParser。它能夠根據某網站的 robots.txt 文件來判斷一個爬取爬蟲是否有權限來爬取這個網頁。github
urllib.robotparseR.RobotFileParser(url='') #只須要在構造方法中傳入robots.txt的連接就能夠了 #也能夠是默認爲空,而後使用set_url()方法進行設置。
咱們在利用urllib處理網頁驗證、處理cookies都是須要Opener、Handler來進行處理,可是requests庫有着更爲強大的用法。
urllib庫的urlopen實際上也使以get的方式請求了一個網頁,而在requests中咱們使用的直接就爲get()方法。而其餘類型相似post或者請求head都是能夠直接用requests.post或者requests.head方法。json
r = requests.get(url,params=data,headers=headers)
這樣請求的網址實際上爲url+data,此外網頁的返回類型若是是json格式,雖然返回的其實是str類型,可是是按照json的格式進行的,因此若是咱們想直接把返回結果解析獲得一個字典格式的話,能夠直接調用json()方法。經過這種方法,能夠將返回結果是json格式的字符串轉化成python中的字典形式。瀏覽器
利用requests能夠模擬提交一些數據:cookie
import requests files={'file':open('favicon.ico','rb')} #文件必須和當前腳本在同一目錄下 r=requests.post(url,files=files) print(r.text)
一樣,能夠利用requests下載文件:網絡
import requests r = requests.get("https://github.com/favicon.ico") with open('favicon.ico', 'wb') as f: f.write(r.content)
比urillb會簡單的許多,只需訪問rrequests的cookies類型便可訪問RequestsCookieJar:session
import requests r = requests.get('https://www.baidu.com') print(r.cookies) for key, value in r.cookies.items(): print(key + '=' + value)
咱們能夠始終保持登陸的狀態,將網頁的cookies保存下來,再寫入headers進行發送:多線程
import requests headers = { 'Cookie': 'q_c1=31653b264a074fc9a57816d1ea93ed8b|1474273938000|1474273938000; d_c0="AGDAs254kAqPTr6NW1U3XTLFzKhMPQ6H_nc=|1474273938"; __utmv=51854390.100-1|2=registration_date=20130902=1^3=entry_date=20130902=1;a_t="2.0AACAfbwdAAAXAAAAso0QWAAAgH28HQAAAGDAs254kAoXAAAAYQJVTQ4FCVgA360us8BAklzLYNEHUd6kmHtRQX5a6hiZxKCynnycerLQ3gIkoJLOCQ==";z_c0=Mi4wQUFDQWZid2RBQUFBWU1DemJuaVFDaGNBQUFCaEFsVk5EZ1VKV0FEZnJTNnp3RUNTWE10ZzBRZFIzcVNZZTFGQmZn|1474887858|64b4d4234a21de774c42c837fe0b672fdb5763b0', 'Host': 'www.zhihu.com', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36', } r = requests.get('https://www.zhihu.com', headers=headers) print(r.text)
以前本身在作學校的信息門戶信息爬取,可是每一次運行程序都抓不到數據,將錯誤信息答應出來發現是監測到有重複登陸的現象。明明是代碼登錄成功後而後繼續get()去請求的,怎麼會出錯呢?
實際上,在requests用了幾回get()或者其餘方法,都至關於打開了一次新的瀏覽器,他們之間是徹底不相關的,因此並不存在第一個post()成功進行了模擬登陸,第二個get()是在成功模擬登陸的基礎上繼續進行操做,而是在打開一個瀏覽器進行新的操做,因此會出錯。
解決方法是,在兩次請求的時候都設置好同樣的cookies,這樣當然可行,可是很是繁瑣,破壞了代碼的簡潔性。因此這裏咱們須要維持同一個會話窗口,使用session對象。分佈式
import requests s = requests.Session() s.get('http://httpbin.org/cookies/set/number/123456789') r = s.get('http://httpbin.org/cookies') print(r.text)
返回結果爲:
{ "cookies": { "number": "123456789" } }
成功顯示了咱們想要提交的cokies內容:number:123456789.