instagram api

$ install instaloader

import instaloader

# インスタンスの作成
L = instaloader.Instaloader()

# 取得したいユーザーのIDを指定
target_profile = "instagram"  # 例としてInstagram公式アカウント

try:
    # プロフィール情報の読み込み
    profile = instaloader.Profile.from_username(L.context, target_profile)

    print(f"ユーザー名: {profile.username}")
    print(f"フォロワー数: {profile.followers}")
    print(f"自己紹介: {profile.biography}")

    # 最新の投稿を3件表示
    print("\n--- 最新の投稿 ---")
    for post in profile.get_posts():
        print(f"投稿日: {post.date}")
        print(f"キャプション: {post.caption[:30]}...") # 最初の30文字だけ
        print(f"URL: {post.url}")
        
        # 3件取得したらストップ
        if post.owner_username == target_profile:
            break 

except Exception as e:
    print(f"エラーが発生しました: {e}")

$ python3 app.py
ユーザー名: instagram
フォロワー数: 698490388
自己紹介: Discover what’s new on Instagram 🔎✨

— 最新の投稿 —
投稿日: 2025-12-26 21:05:21
キャプション: the definition of “never let t…
URL: https://scontent-nrt1-2.cdninstagram.com/v/t51.2885-15/606469868_18689042716001321_9120174716535860606_n.jpg?stp=dst-jpg_e15_fr_p1080x1080_tt6&_nc_ht=scontent-nrt1-2.cdninstagram.com&_nc_cat=1&_nc_oc=Q6cZ2QFZnredhbdVl_SvagHdS1_L6FOS6xwQKfiSolX7tuMyxIYTOVN7Um-LzzQ_jBneDHI&_nc_ohc=VXPBA7g5rlQQ7kNvwFrzZcc&_nc_gid=s6qDPQ_v2Qy2aL1kVrz0Wg&edm=AOQ1c0wBAAAA&ccb=7-5&oh=00_AfmMpzoxHZbJe-l-Inrc-cUqHsm3Nfz13kckIgLq0ttU4A&oe=69584AA3&_nc_sid=8b3546

instaloader は、ブラウザでインスタを見る時と同じような仕組みで情報を読み取っているため、**「公開アカウント」かつ「数件の取得」**であれば、面倒なAPIキーの手続きなしでサクッと動く

「仕事で使いたい」「公式にアプリをリリースしたい」となった場合は、Meta社が提供する**「Instagram Graph API」**を使う必要がある

import instaloader

L = instaloader.Instaloader()

# 検索したいハッシュタグ(#は不要)
hashtag_name = "猫"

try:
    # ハッシュタグオブジェクトの作成
    hashtag = instaloader.Hashtag.from_name(L.context, hashtag_name)

    print(f"#{hashtag_name} の投稿を取得中...")

    # 最新の投稿を5件ループで回す
    for count, post in enumerate(hashtag.get_posts(), 1):
        print(f"\n[{count}件目]")
        print(f"投稿者: {post.owner_username}")
        print(f"いいね数: {post.likes}")
        print(f"キャプション: {post.caption[:50]}...") # 50文字まで
        print(f"URL: {post.url}")

        # 負荷軽減のため5件でストップ
        if count >= 5:
            break

except Exception as e:
    print(f"エラーが発生しました: {e}")

$ python3 cat.py
JSON Query to api/v1/tags/web_info/: 403 Forbidden – “fail” status, message “login_required” when accessing https://i.instagram.com/api/v1/tags/web_info/?__a=1&__d=dis&tag_name=%E7%8C%AB [retrying; skip with ^C]
JSON Query to api/v1/tags/web_info/: 403 Forbidden – “fail” status, message “login_required” when accessing https://i.instagram.com/api/v1/tags/web_info/?__a=1&__d=dis&tag_name=%E7%8C%AB [retrying; skip with ^C]
エラーが発生しました: JSON Query to api/v1/tags/web_info/: 403 Forbidden – “fail” status, message “login_required” when accessing https://i.instagram.com/api/v1/tags/web_info/?__a=1&__d=dis&tag_name=%E7%8C%AB

タグ検索の場合は、ログインが必要となる。
L.login(“自分のユーザー名”, “パスワード”)

本格的にやりたい場合はInstagram Graph API

その他

import instaloader

L = instaloader.Instaloader()

