python爬蟲使用requests庫抓取搜狗圖片(超詳細)

作為一個初學爬蟲的小白,還是決定開始寫一些文章來紀念自己的學習過程,希望自己能有進步.

前幾周學習了python基礎模塊urlllib的使用, 有很多功能實現(xiàn)起來都很復雜, 直到現(xiàn)在學了第三方模塊requests后驚嘆于它的簡潔性與實用性, 但是requests模塊的底層實現(xiàn)還是調用了urllib的有關模塊的.? 不扯遠了, 下面是我用requests庫抓取搜狗圖片的詳細過程:

一般瀏覽器發(fā)起的請求有兩種: get請求和 post請求, 根據(jù)我們的需要使用 get請求就可以實現(xiàn)這個功能了.? 這里稍微區(qū)分下get和post: get一般是把發(fā)送給服務器的信息放在請求頭中, 它的請求有長度限制, 而且不可以處理敏感數(shù)據(jù), 因為它的 傳輸是不加密的 , 所以我們在模擬登錄請求時候一般用的都是post.? post一般是把發(fā)送給服務器的信息放在http消息主體中, 請求長度是沒有限制的, 同時post信息是加密傳輸?shù)? 所以可以用來模擬登錄.. . 粗略介紹了下 get 和 post.?

然后我的想法就是實現(xiàn)一個能根據(jù)輸入關鍵詞爬取圖片的python程序, 那么在傳給搜狗服務的請求參數(shù)中就需要添加這個關鍵詞, 請求長度不是特別長而且可以明文傳輸, 我們用get足矣.??

1. 首先打開搜狗圖片首頁我們需要在里面找到我們的目標url:

(1). 訪問主頁頁面:

很顯然我們要輸入關鍵字的話直接用這個url肯定是不行的, 我們首先嘗試下人工搜索, 看看地址欄url有什么變化(我們首先需要明確一點: 爬蟲是灰色產業(yè), 也就是說既不能說不違法, 也不能說違法(不要太過分就好). 那么為什么說它不違法呢? --- 爬蟲只能訪問用戶可以訪問到的內容, 比如愛奇藝 VIP視頻 , 你普通用戶是看不了的, 那有人問用爬蟲可不可以爬VIP視頻呢? 答案是可以的, 但是有個前提 -> 你必須要用VIP的身份去登陸它的網站再進行爬取. )

這里說這個的意思是, 你爬一個東西前, 最好人工去訪問下你想要爬的內容, 如果你人工都訪問不了, 那么你還是放棄吧! 爬蟲也爬不了的 (如果強行獲取用戶訪問不了的數(shù)據(jù) -> 那就是黑客了, 是犯法了. 我們是spider, 不是 hacker...)?

人工模擬搜索:

上面的url我復制過來是這個:?

https://pic.sogou.com/pics?query=%D0%C7%BF%D5&w=05009900&p=&_asf=pic.sogou.com&_ast=1585124780&sc=index&sut=12529&sst0=1585124779974

這個一看就知道是個get請求, 也就是主url 加上若干個參數(shù)的拼接, 其中參數(shù)用&分開, 我們發(fā)現(xiàn)一共有6個參數(shù):

query, w, p, _asf, _ast, sc, sut, ssto? 這些參數(shù)中肯定有我們有用的, 也肯定有我們不需要的, 我們來分析下, 首先query的意思是查詢, 它其實就是我們要查詢的關鍵字,?%D0%C7%BF%D5 的意思是星空, 只不過是特殊的url編碼表示的"星空", 一般是一種urlencoded格式(用于網絡信息傳輸). 我們可以驗證下:


結果是

發(fā)現(xiàn)不是我們想要的, 其實這是utf-8和gbk格式數(shù)據(jù)的差異, 我們看看搜狗圖片網站的編碼:?

發(fā)現(xiàn)它是gbk格式的, 那么傳輸數(shù)據(jù)的轉換格式也應該用gbk, 我們用gbk試試:

結果:

完全一致,那我們的猜想就對了 query 對應的確實是查詢關鍵字, 那么其他關鍵字呢? 在這里我們可以采取"控制變量法" 去"試", 嘗試去掉某些關鍵字看網頁是否有所改變, 最后我們發(fā)現(xiàn)其他關鍵字都去掉了網頁還是不變:

