如何使用 Python 搜刮 Instagram 数据

评论: 0

由于各种反僵尸机制、登录要求和速率限制,获取 Instagram 数据可能非常棘手。不过,只要使用正确的工具和技术,你就能从公开资料中提取有用的信息。本文将指导你如何使用 Python 通过向 Instagram 后台发出 API 请求、从返回的 JSON 数据中提取信息并将其保存到 JSON 文件中来抓取 Instagram 用户数据。

设置所需的图书馆

在开始代码之前,请确保您已经安装了所需的 Python 库。


pip install requests python-box

  • 请求:提出 HTTP 请求。
  • python-box:通过将字典转化为允许点符号访问的对象,简化了数据访问。

为了更好地理解,我们将把代码分成不同的部分,包括发送请求、获取和解析数据、使用代理避免检测,以及使用 Box 库简化 JSON 解析。

步骤 1.提出应用程序接口请求

Instagram 的前台安全级别很高,但后台提供了无需身份验证即可使用的 API 端点。我们将使用其中一个点。

该 API 提供有关用户个人资料的详细信息,包括他们的描述、追随者数量和帖子。让我们探讨一下如何使用 Python 中的请求库来请求数据。

解释:

  1. 标题:Instagram 通过分析请求头来阻止大多数僵尸请求。x-ig-app-id 非常重要,因为它模拟了来自 Instagram 应用本身的请求。
  2. User-Agent 字符串代表发出请求的浏览器,诱使 Instagram 相信它是一个真实的用户。
  3. 后台 API 请求:URL https://i.instagram.com/api/v1/users/web_profile_info/?username={username} 是 Instagram 后台 API 的一部分。它提供有关公开个人资料的详细信息。
  4. 处理 JSON 响应:我们使用 response.json() 将 API 响应转换为 JSON 对象,以便于解析和提取信息。

import requests

# 定义标头以模拟真实的浏览器请求
headers = {
    "x-ig-app-id": "936619743392459",  # 用于验证请求的 Instagram 应用 ID
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept": "*/*",
}

# 将其替换为您要搜索的用户名
username = 'testtest'

# 发送 API 请求以获取配置文件数据
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers)
response_json = response.json()  # 将响应解析为 JSON 对象

步骤 2.处理代理以绕过速率限制

由于 Instagram 限制来自同一 IP 地址的重复请求,因此使用代理对于大规模搜刮至关重要。代理通过不同的 IP 地址路由你的请求,帮助你避免被发现。

要设置代理服务器,您需要 IP 地址、端口号,如果需要,还需要用于验证的用户名和密码。


proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', headers=headers, proxies=proxies)

步骤 3.使用 Box 简化 JSON 解析

Instagram 的应用程序接口会返回一个复杂的嵌套 JSON 结构,使用传统的基于字典的访问方式很难浏览该结构。为了简化解析,我们可以使用 Box 库,它允许使用点符号而不是字典键访问 JSON 数据。

解释:

  1. 盒子该库将 JSON 字典转换为对象,允许我们使用点符号访问深嵌套字段。例如,我们可以简单地写入 response_json.data.user.full_name,而不是写入 response_json['data']['user']['full_name']。
  2. 提取数据:我们会提取有用的个人资料信息,如用户的全名、ID、简历、是否为企业或专业账户、验证状态和追随者数量。

from box import Box

response_json = Box(response.json())

# 提取用户配置文件数据
user_data = {
    'full name': response_json.data.user.full_name,
    'id': response_json.data.user.id,
    'biography': response_json.data.user.biography,
    'business account': response_json.data.user.is_business_account,
    'professional account': response_json.data.user.is_professional_account,
    'category name': response_json.data.user.category_name,
    'is verified': response_json.data.user.is_verified,
    'profile pic url': response_json.data.user.profile_pic_url_hd,
    'followers': response_json.data.user.edge_followed_by.count,
    'following': response_json.data.user.edge_follow.count,
}

步骤 4.提取视频和时间轴数据

提取个人资料数据后,我们还可以从用户的视频时间线和常规帖子中抓取数据。

解释:

  1. 视频数据:该部分提取有关用户 Instagram 视频的数据,包括视频 URL、查看次数、评论次数和视频时长。
  2. 时间轴媒体:同样,该部分从用户的时间轴中提取数据,捕捉帖子的媒体 URL、赞和评论。

# 提取视频数据
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
    video_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'video url': element.node.video_url,
        'view count': element.node.video_view_count,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
        'duration': element.node.video_duration,
    }
    profile_video_data.append(video_data)

# 提取时间轴媒体数据(照片和视频)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
    media_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'media url': element.node.display_url,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
    }
    profile_timeline_media_data.append(media_data)

步骤 5.将数据保存为 JSON 文件

提取完所有数据后,下一步就是将其保存到 JSON 文件中,以便进一步分析或存储。我们使用 Python 的 json 模块将提取的数据写入 JSON 文件。由于使用了 indent=4 参数,每个文件的格式都很整齐,这样就可以轻松读取和处理数据。


import json

# 将用户数据保存到 JSON 文件
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)

# 将视频数据保存到 JSON 文件
with open(f'{username}_video_data.json', 'w') as file:
    json.dump(profile_video_data, file, indent=4)

# 将时间轴媒体数据保存为 JSON 文件
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)

完整代码

下面是完整的 Python 脚本,它结合了前面讨论的所有部分。这段代码会从 Instagram 抓取用户配置文件数据、视频数据和时间轴媒体数据,处理必要的标题和代理,并将提取的信息保存到 JSON 文件中。


import requests
from box import Box
import json

# 模仿真实浏览器请求 Instagram 后台 API 的头信息
headers = {
    "x-ig-app-id": "936619743392459", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
    "Accept-Language": "en-US,en;q=0.9,ru;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept": "*/*",
}