# --- 修正ポイント:パスワードを使わずブラウザのクッキーを使う ---
# Chromeがインストールされている場合、以下の1行でセッションを読み込めます
# 注意: 初回実行時にOSからブラウザデータへのアクセス許可を求められることがあります
USER = ""
try:
    L.interactive_login(USER) # または L.load_session_from_instaloader(USER)
    # 最も簡単な方法:
    # ブラウザのクッキーをインポートするヘルパー関数(instaloader公式推奨)
    # ※ pip install browser-cookie3 が必要な場合があります
    # 以下の1行でブラウザのログイン状態を引き継ぎます
    L.load_session_from_instaloader(USER) 
except:
    # ブラウザからセッションを取得するスクリプトを別途実行するか
    # 以下のコマンドをターミナルで実行してセッションファイルを作ってください
    # instaloader -l YOUR_USER_NAME
    print("セッションの読み込みに失敗しました。")

# 実行
hashtag_name = "猫"
hashtag = instaloader.Hashtag.from_name(L.context, hashtag_name)

for count, post in enumerate(hashtag.get_posts(), 1):
    print(f"[{count}] {post.owner_username}: {post.caption[:20]}...")
    if count >= 3: break

chatバックエンド側(Python (Flask + PostgreSQL + OpenAI))の作り込み1

chat() の中で  
認証チェックを追加  
DBにユーザーの入力を保存  
OpenAI API や HuggingFace API を呼んで応答を生成  
生成した応答をDBに保存して返却

### step.0 テーブル作成

CREATE TABLE chat_messages (
    id SERIAL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL,
    message TEXT NOT NULL,
    reply TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

### step.1 パッケージインストール
$ install flask psycopg2-binary openai

### step.2 Python (Flask + PostgreSQL + OpenAI)

from flask import Flask, request, Response
import json
import psycopg2
import os
from openai import OpenAI

app = Flask(__name__)

DB_CONFIG = {
    "dbname": os.getenv("DB_NAME"),
    "user": os.getenv("DB_USER"),
    "password": os.getenv("DB_PASSWORD"),
    "host": os.getenv("DB_HOST", "localhost"),
    "port": os.getenv("DB_PORT", 5432)
}


def get_db_connection():
    try:
        conn = psycopg2.connect(**DB_CONFIG)
        return conn
    except Exception as e:
        print(f"Database connection error: {e}")
        return None

@app.route("/chat", methods=["POST"])
def chat():
    try:
        data = request.get_json()

        user_id = data.get("user_id")
        message = data.get("message")

        if not user_id or not message:
            return Response(json.dumps({"error": "user_id and message are required"}), status=400, content_type="application/json; charset=utf-8")

        conn = get_db_connection()
        cur = conn.cursor()

        cur.execute(
            "INSERT INTO chat_messages (user_id, message) VALUES (%s, %s) RETURNING id;",
            (user_id, message)
        )
        chat_id = cur.fetchone()[0]

        client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
        completion = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages = [
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": message}
            ]
        )
        api_reply = completion.choices[0].message.content

        cur.execute(
            "UPDATE chat_messages SET reply = %s WHERE id = %s;",
            (api_reply, chat_id)
        )
        conn.commit()
        cur.close()
        conn.close()
        

        response_json = json.dumps({"reply": api_reply}, ensure_ascii=False)
        return Response(response_json, content_type="application/json; charset=utf-8")

    except Exception as e:
        error_json = json.dumps({"error": str(e)}, ensure_ascii=False)
        return Response(error_json, status=400, content_type="application/json; charset=utf-8")


if __name__ == "__main__":
    app.run(debug=True)

$ curl -X POST http://127.0.0.1:5000/chat -H “Content-Type: application/json” -d ‘{“user_id”: “12345”, “message”: “おはよう!”}’
{“reply”: “おはようございます!元気ですか?何かお手伝いできることがありますか?”}

おおお

openapi-generatorを使いたい2

openapi.yaml

openapi: 3.0.3
info:
  description: "GET/POST IPv4 Address"
  version: "1.0.0"
  title: "openapi-rust"
tags:
  - name: "IP"
paths:
  /ip:
    get:
      responses:
        "200":
          description: "Get Global IPv4 address of the system"
          content:
            application/json:
              schema:
                type: object
                properties:
                  IPv4_address:
                    type: string
                    format: ipv4
                  checked_at:
                    type: string
                    format: date-time
        "500":
          description: "Internal Server Error"
    post:
      requestBody:
        description: "IPv4 address to register"
        content:
          application/json:
            schema:
              properties:
                IPv4_address:
                  type: string
                  format: ipv4
      responses:
        "200":
          description: "The new IPv4 address has been registered"
        "500":
          description: "Internal Server Error"

$ sudo npm install @openapitools/openapi-generator-cli -g

