Skip to content

Instantly share code, notes, and snippets.

@lumynou5
Last active November 28, 2025 18:51
Show Gist options
  • Select an option

  • Save lumynou5/863b900b16eae7059ebf14563057ff6b to your computer and use it in GitHub Desktop.

Select an option

Save lumynou5/863b900b16eae7059ebf14563057ff6b to your computer and use it in GitHub Desktop.
Hide AI-generated illustrations from Pixiv.
// ==UserScript==
// @name Pixiv Dis-AI
// @version 0.4.5
// @description Hide AI-generated illustrations from Pixiv.
// @author Lumynous
// @license MIT
// @match https://www.pixiv.net/*
// @noframes
// @grant GM.getValue
// @grant GM.setValue
// @downloadURL https://gist.github.com/lumynou5/863b900b16eae7059ebf14563057ff6b/raw/pixiv-dis-ai.user.js
// @updateURL https://gist.github.com/lumynou5/863b900b16eae7059ebf14563057ff6b/raw/~meta
// ==/UserScript==
const AI_USER_LIST_URL = 'https://gist.githubusercontent.com/lumynou5/863b900b16eae7059ebf14563057ff6b/raw/users';
const AI_ILLUST_OPACITY = '0.2';
// Sorted by usage (descend) for performance.
const aiTags = [
'AIイラスト',
'AI',
'AI生成',
'AIart',
'AI-generated',
'AI生成作品',
'ai生成',
];
async function fetchUserList(url) {
let arr;
do {
const remoteMt = await fetch(url, {headers: {'Range': 'bytes=0-21'}})
.then((res) => res.ok ? res.text() : Promise.reject())
.then((text) => Date.parse(text.split('\n')[0]))
.catch(() => 0);
const localMt = await GM.getValue('mt', 0);
if (remoteMt <= localMt || isNaN(remoteMt))
break;
arr = await fetch(url, {headers: {'Range': 'bytes=23-'}})
.then((res) => res.ok ? res.text() : Promise.reject())
.then((text) => text.split('\n'))
.catch(() => null);
if (!arr[arr.length - 1]) // Allow the last line ends with a newline character.
arr.pop();
if (arr == null)
break;
GM.setValue('mt', remoteMt);
GM.setValue('user_list', JSON.stringify(arr));
} while (0);
arr ??= JSON.parse(await GM.getValue('user_list', '[]'));
return arr.reduce((acc, val) => (acc[val] = true) && acc, {});
}
const aiUsers = await fetchUserList(AI_USER_LIST_URL);
const watchElm = (function () {
const observer = new MutationObserver(observerCallback);
observer.observe(document, {childList: true, subtree: true});
const callbacks = [];
function observerCallback(mutations) {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== Node.ELEMENT_NODE)
continue;
for (const {selector, callback} of callbacks) {
if (node.matches(selector))
callback(node);
for (const x of node.querySelectorAll(selector))
callback(x);
}
}
}
}
return (selector, callback) => {
for (const elm of document.querySelectorAll(selector))
callback(elm);
callbacks.push({selector, callback});
};
})();
watchElm('li:has(a[href^="/artworks"], a[href^="/novel"])', (elm) => {
// [1] is __reactProps. The property name has a random suffix.
const info = Object.values(elm)[1]?.children.props.thumbnail;
if (!info)
return;
if (info.aiType === 2 || info.tags.some((tag) => aiTags.includes(tag)) || info.userId in aiUsers)
elm.style.opacity = AI_ILLUST_OPACITY;
});
2025-11-29T02:51+08:00
757415
2407113
3328617
5738939
8986455
9013106
13120488
14419145
15325426
16315304
17220560
18036457
18297337
18357648
18433815
18510872
18593130
18780314
19737941
20468285
20557152
22096506
22613374
24033806
26055768
26157153
27004418
27368325
31475021
35992413
36112955
37152734
37168136
39675825
42658393
42926781
42983192
43707514
46503769
49768708
53042082
53434142
53998244
60497488
61598251
65834497
66296433
67629528
70418416
74623069
76316220
77659169
77780865
79152651
85883819
87042098
87174194
87429561
88267790
89803149
90351205
91325601
91332959
92438708
95192705
95485582
96107480
96143216
99610792
100760823
101303554
101555203
101746026
101764596
102713342
102831195
103438231
103438492
103598089
104352874
104935838
105036183
105387263
105518914
105861351
106188743
106461254
106656028
106731484
106784447
108388963
108949679
109080877
109295200
109337851
109676302
109800265
109987538
110293987
110619867
110887422
110978761
110996404
111455398
111638616
111779616
111781384
112551099
112591781
112781710
113293180
113394629
113442197
113574601
113848749
114267011
114323636
114695282
114934423
115203223
115507089
115625960
115710043
115822502
116039247
116040274
116167939
116224005
116342680
116394695
116395108
116685492
116685552
117137417
117210874
117319256
117525623
117564798
117576384
117735677
117766996
117786814
117802569
117830193
117844388
117917884
118145342
118477169
118497372
118571800
119157375
119459961
119549649
119661648
119688810
119846390
119846478
120114927
131566898
// ==UserScript==
// @name Pixiv Dis-AI
// @version 0.4.5
// @description Hide AI-generated illustrations from Pixiv.
// @author Lumynous
// @license MIT
// @match https://www.pixiv.net/*
// @noframes
// @grant GM.getValue
// @grant GM.setValue
// @downloadURL https://gist.github.com/lumynou5/863b900b16eae7059ebf14563057ff6b/raw/pixiv-dis-ai.user.js
// @updateURL https://gist.github.com/lumynou5/863b900b16eae7059ebf14563057ff6b/raw/~meta
// ==/UserScript==
@lumynou5
Copy link
Author

