python網路爬蟲筆記(一)

人間有格發表於2020-10-25
import requests
r = requests.get("http://www.baidu.com")
r.status_code
#200 為正常
r.encoding = "utf-8" 
r.text

request庫有7個主要方法

requests.request() #構造一個請求,支撐以下各方法的基礎方法
requests.get() #獲取HTML網頁的主要方法,對應於HTTP的GET
requests.head() #獲取HTML網頁頭資訊的方法,對應於HTTP的HEAD
requests.post() #向HTML網頁提交POST請求的方法,對應於HTTP的POST
requests.put() #向HTML網頁提交PUT請求的方法,對應於HTTP的PUT
requests.patch() #向HTML網頁提交區域性修改請求,對應於HTTP的PATCH
requests.delete() #向HTML頁面提交刪除請求,對應於HTTP的DELETE

requests.get()方法

r = requests.get(url)

構造一個向伺服器請求資源的Request物件
這個語句返回一個包含伺服器資源的Response物件

requests.get函式完整的使用方法有三個引數:

request.get(url.params=None,**kwargs)

其中url是獲取頁面的url連結。
params是url中額外引數,字典或位元組流格式,可選
**kwargs,是12個控制訪問的引數,可選

get方法是用了requests的方法來封裝:

def get(url, params = None, **kwargs):
    """Sends a Get request.
       :param url:URL for the new :class:'Request' object.
       :param params:(optional) Dictionary or bytes to be sent in the query string for the ...
       :return: :class:'Response<Response>' object
       :rtype: requests.Response
       """

    kwargs.setdefault("allow_redirects",True)
    return request('get',url,params=params,**kwargs)

requests提供了7個常用基礎方法,其中有6個是通過呼叫requests基礎方法來實現。

Response物件屬性(務必牢記)

r.status_code  #HTTP請求的返回狀態,200表示連線成功,404表示失敗
r.text #HTTP響應內容的字串形式,即,url對應的頁面內容
r.encoding #從HTTP header中猜測的響應內容編碼方式
r.apparent_encoding #從內容中分析出的響應內容編碼方式(備選編碼方式)
r.content #HTTP響應內容的二進位制形式

理解Response編碼:

r.encoding #從HTTP header中猜測的響應內容編碼方式
r.apparent_encoding #從內容中分析出的響應內容編碼方式(備選編碼方式)

r.encoding:如果header中不存在charset,則認為編碼為IOS-8859-1,但這個編碼無法解析中文。

r = requests.get(url)

可以獲取任何一個我們想獲取的url的資源。

爬取網頁的通用程式碼框架

import requests
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status() #如果狀態不是200,引發HTTPError異常
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return "產生異常"
 #*******
if __name__ == "__main__":
    url = "http://www.baidu.com"
    print(getHTMLText(url))

HTTP協議

URL格式:http://host[:port][path]
host:合法的Internet主機域名或IP地址
port:埠號,預設埠為80
path:請求資源的路徑

HTTP URL例項:
http://www.bit.edu.cn
http://220.181.111.188/duty

HTTP URL的理解:
URL是通過HTTP協議存取資源的Internet路徑,一個URL對應一個資料資源。

HTTP協議對資源的操作

GET 請求獲取URL位置的資源
HEAD 請求獲取URL位置資源的響應訊息報告,即獲得該資源的頭部資訊
POST 請求向URL位置的資源後附加新的資料,即使用者提交的資源
PUT 請求向URL位置儲存一個資源,覆蓋原URL位置的資源
PATCH 請求區域性更新URL位置的資源,即改變該處資源的部分內容
DELETE 請求刪除URL位置儲存的資源

當一個資源很大的時候,我們可以用HEAD獲取頭部資訊來分析我們想要的內容。

requests.request(method, url, **kwargs)
method: 請求方式
r = requests.request('GET', url, **kwargs)
r = requests.request('HEAD', url, **kwargs)
r = requests.request('POST', url, **kwargs)
r = requests.request('PUT', url, **kwargs)
r = requests.request('PATCH', url, **kwargs)
r = requests.request('delete', url, **kwargs)
r = requests.request('OPTIONS', url, **kwargs)

通過下面這個引數,可以將某些內容新增到url中

**kwargs: 控制訪問的引數,可選
params: 字典或位元組序列,作為引數新增到url中:

>>> kv = {'key1': 'value1', 'key2':'value2'}  #構建一個鍵值段kv,其中有兩個鍵值段
>>> r = requests.request('GET','http://python123.io/ws',params = kv)
>>> print(r.url)
https://python123.io/ws?key1=value1&key2=value2


data:字典、位元組序列或檔案物件,作為Request的內容(不會出現在連線裡,而作為連線對應位置的內容)
>>> kv = {'key1': 'value1', 'key2':'value2'}  #構建一個鍵值段kv,其中有兩個鍵值段
>>> r = requests.request('POST','http://python123.io/ws',data = kv)


