Python-爬蟲(2)---requests庫

今天來聊一下我們爬蟲中必不可少的一個強大的庫requests,如果大家沒有這個包千萬不要忘記在我們最愛的cmd當中pip install一下哦。當然request庫中有很多的方法,我這個博主小白也只是接觸了一點點而已,如果有寫的不對的地方,也請大家給我留言,我會及時糾正的。
當然,根據博主的風格,咱們最開始當然還是要做一個比較大的總結啦,來來來,上圖。
在這裏插入圖片描述
接下來,我們就開始進入今天的主題了,講一下requests庫的具體使用。

requests.get()方法

我們知道很多網址其實都是get方法,怎麼知道網址是get方法還是post方法呢?我們可以查看的哦,首先將打開一個網址然後點右鍵選擇檢查,然後選擇network之後,刷新一下就可以得到很多莫名其妙的文件,可以隨意選擇一個,當然一定不要選擇圖片、音頻、視頻這種,最好是XHR或者是HTML以及XML這種,在 header 中的general中就能夠找到Request Method,這裏會有get或者是post。這樣我們就知道到底是get還是post方法啦。當然由博主微博的經驗來說,一般輸入賬號密碼等都是post方法哦。咱們的例子如題

在這裏插入圖片描述

res.stats_code

這個方法能夠查看請求之後的狀態碼,通常我們打印輸出看到是200就皆大歡喜了,如果不是200,總會覺得內心咯噔一下。

content()&text()

這一對姐妹花我們當然也是不得不提的,因爲她倆是我的最愛,不管請求怎麼網頁,我總是喜歡打印一下她們。這兩個方法都是獲取html內容的方法,但究竟有什麼不同呢?說她們的不同,當然需要特殊的字體提醒一下,以後可千萬不要混了。
content()的內容是字節形式,我們要想正常顯示的話,一定要使用decode(“utf-8”)解碼;text()的內容用是字符串形式的,如果想要正常顯示中文的話,要用encoding(“utf-8”)編碼。 但還有需要注意的是,不一定是utf-8,要看網頁的chat-set是什麼,如果網頁是gbk,我們也要進行相應的修改哦。

get方法中的關鍵字kwargs

看到關鍵字或許有疑問,這個關鍵字是做什麼用的,關鍵字一般是幫助我們進行網址拼接 ,比如我想要在百度上搜索周杰倫哥哥,這裏我們就可以使用上關鍵字了,https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
噗 這到底是什麼,根據我們二十多年來問小度的經常當然會知道我們這是百度了一個什麼東西,可是複製之後怎麼字就變化了呢?這個時候我們又不得不說說URL中的編碼和解碼的了(原理沒有辦法,小白不懂)。如果下次你的損友用不懷好意的表情給你發了一個網址,我們抱着損友不可靠的想法,一定要解碼看一下到底發了什麼,萬一是什麼少兒不宜的網站,那我們豈不是超級吃虧。

res = requests.utils.unquote("%E5%91%A8%E6%9D%B0%E4%BC%A6")
print(res)
res = requests.utils.quote("周杰倫")
print(res)

headers&proxies

headers是什麼呢?在上一篇筆記中提到了各種頭,沒錯猜對了,因爲get方法是請求,當然headers就是我們需要加上的請求頭了。
爲什麼需要加請求頭呢?因爲爬蟲的速度比人點擊速度快,很容易被服務器識別從而禁止訪問,因此我們需要模擬正常的瀏覽器去欺騙服務器
既然提到了headers,那麼proxies也一定不能忘記,代理有什麼作用呢?
代理的作用與headers類似,但是代理更加安全,我們使用代理IP的話可以隱藏自己的真實IP,另一方面,也能夠組成一個IP池,讓服務器認爲是不同的IP訪問的

url = "https://www.baidu.com"
proxies = {
    "HTTPS":"60.167.113.79:9999",
    "HTTPS":"1.197.16.63:9999",

}
res = requests.get(url, proxies=proxies)
print(res)

不知道這兩個代理IP是否還能夠使用,畢竟是幾天前找的了,如果不能,要自己找找哦。

一個小例子

好了好了,前面說了那麼多,咱們來一個小例子,結束get()方法吧。

import requests

header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}
# res = requests.get("http://www.swu.edu.cn/", headers=header)
# print(res)
# print(res.status_code) #打印狀態碼
# print(res.headers)    # 打印反應頭
# print(res.request.headers)  #打印請求頭

# 下載圖片
# url = "http://www.swu.edu.cn/images/notice/292.jpg"
# picture = requests.get(url)
#
# with open("swu.png", "wb") as f:
#     f.write(picture.content)

百度貼吧小例子

class TiebaSpider(object):
    def __init__(self, kw):
        self.kw = kw
        self.url = "https://tieba.baidu.com/f?" + self.kw + "&ie=utf-8&pn={}"
        self.header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}

    def url_list(self):
        # 獲取網址的列表
        return [self.url.format(i*50) for i in range(10)]

    def request_url(self,url):
        # 請求url地址
        res = requests.get(url, headers=self.header)
        # res.encoding("utf-8")
        # content = res.text
        return res.text

    def save_text(self,content,page_num):
        # 保存獲取的頁面
        with open("{}_第{}頁.txt".format(self.kw, page_num), "w+") as f:
            f.write(content)

    def run(self):
        url_list = self.url_list()
        page_num = 0
        for url in url_list:
            url_content = self.request_url(url)
            url_content.encode(encoding='utf-8')
            # print(url_content)
            # exit()
            page_num += 1
            self.save_text(url_content, page_num)


if __name__ == "__main__":
    TS = TiebaSpider("周杰倫")
    TS.run()

timeout&assert

如果指定了timeout=3一般是請求這個網址超過三秒就結束了,並不會再次請求,但是怎麼在請求不成功時再次請求呢,如果請求成功了就不再請求了,當然循環加上判斷肯定可以實現,但是如何用外部方法實現呢?這個時候可以使用retry方法。代碼實現如下:

import requests
from retrying import retry


header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}

@retry(stop_max_attempt_number=3)
#在超時的情況下,讓代碼重複執行幾次,如果請求一次就成功了的話,就不會重複執行
def _parse_url(url):
    print("代碼執行了幾次?")
    res = requests.get(url, headers=header, timeout=3)
    assert res.status_code == 200
    return res.content.decode()


def parse_url(url):
    try:
        html_str = _parse_url(url)
    except:
        html_str = None

    return html_str


if __name__ == '__main__':
    url = 'https://www.baidsu.com'
    # print(parse_url(url))
    parse_url(url)

requests.post()方法