# 设置代理以避免速率限制和检测(可选)
proxies = {
    'http': 'http://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
    'https': 'https://<proxy_username>:<proxy_password>@<proxy_ip>:<proxy_port>',
}

# 要搜索的 Instagram 用户名
username = 'testtest'

# 向 Instagram 后台 API 发送请求,获取个人资料数据
response = requests.get(f'https://i.instagram.com/api/v1/users/web_profile_info/?username={username}', 
                        headers=headers, proxies=proxies)
response_json = Box(response.json())  # 将响应转换为方框对象,以便于导航

# 提取用户配置文件数据
user_data = {
    'full name': response_json.data.user.full_name,
    'id': response_json.data.user.id,
    'biography': response_json.data.user.biography,
    'business account': response_json.data.user.is_business_account,
    'professional account': response_json.data.user.is_professional_account,
    'category name': response_json.data.user.category_name,
    'is verified': response_json.data.user.is_verified,
    'profile pic url': response_json.data.user.profile_pic_url_hd,
    'followers': response_json.data.user.edge_followed_by.count,
    'following': response_json.data.user.edge_follow.count,
}

# 从用户的视频时间轴中提取视频数据
profile_video_data = []
for element in response_json.data.user.edge_felix_video_timeline.edges:
    video_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'video url': element.node.video_url,
        'view count': element.node.video_view_count,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
        'duration': element.node.video_duration,
    }
    profile_video_data.append(video_data)

# 提取时间轴媒体数据(照片和视频)
profile_timeline_media_data = []
for element in response_json.data.user.edge_owner_to_timeline_media.edges:
    media_data = {
        'id': element.node.id,
        'short code': element.node.shortcode,
        'media url': element.node.display_url,
        'comment count': element.node.edge_media_to_comment.count,
        'like count': element.node.edge_liked_by.count,
    }
    profile_timeline_media_data.append(media_data)

# 将用户配置文件数据保存到 JSON 文件
with open(f'{username}_profile_data.json', 'w') as file:
    json.dump(user_data, file, indent=4)
print(f'saved json: {username}_profile_data.json')

# 将视频数据保存到 JSON 文件
with open(f'{username}_video_data.json', 'w') as file:
    json.dump(profile_video_data, file, indent=4)
print(f'saved json: {username}_video_data.json')

# 将时间轴媒体数据保存为 JSON 文件
with open(f'{username}_timeline_media_data.json', 'w') as file:
    json.dump(profile_timeline_media_data, file, indent=4)
print(f'saved json: {username}_timeline_media_data.json')

使用 Python 可以利用 Instagram 提供的后台 API 抓取 Instagram 数据,这有助于绕过一些前端限制。使用正确的标头来模仿浏览器行为,并使用代理来避免速率限制,这些都是至关重要的步骤。Box 库使用点符号使 JSON 解析更加直观,从而进一步简化了过程。在开始大规模搜索 Instagram 之前,请记住遵守 Instagram 的服务条款,并确保您的搜索行为不违反其政策。

评论:

0 评论