學習筆記-Python-爬蟲1-urllib、chardet

# 爬蟲
- 兩大特徵
- 按做者要求下載數據或者內容
- 能自動在網絡上流竄
- 三大步驟
- 下載網頁
- 提取正確的信息
- 根據必定規則自動跳轉到另外的網頁上執行
- 爬蟲分類
- 通用爬蟲
- 專用爬蟲(聚焦爬蟲)
- Python網絡包簡介
- Python2.x:urllib, urllib2, urllib3, httplib, httplib2, requests
- Python3.x:urllib, urllib3, httplib2, requests
- Python2:urllib和urllib2配合使用,或者requests
- Python3:urllib, requests
- urllib
- 包含模塊
- urllib.request:打開和讀取url
- urllib.error:包含urllib.requests產生的常見的錯誤,使用try捕捉
- urllib.parse:包含解析url方法(字典性的數據做爲參數使用)
- urllib.robotparse:解析robots.txt文件
- 案例v1
- 網頁編碼問題解決
- chardet:能夠自動檢測頁面文件的編碼格式,可是,可能有誤
- 須要先安裝:conda install chardet
- 案例v2
- urlopen的返回對象
- 案例v3
- geturl:返回請求對象的url
- info:請求反饋對象的meta信息
- getcode:返回的http code
- request.data的使用
- 訪問網絡的兩種方法
- get
- 利用參數給服務器傳遞信息
- 參數爲dict格式,而後用parse編碼
- 案例v4
- post
- 通常向服務器傳遞參數使用
- post是把信息自動加密處理
- 咱們若是想使用post方式傳遞信息,須要用到data參數
- 使用post意味着Http的請求頭可能須要更改:
- Content-Type:application/x-www.form-urlencode
- Content-Length:數據長度
- 簡而言之,一旦更改請求方法,請注意其餘請求頭部信息相適應
- urllib.parse.urlencode能夠將字符串自動轉換成上面的
- 案例v5
- 爲了更多的設置請求信息,單純的經過urlopen已經不太好用了
- 須要利用request.Request類
- 案例v6
- urllib.error
- URLError產生緣由:
- 沒網
- 服務器連接失敗
- 找不到指定服務器
- 自己是OSError的子類
- 案例v7
- HTTPError是URLError的一個子類
- 案例v8
- 二者區別:
- HTTPError是對應的HTTP請求的返回碼錯誤,若是返回錯誤碼是400以上,則引起HTTPError
- URLError對應的通常是網絡出現問題,包括url錯誤
- 關係區別:OSError-URLError-HTTPError
- UserAgent
- UserAgent:用戶代理,簡稱UA,屬於headers的一部分,服務器經過UA來判斷訪問者的身份
- 常見的UA值,使用的時候能夠直接複製粘貼,也能夠用瀏覽器訪問的時候抓包
- 目前有Android、Firefox、Google Chrome、ios的UA
- 這個是例子:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
- 設置UA能夠經過兩種方式
- headers
- add_header
- 案例v9
- ProxyHandler處理(代理服務器)
- 使用代理IP,是爬蟲的經常使用手段
- 獲取代理服務器的地址
- www.xicidaili.com
- www.goubanjia.com
- 代理用來隱藏真實訪問地址,代理也不容許頻繁訪問某一個固定網站,因此,代理必定要不少不少
- 基本使用步驟:
一、設置代理地址
二、建立ProxyHandler
三、建立Opener
四、安裝Opener
- 案例v10
- cookie & session
- 因爲http協議的無狀態性(無記憶性),人們爲了彌補這個缺憾,所採用的一個補充協議
- cookie是發給用戶(即http瀏覽器)的一段信息;session是保存在服務器上的對應另外一半的信息,用來記錄用戶信息
- cookie和session區別:
- 存放位置不用
- cookie不安全
- session會保存在服務器上必定時間,會過時
- 單個cookie保存數據不超過4K,不少瀏覽器限制一個站點最多保存20個
- session的存放位置
- 存在服務器端
- 通常狀況,session是放在內存中或者數據庫中
- 沒有cookie登錄,案例v11,能夠看到,沒使用cookie則反饋網頁未登錄
- 使用cookie登錄
- 直接把cookie複製下來,而後手動放入請求頭,案例v12
- http模塊包含一些關於cookie的模塊,經過他們咱們能夠自動使用cookie
- CookieJar
- 管理存儲cookie,向傳出的http請求添加cookie
- cookie存儲在內存中,CookieJar實例回收後cookie將消息
- FileCookieJar(filename, delayload=None, policy=None)
- 使用文件管理cookie
- filename是保存cookie的文件
- MozillaCookieJar(filename, delayload=None, policy=None)
- 建立與mozilla瀏覽器cookie.txt兼容的fileCookieJar實例
- LwpCookieJar(filename, delayload=None, policy=None)
- 建立與libwww-perl標準兼容的Set-Cookie3格式的FileCookieJar實例
- 他們之間的關係是CookieJar-->FileCookieJar-->MozillaCookie & LwpCookieJar
- 利用cookieJar訪問妙味課堂,案例v13
- 自動使用cookie登錄,大體流程是:
一、打開登錄頁面後自動經過用戶名和密碼登錄
二、自動提取反饋回來的cookie
三、利用提取的cookie登錄
- handler是Handler的實例,經常使用參看案例代碼以下:
- 用來處理複雜請求
# 生成cookie管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 生成http請求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
- 建立handler後,使用opener打開,打開後相應的業務由相應的handler處理
- cookie做爲一個變量,打印出來,案例v14
- cookie的常見屬性
- name:名稱
- value:值
- domain:能夠訪問此cookie的域名
- path:能夠訪問的cookie頁面路徑
- expires:過時時間
- size:大小
- Http字段
- cookie的保存-FileCookieJar 案例v15
- cookie的讀取,案例v16

 

