1. 程式人生 > >用Ajax爬取今日頭條圖片集

用Ajax爬取今日頭條圖片集

urllib sta os.path images amp int jpg asc scrip

Ajax原理

? 在用requests抓取頁面時,得到的結果可能和瀏覽器中看到的不一樣:在瀏覽器中可以正常顯示的頁面數據,但用requests得到的結果並沒有。這是因為requests獲取的都是原始 HTML文檔,而瀏覽器中頁面
則是經過Ajax處理數據後生成的。這些數據可能在HTML文檔中,也可能是經過JavaScript和特定算法後生成的。
? 剛開始HTML文檔中不包含某些數據,當原始頁面加載完後,會向服務器發送Ajax請求獲取數據,這些數據被JavaScript處理形成一些新頁面。

? Ajax: 即異步的JavaScript和XML,是利用JavaScript在保證頁面不刷新、鏈接不改變的情況下與服務器交換數據的並更新
部分網頁的技術。

示例:用Ajax爬取今日頭條圖片

最近想買工裝褲穿,可又不知道怎麽搭配,所以就用爬蟲爬下頭條上工裝褲的穿搭圖片啦

(1) 獲取網頁頁面的JSON文檔
import os
import requests
from urllib.parse import urlencode           #來構造url參數的
from hashlib import md5                      #用來解析圖片二進制的

#獲取頁面json
def get_page(offest):
    params={
            ‘aid‘:‘24‘,
            ‘offest‘:offest,
            ‘format‘:‘json‘,
            ‘keyword‘:‘%E5%B7%A5%E8%A3%85%E8%A3%A4‘,
            ‘autoload‘:‘true‘,
            ‘count‘:‘20‘,
            ‘cur_tab‘:‘1‘,
            ‘from‘:‘search_tab‘,
            ‘pd‘:‘synthesis‘
            }
    url=‘https://www.toutiao.com/api/search/content/?aid=24&offset=0&format=json&keyword=%E5%B7%A5%E8%A3%85%E8%A3%A4&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis‘+urlencode(params)
        #用urlencode構造url中參數
    try:
        response=requests.get(url)
        if response.status_code==200:                #當請求成功時(status_code=200時)才繼續下面代碼
            return response.json()                   #用json方法將結果轉化成JSON格式
    except requests.ConnectionError:
        return None

註意:
1)構造Ajax請求時,先探索清楚當前頁面中Ajax請求鏈接的結構和規律。這裏是Offest改變,其他參數不變。
2)使用urlencode方法構造請求的GET參數
3)發現只有offest發生改變,第一頁0,第二頁20,第三頁40,依次增加20

(2)構造包含圖片鏈接和標題的字典
#提取圖片url和標題
def parse_page(json):
    if json.get(‘data‘):
        for item in json.get(‘data‘):      #找到所需數據所處位置
            if item.get(‘title‘)==None:    #運行後發現不是每個item裏都有圖片鏈接和title,沒有的直接跳過
                continue
            title=item.get(‘title‘)        #找到標題
            print(title)
            images=item.get(‘image_list‘)
            print(images)
            for image in images:
                yield{
                    ‘image‘:image.get(‘url‘), #找到這個標題下的所以圖片url 形成字典生成器
                    ‘title‘:title
                }

註意:
1)yield{}方法構造字典生成器非常簡單,快速。
2)用json.get()方法在json文檔中找取參數值非常快。

(3)把數據保存到本地
#實現保存圖片的方法
def save_image(item):
    if not os.path.exists(item.get(‘title‘)):      #創建以標題為名稱的文件夾
        os.mkdir(item.get(‘title‘))
    try:
        response=requests.get(item.get(‘image‘))  #訪問圖片的url
        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):     #名稱file_path使用其內容的md5值,可以去除重復
                with open(file_path,‘wb‘) as f:  #訪問成功後,將其二進制代碼存入file_path.jpg中
                    f.write(response.content)
            else:
                print(‘Already Download‘,file_path)
    except requests.ConnectionError:
        print(‘Failed to save image‘)

註意:
1)這裏的item就是(2)中得到的包含url和標題的字典
1)是以二進制寫的方式存入文件,‘wb‘

(4)構造offest 進行遍歷
def main(offest):
    json=get_page(offest)
    for item in parse_page(json):
        print(item)
        save_image(item)

if __name__==‘__main__‘:
    for i in range(0,4):
        offest=i*20
        main(offest)
PS:代碼敘述有不完整的地方,歡迎大家私信我。完整代碼鏈接https://github.com/xubin97

用Ajax爬取今日頭條圖片集