Python網絡爬蟲(四)

關於Robots協議

Robots協議也稱爲爬蟲協議,是網絡爬蟲排除標準(Robots Exclusion Protocol),用來告訴爬蟲和搜索引擎哪些頁面能夠抓取,哪些不能夠抓取。由於咱們若是無限制的使用爬蟲爬取信息的話,且不說技術上可否突破某些網站上的發爬蟲措施,若是毫無限制的進行爬取,再加上個分佈式和多線程,則有可能致使把訪問網站跑崩掉(雖然這種機率很小);可是這也說明了咱們須要對咱們的爬蟲進行規範化處理,只能爬取咱們須要的別人願意給的數據,這樣就不會違反一些法律。
咱們能夠在任何一個網站上加上/robots.txt查看這個網站對於爬蟲是否有限制,在這裏舉一個知乎的例子:https://www.zhihu.com/robots.txt,出現的爲下圖:python

知乎裏有User-agent與Disallow,Disallow 指定了不容許抓取的目錄,而知乎裏的意思就是禁止全部爬蟲訪問下面所列舉的目錄。git

urllib的robotparser

咱們能夠利用robotparser模塊來解析robots.txt,robotparser 模塊提供了一個類,叫作 RobotFileParser。它能夠根據某網站的 robots.txt 文件來判斷一個爬取爬蟲是否有權限來爬取這個網頁。github

urllib.robotparseR.RobotFileParser(url='')
#只須要在構造方法中傳入robots.txt的連接就能夠了
#也能夠是默認爲空,而後使用set_url()方法進行設置。

關於Requests

咱們在利用urllib處理網頁驗證、處理cookies都是須要Opener、Handler來進行處理,可是requests庫有着更爲強大的用法。
urllib庫的urlopen實際上也使以get的方式請求了一個網頁,而在requests中咱們使用的直接就爲get()方法。而其餘類型相似post或者請求head都是能夠直接用requests.post或者requests.head方法。json

GET請求

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)

Cookies

比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.

相關文章
相關標籤/搜索