'''
案例v5
利用parse模塊模擬post請求
如下是分析百度詞典的步驟:
一、打開F12
二、嘗試輸入girl單詞,每次敲一個字母后都有請求
三、請求地址是https://fanyi.baidu.com/sug
四、利用Network-sug-Headers,查看發現Form Data的值是kw:girl
五、檢查返回內容格式,根據返回頭Response Headers下的Content-Type:application/json發現返回的是json格式內容,須要用到json包
'''
from urllib import request, parse
import json

'''
大體流程是:
一、利用data構造內容,而後urlopen()打開
二、返回一個json格式結果
三、結果就應該是girl的釋義
'''
baseurl = 'https://fanyi.baidu.com/sug'
# 存放用來模擬form的數據必定是dict格式
data = {
    # girl是翻譯輸入的英文內容,應該由用戶輸入,此處使用硬編碼
    'kw':'girl'
}
# 須要使用parse模塊對data編碼獲得str類型,可是要用bytes格式才能傳遞,因此用encode()編碼
data = parse.urlencode(data).encode()
print(type(data))
# 咱們須要構造一個請求頭,請求頭部應該至少包含傳入的數據的長度
# request要求傳入的請求頭是一個dict格式
headers = {
    # 由於使用post,因此至少包含Content-Length字段
    'Content-Length':len(data)
}
# 有了headers, data, url就能夠嘗試發出請求
rsp = request.urlopen(baseurl, data=data)
# 讀取返回內容,而後對內容進行解碼,但下面解碼失敗了
json_data = rsp.read().decode('utf-8')
print(type(json_data))
print(json_data)

# 把json字符串轉換成字典
json_data = json.loads(json_data)
print(type(json_data))
print(json_data)
for item in json_data['data']:
    print(item['k'],'---',item['v'])
'''
案例v6
利用parse模塊模擬post請求
利用Request構造請求信息實例
如下是分析百度詞典的步驟:
一、打開F12
二、嘗試輸入girl單詞,每次敲一個字母后都有請求
三、請求地址是https://fanyi.baidu.com/sug
四、利用Network-sug-Headers,查看發現Form Data的值是kw:girl
五、檢查返回內容格式,根據返回頭Response Headers下的Content-Type:application/json發現返回的是json格式內容,須要用到json包
'''
from urllib import request, parse
import json

'''
大體流程是:
一、利用data構造內容,而後urlopen()打開
二、返回一個json格式結果
三、結果就應該是girl的釋義
'''
baseurl = 'https://fanyi.baidu.com/sug'
# 存放用來模擬form的數據必定是dict格式
data = {
    # girl是翻譯輸入的英文內容,應該由用戶輸入,此處使用硬編碼
    'kw':'girl'
}
# 須要使用parse模塊對data編碼獲得str類型,可是要用bytes格式才能傳遞,因此用encode()編碼
data = parse.urlencode(data).encode()
print(type(data))
# 咱們須要構造一個請求頭,請求頭部應該至少包含傳入的數據的長度
# request要求傳入的請求頭是一個dict格式
headers = {
    # 由於使用post,因此至少包含Content-Length字段
    'Content-Length':len(data)
}
# 構造一個Request實例,用來設置請求頭各類信息
req = request.Request(baseurl, data, headers)
# 由於已經構造了一個Request的請求實例,則能夠直接傳入urlopen中
rsp = request.urlopen(req)
# 讀取返回內容,而後對內容進行解碼,但下面解碼失敗了
json_data = rsp.read().decode('utf-8')
print(type(json_data))
print(json_data)

# 把json字符串轉換成字典
json_data = json.loads(json_data)
print(type(json_data))
print(json_data)
for item in json_data['data']:
    print(item['k'],'---',item['v'])

 

 

'''
案例v9
訪問一個網址
更改本身的UserAgent進行假裝
'''
from urllib import request, error
if __name__ == '__main__':
    url='http://www.baidu.com'
    try:
        # 使用heads方法假裝UA
        # 第一種方法
        #headers = {}
        #headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'
        #req = request.Request(url, headers=headers)

        # 第二種方法
        req = request.Request(url)
        req.add_header('User-Agent','Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36')

        rsp = request.urlopen(req)
        html = rsp.read().decode()
        print(html)
    except error.HTTPError as e:
        print(e)
    except error.URLError as e:
        print(e)
    except Exception as e:
        print(e)
    print('Done...')

 

 

 

 

