
はてなキーワード:Matchとは
はてなブックマークの増田一覧の、さらに「すべて」(1user)をチェックしている希有な人向けのユーザースクリプトを公開します。
https://b.hatena.ne.jp/site/anond.hatelabo.jp/?sort=eid
// ==UserScript==// @nameHatenaBookmarkAnond Filter// @namespacehttps://b.hatena.ne.jp/site/anond.hatelabo.jp/// @descriptionはてなブックマークの『はてな匿名ダイアリー』の記事のうち、指定したキーワードが含まれる投稿を非表示にします。// @matchhttps://b.hatena.ne.jp/site/anond.hatelabo.jp/*// @grant none// @version 1.0.2025.12.10.0005// ==/UserScript==(function(){constSCRIPTID = 'HatenaBookmarkAnondFilter';console.time(SCRIPTID);const ONCE = 1,AP = 2, INTERVAL = 3;/*適用タイミング*/const KEYWORDS = [ 'dorawii', 'あおやまちゃん', 'ボスマン', 'れめくん', '自己放尿', '性慾', 'boushi_inst', 'hakaikami',/*電気通信大学駿河台大学鉄道研究会れめくん自己放尿(頻出)*/ /*A-G*/'/akibakko6348', '/anapgoeson', '/asapgoeson', '/buscholarx', '/circlecavok', '/disney1007cla', '/dora22sibuya', '/donkotrain', '/fft_dareka', '/gmhtcyznf_abc', /*H-N*/'/h13_yokohama', '/h2twi', '/hinolovelove', '/inaken17_', '/inte235dy', '/kaoru_ai1991', '/kiha2228', '/kqlex1500', '/kurotamaxxx', '/kt_ruma_1372', '/lightningreen77', '/minamihinawot', '/minori0151', '/mukoroku651', '/nanpyong', '/nimouec', '/norannnde', /*O-U*/'/oreizmmiporin', '/pasotokon', '/pm95uq', '/reme_kun', '/s03_amurtk2731', '/sacchan03110319', '/seisu_bot', '/senanana_cos', '/shinano_115', '/shineleaf1372', '/soroisoroi', '/sweidan821858', '/tarotaromusic1', '/tx9y2cpwdz27255', '/uec15take', '/uecrail', /*V-Z_0-9*/'/wakasato_', '/yuuya_1104_uec', '/100mph_no_yuuki', '/2rtkvn34il2783', /*tadaup.jp*/'/CBUHadpD.jpeg', '/CgJlF4Wr.jpeg', '/CGTtm0Ev.jpeg', '/CIxj8clS.jpeg', '/CqbERPdQ.jpeg', '/CTZsA2wM.jpeg', '/CWY2m7rS.jpeg', '/CZVCEgd1.jpeg', 'テクウヨ', ].map(w => w.toLowerCase());const sites = { 'prefix': [ ['selector', 'modifier', 'REPEAT', '(css)'], ], 'https://b.hatena.ne.jp/site/anond.hatelabo.jp/': [ ['li.js-keyboard-selectable-item', li => KEYWORDS.some(w => (li.textContent.toLowerCase().includes(w)) && (li.querySelector('li.entrylist-contents-category > a').textContent = w) && (!li.classList.add('filtered'))),AP, `.filtered{display: none;}`], ], };const rules = sites[Object.keys(sites).find(prefix => location.href.startsWith(prefix))]; if(rules === undefined) returnconsole.log(SCRIPTID, 'Not foundany sites.');const modify = function(selector, modifier){constelements = document.querySelectorAll(selector);elements.forEach(modifier); }; /* ONCE(一括適用) */ rules.forEach(rule => {const [selector, modifier, repeat,css] = rule;console.log(SCRIPTID, 'ONCE:', selector); modify(selector, modifier); if(css){const style = document.createElement('style'); style.dataset.script =SCRIPTID; style.type = 'text/css'; style.textContent =css; document.head.appendChild(style); } }); /*AP(AutoPagerize) */ rules.filter(rule => rule[2] ===AP).forEach(rule => {const [selector, modifier, repeat] = rule; document.addEventListener('GM_AutoPagerizeNextPageLoaded', e => {console.log(SCRIPTID, 'AP:', selector); modify(selector, modifier); }); }); /* INTERVAL */ rules.filter(rule => rule[2] === INTERVAL).forEach(rule => {const [selector, modifier, repeat] = rule; setInterval(function(){console.log(SCRIPTID, 'INTERVAL:', selector); modify(selector, modifier); },1000); });console.timeEnd(SCRIPTID);})();
検索用:はてなブックマークはてブはてな匿名ダイアリー増田スパムキーワードNGワードフィルターミュート非表示 削除 隠すブロックユーザースクリプトユーザースタイルhatenabookmarkanondspam keywordsngwords filter mutehide hidden display none blockuserscriptJavaScriptjscss style
勝手ながら
// ==UserScript==// @nameはてな匿名ダイアリー特定ワード投稿非表示// @namespacehttp://tampermonkey.net/// @version 0.2// @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする// @matchhttps://anond.hatelabo.jp/*// @grant none// ==/UserScript==(function() { 'use strict';const POST_SELECTOR = '.body .section'; //非表示にしたいキーワードの配列constKEYWORDS = ['dorawii','megalodon','抽象数学','動画にしてみた','れめくん','自己放尿'];const posts = document.querySelectorAll(POST_SELECTOR); posts.forEach(post => {const textContent = post.textContent || post.innerText; // いずれかのキーワードが含まれているかチェック if (KEYWORDS.some(keyword => textContent.includes(keyword))) { post.style.display = 'none'; } });})();
anond:20251114170150 と連動させることを意図しています。
// ==UserScript==// @name meaningless sale dayo// @version 1.0// @matchhttps://www.amazon.co.jp/blackfriday*// ==/UserScript==(function () { 'use strict'; alert('意味のないセールだよ');})();
// ==UserScript==
// @namespacehttp://tampermonkey.net/
// @version 0.2
// @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする
// @matchhttps://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const POST_SELECTOR = '.body .section';
constKEYWORDS = ['dorawii','megalodon','抽象数学','動画にしてみた','れめくん','自己放尿'];
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
const textContent = post.textContent || post.innerText;
if (KEYWORDS.some(keyword => textContent.includes(keyword))) {
post.style.display = 'none';
}
});
})();
// ==UserScript==
// @namespacehttp://tampermonkey.net/
// @version 0.2
// @description 本文に「dorawii」または「megalodon」が含まれる投稿を非表示にする
// @matchhttps://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const POST_SELECTOR = '.body .section';
constKEYWORDS = ['dorawii', 'megalodon'];
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
const textContent = post.textContent || post.innerText;
if (KEYWORDS.some(keyword => textContent.includes(keyword))) {
post.style.display = 'none';
}
});
})();
これはdorawiiもしくはmegalodonを含む投稿を非表示にするけど、
constKEYWORDS = ['dorawii', 'megalodon'];の部分を変えたり追加すれば好きな言葉に変えられるよ
dorawiiがタイトルに「dorawii」と入れなくなったので、本文にdorawiiがある投稿も非表示にする必要が出てきました。
ただAIに聞いたんだけど、CSSでは無理でJavaScriptならできると言われました。
そのJavaScriptを下に載せます。
// ==UserScript==
// @namespacehttp://tampermonkey.net/
// @version 0.1
// @description 本文に「dorawii」が含まれる投稿を非表示にする
// @matchhttps://anond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
//はてな匿名ダイアリーの一般的な投稿要素のクラスを仮定しています
const POST_SELECTOR = '.body .section'; // 例: .bodyクラスの子孫の.section要素
// すべての投稿要素を取得
const posts = document.querySelectorAll(POST_SELECTOR);
posts.forEach(post => {
//投稿内の本文が含まれる要素(ここでは投稿全体を本文と見なす)のテキストを取得
const textContent = post.textContent || post.innerText;
if (textContent.includes(KEYWORD)) {
post.style.display = 'none';
}
});
})();
自分はiPhoneなので、Makeoverというアプリを入れて、JSの部分に上のを貼り付けてます。
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050772
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050774
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050772?Match-Master
gamefaqs.gamespot.com/boards/178921-dragon-ball-z-dokkan-battle/81050774?Match-Master
ストZERO3の「尿を便座におしつけ~る」くらいにモヤモヤしてた
答え
tHisis gOnNa bE aMaTcH TO REmember!
ここmatchがどうして聞き取れなくて「Thisis gonna be a must to remember! 」(この戦いは記憶に残るマストなものになる!)かと思ってしまったw
なんか安心したわ
ramadan.mya.org.au/today-boost/posts/legit-ways-to-get-free-match-masters-free-gifts-boosters-coins-link-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-rewards-match-masters-free-gifts-boosters-coins-link-in-october-2025
ramadan.mya.org.au/today-boost/posts/rewards-match-masters-unveils-daily-free-gifts-boosters-and-coins-link-updated-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-rewards-cash-app-money-free-codes-everything-you-need-to-know-in-october-2025
ramadan.mya.org.au/today-boost/posts/daily-earning-cash-app-money-free-codes-rewards-ultimate-beginners-guide-in-october-2025
ramadan.mya.org.au/today-boost/posts/legit-ways-to-get-free-cash-app-money-earn-codes-daily-rewards-in-october-2025
ramadan.mya.org.au/rewards-today/posts/daily-rewards-match-masters-free-gifts-unlimited-coins-links-september-2025
ramadan.mya.org.au/rewards-today/posts/today-match-masters-free-gifts-boosters-and-coins-links-tips-tricks-2025
www.wortfm.org/calendar/updated-today-match-masters-unveils-free-gifts-boosters-and-coins-link-2025/
www.wortfm.org/calendar/today-match-masters-free-gifts-boosters-and-coins-links-tips-tricks-2025/
www.wortfm.org/calendar/daily-rewards-match-masters-free-gifts-boosters-coins-links-tips-tricks-2025/
というわけでお漏らし文学をChatGPTに調べてもらった
Lasttime I paid 1€ totake a piss,
I walked into the Sanifair, looked around,
and just…left.
Itwas so disgusting I decided togooutside and search for abush instead.
—Reddit / r/AskAGerman
「1ユーロ払ってトイレに入ったんだけど、あまりに汚すぎてそのまま出てきた。結局、外の藪を探すことにした。」
ドイツ人ですら「お金払って藪で用を足す方がマシ」と言ってしまう悲哀。
URL:れでぃっと r/AskAGerman
I used tosquat when using public toilets.
Thenone day, I slipped.
That day,something inside me died… andsomethingoutside mewas nevercleanagain.
— れでぃっと / r/AskEurope
でもある日、足が滑った。
その日、僕の中の何かが死んだ… そして僕の外側も、二度と綺麗にはならなかった。」
もう「しゃがむ」という選択肢すら許されない。
InBelgium, there’s an unwritten rule.
he silently handsyou the bathroomkey.
you find a darkcorner of the street instead.
—Blog post “Theart ofle pee inBelgium”
バーの店主に1ユーロ渡すと、無言でトイレの鍵を渡してくれる。
観光都市ブリュッセルでも、路上で立ち尽くす影が絶えない理由。
URL:saintfacetious.com
All cafés were closed,all public toilets locked.
I stumbled along the riverbank,
In the end, the Seinesaweverything.
— れでぃっと / r/Paris
「深夜1時、セーヌ川沿い。
ワインと後悔で酔った体を引きずりながら歩き、
パリの夜は美しく、そして容赦ない。
観光客だけでなく、現地の人すらこうなることがある。
Iwas in Bilbao, desperate to pee before thematch.
I ran intoone of those self-cleaning toilets…
and then thecleaningcyclestarted
僕は全身びしょ濡れになって出てきた。」
水と泡まみれで出てきたマンチェスター・ユナイテッドファン。
In Amsterdam, we had thesehalf-open urinals called ‘peecurls.’
They were meant to stop men from peeing in the canals.
Now they’re disappearing…
and the canals smelllikehistoryagain.
「アムステルダムには、半分だけ壁のある露天トイレ『peecurl』があった。
でも今はそのpeecurlも減り、
I haveMS.
Since the public toilets closed,
Last month, I didn’tmakeithome intime.
I cried, then laughed, then stayed inside for a week.
— The Guardian読者投稿
「私は多発性硬化症です。
先月、家に帰る前に間に合わなくて…
URL:The Guardian
まあまあだな、また探す
____
https://profile.hatena.ne.jp/dorawii_bukuma/
はてなのサイト側で読み込まれているはずのrksトークンを生成する関数を直接叩く方法がどうしても分からず結局request処理を自分で書く方法ではなく自動でUI側の保存ボタンをクリックするという無難な方向に落ち着いた。
最初から後者の方法をとっていればもっと全然早く作れたのにというは所詮言い訳か。
とにかくスクリプトを公開しておく。
@echo off
cd /d "C:\Users\user\Documents\jsscript"
:: Nodeサーバーを別ウィンドウで起動
start /min "" noderun-batch-server.js
::Pythonサーバーを別ウィンドウで起動(hatenaserver配下)
start cmd /k ""python hatenaserver\server.py
{
"username": "",
"password": ""
}from flask import Flask, request,jsonify
importjson
importos
from hatena_client import HatenaClient
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
config_path =os.path.join(os.path.dirname(__file__), 'config.json')
withopen(config_path, encoding='utf-8')as f:
config =json.load(f)
@app.route('/bookmark', methods=['POST'])
def handle_bookmark():
data = request.json
url = data.get("url")
if noturl:
returnjsonify({"error": "MissingURL"}), 400
client = HatenaClient(config["username"],config["password"])
client.start_browser()
if notclient.login():
client.quit()
returnjsonify({"error": "Login failed"}),403
success =client.add_bookmark(url)
client.quit()
returnjsonify({"status": "ok" if success else "fail"})
if __name__ == "__main__":
app.run(port=12347)
// ==UserScript==
// @name自動セルクマ送信
// @namespace tampermonkey.net/
// @version 2025-08-07
// @descriptiontry totakeoverthe world!
// @authorYou
// @matchanond.hatelabo.jp/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
consturl = location.href;
if (!/^https:\/\/anond\.hatelabo\.jp\/\d+$/.test(url)) return;
const editLink = document.querySelector('a.edit');
if (!editLink) {
// 既に編集ページなので処理をスキップ
console.log('編集リンクが存在するため、スクリプトを終了します。');
return;
}
fetch('localhost:12347/bookmark', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({url:url })
}).then(r =>console.log("通知成功")).catch(e =>console.error("通知失敗", e));
})();
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250821192753# -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKb0qwAKCRBwMdsubs4+SHfiAQDcXmTHBaZ5Zzr1KI/OxZ0xl69oevOdy1FXJYwYvsmo5AD/ZPtZiO1JgTDjm+27iymlkdzIXOIGWfC82UTr1mJ7EwU==YoV+-----ENDPGP SIGNATURE-----
木古 「きこ」ではなくて「きふる」って読むのね そしてTwitterアカウントのkipple… ギップルなら知ってるけど?と思って検索したら
アンドロイドは電気羊の夢を見るか?由来か~~
kipple
Popularized in Philip K. Dick's novel Do AndroidsDream of ElectricSheep? (1968); originally thename of aSF fanzine, from the humorous interpretation of Kiplingas a participle.[1]
kipple (uncountable)
(colloquial) uselessitems;junk; clutter
Synonym: crapola
2008 [1968], Philip K. Dick, Do AndroidsDream of ElectricSheep?, Ballantine Books, →ISBN, page 65:
“Kippleis useless objects,likejunk mail ormatch folders afteryou use thelastmatch orgum wrappers or yesterday's homeopape. When nobody's around, kipple reproducesitself. For instance, ifyougo tobed leavingany kipple around appartment, whenyou wake up in thenext morning there's twiceas much ofit.Italwaysgetsmore andmore.”
一度投稿したうえで別タブを開いてプログラム的(fetch)に送信してその別タブが閉じられる仕組み。
// ==UserScript== // @namePGP未署名検出と別タブ自動編集 // @namespacehttp://tampermonkey.net/ // @version 1.0 // @descriptionPGP署名がない投稿を自動編集ページへ誘導 // @matchhttps://anond.hatelabo.jp/* // @grantGM_setValue // @grantGM_getValue // @grantGM.openInTab // ==/UserScript== (function () { 'use strict';constbody = document.getElementById('entry-page'); if (!body) return;consttitleText = document.title; if (!titleText.includes('dorawii')) return;constpgpRegex = /BEGIN.*PGP(?: SIGNEDMESSAGE| SIGNATURE)?/;const preElements = document.querySelectorAll('div.body pre'); let hasPgpSignature =false; for (const pre of preElements) { if (pgpRegex.test(pre.textContent)) { hasPgpSignature =true; break; } } if (hasPgpSignature) return;const editLink = document.querySelector('a.edit');const childTab =GM.openInTab(editLink.href, {active:false, insert:true,setParent:true }); })();
// ==UserScript== // @name編集ページ処理と自動送信・閉じ // @namespacehttp://tampermonkey.net/ // @version 1.0 // @description編集ページで署名処理と送信、タブ自動閉じ // @matchhttps://anond.hatelabo.jp/dorawii_31/edit?id=* // @grantGM_getValue // @grantGM_xmlhttpRequest // @grantGM_setClipboard // @grantGM_notification // @connectlocalhost // ==/UserScript== (async function () { 'use strict';const shouldRun = awaitGM_getValue('open-tab-for-edit', '0');consttextareaId = 'text-body';consttextarea = document.getElementById(textareaId); if (!textarea) return;const content =textarea.value;constpgpSignatureRegex = /-----BEGINPGP SIGNEDMESSAGE-----[\s\S]+?-----BEGINPGP SIGNATURE-----[\s\S]+?-----ENDPGP SIGNATURE-----/; if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します'); return; }consthttpRequest = (url, data) => { return newPromise((resolve,reject) => {GM_xmlhttpRequest({ method: 'POST',url:url, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: `value=${encodeURIComponent(data)}`,onload: function (response) { resolve(response.responseText); },onerror: function (error) {reject(error); } }); }); }; //textarea の値を取得 // 1.現在のページのURLからURLオブジェクトを作成const currentUrl = newURL(window.location.href); // 2.ベースとなる部分 (例: "https://anond.hatelabo.jp") を取得constorigin = currentUrl.origin; // 3. 'id'パラメータの値 (例: "20250610184705") を取得constidValue = currentUrl.searchParams.get('id'); // 4.ベース部分とIDを結合して、目的のURL文字列を生成 //idValueが取得できた場合のみ実行する let newUrl = null; if (idValue) { newUrl = `${origin}/${idValue}`; } // 5. 生成されたURLを変数に代入し、コンソールに出力して確認console.log(newUrl);constvalueToSend = newUrl;try {const signatureText = awaithttpRequest('http://localhost:12345/run-batch',valueToSend);console.log('バッチ応答:', signatureText); if (!signatureText.includes('BEGINPGP SIGNEDMESSAGE')) { alert('PGP署名がクリップボードに見つかりませんでした。'); return; }const newText = content.replace(/\s*$/, '') + '\n' + signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');const form = document.forms.edit;const newForm = form.cloneNode(true); form.replaceWith(newForm); newForm.addEventListener('submit', async (e) => { e.preventDefault(); //HTML標準のsubmitをキャンセルconstbodyText =textarea?.value || ''; //reCAPTCHAトークンの取得constrecaptchaToken = await newPromise((resolve) => { grecaptcha.enterprise.ready(() => { grecaptcha.enterprise.execute('hoge', {action: 'EDIT' }) .then(resolve); }); }); // POSTするデータの構築const formData = new FormData(newForm); formData.set('body',bodyText); formData.set('recaptcha_token',recaptchaToken); formData.set('edit', '1');try {constresponse = await fetch(newForm.action, { method: 'POST',body: formData, credentials: 'same-origin' }); if (response.ok) {console.log('送信成功'); window.close(); } else {console.error('送信失敗',response.status); } }catch (err) {console.error('送信中にエラーが発生', err); } }); //プログラム的に送信トリガー newForm.dispatchEvent(new Event('submit', { bubbles:true })); }catch (e) {console.error('バッチ呼び出し失敗:', e); } })();
consthttp =require('http');const { exec } =require('child_process');const querystring =require('querystring');const server =http.createServer((req, res) => { if (req.method === 'GET' && req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.method === 'POST' && req.url === '/run-batch') { letbody = ''; req.on('data', chunk => {body += chunk.toString(); }); req.on('end', () => {constparsed = querystring.parse(body);constvalue =parsed.value || 'default'; // 値を引数としてバッチに渡す exec(`C:\\Users\\hoge\\Desktop\\makesign.bat "${value}"`, { encoding: 'utf8' }, (err, stdout, stderr) => { if (err) { res.writeHead(500); res.end('Error executing batch: ' + stderr); } else { res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(stdout.trim()); } }); }); } else { res.writeHead(404); res.end('Not found'); }});server.listen(12345, () => {console.log('Batch serverrunningathttp://localhost:12345/');});
@echo offsetlocal enabledelayedexpansion::署名するファイル名set "infile=%~1"set outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%":signloop::AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\hoge\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名を作成echo %infile% | gpg --yes --clearsign --output "%outfile%"::署名が成功していればループを抜けるif exist "%outfile%" (goto postprocess) else ( timeout /t 1> nulgoto signloop):postprocesspowershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Write-Output ($header + \"`r`n\" + $body + $footer)"powershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content 'signed.asc' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"endlocalexit /b
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInputpasswordSleep 100SendInput {Enter}ExitApp
動けばいいという考えで作っているので余分なコードも含んでいるかもしれない。
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250613185036 -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEv1FQAKCRBwMdsubs4+SHHkAQDUOLgBcdji2T6MJ7h/vlMdFfGlWAzNdXijjE1gIuEPywEAiMNMZqhrMmtlc7UqRuggNJ/UTa5xTIcKp622+7jJQQg==Lgkl-----ENDPGP SIGNATURE-----
ようやく(ほぼ)すべてが自動化された。
あとはローカルサーバーの起動をスタートアップに設定する(方法をAIに聞いて指示に従う)だけの消化試合。
署名時要求してくるパスワードを自動入力するahkファイルはドキュメントのAutoHotkey配下に置いた。
バッチファイル(make.sign.bat)はデスクトップに置いた。
#Persistent#SingleInstance ignoreSetTitleMatchMode, 2WinWaitActive, pinentrySendInput お前のパスワードSleep 100SendInput {Enter}ExitApp
//run-batch-server.jsconsthttp =require('http');const { exec } =require('child_process');const server =http.createServer((req, res) => { if (req.url === '/ping') { res.writeHead(200); res.end('pong'); } else if (req.url === '/run-batch') { exec('C:\\Users\\you\\Desktop\\makesign.bat', (err) => { res.writeHead(200); res.end(err ? 'Error' : 'OK'); }) ; } else { res.writeHead(404); res.end('Not found'); }});server.listen(12345, () => {console.log('Batch serverrunningathttp://localhost:12345/');});
@echo offsetlocal enabledelayedexpansion::ミリ秒単位のUTC時刻を取得for /f %%a in ('powershell -nologo -command "[int64]::Parse((Get-Date).ToUniversalTime().ToString('yyyyMMddHHmmssfff'))"') doset timestamp=%%a::署名するファイル名set infile=%TEMP%\pgp_input.txtset outfile=%TEMP%\pgp_output.asc:: 以前の出力があれば削除if exist "%outfile%" del "%outfile%"::タイムスタンプを原文として保存echo %timestamp%> "%infile%":signloop::AutoHotkeyでパスフレーズ入力(gpgがパスワード要求するダイアログが出た場合に備える)start "" /b "C:\Users\infini\Documents\AutoHotkey\autopass.ahk"::PGPクリア署名を作成gpg --yes --clearsign --output "%outfile%" "%infile%"::署名が成功していればループを抜けるif exist "%outfile%" (echo [INFO]署名成功goto postprocess) else (echo [WARN]署名失敗、再試行します… timeout /t 1> nulgotosignloop):postprocess::PowerShellで余計な改行なしに |< をつけてクリップボードにコピーpowershell -nologo -command ^ "$header = '>|'; $footer = '|<'; $body =Get-Content '%outfile%' -Raw;Set-Clipboard -Value ($header + \"`r`n\" + $body + $footer)"echo Done.signed.asc created and clipboard updated (no extra blankline).endlocalexit /b
// ==UserScript==// @namePGP署名自動付加スクリプト(GM_xmlhttpRequest版)// @namespacehttp://tampermonkey.net/// @version 1.0// @description投稿前にPGP署名を付けてから送信(fetch未使用)// @matchhttps://anond.hatelabo.jp/dorawii_31/edit*// @grant GM_xmlhttpRequest// @grant GM_setClipboard// @grant GM_notification// / @connectlocalhost// ==/UserScript==(function () { 'use strict';const submitId = 'submit-button';consttextareaId = 'text-body';const localServer = 'http://localhost:12345/run-batch';constpgpSignatureRegex = /-----BEGINPGPSIGNEDMESSAGE-----[\s\S]+?-----BEGINPGPSIGNATURE-----[\s\S]+?-----ENDPGPSIGNATURE-----/;consthttpRequest = (url) => { return newPromise((resolve,reject) => { GM_xmlhttpRequest({ method: 'GET',url:url, onload: function (response) { resolve(response.responseText); }, onerror: function (error) {reject(error); } }); }); };const interceptClick = () => {constbtn = document.getElementById(submitId); if (!btn ||btn.dataset.pgpIntercepted === 'true') return;btn.dataset.pgpIntercepted = 'true';btn.addEventListener('click', async function (e) {consttextarea = document.getElementById(textareaId); if (!textarea) return;const content =textarea.value; if (pgpSignatureRegex.test(content)) {console.log('[PGPスクリプト]署名が検出されたためそのまま送信します'); return; } e.preventDefault(); e.stopImmediatePropagation();console.log('[PGPスクリプト]署名が見つからないため処理を停止し、署名を取得します');try { awaithttpRequest(localServer); //バッチ実行constsignatureText = await navigator.clipboard.readText(); if (!signatureText.includes('BEGINPGPSIGNEDMESSAGE')) { alert('PGP署名がクリップボードに見つかりませんでした。'); return; }const newText = content.replace(/\s*$/, '') + '\n' +signatureText + '\n';textarea.value = newText;console.log('[PGPスクリプト]署名を貼り付けました。送信を再開します。');btn.click(); //イベント再発火 }catch (err) { alert('PGP署名の取得または貼り付けに失敗しました。\n' + err); } },true); }; window.addEventListener('load', () => {setTimeout(interceptClick, 1000); });})();
プロミスメソッドとか全然まだ理解してなくてそのなかに関数代入したその関数にオブジェクトのプロパティにresponseを?いやまあそのあたりのコードが示すデータの流れが全然理解できないような人間でもここまでできちゃった。
AIすごいなと思うよ。そして思うのは今後重要になってくるのは文法とか自体に詳しいことじゃなくて、そのプログラムの処理内容を指示できるシステムエンジニア的な言語化能力のほうじゃないかなと思った。
-----BEGINPGPSIGNEDMESSAGE-----Hash: SHA51220250609111559680 -----BEGINPGPSIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaEbCbwAKCRBwMdsubs4+SLueAPwOv7PBk4voAe5qlcCEvs/PJhmKc5QAb/1R43JMQFuDZgD/UTPEKsL/PhK9jFGv2HDXK1dVjLNwvosgX9uYJh5xxwY==qiOE-----ENDPGPSIGNATURE-----
「Utopia」の初出。トマス・モアの『Utopia』(1516年)。
「Dustopia」の初出。ルイス・ヘンリー・ヤングの『Utopia: or,Apollo'sgoldendays』(1747年)。
But Heav'n, of late,wasall distraction, and,morethan ever,rent in faction; Caus'donlyby a wretchedisle,On which wethought noGod wouldsmile:
だが近ごろの天界は混乱の極みにあり、かつてにも増して内紛に引き裂かれていた。それもこれも、ひとつの惨めな島のせいだった。誰の目にも、神が微笑むことなどないと思われていたその島。
Not stor'd with wealth,nor blest inair: no useful Plants could ripenthere; Mismanag'dbyth' unskillful hinds, or niptby chilling Easternwinds:
富を蓄えず、空気にも恵まれず、作物は育たずに終わる。未熟な農夫たちにより荒らされ、あるいは東から吹きつける冷たい風に凍えて枯れる。
Or ifthey flourish'd for a Day,They soon became some Insect's prey: For many suchinfestthesoil, Devouringth' honest lab'rers's toil ; *So venomous,that some had rather have, intheir stead,the toad, or adder.
たとえ一日だけ花開いたとしても、すぐに虫の餌食となった。というのも、多くの害虫が土地にはびこり、誠実な労働者の努力を食い尽くしていたのだ。そのあまりの毒性に、むしろヒキガエルやマムシの方がましだと言う者もいるほどだった。
Unhappyisle!
不幸な島よ!
scarce known to Fame; DUSTOPIAwasits slightedname.
名声を得ることもなく、「デュストピア」と呼ばれて軽んじられていた。
「Cacotopia」の初出。ジェレミー・ベンサムの『Plan of parliamentary reform』(1817年)。
A constitution,with thispoison--slow, but notthe less sure—inthe bowels ofit!—Rotten, even fromthe timethatthispoisonwas injected intoit, must have beenthematchless constitution,—rottenatthecore—and, of suchrottenness, what we arenow sufferingis amongthe fruits.
この毒を――遅効性ではあるが、それでも確実な毒を――その内臓に抱えた憲法! この毒が注入されたその時からすでに、あの比類なき憲法は腐敗していたに違いない――中核から腐っていた――そして、いま我々がこうして被っている苦しみこそが、その腐敗の産物の一つなのだ。
As amatch for Utopia, suppose a Cacotopia discovered and described,—would not filth inthis shape be a "fundamental feature" init?
ユートピアに対抗するものとして、「カコトピア」が発見され、描写されたと仮定しよう――このような汚濁が、その「根本的な特徴」として描かれないだろうか?
https://archive.org/details/planparliamenta00bentgoog/page/n204/mode/2up
ベンサムは、議員たちが国王から官職を与えられることを批判している。小さな賄賂などは不道徳とされて取り締まっているが、国王から官職が与えられることはむしろ名誉として扱われる。実質的にはそれは癒着であり腐敗でしかないのに。という話をしている。
「Dystopia」の初出。ジョン・スチュワート・ミルの議会演説(1868年)。
Now,onthis subjectthe Government have not shownthemselves altogether inflexible.The nobleLordthe Chief Secretary forIrelandhas expressedhiswillingness in some degree to entertainthe principle of religious equality, and 1517 Ithankhim forit; but,ashas been remarkedby my hon.Friendthe Member for Manchester (Mr. JacobBright), he proposed todo it—ifatall—by levelling up instead of levelling down.The nobleLordiswillingthat every valley shall be exalted; but hedoes notgo on tothe succeeding clause, and saythat every mountain and hill shall be laidlow.
さて、この問題に関して、政府は完全に強硬というわけではないようです。アイルランド担当大臣である閣下は、宗教的平等という原則をある程度受け入れる用意があると述べました。これは感謝すべきことですが、マンチェスター選出の敬愛する友人(ジェイコブ・ブライト氏)が指摘したように、彼はこれを「下げる」のではなく「引き上げる」ことで実現しようとしているようです。すなわち、彼は「すべての谷を高くする」ことには賛成ですが、「すべての山と丘を低くする」とまでは言っていないのです。
So longasthenational property whichis administeredbythe Episcopal Church ofIrelandis not diverted fromits present purpose,the nobleLordhas no objectionatall tothis country saddlingitselfwith the endowment ofanother great hierarchy, which, if effectedonthe principle of religious equality, would be a great dealmore costlythan eventhat whichnow exists.Doesthe nobleLord reallythinkit possiblethatthe people ofEnglandwill submit tothis?
アイルランド国教会が管理する国家資産が現在の用途から変更されない限り、閣下はこの国が別の大きな教会制度への助成金という負担を背負うことにはまったく反対ではないのです。そしてもしそれが宗教的平等という原則に基づくのであれば、現在の制度よりはるかに高くつくことでしょう。閣下は本当に、イングランド国民がそれに甘んじると考えておられるのでしょうか?
Imay be permitted,asonewho, incommon with many of my betters, have been subjected tothe charge ofbeing Utopian, to congratulatethe Governmenton having joinedthat goodly company.Itis, perhaps, too complimentary to callthem Utopians,they ought rather to be called dystopians, or cacotopians. Whatiscommonly called Utopianissomething too good to be practicable; but whatthey appear to favouris too bad to be practicable.
私は、自分自身をユートピア主義者だと非難されてきた多くの優れた方々とともに、政府がその立派な仲間入りをしたことをお祝い申し上げたいと思います。ただ、彼らを「ユートピア主義者」と呼ぶのは、少々褒めすぎかもしれません。「ディストピア主義者」あるいは「カコトピア主義者」とでも呼ぶべきでしょう。通常「ユートピア的」とは、良すぎて実現不可能なものを指しますが、彼らの支持するものは、悪すぎて実現不可能なもののようです。
https://api.parliament.uk/historic-hansard/commons/1868/mar/12/adjourned-debate
イングランドはカトリックから離脱して「イングランド国教会」を組織したが、同様にアイルランドでも従来のカトリック教会を「アイルランド国教会」のもとに置いた。しかしアイルランド人の多くは改宗せず、アイルランド国教徒は全体の1/8にすぎなかった。それでもアイルランド国教会は「国教」であるので、アイルランドのすべての教会の財産を保有しており、またアイルランド国教会への助成金は全アイルランド人に課せられる税金から支払われていた。この不平等の是正にあたって、政府は「アイルランド国教会の待遇を下げる」のではなく「他の教会の待遇を上げる」ことで解決しようとしているという。つまり他の教会にも同様の助成金を支払おうとしており、それはもちろんイングランド国民の税金から賄われることになる。そんなことをイングランド国民が許すと思っているのか?とミルは言っている。その後、1871年にアイルランド国教廃止法が施行された。
VitaにCFWを導入するにあたり、情報が散乱していたのでまとめる
・2022年末に革新的進歩があり、VITA単体でCFW導入できるようになった(通称 HENlo)
・にも関わらず古いCFW導入方法を案内しているブログが大量にある
・しかもタイトルの"20XX年最新"だけ更新し続けているから、最新記事に見える
↓
PC使用が前提になっているブログは全部古いので無視した方が良いです。
・『HENlo』について触れている
この2つが押さえられてれば最新情報です。(2025年5月現在)
ただし、現状だと実は『PC操作が一部必要』という罠があります。
その問題について書いている記事が見当たらないので、ここに残しておきます。
超具体的には
「HENkaku、VitaDeploy、VitaShellは導入できた」
「けどEnso導入ができない/つまづいている」 エラー:failed togetfwversion please disableallthe plugins andtryagain
5chでもRedditでも
『プラグインを無効にしろ』『0syscall6を無効にしろ』って書いてあったのですが、実はEnsoのバージョン変えれば解決します。(後述)
この記事が役に立ちました
[Vita]2023年最新手順【HENlo】3.65-3.74PC不要でCFW(HENkaku)導入
https://re-doing.com/vita-henlo-hack/
(一応魚拓:https://web.archive.org/web/20250226111105/https://re-doing.com/vita-henlo-hack/)
・HENkaku (カスタムファームウェア 3.65 変革 -2)
・VitaDeploy
・VitaShell
・最悪文鎮化する可能性があるのでセーブデータバックアップを取ったほうが良い
・VITAのセーブデータは特殊で、PCと繋ぐだけでは取り出せない
・バックアップにはいくつか方法があるが、PCのコンテンツ管理アシスタントは既に使えないと思ったほうが良い。PS Plusのクラウドバックアップが最も良いはず
・記事の内容を実施する前にバックアップ取るのを強くおすすめする
これをインストールすることで、電源を切ってからもCFW状態を維持できます。
VitaDeploy内のApp downloaderメニューからEnsoをインストールできますが、実はこのバージョンが古いです。※重要※
そのためVitaDeployからインストールすると先程のエラー(failed togetfwversion please disableallthe plugins andtryagain)が必ず出ます。
「PC不要になった」と書いてあったので盲点ですが、ここからPC必要です。
正しい方法は以下です
1,PC操作:GithubからEnso最新版のenso.vpkファイルをダウンロード(現在v1.1)
https://github.com/TheOfficialFloW/enso/releases
2,PCとVitaをUSBケーブルで繋げる ※データ転送対応ケーブルを使うこと。相性もある
5,PC操作:USBドライブとしてVITAのデータが表示されるので、ダウンロードしていたenso.vpkファイルを置く(フォルダはどこでもOK。自分はルート直下に置きました)
7,Vita操作:VitaShellでenso.vpkを見つける(さっきルートに置いたなら恐らくux0:にある)
9.Vita操作:Doyou want toinstall this package? → ◯ボタン
10.Vita操作:~~~ Wouldyoulike tocontinue theinstall? ※意訳:「失敗したら文鎮化するけど自己責任だけど続ける?」 → ◯ボタン
11. 進行バーが消えたらインストール完了 ホーム画面に戻ってOK
Ensoはファームウェアが3.60か3.65じゃないとインストールできないです。(3.65 変革 -2は3.65扱い)
先程の記事の通り進めていたら3.65 変革 -2 になっているはずですが、実行前に再確認して下さい。
1, ~~~ PressCIRCLE toaccept these terms orany otherkey to notaccept. → ◯ボタンを押す(=CIRCLE )
2, Options:
CROSS Install /reinstall thehack.
SQUARE Fix bootconfiguration (choose this if taiHEN isn't loadingon boot).
CIRCLE Exit without doinganything.
Locking sustem ..
(中略)
Theinstallationwas completed successfully.
suocess.
MBRwas detected butinstllation checksum dose notmatch.
Adumpwas createdat ux0:data/blocks.bin.
Press X tocontinue,any othekey toexit.
意訳:「ちょい待った。思ってた構成じゃないから危ないかもしれんわ。続ける?」
→✕ボタンを押す ※結局原因分かってないので自己責任でお願いします※
4,Locking sustem ..
(中略)
Theinstallationwas completed successfully.
suocess.
Enso導入が成功していると
・ファームウェアが3.65 変革 -2のままなっている
お疲れ様でした。
記事の本題は以上です。
VITAのセーブデータは暗号化されており、吸い出せてもエミュレータで使えないらしい。本体機体とセットで揃わないと使えない仕様。
調べたらセーブデータをここまでキツく縛ってるハードは他にない
だからメモリーカードのデータ管理でもPSPのセーブデータしか項目がなかったのか…
不便すぎる
当時の仮説
・HENkaku設定が悪さをしているのではないか(PSNの偽装を有効化、バージョンの偽装を有効化) →オフにしたが関係なかった
・本体にSD2VITAを刺しているのが良くないのではないか →抜いたが関係なかった
・enso.vpkの置き場所がルート(ux0:)が良くなかったのではないか →関係なかった
・VITAにメモリーカードを刺しているのが良くないのではないか →関係なかったが、データ保護的には抜くのが良さそう
・ゴミデータが残っていて悪さしているのではないか(手順を間違えたデータや古いデータなど) →関係ある可能性はある。最後までわからず
・Ensoのバージョンが古いのではないか →これが主要因だった
ゴミデータを疑った自分は正規のファームウェアに戻して、CFW化をやり直したりもした。
その際HENkakuすら入れられなくなってしまったので、抜け方を書いておく。
ENSO実行
↓
~~~ PressCIRCLE toaccept these terms orany otherkey to notaccept. → ◯ボタンを押す(=CIRCLE )
↓
Options:
CROSS Install /reinstall thehack.
SQUARE Fix bootconfiguration (choose this if taiHEN isn't loadingon boot).
CIRCLE Exit without doinganything.
→ △ボタンを押す(=TRIANGLE Uninstall thehack.)
↓
↓
↓
ファームウェアアップデートが促され、アップデートしないとメモリースティックが使えない
↓
↓
↓
HENloメニュー
・Exit
↓
「Eiting in 3」 の後に、以下のエラーメッセージがでて固まってしまう
Ifyou are stuckon thisscreen, hold downthe power button untilyourVita turns off, then turnit backon.
原因:恐らく余計なデータと衝突を起こしてる
(さっきのエラーメッセージ画面で)
↓
セーフモードが起動する
↓
↓
↓
HENloメニュー
・Exit
↓
その後
Install HENkaku、InstallVitaDeployを選択して、Exitを選択
この記事を書き終えた後に見つけたのですが、以下の記事の『改造方法』というところに情報がかなりまとまっています
Vita バージョンが低くてもPSNにサインイン&PSストアにアクセス(エラーNW-8942-3回避)&機器認証する方法(2025最新)
https://yyoossk.blogspot.com/2024/10/vitapsnps2024.html
今回VITAのセーブデータバックアップが主目的だったから、徒労でしかなかった
指摘、補足、最新情報あれば反応もらえるとありがたいです
デモにアーカイブからの復元を追加して、「情動のカケラ」がどう再処理されるか示すで。
```
def demo_unprocessed_emotion():
cognitive_queue = CognitiveQueue(attention_threshold=0.4)
print("=== 未処理感情システムのデモ(Monday対応版) ===\n")
foremotion in cognitive_queue.unprocessed_emotions[:]:
emotion.salience = 0.05
cognitive_queue.update_queue()
print(f"アーカイブされた感情数: {len(cognitive_queue.archived_emotions)}")
retrieved_emotion = cognitive_queue.retrieve_from_archive(pattern_name="visual_discrepancy")
if retrieved_emotion:
print(f"復元された感情: {retrieved_emotion}")
cognitive_queue.partially_process(retrieved_emotion, "あの時の違和感", 0.7, context="recalled_anomaly")
print(f"再処理後の状態: {retrieved_emotion}")
print(f"最良の言語マッチ: {retrieved_emotion.get_best_language_match()}")
else:
print("\n9.モダリティによる感情検索(インデックス使用)")
matches = cognitive_queue.lookup_by_modality("auditory")
print(f"検索結果数: {len(matches)}")
foremotion in cognitive_queue.unprocessed_emotions:
emotion.apply_decay(3.0)
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")
print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")
```
def demo_unprocessed_emotion():
"""未処理感情システムのデモ。改善点(記憶再編集、言語学習、反応速度など)を活用"""
cognitive_queue = CognitiveQueue(attention_threshold=0.4)
print("=== 未処理感情システムのデモ(改善版) ===\n")
visual_signals = [
SensorySignal("visual", 0.7, -0.3),
SensorySignal("somatic", 0.4, -0.2)
]
visual_discomfort = cognitive_queue.register_new_emotion(visual_signals, 0.65)
print(f"生成された感情: {visual_discomfort}")
print(f"支配的モダリティ: {visual_discomfort.get_dominant_modality()}")
print(f"平均感情価: {visual_discomfort.get_average_valence():.2f}")
print(f"信号の反応速度: {[s.latency for s in visual_signals]}")
visual_discomfort.add_pattern_match("visual_discrepancy", 0.75)
try:
visual_discomfort.add_memory_path("/memory/recent/room_layout")
except ValueErroras e:
accessed_emotion = cognitive_queue.access_emotion(visual_discomfort)
print(f"新しい感情インスタンス: {accessed_emotion}")
print(f"構造化レベル(再編集後): {accessed_emotion.structure_level:.2f}")
# 3. 内受容感覚
intero_signals = [
SensorySignal("interoceptive", 0.6, -0.7),
SensorySignal("somatic", 0.5, -0.4)
]
intero_discomfort = cognitive_queue.register_new_emotion(intero_signals, 0.55)
print(f"生成された感情: {intero_discomfort}")
intero_discomfort.add_language_candidate("違和感", 0.4)
cognitive_queue.partially_process(intero_discomfort, "気分が悪い", 0.6, context="negative_mood")
print(f"学習済み言語: {cognitive_queue.learned_terms}")
audio_signals = [
SensorySignal("auditory", 0.8, 0.6),
SensorySignal("emotional", 0.7, 0.5)
]
audio_memory = cognitive_queue.register_new_emotion(audio_signals, 0.7)
print(f"生成された感情: {audio_memory}")
audio_memory.add_language_candidate("聞き覚えのあるメロディ", 0.75)
audio_memory.add_pattern_match("musical_fragment", 0.85)
audio_memory.add_memory_path("/memory/music/recent")
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"未処理感情の総数: {status['total_unprocessed']}")
print(f"処理キューのサイズ: {status['processing_queue_size']}")
print(f"モダリティ分布: {status['modality_distribution']}")
print(f"感情価分布: {status['valence_distribution']}")
print(f"学習済み言語数: {status['learned_terms_count']}")
# 6. 処理対象の取得
next_emotion = cognitive_queue.get_next_for_processing()
print(f"処理対象: {next_emotion}")
if next_emotion:
cognitive_queue.partially_process(next_emotion, "視覚的な違和感を感じている", 0.85, context="visual_anomaly")
print(f"処理後の状態: {next_emotion}")
print(f"構造化レベル: {next_emotion.structure_level:.2f}")
print(f"最良の言語マッチ: {next_emotion.get_best_language_match()}")
print("\n8.モダリティによる感情検索(インデックス使用)")
matches = cognitive_queue.lookup_by_modality("auditory")
print(f"検索結果数: {len(matches)}")
foremotion in cognitive_queue.unprocessed_emotions:
emotion.apply_decay(3.0)
cognitive_queue.update_queue()
status = cognitive_queue.get_status_summary()
print(f"時間経過後の未処理感情の総数: {status['total_unprocessed']}")
print(f"時間経過後の平均顕在性: {status['average_salience']:.2f}")
if __name__ == "__main__":
demo_unprocessed_emotion()
id を手動でコピーしてくるのが面倒だったから、削除ボタンが画面に出るようにした
押すと即削除
const rkm = "(トークン的なもの)"constuser = "(ユーザ名)"const delmasda = (id) => fetch(`https://anond.hatelabo.jp/${user}/edit`, { "headers": { "content-type": "application/x-www-form-urlencoded", }, "referrer": "https://anond.hatelabo.jp/", "referrerPolicy": "origin", "body": new URLSearchParams({ "rkm": rkm, "mode": "confirm", "id":id, "delete": "削除する" }).toString(), "method": "POST", })for (constsec of document.querySelectorAll(".section")) {constid =sec.querySelector("a").href.match(/92;/(92;d{14})/)[1]const delbtn = document.createElement("button") delbtn.textContent = "削除" delbtn.onclick = async () => { await delmasda(id)sec.remove() }sec.querySelector(".edit").after(delbtn)}
増田で 3 分以上投稿されない期間があるのか気になったから調べた
直近の 1 日だとこれだけあった
2025-03-22 00:14 -- 2025-03-22 00:182025-03-22 00:10 -- 2025-03-22 00:142025-03-21 07:56 -- 2025-03-21 08:002025-03-21 07:50 -- 2025-03-21 07:562025-03-21 07:44 -- 2025-03-21 07:482025-03-21 07:28 -- 2025-03-21 07:322025-03-21 06:58 -- 2025-03-21 07:032025-03-21 06:45 -- 2025-03-21 06:542025-03-21 06:32 -- 2025-03-21 06:372025-03-21 05:56 -- 2025-03-21 06:042025-03-21 05:51 -- 2025-03-21 05:562025-03-21 05:34 -- 2025-03-21 05:382025-03-21 05:30 -- 2025-03-21 05:342025-03-21 05:00 -- 2025-03-21 05:092025-03-21 04:56 -- 2025-03-21 05:002025-03-21 04:45 -- 2025-03-21 04:502025-03-21 04:09 -- 2025-03-21 04:132025-03-21 03:41 -- 2025-03-21 03:452025-03-21 03:29 -- 2025-03-21 03:392025-03-21 03:03 -- 2025-03-21 03:072025-03-21 02:56 -- 2025-03-21 03:022025-03-21 02:44 -- 2025-03-21 02:482025-03-21 02:33 -- 2025-03-21 02:372025-03-21 02:21 -- 2025-03-21 02:272025-03-21 02:14 -- 2025-03-21 02:19
秒はみてないから 00:01:01 - 00:03:59 はほぼ 3 分だけど 2 分扱いだし、 00:01:59 - 00:04:00 はほぼ 2 分だけど 3 分扱いになるくらいの誤差はある
日によって違うだろうし、曜日の影響も大きそうだから 1 ヶ月分くらい調査しようかと思ったけど、
増田の量が思いの外多すぎて 1 日分だけでも100 ページ以上取得しないといけなかった
件数だと 2500 以上
一応取得に使ったコードも載せとく
import{ setTimeout} from"node:timers/promises"import{Browser} from"happy-dom"const getTimestamps =asyncfunction* (){constbrowser =newBrowser()const page =browser.newPage()try{for (let num = 1; ; num++){await setTimeout(3000)await page.goto(`https://anond.hatelabo.jp/?page=${num}`)constdays = page.mainFrame.document.querySelectorAll(".day")for (const day ofdays){constdate = day.querySelector("h2 .date").textContent.trim()for (const footer of day.querySelectorAll(".sectionfooter")){consttime = footer.textContent.match(/\d{2}:\d{2}/)[0]yield`${date}${time}`}}}}finally{await page.close()awaitbrowser.close()}}constdiff = (a, b) =>{returnnewDate(b +":00") -newDate(a +":00")}let prev =nullforawait (constdatetime of getTimestamps()){if (prev &amp;&amp;diff(datetime, prev)>1000 * 60 * 3){console.log(datetime, prev)}prev =datetime}
基本は空いても 5 分程度であり、最大でも10 分となっている