国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python3網絡爬蟲實戰---36、分析Ajax爬取今日頭條街拍美圖

Leck1e / 2255人閱讀

摘要:上一篇文章網絡爬蟲實戰數據爬取下一篇文章網絡爬蟲實戰動態渲染頁面抓取本節我們以今日頭條為例來嘗試通過分析請求來抓取網頁數據的方法,我們這次要抓取的目標是今日頭條的街拍美圖,抓取完成之后將每組圖片分文件夾下載到本地保存下來。

上一篇文章:Python3網絡爬蟲實戰---35、 Ajax數據爬取
下一篇文章:Python3網絡爬蟲實戰---37、動態渲染頁面抓取:Selenium

本節我們以今日頭條為例來嘗試通過分析 Ajax 請求來抓取網頁數據的方法,我們這次要抓取的目標是今日頭條的街拍美圖,抓取完成之后將每組圖片分文件夾下載到本地保存下來。

1. 準備工作

在本節開始之前請確保已經安裝好了 Requests 庫,如沒有安裝可以參考第一章的安裝說明。

2. 抓取分析

在抓取之前我們首先要分析一下抓取的邏輯,首先打開今日頭條的首頁:http://www.toutiao.com/,如圖 6-15 所示:

圖 6-15 首頁內容
在右上角有一個搜索入口,在這里我們嘗試抓取街拍美圖,所以輸入“街拍”二字搜索一下,結果圖 6-16 所示:

圖 6-16 搜索結果
這樣我們就跳轉到了搜索結果頁面。
這時打開開發者工具,查看一下所有網絡請求,我們首先打開第一個網絡請求,這個請求的 URL 就是當前的鏈接:http://www.toutiao.com/search...,打開 Preview 選項卡查看 Response Body,如果頁面中的內容是直接請求直接加載出來的,那么這第一個請求的源代碼中必然包含了頁面結果中的文字,為了驗證,我們可以嘗試嘗試搜索一下搜索結果的標題,比如“路人”二字,如圖 6-17 所示:

圖 6-17 搜索結果
然而發現網頁源代碼中并沒有包含這兩個字,搜索匹配結果數目為 0。
所以我們就可以初步判斷出這些內容是由 Ajax 加載然后用JavaScript 渲染出來的,所以接下來我們可以切換到 XHR過濾選項卡查看一下有沒有 Ajax 請求。

不出所料,此處出現了一個比較常規的 Ajax 請求,觀察一下它的結果是否包含了頁面中的相關數據。
點擊 data 字段展開,發現這里有許多條數據,我們點擊第一條繼續展開,可以發現有一個 title 字段,它的值正好就是頁面中的第一條數據的標題,再檢查一下其他的數據也正好是一一對應的,如圖 6-18 所示:

圖 6-18 對比結果
那這就確定了這些數據確實是由 Ajax 加載的。
我們的目的是要抓取其中的美圖,這里一組圖就對應上文中的 data 字段中的一條數據,每條數據還有一個image_detail 字段,它是一個列表形式,這其中就包含了組圖的所有圖片列表,如圖 6-19 所示:

圖 6-19 圖片列表信息
所以我們只需要將列表中的 url 字段提取出來并下載下來就好了,每一組圖都建立一個文件夾,文件夾的名稱就命名為組圖的標題。
接下來我們就可以直接用 Python 來模擬這個 Ajax 請求,然后提取出相關美圖鏈接并下載即可。但是在這之前我們還需要分析一下 URL 的規律。
切換回 Headers 選項卡,我們觀察一下它的請求 URL 和 Headers 信息,如圖 6-20 所示:

圖 6-20 請求信息
可以看到這是一個 GET 請求,請求 URL 的參數有 offset、format、keyword、autoload、count、cur_tab,我們需要找出這些參數的規律才方便用程序構造出來。
接下來我們可以滑動頁面,多加載一些新的結果,在加載的同時可以發現 Network 中又出現了許多 Ajax 請求,如圖 6-21 所示:

evernotecid://D603D29C-DFBA-4C04-85E9-CCA3C33763F6/appyinxiangcom/23852268/ENResource/p193

圖 6-21 Ajax 請求
在這里觀察一下后續鏈接的參數,可以發現變化的參數只有offset,其他的都沒有變化,而且第二次請求的 offset 值為 20,第三次為 40,第四次為 60,所以可以發現規律,這個 offset 值就是偏移量,而進而可以推斷出 count 參數就是一次性獲取的數據條數,所以我們可以用 offset 參數來控制數據分頁,這樣一來,我們就可以通過接口批量獲取數據了,然后將數據解析,將圖片下載下來就大功告成了。

3. 實戰演練

我們剛才已經分析了一下 Ajax 請求的邏輯,下面我們就用程序來實現美圖下載吧。
首先我們實現一個方法用于加載單個 Ajax 請求的結果,叫做 get_page(),其中唯一變化的參數就是 offset,所以我們將 offset 當作參數傳遞,方法實現如下:

import requests
from urllib.parse import urlencode

def get_page(offset):
??? params = {
??????? "offset": offset,
??????? "format": "json",
??????? "keyword": "街拍",
??????? "autoload": "true",
??????? "count": "20",
??????? "cur_tab": "1",
??? }
??? url = "http://www.toutiao.com/search_content/?" + urlencode(params)
??? try:
??????? response = requests.get(url)
??????? if response.status_code == 200:
??????????? return response.json()
??? except requests.ConnectionError:
??????? return None

在這里我們用 urlencode() 方法構造了請求的 GET 參數,然后用 Requests 請求這個鏈接,如果返回狀態碼為 200,則調用 response 的 json() 方法將結果轉為 Json 格式,然后返回。
接下來我們再實現一個解析方法,提取每條數據的 image_detail 字段中的每一張圖片鏈接,將圖片鏈接和圖片所屬的標題一并返回,構造一個生成器,代碼如下:

def get_images(json):
??? if json.get("data"):
??????? for item in json.get("data"):
??????????? title = item.get("title")
??????????? images = item.get("image_detail")
??????????? for image in images:
??????????????? yield {
??????????????????? "image": image.get("url"),
??????????????????? "title": title
??????????????? }

接下來我們實現一個保存圖片的方法,item 就是剛才get_images() 方法返回的一個字典,在方法中我們首先根據 item 的 title 來創建文件夾,然后請求這個圖片鏈接,獲取圖片的二進制數據,以二進制的形式寫入文件,圖片的名稱可以使用其內容的 MD5 值,這樣可以去除重復。

import os
from hashlib import md5

def save_image(item):
??? if not os.path.exists(item.get("title")):
??????? os.mkdir(item.get("title"))
??? try:
??????? response = requests.get(item.get("image"))
??????? if response.status_code == 200:
??????????? file_path = "{0}/{1}.{2}".format(item.get("title"), md5(response.content).hexdigest(), "jpg")
??????????? if not os.path.exists(file_path):
??????????????? with open(file_path, "wb") as f:
??????????????????? f.write(response.content)
??????????? else:
??????????????? print("Already Downloaded", file_path)
??? except requests.ConnectionError:
??????? print("Failed to Save Image")

最后我們只需要構造一個 offset 數組,遍歷 offset,提取圖片鏈接,并將其下載即可。

from multiprocessing.pool import Pool

def main(offset):
??? json = get_page(offset)
??? for item in get_images(json):
??????? print(item)
??????? save_image(item)


GROUP_START = 1
GROUP_END = 20

if __name__ == "__main__":
??? pool = Pool()
??? groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)])
??? pool.map(main, groups)
??? pool.close()
??? pool.join()

在這里定義了分頁的起始和終止頁數,分別為 GROUP_START 和 GROUP_END,還利用了多線程的線程池,調用其 map() 方法實現多線程下載。
這樣整個程序都就完成了,運行之后可以發現街拍美圖都分文件夾保存下來了,如圖 6-22 所示:

圖 6-22 保存結果

4. 本節代碼

本節代碼地址:https://github.com/oldmarkfac...

5. 結語

以上便是抓取今日頭條街拍美圖的過程,通過本節我們可以了解 Ajax 分析的流程、Ajax 分頁的模擬以及圖片的下載過程。
本節的內容需要熟練掌握,在后面的實戰中我們還會用到很多次這樣的分析和抓取。

上一篇文章:Python3網絡爬蟲實戰---35、 Ajax數據爬取
下一篇文章:Python3網絡爬蟲實戰---37、動態渲染頁面抓取:Selenium

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/44113.html

相關文章

  • Python3網絡爬蟲實戰---35、 Ajax數據爬取

    摘要:所以說,我們所看到的微博頁面的真實數據并不是最原始的頁面返回的,而是后來執行后再次向后臺發送了請求,拿到數據后再進一步渲染出來的。結果提取仍然是拿微博為例,我們接下來用來模擬這些請求,把馬云發過的微博爬取下來。 上一篇文章:Python3網絡爬蟲實戰---34、數據存儲:非關系型數據庫存儲:Redis下一篇文章:Python3網絡爬蟲實戰---36、分析Ajax爬取今日頭條街拍美圖 ...

    Thanatos 評論0 收藏0
  • python爬蟲實戰,requests模塊,Python實現抓取頭條街拍美圖

    摘要:前言利用爬取的是今日頭條中的街拍美圖。詳細瀏覽器信息獲取文章鏈接相關代碼街拍獲取失敗這里需要提一下模塊的報錯在對象上調用方法如果下載文件出錯會拋出異常需要使用和語句將代碼行包裹起來處理這一錯誤不讓程序崩潰。 ...

    番茄西紅柿 評論0 收藏2637
  • Python3網絡爬蟲實戰---37、動態渲染頁面抓取:Selenium

    摘要:不過動態渲染的頁面不止這一種。再有淘寶這種頁面,它即使是獲取的數據,但是其接口含有很多加密參數,我們難以直接找出其規律,也很難直接分析來抓取。我們用一個實例來感受一下在這里們依然是先打開知乎頁面,然后獲取提問按鈕這個節點,再將其 上一篇文章:Python3網絡爬蟲實戰---36、分析Ajax爬取今日頭條街拍美圖下一篇文章:Python3網絡爬蟲實戰---38、動態渲染頁面抓取:Spla...

    zhjx922 評論0 收藏0
  • node網絡爬蟲實例了解下?

    摘要:今天給大家分享的是爬蟲,寫得不好的大家多關照,指出背景交代,以下寫的都是參照網絡爬蟲開發實戰用實現的,所以的具體思路什么的,大家可以去看書上的介紹,感興趣的,可以去了解一波。 今天給大家分享的是node爬蟲,寫得不好的大家多關照,指出 背景交代,以下寫的demo都是參照《python3網絡爬蟲開發實戰》用node實現的,所以demo的具體思路什么的,大家可以去看書上的介紹,感興趣的,可...

    陸斌 評論0 收藏0
  • Python3網絡爬蟲實戰---10、爬蟲框架的安裝:PySpider、Scrapy

    摘要:所以如果對爬蟲有一定基礎,上手框架是一種好的選擇。缺少包,使用安裝即可缺少包,使用安裝即可上一篇文章網絡爬蟲實戰爬取相關庫的安裝的安裝下一篇文章網絡爬蟲實戰爬蟲框架的安裝 上一篇文章:Python3網絡爬蟲實戰---9、APP爬取相關庫的安裝:Appium的安裝下一篇文章:Python3網絡爬蟲實戰---11、爬蟲框架的安裝:ScrapySplash、ScrapyRedis 我們直接...

    張憲坤 評論0 收藏0

發表評論

0條評論

Leck1e

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<