Python之Instagram圖片爬蟲(二)

上回我們講到了基礎(chǔ)的圖片的URL的獲取——Python之Instagram圖片爬蟲(一)亭病,這回將要講的就是獲取加載更多時的圖片URL,從而能夠獲取所屬當(dāng)前用戶的所有的圖片的URL鏈接住涉。


分析頁面

還記得上回我們并沒有點擊更多這個按鈕战惊,僅僅獲取了首頁的圖片具體鏈接。

首頁

在首頁中分析出來的HTML中但两,提取到了這樣的json數(shù)據(jù)塊鬓梅。

json數(shù)據(jù)塊

也成功提取了其中的圖片鏈接,這回讓我們先清空一下Chrome 調(diào)試中Network Tab頁面的跟蹤信息谨湘,緊接著點擊一下更多按鈕绽快。

更多的請求

這時就可以瞧見第一條的請求記錄芥丧,再來點開它的response,查看一下具體的返回內(nèi)容坊罢。

提取出來的返回內(nèi)容

哇续担?可不是json格式的內(nèi)容,這樣就可以很好的查看到更多的圖片鏈接了活孩。但是查看node的信息物遇,發(fā)現(xiàn)圖片僅僅只有幾張,因此可以猜測這樣的請求絕對不止一個憾儒。當(dāng)我們往下拉時挎挖,發(fā)現(xiàn)Instagram自動加載了新的內(nèi)容,同時發(fā)現(xiàn)了新的請求航夺。

加載的異步請求

同樣返回熟悉的json數(shù)據(jù)蕉朵,但是問題是它是怎么請求下一次的呢?請求的參數(shù)是什么呢阳掐?

請求參數(shù)

如上圖所示始衅,其中的參數(shù)有這么幾個:

  • query_id
  • id【包裹在json中】
  • first
  • after

這幾個參數(shù)中,對比兩次請求的參數(shù)缭保,我們可以看到first參數(shù)沒有變化汛闸。id參數(shù)也沒變,依據(jù)經(jīng)驗艺骂,這個參數(shù)一定是隨著不同的Instagram賬號而變化的诸老,但肯定容易獲取。所以難點就是獲取另外兩個參數(shù)钳恕。我們優(yōu)先查看第一次提取的HTML中的json數(shù)據(jù)庫别伏。

看圖中有幾個參數(shù)

查看上圖,火眼金睛應(yīng)該能看出其中的幾個參數(shù):

  • id
  • end_cursor 【剛好就是第一次query請求的after參數(shù)】

那么query_id去哪里了忧额?這個確實復(fù)雜厘肮,我們在HTML中搜索發(fā)現(xiàn)并沒有存在這個參數(shù),這時就要分析Instagram的動態(tài)加載的JavaScript代碼睦番。

script節(jié)點

按照一般的經(jīng)驗类茂,我們查詢JavaScript的代碼通常從網(wǎng)站所屬公司的同源的文件開始,我們先去第一個zh_CN_Common查詢query_id所對應(yīng)的數(shù)字托嚣,發(fā)現(xiàn)確實出現(xiàn)了一條記錄巩检。

匹配一條

再進行queryId字符串的搜索,結(jié)果出現(xiàn)好多條示启,于是我們打算進行正則匹配兢哭,但遇到的數(shù)字很多。根據(jù)正則匹配的結(jié)果丑搔,我們發(fā)現(xiàn)了幾個厦瓢,來自我的猜測提揍,前面幾個都是以前的版本號,所以我們選取最后一個煮仇。

queryId

代碼

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
 @File       : spider.py
 @Time       : 2017/8/12 0012 21:22
 @Author     : Empty Chan
 @Contact    : chen19941018@gmail.com
 @Description:
"""
import re
import json
import os
from lxml import etree
import requests
import click
from urllib import parse
import time

PAT = re.compile(r'queryId:"(\d*)?"', re.MULTILINE)
headers = {
    "Origin": "https://www.instagram.com/",
    "Referer": "https://www.instagram.com/morisakitomomi/",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/58.0.3029.110 Safari/537.36",
    "Host": "www.instagram.com",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "accept-encoding": "gzip, deflate, sdch, br",
    "accept-language": "zh-CN,zh;q=0.8",
    "X-Instragram-AJAX": "1",
    "X-Requested-With": "XMLHttpRequest",
    "Upgrade-Insecure-Requests": "1",
}

# jso = {"id": "1179476381", "first": 12, "after": ""}
jso = {"id": "", "first": 12, "after": ""}

BASE_URL = "https://www.instagram.com"

# QUERY = "/morisakitomomi/"  # 森咲智美
QUERY = "/_8_jjini/"
NEXT_URL = 'https://www.instagram.com/graphql/query/?query_hash={0}&variables={1}'

proxy = {
    'http': 'http://127.0.0.1:38251',
    'https': 'http://127.0.0.1:38251'
}


def crawl():
    click.echo('start...')
    try:
        all_imgs_url = []
        res = requests.get(BASE_URL + QUERY, headers=headers, proxies=proxy)  # , verify=False)
        html = etree.HTML(res.content.decode())
        all_a_tags = html.xpath('//script[@type="text/javascript"]/text()')  # 圖片數(shù)據(jù)源
        query_id_url = html.xpath('//script[@crossorigin="anonymous"]/@src')  # query_id 作為內(nèi)容加載
        click.echo(query_id_url)
        for a_tag in all_a_tags:
            if a_tag.strip().startswith('window'):
                data = a_tag.split('= {')[1][:-1]  # 獲取json數(shù)據(jù)塊
                js_data = json.loads('{' + data, encoding='utf-8')
                id = js_data["entry_data"]["ProfilePage"][0]["graphql"]["user"]["id"]
                edges = js_data["entry_data"]["ProfilePage"][0]["graphql"]["user"]["edge_owner_to_timeline_media"]["edges"]
                print(edges)
                end_cursor = js_data["entry_data"]["ProfilePage"][0]["graphql"]["user"]["edge_owner_to_timeline_media"]["page_info"]["end_cursor"]
                has_next = js_data["entry_data"]["ProfilePage"][0]["graphql"]["user"]["edge_owner_to_timeline_media"]["page_info"]["has_next_page"]
                for edge in edges:
                    if top_url and top_url == edge["node"]["display_url"]:
                        in_top_url_flag = True
                        break
                    click.echo(edge["node"]["display_url"])
                    new_imgs_url.append(edge["node"]["display_url"])
                    # click.echo(qq.get(node["display_src"], proxies=proxy).status_code)

                    # 請求query_id
                    query_content = requests.get(BASE_URL + query_id_url[1], headers=headers, proxies=proxy)
                    query_id_list = PAT.findall(query_content.text)
                    for u in query_id_list:
                        click.echo(u)
                    query_id = query_id_list[1]
                    count = 0
                    # 更多的圖片加載
                    while has_next and count <= 1:
                        jso["id"] = id
                        jso["first"] = 12
                        jso["after"] = end_cursor
                        text = json.dumps(jso)
                        url = NEXT_URL.format(query_id, parse.quote(text))
                        res = requests.get(url, headers=headers, proxies=proxy)
                        time.sleep(2)
                        html = json.loads(res.content.decode(), encoding='utf-8')
                        has_next = html["data"]["user"]["edge_owner_to_timeline_media"]["page_info"]["has_next_page"]
                        end_cursor = html["data"]["user"]["edge_owner_to_timeline_media"]["page_info"]["end_cursor"]
                        edges = html["data"]["user"]["edge_owner_to_timeline_media"]["edges"]
                        for edge in edges:
                            click.echo(edge["node"]["display_url"])
                            count += 1
                            # all_imgs_url.append(edge["node"]["display_url"])
                    click.echo('ok')
    except Exception as e:
        raise e

if __name__ == '__main__':
    crawl()

什么劳跃,你說怎么下載?那是下回的事情了浙垫,哈哈刨仑,相信有興趣的小伙伴早就是想法設(shè)法下載了。大家下回見哦夹姥,下回將整理整個代碼~~

下一篇

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杉武,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辙售,更是在濱河造成了極大的恐慌轻抱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旦部,死亡現(xiàn)場離奇詭異祈搜,居然都是意外死亡,警方通過查閱死者的電腦和手機士八,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門容燕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人婚度,你說我怎么就攤上這事蘸秘。” “怎么了蝗茁?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵醋虏,是天一觀的道長。 經(jīng)常有香客問我评甜,道長灰粮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任忍坷,我火速辦了婚禮,結(jié)果婚禮上熔脂,老公的妹妹穿的比我還像新娘佩研。我一直安慰自己,他們只是感情好霞揉,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布旬薯。 她就那樣靜靜地躺著,像睡著了一般适秩。 火紅的嫁衣襯著肌膚如雪绊序。 梳的紋絲不亂的頭發(fā)上硕舆,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音骤公,去河邊找鬼抚官。 笑死,一個胖子當(dāng)著我的面吹牛阶捆,可吹牛的內(nèi)容都是我干的凌节。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼洒试,長吁一口氣:“原來是場噩夢啊……” “哼倍奢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起垒棋,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤椭符,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弱匪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砖茸,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年碉碉,在試婚紗的時候發(fā)現(xiàn)自己被綠了柴钻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡垢粮,死狀恐怖贴届,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜡吧,我是刑警寧澤毫蚓,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站昔善,受9級特大地震影響元潘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜君仆,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一翩概、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧返咱,春花似錦钥庇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萤晴,卻和暖如春吐句,著一層夾襖步出監(jiān)牢的瞬間胁后,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工嗦枢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留攀芯,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓净宵,卻偏偏與公主長得像敲才,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子择葡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理紧武,服務(wù)發(fā)現(xiàn),斷路器敏储,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,079評論 25 707
  • 聲明:本文講解的實戰(zhàn)內(nèi)容阻星,均僅用于學(xué)習(xí)交流,請勿用于任何商業(yè)用途已添! 一妥箕、前言 強烈建議:請在電腦的陪同下,閱讀本文...
    Bruce_Szh閱讀 12,704評論 6 28
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,758評論 0 15
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫更舞、插件畦幢、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,094評論 4 62