# 案例v13
from urllib import request,parse
from http import cookiejar

# 建立一個cookiejar的實例
cookie = cookiejar.CookieJar()
# 生成cookie管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 生成http請求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
# 建立請求管理器
opener = request.build_opener(http_handler, https_handler, cookie_handler)

def login():
    '''
    負責初次登錄
    須要輸入用戶名密碼,用來獲取登錄cookie憑證
    :return:
    '''
    # 點擊登錄按鈕後,觀察Network下發送的請求
    url = 'http://study.miaov.com/account/login/ajaxindex'
    # 此值須要從頁面中用戶名和密碼的元素中提取
    data = {
        "account":"188xxxxxxxx",
        "pwd":"xxxxxxxxxx"
    }
    # 把數據進行編碼
    data = parse.urlencode(data).encode()
    # 建立一個請求對象
    req = request.Request(url, data)
    # 使用opener發起請求
    rsp = opener.open(req)
def getHomePage():
    url = "http://study.miaov.com/account/user/history"
    # 若是已經執行了login函數,則opener自動已經包含對應的cookie
    rsp = opener.open(url)
    html = rsp.read().decode()
    with open("rsp_v13.html", "w") as f:
        f.write(html)
if __name__ == '__main__':
    login()
    getHomePage()
# 案例v14
# 在案例v13基礎上打印cookie
from urllib import request,parse
from http import cookiejar

# 建立一個cookiejar的實例
cookie = cookiejar.CookieJar()
# 生成cookie管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 生成http請求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
# 建立請求管理器
opener = request.build_opener(http_handler, https_handler, cookie_handler)

def login():
    '''
    負責初次登錄
    須要輸入用戶名密碼,用來獲取登錄cookie憑證
    :return:
    '''
    # 點擊登錄按鈕後,觀察Network下發送的請求
    url = 'http://study.miaov.com/account/login/ajaxindex'
    # 此值須要從頁面中用戶名和密碼的元素中提取
    data = {
        "account":"188xxxxxxxx",
        "pwd":"xxxxxxxxxx"
    }
    # 把數據進行編碼
    data = parse.urlencode(data).encode()
    # 建立一個請求對象
    req = request.Request(url, data)
    # 使用opener發起請求
    rsp = opener.open(req)

if __name__ == '__main__':
    '''
    執行完login以後,會獲得受權孩子後的cookie
    而後咱們嘗試把cookie打印出來
    '''
    login()
    print(cookie)
    for item in cookie:
        print(type(item))
        print(item)
       
# 案例v15
# 修改案例v13,改用文件管理cookie
from urllib import request,parse
from http import cookiejar

filename = "cookie.txt"
# 建立一個cookiejar的實例
cookie = cookiejar.MozillaCookieJar(filename)
# 生成cookie管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 生成http請求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
# 建立請求管理器
opener = request.build_opener(http_handler, https_handler, cookie_handler)

def login():
    '''
    負責初次登錄
    須要輸入用戶名密碼,用來獲取登錄cookie憑證
    :return:
    '''
    # 點擊登錄按鈕後,觀察Network下發送的請求
    url = 'http://study.miaov.com/account/login/ajaxindex'
    # 此值須要從頁面中用戶名和密碼的元素中提取
    data = {
        "account":"188xxxxxxxx",
        "pwd":"xxxxxxxxxx"
    }
    # 把數據進行編碼
    data = parse.urlencode(data).encode()
    # 建立一個請求對象
    req = request.Request(url, data)
    # 使用opener發起請求
    rsp = opener.open(req)
    # 保存cookie到文件
    # ignore_discard表示即便cookie將要被丟棄也要保存
    # ignore_expires表示若是該文件中cookie即使已通過期,也要保存
    cookie.save(ignore_discard=True, ignore_expires=True)
if __name__ == '__main__':
login()
# 案例v16
# 讀取v15生成的cookie
from urllib import request,parse
from http import cookiejar

# 建立一個cookiejar的實例
cookie = cookiejar.MozillaCookieJar()
cookie.load("cookie.txt", ignore_discard=True, ignore_expires=True)
# 生成cookie管理器
cookie_handler = request.HTTPCookieProcessor(cookie)
# 生成http請求管理器
http_handler = request.HTTPHandler()
# 生成https管理器
https_handler = request.HTTPSHandler()
# 建立請求管理器
opener = request.build_opener(http_handler, https_handler, cookie_handler)


def getHomePage():
    url = "http://study.miaov.com/account/user/history"
    # 若是已經執行了login函數,則opener自動已經包含對應的cookie
    rsp = opener.open(url)
    html = rsp.read().decode()
    with open("rsp_v16.html", "w") as f:
        f.write(html)
if __name__ == '__main__':
    getHomePage()
相關文章
相關標籤/搜索