Makefile

generate:
  openapi-generator-cli generate \
    -i ./openapi.yaml \
    -g rust-server \
    -o .

なんか上手くいかないです

openapi-generatorを使いたい

openapi.yaml

openapi: 3.0.2
info:
  version: 0.1.0
  title: example
servers:
  - url: 'http://192.168.56.10:8080/example'
paths:
  /hello:
    get:
      description: Hello World
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Hello'
      tags:
        - example
components:
  schemas:
    Hello:
      type: object
      properties:
        message:
          type: string
          example: 'Hello World'
      x-tags:
        - example

application.yaml

inputSpec: 'openapi.yaml'
generatorName: spring
outputDir: modules/application
additionalProperties:
  configPackage: 'com.mamezou_tech.example.controller.configuration'
  modelPackage: 'com.mamezou_tech.example.controller.model'
  apiPackage: 'com.mamezou_tech.example.controller.api'
  invokerPackage: 'com.mamezou_tech.example.controller.api'
  groupId: 'com.mamezou_tech.example-service'
  dateLibrary: java8
  java8: true
  library: spring-boot
  artifactId: 'example-application'
  artifactVersion: '0.1.0'
  snapshotVersion: 'true'
  useTags: true

$ sudo docker run -it –rm -v `pwd`:/build -v example:/root/.m2 maven:3.8-eclipse-temurin-17-focal bash
$ curl -L https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.0/openapi-generator-cli-6.0.0.jar -o /tmp/openapi-generator-cli.jar
$ cd /build
$ java -DsupportingFiles -jar /tmp/openapi-generator-cli.jar batch application.yaml
[main] INFO o.o.codegen.cmd.GenerateBatch – Batch generation using up to 4 threads.
Includes: /build
Root: /build
[pool-1-thread-1] Generating spring (outputs to /build/modules/application)…
################################################################################
# Thanks for using OpenAPI Generator. #
# Please consider donation to help us maintain this project 🙏 #
# https://opencollective.com/openapi_generator/donate #
################################################################################
[pool-1-thread-1] Finished generating spring…
[SUCCESS] Batch generation finished 1 generators successfully.
$ cd modules/application
$ mvn install

なんだろう、spring bootが多いな

Swaggerの各フィールドの詳細

Info

info:
  title: Sample API
  description: A short description of API.
  termsOfService: http://example.com/terms/
  contact:
    name: API support
    url: htttp://www.example.com/support
    email: support@example.com
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.0

servers

servers:
  - url: https://dev.sample-server.com/v1
    description: Development server
  - url: https://stg.sample-server.com/v1
    description: Staging server
  - url: https://api.sample-server.com/v1
    description: Production server

Path

paths:
  /users:
    get:
      tags:
        - users
      summary: Get all users.
      description: Returns an array of User model
      parameters: []
      response:
        '200': # http status
          description: A Json array of User model
          content:
            application/json: # レスポンスの形式指定
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User' # 参照するモデル
                example: 
                  - id: 1
                    name: Jane Doe
                  - id: 2
                    name: Jane Doe
    post:
      tags:
        - users
      summary: Create a new User
      descrpption: Create a new User
      parameters: []
      requestBody:
        description: user to create
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
            example:
              id: 3
              name: Richard Roe
      responses:
        '201':
          description: CREATED
  /users/{userId}:
    get:
      tags:
        - users
      summary: Get user by ID.
      description: Returns a single User model
      parameters: # リクエストパラメター
        - name: userId
          in: path # パラメータをパス内に含める
          description: user id
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: A single User model
          content:
            application/json:
              schema:
                type: object
                items:
                  $ref: '#/components/schemas/User'
                example:
                  id: 1
                  name: John Doe

components
L 定義したモデルは $ref: ‘#/components/schemas/User’ というように参照する
L modelエリアに表示され、構造やサンプル値が参照できる

components:
  schemas:
    User:
      type: object # 型
      required:
        - id
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Product:
      type: object
      required:
        - id
        - price
      properties:
        id:
          type: integer
          format: int64
          example: 1
        name:
          type: string
          example: Laptop
        price:
          type: integer
          example: 1200

security
メソッド定義部分に鍵マークが表示される

security:
  - api_key []
  - users_auth:
    - write:users
    - read:users

externalDocs

exeternalDocs:
  description: Find more info here
  url: https://example.com

tags:

tags:
  - name: users
    description: Access to users
  - name: products
    descrption: Access to Products

なるほど、実際に書いてみると全然違うな…

Swaggerの基本構造を学びたい

sample.yaml

