You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python爬取完整Instagram页面?解决仅获取12张图片的问题

解决Instagram爬虫仅获取12张图片的问题

嘿,我完全懂你的困扰!Instagram网页版用了动态加载机制——初始页面只会渲染前12条帖子,剩下的内容都是在你滚动页面时,通过后台GraphQL API异步加载的。所以直接用requests.get只能拿到初始加载的内容,要抓取所有图片,得模拟这个异步请求的过程才行。

下面我给你一步步拆解解决方案,用requests实现完整的内容抓取:

核心思路

  1. 从初始页面提取关键参数:用户ID、分页标记(end_cursor)、CSRF Token(需要登录后获取有效会话,否则API会限制访问)。
  2. 循环调用Instagram的GraphQL API,每次请求获取下一页的帖子,直到没有更多内容为止。
  3. 从每一页的API响应中提取图片链接。

完整代码实现

import json
import requests
from bs4 import BeautifulSoup
import time

def get_instagram_all_images(username):
    # 初始化会话,保持登录状态
    session = requests.Session()
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    base_url = f"https://www.instagram.com/{username}/"
    
    # 1. 初始请求,获取基础参数
    response = session.get(base_url, headers=headers)
    soup = BeautifulSoup(response.text, 'lxml')

    # 提取页面内嵌的共享数据
    script_tag = soup.find('script', string=lambda t: t and 'window._sharedData' in t)
    shared_data = json.loads(script_tag.text.replace('window._sharedData = ', '')[:-1])
    
    # 提取用户ID、初始分页标记和是否还有下一页
    user_data = shared_data['entry_data']['ProfilePage'][0]['graphql']['user']
    user_id = user_data['id']
    media_info = user_data['edge_owner_to_timeline_media']
    end_cursor = media_info['page_info']['end_cursor']
    has_next_page = media_info['page_info']['has_next_page']

    # 提取CSRF Token(从会话Cookie中获取)
    csrf_token = session.cookies.get('csrftoken')

    # 收集所有图片链接,先加入初始的12张
    all_image_urls = []
    for post in media_info['edges']:
        if post['node']['display_url']:
            all_image_urls.append(post['node']['display_url'])

    # 2. 循环请求GraphQL API加载更多内容
    graphql_url = "https://www.instagram.com/graphql/query/"
    # 注意:query_hash可能随Instagram更新变化,失效时需抓包获取最新值
    query_hash = "e769aa130647d2354c40ea6a439bfc08"

    while has_next_page:
        # 构造请求参数
        params = {
            "query_hash": query_hash,
            "variables": json.dumps({
                "id": user_id,
                "first": 12,
                "after": end_cursor
            })
        }

        headers.update({
            "X-CSRFToken": csrf_token,
            "Referer": base_url
        })

        # 发送请求,添加延迟避免被封
        time.sleep(2)
        graphql_response = session.get(graphql_url, params=params, headers=headers)
        
        if graphql_response.status_code != 200:
            print(f"请求失败,状态码:{graphql_response.status_code}")
            break

        # 解析响应数据,提取图片链接
        data = graphql_response.json()
        new_posts = data['data']['user']['edge_owner_to_timeline_media']['edges']
        for post in new_posts:
            if post['node']['display_url']:
                all_image_urls.append(post['node']['display_url'])

        # 更新分页参数
        page_info = data['data']['user']['edge_owner_to_timeline_media']['page_info']
        has_next_page = page_info['has_next_page']
        end_cursor = page_info['end_cursor']

    return all_image_urls

# 使用示例(替换成目标账号名)
if __name__ == "__main__":
    target_username = "accountName"
    all_images = get_instagram_all_images(target_username)
    print(f"共抓取到 {len(all_images)} 张图片")
    # 打印前5张链接示例
    for idx, url in enumerate(all_images[:5]):
        print(f"第{idx+1}张:{url}")

重要注意事项

  • 登录会话要求:现在Instagram对未登录用户的API访问限制极严,你需要先登录网页版Instagram,从浏览器Cookie中获取sessionid,并手动添加到session的cookies中(否则会返回403或空数据)。
  • Query Hash 更新:Instagram的GraphQL查询哈希值(query_hash)可能不定期更新,如果代码突然失效,打开浏览器开发者工具的Network面板,抓取滚动加载时的GraphQL请求,就能拿到最新的query_hash。
  • 请求频率控制:务必添加请求延迟(比如time.sleep(2)),频繁请求会触发Instagram的反爬机制,导致IP被封禁。
  • 账号权限:确保目标账号是公开的,爬取私人账号需要对应权限,否则会被拒绝访问。

内容的提问来源于stack exchange,提问作者WeDa Beast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:04:20