Gyazoの内部API
https://gyazo.com/:image_id.json
応答
OCR及びEXIFは、すでに解析済みならproでなくても取得できるようだ
詳細ページからは取得できないが、APIからなら取得できる
Proをやめても取得できるのはよくない設計な気もするが
code:types.ts
interface GyazoImage {
accessible: boolean;
image_id: string;
alias_id: string;
file_size: number;
metadata_is_public: boolean;
scale: {
width: number;
height: number;
scale: number;
};
type: GyazoType;
page_title: string;
updated_at: ISOTime | null;
exif_captured_at: ISOTime | null;
desc: string;
draw_src_id: string | null;
draw_materials: unknown | null;
deletable: boolean;
owned: boolean;
drawable: boolean;
is_pro: boolean;
access_policy: "anyone";
cross_origin: "anonymous";
url: IGyazoURL;
permalink_url: PermalinkURL;
permalink_path: /${string};
file_only: boolean;
has_files: boolean;
attached_files: unknown[];
thumb_url: ThumbURL;
poster_thumb_url: ThumbURL;
thumb1000: IThumbURL;
grid_thumbs: GridThumbs;
non_cropped_thumb: {
url: ThumbURL;
scaled: {
url: ThumbURL;
size: number;
scale: number;
};
};
user: User | null;
explicit: boolean;
categories: string[];
next: {
image_id: string;
alias_id: string;
permalink_url: PermalinkURL;
permalink_path: /${string};
};
prev: {
image_id: string;
alias_id: string;
permalink_url: PermalinkURL;
permalink_path: /${string};
};
has_mp4: boolean;
mp4_url: https://i.gyazo.com/${string}.mp4;
download_mp4_url: https://i.gyazo.com/download/${string}.mp4;
download_gif_url: https://i.gyazo.com/download/${string}.gif;
is_preview_gif: boolean;
has_audio: boolean;
has_voice: boolean;
boards: unknown[];
external_comments: unknown[];
metadata?: {
app: string;
title: string;
url: string;
desc: string;
ocr_started: boolean;
ocr: {
locale: string;
description: string;
boundingPoly: BoundingPoly;
} | {
description: "";
};
ocrAnnotations: {
description: string;
boundingPoly: BoundingPoly;
}[] | null;
exif: Exif;
exif_status: {
captured_at: "from_created_at";
ok: true;
msg: "ok";
};
exif_normalized: {
timezone: "unknown";
} | {
timezone: "utc";
latitude: number;
longitude: number;
time: ISOTime;
};
};
}
/api/internal
internalとなっているが、robots.txtではとくに制限されていないので、勝手に使っても問題なさそう 認証
ログアウトすれば無効になるみたい?
自動でログイン画面にredirectする
htmlファイル中に含まれている認証情報使っている?
https://gyazo.com/api/internal/images
画像一覧を取得
URL paramerters
page (number)
per (number)
一度に取得する画像の最大数
timestamp (number)
なにこれ
応答
Image[]
PATCH https://gyazo.com/api/internal/images/:image_id
parameters
bodyにJSONとして送る
access_policy
"anyone": password解除
"passphrase": passwordかける
passphrase
access_policy: "passphase"のときのみ必要
password
https://gyazo.com/api/internal/search_histories
検索履歴を取得する
URL parameters
page (number)
paging
応答
SearchHistory[]
thumb系が常にあるかは調べてない
code:types.ts
interface SearchHistory {
id: string;
title: string;
pinned: boolean;
image: {
alias_id: string;
image_id: string;
thumb_url: ThumbURL;
thumb_url_2x: ThumbURL;
thumb_url_webp: ThumbWebpURL;
thumb_url_webp_2x: ThumbWebpURL;
file_only: boolean;
has_files: boolean;
file_types: string | null; // nullしか観測していない
file_names: string | null; // nullしか観測していない
cross_origin: "anonymous";
};
};
https://gyazo.com/api/internal/search_result
検索する
URL parameters
必須
per (number)
受け取る検索結果の最大数
10か30が使われる?
query (string)
検索文字列
これを抜かすと500 internal errorが発生する
page (number)
offset
exclude_linked_images (boolean)
普通はtrue
不明
渡さなくてもエラーにならない
timestamp (number)
応答
2024-11-10 11:16:31 今は不明
EXIFとサムネURL周りのpropertiesはoptionalかも ヒット箇所は返されないようだ
code:types.ts
interface SearchResults {
captures: Image[];
number_of_captures: number;
query: string;
engine: "Elasticsearch";
index: image-${number},
/** falseのみ? */
start_indexing: boolean;
conditions: {
must: Query[];
must_not: Query[];
}
}
code:ts
type Query = {
/** 複数条件当てはまるときは、その分だけQueryが返される */
match_phrase: { everything: string; } | { url: string } | { title: string } | { app: string } | { type: string };
} | {
/**
* lteがuntil, gteがsince
*
* month:2021-01にしたら、gteに"2021-01-01||+1M"が入った。
* date:2021-01-01だと、gteに"2021-01-01||+1d"が入った。
*
*/
range: { date: { lte: ${number}-${number}-${number}; } | { gte: ${number}-${number}-${number}; }; };
};
関連するコード
code:js
32159: (e, t, a) => {
a.d(t, {
g: () => c
});
var s = a(96540)
, i = a(23041)
, r = a(72737)
, n = a(13930)
, o = a(34710);
const d = e => (0,
n.C6)()(e).then((e => ({
...e,
captures: e.captures.map((e => (0,
r.xZ)(e)))
})))
, c = ({query: e, perPage: t, excludeLinkedImages: a=!1}) => {
const {data: r, size: n, setSize: c} = (0,
i.Ay)(( (s, i) => {
if (!e)
return null;
if (0 < s && i.numberOfCaptures <= s * t)
return null;
const r = new URLSearchParams;
return r.append("query", e),
r.append("per", t.toString()),
r.append("page", (s + 1).toString()),
r.append("exclude_linked_images", a.toString()),
/api/internal/search_result?${r}
}
), d, {
use: [(0,
o.Cb)("images/update")],
revalidateFirstPage: !1
})
, l = (0,
s.useCallback)(( () => {
c(n + 1)
}
return {
images: r?.flatMap(( ({captures: e}) => e)),
loading: !r,
loadNext: l,
startIndexing: !!r?.0?.startIndexing, numberOfResults: r?.0?.numberOfCaptures }
}
}
n.C6=t=>w("GET", t)
code:w.js
async function w(t, e, r=null, n=!1, i={}) {
const {disableCsrf: o, ...s} = i;
let a = e.startsWith("/") ? location.origin + e : e;
const c = m(e);
if (y(t, r) && Object.keys(r).length > 0) {
const t = new URLSearchParams;
Object.entries(r).forEach(( (e,r) => { null != r && (Array.isArray(r) ? r.forEach((r => t.append(${e}[], r.toString()))) : t.append(e, r.toString()))
}
)),
a = a + "?" + t.toString()
}
const u = await fetch(a, {
method: t,
..."GET" === t || null === r ? {} : {
body: JSON.stringify(r)
},
...g(t, o, c),
...s
});
return b(u, c, n)
}
https://gyazo.com/api/internal/images/:image_id/similar_images
関連画像
応答
Image[]
free userだと空配列が返ってくる
https://gyazo.com/api/internal/images/:image_id/close_date_images
前後にuploadされた画像
応答
code:types.ts
interface CloseDateImages {
before: Image[];
after: Image[];
}
https://gyazo.com/api/internal/images/:image_id/similar_metadata_images
各属性の関連画像
応答
free userだと空配列が返ってくる
code:types.ts
type SimilarMetadata = {
keyword: string;
images: Image[];
};
};
https://gyazo.com/api/internal/images/:image_id/near_images
近くの場所で撮影された画像
応答
code:types.ts
type NearImages = {
message: "no location";
count: 0;
images: [];
} | {
message: "ok";
count: number;
images: Image[];
};
https://gyazo.com/api/internal/boards/visits
https://gyazo.com/api/internal/images_summary
応答
なにこれ
code:types.ts
interface ImagesSummary {
monthly_counts: Record<number, Record<number, number>>;
}
https://gyazo.com/api/internal/boards/visits/images
画像の閲覧履歴を取得する
URL parameters
limit
取得する画像の最大数
cursor
paging用のID
応答
code:types.ts
interface VisitedImages {
cursor: string;
images:
}