下一步是分析網頁構造:

我們首先選定一張圖片, 右鍵點擊它, 選擇復制圖片地址, 然后我們用Google提供的查看網頁源代碼功能, 在源代碼界面按 ctrl + F 查找元素, 然后粘貼圖片地址:?

然后根據(jù)匹配項(橙色部分)前面的屬性值確定圖片是放在哪里的, 這里圖片是放在?"thumbUrl"這個屬性里面, 我們再用同樣的方法搜索這個屬性名, 看看有幾個匹配項:

這里有48個圖片, 也就是48個匹配項, 48張圖片, 我們來檢查下是不是一一對應的:?

然后在新窗口中輸入這個url:

發(fā)現(xiàn)確實是對的, 我們屬性也找對了. 現(xiàn)在來說說兩個"問題":

一 : 我們發(fā)現(xiàn), 搜狗圖片的顯示好像是"無窮無盡"的, 為什么我們這個源代碼頁面只有48個? 其實當我們把滑條向下拉動時會一直有新的圖片出來, 沒有"下一頁"的選項, 這里其實用到了web開發(fā)一種技術: AJAX, 我們不需要具體去學AJAX, 我們只要知道它是啥東西就行了, AJAX技術實現(xiàn)了網頁的動態(tài)加載(網頁不是一次性加載出全部資源, 而是動態(tài)加載資源, 避免了因為網頁過于臃腫而影響加載速度). 我們如何從動態(tài)加載的網頁中找出"目標url"? --> 這個就是我們的目的.? 這里我們可以借助Google瀏覽器的開發(fā)者工具:?

打開開發(fā)者工具的快捷鍵是 ctrl + shift + i (或者 ctrl + shift + c), 進到開發(fā)者工具后我們點擊 network選項:

里面就會有網頁所有的元素, 這里我們需要關注的是一個XHR的選項:

XHR全程XMLHttpRequest, 意思是可擴展超文本傳輸請求, XHR對象可以在不向服務器提交整個頁面的情況下實現(xiàn)局部更新網頁. 當頁面全部加載完畢后, 客戶端通過該對象向服務器請求數(shù)據(jù), 服務器端接收數(shù)據(jù)并處理后向客戶端反饋數(shù)據(jù), XHR對象提供了對HTTP協(xié)議的完全訪問, 包括POST和HEAD請求以及普通的GET請求的能力, XHR可以同步或異步返回web服務器的響應, 能以文本或DOM文檔的形式返回內容..........?

不說遠了, 它對我們完成程序至關重要, 現(xiàn)在我們的XHR里面的內容是空的:

是因為我們在打開開發(fā)者工具抓包前它已經返回了請求的數(shù)據(jù), 所以這里抓包沒抓到, 我們可以在保持開發(fā)者工具打開的情況下刷新下網頁來獲得初始數(shù)據(jù), Google瀏覽器按ctrl + r或點擊左上角的刷新按鈕實現(xiàn)刷新:

現(xiàn)在XHR里面已經有了一個數(shù)據(jù), 我們來看看它是什么:

首先左鍵點擊它:

在這里選擇Preview或者左鍵連點兩次可以打開在新標簽頁打開服務器返回的數(shù)據(jù)(可能更方便查找數(shù)據(jù)).

我們右鍵在新標簽頁打開這個url:

我們首先跟上面一樣, 第一步分析url結構:

這樣得到一個url:?https://pic.sogou.com/pics?query=%D0%C7%BF%D5&mode=1&start=48&reqType=ajax&reqFrom=result&tn=0

我們還是可以找出這個get請求由哪些關鍵詞組成: query, mode, start, reqType, reqFrom, tn

我們繼續(xù)用"控制變量法"分析它, query肯定需要, 是查詢的關鍵詞, 分析過程如下:

一: 先把出了query的關鍵詞全部去掉:?https://pic.sogou.com/pics?query=%D0%C7%BF%D5,?

發(fā)現(xiàn)它跳到了這個界面,不是我們需要的數(shù)據(jù):

然后我們可以保留一個關鍵詞,例如start , 猜測它是很有用的:https://pic.sogou.com/pics?query=%D0%C7%BF%D5&start=48,?

發(fā)現(xiàn)它還是跳到了一個圖片網站, 只是起始圖片不同了:

證明它是有用的, 可以告訴服務器從第幾張圖片開始返回, 我們保留它, 剩下的關鍵詞我們猜測reqType是有用的, 因為它等于AJAX, 正好是前面講的一種web開發(fā)技術, 我們試試這個url:?https://pic.sogou.com/pics?query=%D0%C7%BF%D5&start=48&reqType=ajax:

我們檢驗下這個頁面的第一個圖片:

發(fā)現(xiàn)不是最初頁面的第一張, 然后我們剛剛不是分析了start嗎? 我們可以嘗試修改start=0, 試試返回的第一張應該就是最初頁面的第一張圖了:

驗證下,果然就是第一張圖:

到這里我們分析差不多結束了, 我們分析得到的最終url類似這樣:

https://pic.sogou.com/pics?query=%D0%C7%BF%D5&start=0&reqType=ajax

這里我說明下,其他參數(shù)什么意思我也不知道, 但是不影響我們爬圖片, 其實加上也可以, 沒必要去試, 就把所有的參數(shù)都帶上, 省時間.??

經過前面的分析, 怎么爬取多個圖片? 好像我們每次請求, 他只返回給我們48張圖片(不管我們的start變成多少), 這里我們怎么辦呢? 很簡單 ---- > 我們可以在python代碼里面循環(huán)更改start的值, 就可以從不同的起始圖開始爬取數(shù)據(jù)了 . 比如,? 我們可以讓start 最初為 0 , 然后爬取完一組數(shù)據(jù)后讓start += 48 , 就可以啦 .. 為什么要加48, emmm,? 因為搜狗服務器一次只返回給我們48張....??

綜上所述, url,也找出來了,? 結果也分析出來了,? 本來我們可以開始代碼了, 但是我后來代碼寫完才發(fā)現(xiàn)爬取到的圖片好小,? 根本不是那種特別清晰的,? 總之比起我們單擊搜狗圖片里面某個圖片后打開的圖片來說完全就是"縮小版",?

像這樣:

左邊的是我們爬到的, 右邊的是點開圖片后搜狗圖片展示的, 我們怎么辦? --> 我們肯定要追求最好是不? 然后我果斷選擇繼續(xù): 我首先就在搜狗圖片詳情頁復制了下圖片地址然后去返回的請求里找看有沒有:

詳情頁就是這個頁面(單機圖片后的):

我們最后找到了, 而且還有好幾個匹配的項:


我們發(fā)現(xiàn)這個屬性名不是前面那個"thumbUrl", 但是它們確實都在同一個頁面, 只不過是在屬性名不同的值里面, 我們最后只要稍微修改下代碼就好了.?

注意點:




這里我代碼里面是把所有的參數(shù)都拼接上去了, 其實只需要下面兩個參數(shù)即可, 一個query, 一個start,? 這是我們分析出來的.? ?url? 就是去掉所有參數(shù)后剩下的, user-agent 用來辨別用戶身份, 如果不自己修改的話, 最后的請求頭python會自動給你加上 帶有python字樣的user-agent,? 那別人就很容易知道你是爬蟲來處理你. 所以每次爬的時候都要帶上.? 然后請求數(shù)據(jù)就兩行:


這里講下用response的好處, 我們之前不是看到 關鍵詞 "星空" 在url里是有著urlencoded格式的特殊類型, 所以本來我們在請求的時候需要將url里不符合規(guī)范的格式全部改成urlencoded格式(在urllib底層庫里我們需要手動改),? 當然在第三方模塊 requests中 它會自動將不是標準格式的url改成標準格式, 很方便, 而且相比urllib的請求, requests多了個 params參數(shù):

它可以自動將python字典,元組組成的列表或者bytes類型轉化為標準格式并拼接到url后面, 也是很方便.?

這里最后說下返回值的問題: 我們打開請求網頁也看到了, 服務器返回給我們的其實是一個json對象, 遇到這種情況, 我們也不需要將返回的改成字符串然后用正則或者xpath去解析, 直接將它轉化為json對象(在python代碼里表現(xiàn)為字典格式), 然后直接從字典去找需要的元素. 怎么轉換成json格式, 有兩種方法, 第一種就是利用強大的requests模塊的json方法:

def json(self,**kwargs):

? ? r"""Returns the json-encoded content of a response, if any.

:param \*\*kwargs: Optional arguments that ``json.loads`` takes.

:raises ValueError: If the response body does not contain valid json.

? ? """

這是源碼里的, 就是如果返回的response對象包含一個合法的json, 就可以直接將返回對象轉換成json格式(也就是個字典); 第二種方法就是, import json? 然后將返回值轉換成字符串或者bytes 然后用 response = json.loads(response.content(或者response.text)), 也可以實現(xiàn), 原理是一樣的, 只不過requests別人幫我們封裝好了.?

之后就沒啥難點了, 就是保存文件是用二進制將返回的數(shù)據(jù)保存到本地, 原理是所有mp4, mp3, jpg, mkv, png等等等等 都是將視頻,音樂等對象用不同的壓縮算法將它們壓縮成計算機能保存的(0, 1流)二進制文件, 自然我們只要取得這二進制文件完全相同的所有字節(jié)就相當于"下載" 了.?



運行結果如下:


(從第50張開始下是因為之前下過前50張, 不會重復下)




最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末锁蠕,一起剝皮案震驚了整個濱河市件缸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贮懈,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹦倚,死亡現(xiàn)場離奇詭異涩赢,居然都是意外死亡,警方通過查閱死者的電腦和手機耸彪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忘苛,“玉大人蝉娜,你說我怎么就攤上這事唱较。” “怎么了召川?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵南缓,是天一觀的道長。 經常有香客問我荧呐,道長汉形,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任倍阐,我火速辦了婚禮吠各,結果婚禮上英妓,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好掰茶,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布惫霸。 她就那樣靜靜地躺著寂汇,像睡著了一般西采。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鞠柄,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天侦高,我揣著相機與錄音,去河邊找鬼厌杜。 笑死奉呛,一個胖子當著我的面吹牛,可吹牛的內容都是我干的期奔。 我是一名探鬼主播侧馅,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼危尿,長吁一口氣:“原來是場噩夢啊……” “哼呐萌!你這毒婦竟也來了?” 一聲冷哼從身側響起谊娇,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤肺孤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后济欢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赠堵,經...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年法褥,在試婚紗的時候發(fā)現(xiàn)自己被綠了茫叭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡半等,死狀恐怖揍愁,靈堂內的尸體忽然破棺而出呐萨,到底是詐尸還是另有隱情,我是刑警寧澤莽囤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布谬擦,位于F島的核電站,受9級特大地震影響朽缎,放射性物質發(fā)生泄漏惨远。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一话肖、第九天 我趴在偏房一處隱蔽的房頂上張望北秽。 院中可真熱鬧,春花似錦最筒、人聲如沸羡儿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掠归。三九已至,卻和暖如春悄泥,著一層夾襖步出監(jiān)牢的瞬間虏冻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工弹囚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厨相,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓鸥鹉,卻偏偏與公主長得像蛮穿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毁渗,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內容

  • 上一篇:8.Urllib庫基本使用下一篇:10.正則表達式基礎 requests是python實現(xiàn)的最簡單易用的H...
    在努力中閱讀 3,362評論 2 11
  • 快速上手 迫不及待了嗎践磅?本頁內容為如何入門 Requests 提供了很好的指引。其假設你已經安裝了 Request...
    Aedda閱讀 640評論 0 0
  • 概要 64學時 3.5學分 章節(jié)安排 電子商務網站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,223評論 0 3
  • iOS開發(fā)系列--網絡開發(fā) 概覽 大部分應用程序都或多或少會牽扯到網絡開發(fā)灸异,例如說新浪微博府适、微信等,這些應用本身可...
    lichengjin閱讀 3,671評論 2 7
  • 我給烈日 撒點鹽 讓陽光 別那么刺眼 我給時光 畫讓句點 讓節(jié)氣 定格在春天 我把月亮 裝進口袋 讓月色 伴我入眠...
    妖已成精閱讀 312評論 2 2