json:JSON格式的資料,作為Request的內容
>>> kv = {'key1': 'value1'}  #構建一個鍵值段kv,其中有兩個鍵值段
>>> r = requests.request('POST','http://python123.io/ws, json = kv) #這個鍵值段被賦值到了伺服器的json域上。


headers:字典,HTTP定製頭
我們可以修改HTTP中的user-agent欄位,定義好欄位然後賦值給headers:
>>> hd = {'user-agent':'Chrome/10'}
>>> r = requests.request('POST','http://python123.io/ws',headers = hd)


cookies:字典或CookieJar,Request中的cookie
auth:元組,支援HTTP認證功能
files:字典型別,傳輸檔案

>>> fs = {'file':open('data.xls','rb')}
>>> r = requests.request('POST','http://python123.io/ws',files=fs)
timeout: 設定超時時間,秒為單位
proxies:字典型別,設定訪問代理伺服器,可以增加登陸認證


>>> pxs = {'http':'http://user:pass@10.10.10.1:1234'
           'http':'https://10.10.10.1:4321'}
>>> r = requests.request('GET'.'http://www.baidu.com', proxies=pxs)

這樣我們在訪問以上地址時,所使用的地址就是代理伺服器的地址。

allow_redirects: True/False, 預設為True,重定向開關
stream: True/False, 預設為True,獲取內容立即下載開關
verify:True/False, 預設為True,認證SSL證照開關
cert:本地SSL證照路徑

request.get()

request.get(url,params=None,**kwargs)
url:擬獲取頁面url連結
params:url中的額外引數,字典或位元組流格式,可選
**kwargs:12個控制訪問的引數

網路爬蟲的限制

來源審查:判斷User-Agent進行限制
    檢查來訪HTTP協議頭的User-Agent域,只響應瀏覽器或友好爬蟲的訪問

釋出公告:Robots協議
    告知所有爬蟲網站的爬取策略,要求爬蟲遵守

Robots協議
Robots Exclusion Standard網路爬蟲排除標準
作用:網站告知網路爬蟲哪些頁面可以爬取,哪些不行。
形式:在網站根目錄下的robots.txt檔案
robots.txt檔案:寫明瞭在一個網站裡,哪些目錄是允許爬蟲爬取的,哪些目錄是不允許的。

案例:京東的Robots協議

https://www.jd.com/robots.txt

Disallow: 後面的是不允許訪問的

import requests
url = "https://item.jd.com/2967929.html"
try:
    r = requests.get(url)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[:1000])
except:
    print("爬取失敗")

https://item.jd.com/100014199518.html

r.request.headers #檢查User-Agent

當我們有時訪問出現錯誤時,有可能是瀏覽器不支援爬蟲訪問。通過r.request.headers,中的User-Agent,我們可以看到程式是否顯示此次訪問由爬蟲程式進行。

為了避免這種情況被拒絕訪問,我們可以修改程式以模擬瀏覽器的訪問。

kv = {'user-agent':'Morilla/5.0'}
url = "https://item.jd.com/100014199518.html"
r = requests.get(url, headers = kv)
r.status_code
r.request.headers
r.text

這就從新定義了User-agent的內容,使他等於Morilla/5.0,這是一個很標準的瀏覽器標識欄位。
下面是全部程式碼:

import requests
url = "https://www.amazon.cn/gp/product/BO1M8L5Z3Y"
try:
    kv = {'user-agent':'Morilla/5.0'}
    r = requests.get(url, headers = kv)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[1000:2000])
except:
    print("爬取失敗")

網路圖片的爬取

網路圖片連結的格式:

http://www.example.com/picture.jpg

國家地理:

http://www.nationalgeographic.com.cn/

選擇一個圖片Web頁面:

http://www.nationalgeographic.com.cn/photography/photo_of_the_day/3921.html
>>> import requests
>>> path = "/Users/wangningzhi/Desktop/abc.jpg"
>>> url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
>>> r = requests.get(url)
>>> r.status_code
200
>>> with open(path,'wb') as f:
...     f.write(r.content)
... 
228206

全部程式碼

import requests
url = "http://image.nationalgeographic.com.cn/2017/0211/20170211061910157.jpg"
root = "/Users/wangningzhi/Desktop/"
path = root + url.split('/')[-1]
try:
    if not os.path.exists(root):
        os.mkdir(root)
    if not os.path.exists(path):
        r = requests.get(url)
        with open(path,'wb') as f:
            f.write(r.content)
            f.close()
            print("檔案儲存成功")
    else:
        print("檔案已存在")
except:
    print("爬取失敗")

向網頁自動提交資料

import requests

url = "http://m.ip138.com/ip.asp?ip="
try:
    r = requests.get(url + '202.204.80.112')
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    print(r.text[-500:])
except:
    print("爬取失敗")

相關文章