openapi: 3.0.0
info:
  ...
servers:
  ...
paths:
  ...
components:
  ...
security:
  ...
tags:
  ...
exeternalDocs:
  ....

openapi: バージョンを記載(必須)
info: APIのメタデータ(必須) title, description, termsOfService, contact, license, version
servers: APIを提供するサーバを記述(配列で複数記述可能, 任意)
paths: APIで利用可能なエンドポイントやメソッドを記述(必須)
L put(tag, summary, description, operationId, requestBody(description, contents(application/json, xml, x-www-form-urlencoded), required), responses)
L post(tags, summary, description, operationId, requestBody(description, contents(application/json, xml, x-www-form-urlencoded), required)), response)
L get (tags, summary, description, operationId, requestBody(description, contents(application/json, xml, x-www-form-urlencoded), required)), response, security)
L get (tags, summary, description, operationId, parameters, response)
components: APIで使用するオブジェクトスキーマを記述(必須)
L schimas: type, properties(type(integer, string, array), format(int64, int32, date-time), example, required)
security: API全体を通して使用可能なセキュリティ仕様を記述する(OAuth)
tags: name, description, externalDocs, APIで使用されるタグのリスト。各種ツールによってパースされる際は、記述された順序で出力される。タグ名はユニークでなければならない。(任意)
externalDocs: 外部ドキュメントを記述する(API仕様書)

なるほど、swaggerの仕様を理解するだけで大分違うな…

OpenAPI, Swagger入門

OpenAPI: RESTful APIの仕様を記述するフォーマット
Swagger: OpenAPIを使用するツール

## Swagger Editor
$ git clone https://github.com/swagger-api/swagger-editor.git
$ cd swagger-editor
$ npm start

http://192.168.56.10:3001/

なんだこれは…

OpenAPIに慣れたい

swaggerのbasic structure
https://swagger.io/docs/specification/basic-structure/

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require zircote/swagger-php
$ php composer.phar exec openapi -h

openapiファイルの作成
$ vendor/bin/openapi -o ${出力先} –format ${出力フォーマット} ${スキャン対象ディレクトリ}
$ vendor/bin/openapi -o openapi.json –format json app/Http/Controller/Api

<?php

use OpenApi\Annotations as OA;

class OpenApi {}

class MyController {

	public funtion getResource(){
		
	}
}

https://zircote.github.io/swagger-php/guide/
The idea is to add swagger-php annotations or attributes next to the relevant PHP code in your application. These will contain the details about your API and swagger-php will convert those into machine-readable OpenAPI documentation.

require("vendor/autoload.php");

$openapi = \OpenApi\Generator::scan(["project"]);

header('Content-Type: application/x-yaml');
echo $openapi->toYaml();

annotation:あるデータに対して関連する情報(メタデータ)を注釈として付与すること

/**
 * @OA\Get(
 * tags={"Common"},
 * path="/api/user",
 * @OA\Response(
 *		response="200".
 *		description="success",
 *		@OA\JsonContent(ref="#/components/schemas/user_responder")
 * ),
 * @OA\Response(
 *		response="204",
 *		description="there is no authorized user",
 *		@OA\JsonContent(ref="#/components/schemas/204_no_content")
 *		)
 *	)
 */

schema:

/**
 * @OA\Schema(
 *	schema="user_responder",
 *	required={"id", "name", "email","created_at"},
 *	@OA\Property(
 *		property="id",
 *		type="integer",
 *		description="userId",
 *		example-"1"
 *	),
 *	@OA\Property(
 *		property="name",
 *		type="string",
 *		description="username",
 *		example="sample taro"
 *	),
 *
 *)
 */

annotationはパスとレスポンスで、schemaは入力値を定義しとるんかな。
どちっかというと、swaggerがよくわかってない。

Swagger Codegenとドライバ・スタブコード

Swagger Codegenを使用するとAPIコンシューマのドライバコードやAPIプロバイダのスタブコードを自動生成できる。
Swagger UIでインターフェース仕様書を作成し、APIコンシュマー、プロバイダを自動生成する

スタブコードとは?
– テスト実行時に呼び出し先が未完成の時に代替えとして使用する
– 値を返すダミー(本物に似ているが中身はない)
– スタブとは切り株という意味
– 呼び出し元コードから見て下位

ドライバ(代替)とは
– テスト実行時に、呼び出し元が未完成等の時に代替えとして使用
– ダミー(本物に似ているが中身はない)
– 対象コードから見てドライバは上位に当たる

呼び出す側がドライバで呼び出される側がスタブって意味か