lumynou5 commented May 14, 2025

Pixiv Dis-AI [en]

Hide AI-generated illustrations from Pixiv.

Besides the AI type set by the author, this userscript also respects community-added AI illustration tags, such as AIイラスト, to avoid the case that the author didn't mark their illustrations as AI-generated. This can't be without the community, so if you find something AI-generated without the tags, add it, and everyone appreciates that.

However, sometimes no more tags can be added because of the limit of tags, and still seeing AI-generated illustrations that are too new to be tagged is annoying. Therefore, this userscript experimentally maintains a list of AI users. If you find an user using AI that is not in the list, you may report by leaving a comment here.

The Protocol

You can actually maintain a user list by yourself. It should be a UTF-8 text file without BOM.

The first line of the file is a time in ISO format precise to minutes with the time zone, i.e. YYYY-MM-DDTHH:mm+ZZ:ZZ, to indicate the modification time of the list. You can generate the time by command date -Iminute on Linux.

The rest part of the file contains user IDs in the list, and each ID is terminated with a newline character (U+000A, \n). The last ID may have no newline character followed (newline is line separator), or may have one followed (newline is line terminator); however, trailing empty lines are not allowed.

Pixiv 反 AI [zh-TW]

隱藏 Pixiv 上 AI 生成的作品。

此使用者腳本除了作者自己設定的 AI 類型,也認得社群新增的 AI 插畫標籤,如 AIイラスト 等,來避免作者不正確設定作品類型的情況。這一切都依賴社群的互助,因此如果你發現有 AI 生成的作品上沒有標籤,加上它。

不過,有時候會因達到上限而沒辦法加上更多標籤,而且瀏覽時仍會看到新上傳、還沒有人來得及加上標籤的 AI 生成作品很煩。所以我實驗地維護了一份 AI 使用者的名單。若你找到不在名單上的 AI 使用者,可以透過留言回報。

Pixiv Dis-AI [ja]

Pixiv で AI 生成イラスト非表示にします。

このユーザースクリプトは、作者が設定した AI タイプに加えて、AIイラスト 等コミュニティが追加したタグも認識し、作者がイラストのタイプを誤って設定した場合でも動作します。これは全てコミュニティの協力なしには実現できません。タグが付いていない AI イラストを見つけた場合は追加してください。

ただし、タグの上限に達してタグを追加できない場合があり、誰もタグを追加していない AI 生成作品が表示されるのは煩わしいです。そこで、実験的に AI ユーザーリストを維持しています。リストに載っていない AI ユーザーを見つけた場合は、コメントで報告してください。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment