Python爬蟲之-Requests庫

前言

本章不做過多前期的講解直接上Requests
有關pip安裝或者其他亂七八糟簡單語法暫不提供

Requests認知

Tips: 以上認知只是個人對該庫的理解,不想看直接去代碼自己實操總結自己的一套認知理念。
個人理解Requests庫和Scarypy相比Requests不用說肯定相比而言簡單很多,剛開始想學爬蟲瞭解了Scarypy發現是個爬站的大框架所以上手就會難點,從簡單的開始Requests是爬頁面而不是整個站,兩者之間最大的區別莫過於此了吧。本章講解的也只是Requests片面的方法使用,更多的功能後期也會隨着時間不斷地更新。

傳遞 URL 參數

你也許經常想爲 URL 的查詢字符串(query string)傳遞某種數據。如果你是手工構建 URL,那麼數據會以鍵/值對的形式置於 URL 中,跟在一個問號的後面。例如, httpbin.org/get?key=val。 Requests 允許你使用 params 關鍵字參數,以一個字符串字典來提供這些參數。舉例來說,如果你想傳遞 key1=value1 和 key2=value2 到 httpbin.org/get

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)

通過打印輸出該 URL,你能看到 URL 已被正確編碼:

>>> print(r.url)
http://httpbin.org/get?key2=value2&key1=value1

定製請求頭

>>> url = 'https://api.github.com/some/endpoint'
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = requests.get(url, headers=headers)
>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
>>> r = requests.get('http://httpbin.org/get', params=payload)
>>> print(r.url)
http://httpbin.org/get?key1=value1&key2=value2&key2=value3

注意: 定製 header 的優先級低於某些特定的信息源,例如:

如果在 .netrc 中設置了用戶認證信息,使用 headers= 設置的授權就不會生效。而如果設置了 auth= 參數,.netrc 的設置就無效了。
如果被重定向到別的主機,授權 header 就會被刪除。
代理授權 header 會被 URL 中提供的代理身份覆蓋掉。
在我們能判斷內容長度的情況下,header 的 Content-Length 會被改寫。
更進一步講,Requests 不會基於定製 header 的具體情況改變自己的行爲。只不過在最後的請求中,所有的 header 信息都會被傳遞進去。

注意: 所有的 header 值必須是 string、bytestring 或者 unicode。儘管傳遞 unicode header 也是允許的,但不建議這樣做。

更加複雜的 POST 請求

通常,你想要發送一些編碼爲表單形式的數據——非常像一個 HTML 表單。要實現這個,只需簡單地傳遞一個字典給 data 參數。你的數據字典在發出請求時會自動編碼爲表單形式:

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}
你還可以爲 data 參數傳入一個元組列表。在表單中多個元素使用同一 key 的時候,這種方式尤其有效:

>>> payload = (('key1', 'value1'), ('key1', 'value2'))
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  ...
}
很多時候你想要發送的數據並非編碼爲表單形式的。如果你傳遞一個 string 而不是一個 dict,那麼數據會被直接發佈出去。

響應狀態碼

響應頭
我們可以查看以一個 Python 字典形式展示的服務器響應頭:

>>> r.headers
{
    'content-encoding': 'gzip',
    'transfer-encoding': 'chunked',
    'connection': 'close',
    'server': 'nginx/1.0.4',
    'x-runtime': '148ms',
    'etag': '"e1ca502697e5c9317743dc078f67693f"',
    'content-type': 'application/json'
}
但是這個字典比較特殊:它是僅爲 HTTP 頭部而生的。根據 RFC 2616, HTTP 頭部是大小寫不敏感的。

因此,我們可以使用任意大寫形式來訪問這些響應頭字段:

>>> r.headers['Content-Type']
'application/json'

>>> r.headers.get('content-type')
'application/json'
它還有一個特殊點,那就是服務器可以多次接受同一 header,每次都使用不同的值。但 Requests 會將它們合併,這樣它們就可以用一個映射來表示出來,參見 RFC 7230:

A recipient MAY combine multiple header fields with the same field name into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.

接收者可以合併多個相同名稱的 header 欄位,把它們合爲一個 "field-name: field-value" 配對,將每個後續的欄位值依次追加到合併的欄位值中,用逗號隔開即可,這樣做不會改變信息的語義。

Requests代碼

Code已經做了簡單的封裝直接拆解調用某個function即可,或者直接使用也行。

#!/usr/bin/python3
#-*- coding:utf-8 -*-

import requests
import time

class website():

    def __init__(self,url):
        """This is about requests module usage."""
        self.url = url

    def _simpleInfo(self): 
        """This function is get about site status"""

        r = requests.get(self.url)
        print("I will write simple code to here.")
        print("*"*30)
        time.sleep(3)
        print("This is site status code: "+str(r.status_code)) 
        print("The module is coding: "+str(r.encoding))
        change = r.encoding='utf-8'
        print("Changed site type is: "+str(change))

    def _getHead(self):
        """This function is get site head info"""

        cookies = dict(cookies_are='working')
        r = requests.get(self.url, cookies = cookies)
        info  = [r.headers['server'], \
                r.headers['date'], \
                r.cookies, \
                r.headers['transfer-encoding'], \
                r.headers['connection']
                ]
        #print(r.headers)
        print("*"*50)
        print("Version: %s" %info[0])
        print("date: %s" %info[1])
        print("Cookies: %s" %info[2]) 
        print("Transfer type: %s" %info[3])
        print("Connection: %s" %info[4])
        print("*"*50)
        
    def _reWirte(self):
        """This function about for site rewrite."""

        r = requests.get(self.url, allow_redirects=False)
        """True 爲做跳轉False則反之"""
        status = [r.url, r.status_code, r.history]
        print("site: %s" %status[0])
        print("Status: %s" %status[1])
        print("Recheck: %s" %status[2])

    def _setVariable(self):
        """Set variable to chage site post."""
        
        payload = {'id':'90', 'uid':'7'}
        headers = {'user-agent' : 'myapp/0.0.1'}
        """賦值時必須同步變量名才能覆蓋原有值"""
        r = requests.get(self.url, headers=headers, params=payload)
        r.encoding = 'utf-8'
        print(r.text)
        

def Control():
	“”“這個作爲class的控制器“”“
    #url = "http://www.mifan.com.tw"
    #url = "http://www.baidu.com"
    #url = "http://www.github.com"
    url = "http://www.njfhyey.com/new_vw.php"
    site = website(url)
    #site._getHead()
    #site._reWirte()
    site._setVariable()

Control()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章