Emmm~ 目前爲止,我的post方法學的並不怎麼好,這一點自己也是知道的,所以關於post方法我就不自己贅述了,給出老師筆記的網址(居然老師爬蟲教程

#發送POST請求
# 百度翻譯案例

# data = {
#     'from':' zh',
#     'to':' en',
#     'query':' 翻譯',
#     'transtype':' translang',
#     'simple_means_flag':' 3',
#     'sign':' 31941.303092',
#     'token':' bbfb7b73aadf7414e2a54a40a39c157b',
# }
#
# post_url = "https://fanyi.baidu.com/v2transapi?from=zh&to=en"
# res = requests.post(post_url, data=data, headers=header)
# print(res.text)
# PC端與手機端的區別就是請求頭不一樣

session&cookie

我們利用session和cookie可以獲取登錄後網頁內容,使用方法以登錄人人網爲例

# session和cookie 保存用戶信息
# 登錄人人網
# session = requests.session()
# url = "http://www.renren.com/PLogin.do"
# post_data ={
#     "emial":"[email protected]",
#     "password":"*******",
#     }
# # cookie保存在其中
# session.post(url, data=post_data, headers=header)
#
# res = session.get("http://www.renren.com/973411857/newsfeed/photo", headers=header)
# print(res)

# header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36",
#           "Cookie":"anonymid=k57gya8e-5x01gg; depovince=GW; _r01_=1; ick_login=09eb4eb4-0402-4722-80ae-81a5110082b8; taihe_bi_sdk_uid=8a4532b966136e9c7567787490ea64cb; taihe_bi_sdk_session=1416785d026288e239dbe4d6d8f8f1e8; loginfrom=null; jebe_key=efcf56f9-1bfb-4624-a3b6-756e7d32e7b6%7Cddeaa5791216f5acf04b825b64bc0fa2%7C1578619044992%7C1%7C1578619044919; _de=FAA24AFD253015DB247380B22A94C474696BF75400CE19CC; t=a9f3f05577d82c4855119f41118679817; societyguester=a9f3f05577d82c4855119f41118679817; id=973411857; xnsid=72759b24; jebecookies=1748263d-5acd-4e20-b63a-0b1d5b35b19e|||||; ver=7.0; wp_fold=0"
#           }
#
# res = requests.get("http://www.renren.com/973411857/newsfeed/photo",headers=header)
# with open("qinghuan.html","w",encoding="utf-8") as f:
#     f.write(res.text)

cookie = "anonymid=k57gya8e-5x01gg; depovince=GW; _r01_=1; ick_login=09eb4eb4-0402-4722-80ae-81a5110082b8; taihe_bi_sdk_uid=8a4532b966136e9c7567787490ea64cb; taihe_bi_sdk_session=1416785d026288e239dbe4d6d8f8f1e8; loginfrom=null; jebe_key=efcf56f9-1bfb-4624-a3b6-756e7d32e7b6%7Cddeaa5791216f5acf04b825b64bc0fa2%7C1578619044992%7C1%7C1578619044919; _de=FAA24AFD253015DB247380B22A94C474696BF75400CE19CC; t=a9f3f05577d82c4855119f41118679817; societyguester=a9f3f05577d82c4855119f41118679817; id=973411857; xnsid=72759b24; jebecookies=1748263d-5acd-4e20-b63a-0b1d5b35b19e|||||; ver=7.0; wp_fold=0"
Cookie = {i.split('=')[0]:i.split('=')[1] for i in cookie.split(';')}
# print(Cookie)
res = requests.get("http://www.renren.com/973411857/newsfeed/photo", headers=header, cookies=cookie)
print(res)

requests庫中有函數可以將cookie對象轉換爲字典,也能夠將字典轉換爲cookie對象。

#將cookie對象轉爲字典, 字典轉爲cookie對象
# url = "https://www.baidu.com"
# header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
# res = requests.get(url, headers=header)
# cookies = requests.utils.dict_from_cookiejar(res.cookies)
# # 把字典轉化爲cookies對象是cookiejar_from_dict()
# print(cookies)
# a = requests.utils.cookiejar_from_dict(cookies)
# print(a)

json數據

JSON是一種輕量級的數據交換格式,它使得人們很容易的進行閱讀和編寫。同時也方便了機器進行解析和生成。適用於進行數據交互的場景,比如網站前臺與後臺之間的數據交互。(關於json數據更多的內容,參考居然老師爬蟲教程
請求頭添加:https://curl.trillworks.com/

練習代碼的小案例

這個案例是爬取王者榮耀英雄的個數,這個網址是一個標準的json數據,但是我也不知道這個網址是怎麼來的。

#英雄列表URL地址
import requests
import os
from urllib.request import urlretrieve
def main(url, header):
    res = requests.get(url, headers=header)
    req = res.json()
    hero_num = len(req['list'])
    print("一共有{}位英雄" .format(hero_num))
    hero_images_path = "hero_images"
    if not os.path.exists(hero_images_path):
        os.mkdir(hero_images_path)
    hero_list = req['list']
    for each_hero in hero_list:
        hero_photo_url = each_hero['cover']
        hero_name = each_hero['name'] + '.jpg'
        filename = hero_images_path + '/' +hero_name
        print("正在下載{}的圖片" .format(each_hero['name']))
        urlretrieve(url=hero_photo_url, filename=filename)
        # 根據url地址下載圖片,第一個參數是地址,第二個參數是文件路徑
        # with open('{}'.format(filename), 'wb') as f:
        #       f.write()


if __name__ == '__main__':
    heros_url = "http://gamehelper.gm825.com/wzry/hero/list"
    header = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    main(heros_url, header)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章