
はてなキーワード:bookmarkとは
昨日一番肝心なファイルなのにURLとみなされる部分が多いことの関係で投稿できなかったのでそれを小分けにして書く。
小分けというか例のスパムの影響でNGワードに引っかかっていたようなのでそこだけ書き換えた。
suuportと書いていある部分は元のコードでは当然uが一つ少ないので利用するときはそうすること。
fromselenium importwebdriver
fromselenium.webdriver.chrome.options import Options
fromselenium.webdriver.chrome.service import Service
fromwebdriver_manager.chrome importChromeDriverManager # ← 追加
fromselenium.webdriver.common.by importBy
fromselenium.webdriver.suupport.ui importWebDriverWait
fromselenium.webdriver.suupport import expected_conditionsasEC
importtime,json
fromselenium.common.exceptions importTimeoutException
class HatenaClient:
def __init__(self, username,password):
self.username = username
self.password =password
self.driver = None
def start_browser(self):
options = Options()
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
options.add_argument("--headless=new") # 開発中は消してよい
options.add_argument("--disable-gpu")
# ✅webdriver-manager を使ってChromeDriver を自動取得・設定
service = Service(ChromeDriverManager().install())
self.driver =webdriver.Chrome(service=service, options=options)
deflogin(self):
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)
self.driver.get("https://www.hatena.ne.jp/login")
time.sleep(2)
self.driver.find_element(By.NAME, "username").send_keys(self.username)
self.driver.find_element(By.NAME, "password").send_keys(self.password)
self.driver.find_element(By.XPATH, "//button[contains(text(), 'ログイン')]").click()
WebDriverWait(self.driver,10).until(lambda d: "my" in d.current_url or "login" not in d.current_url)
if "passkeys" in self.driver.current_url:
self.driver.get("https://b.hatena.ne.jp/my")
print(self.driver.current_url)
print(self.driver.title)
return "dorawii" in self.driver.current_url
defadd_bookmark(self, target_url):
self.driver.get(f"https://b.hatena.ne.jp/{self.username}/add.confirm?url={target_url}")
time.sleep(2)
try:
#コメントがあれば入力
comment_box = self.driver.find_element(By.CSS_SELECTOR, "textarea.bookmarkadd-comment-form")
comment_box.clear()
comment_box.send_keys("わしが書いた")
#登録ボタンを押す
save_button = self.driver.find_element(By.CSS_SELECTOR, "input.bookmarkadd-submit-btn")
save_button.click()
time.sleep(2)
returnTrue
except Exceptionas e:
print(f"Bookmark failed: {e}")
returnFalse
def quit(self):
self.driver.quit()
-----BEGINPGP SIGNEDMESSAGE-----
Hash: SHA512
https://anond.hatelabo.jp/20250822131958#
-----BEGINPGP SIGNATURE-----
iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaKfv9AAKCRBwMdsubs4+
SE26AQCkpJE4RdUbFIDIJjOunjFYRQ34zdS1cqV7IX277S7IPAEAshVE/rD8Ggcr
9UKo5yOY6GNrHGYJJtYTYkn3cySu6AA=
=E4vq
-----ENDPGP SIGNATURE-----
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-----
Japanese company'sdel.icio.usalternative celebrates20thanniversary this year
https://piefed.social/post/1140765
HatenaBookmark, a socialbookmarking servicebyHatena Inc. thatlaunchedonFebruary10,2005,is celebratingits20thanniversary this year.
The servicewas launchedas aJapanesealternative todel.icio.us,the world'snumberone socialbookmarking service, and evennow,20 years later,itisstill actively running, with hundreds of peoplebookmarking dozens of articles every day.
Incidentally,Hatena Inc., the company that operates this service,is world-famous forits workas theoutsourced administrator of the social media portion ofNintendo Co.,Ltd.'s FilipnoteStudio, and fordeveloping the "SplatNet" app forNintendo'sSplatoon series of games.
はてなブックマークをするときのリクエストの実体がわからない。
とりあえず保存するボタンを押した瞬間に作られるリクエストの送信先urlをurl:/api/で絞ったものの一覧がこれ。
どれ見てもコメントを格納してるっぽいリクエストが見つからない。
https://b.hatena.ne.jp/api/internal/bookmarks/shares_and_clicks
b.hatena.ne.jp/api/related_entries/https%3A%2F%2Fanond.hatelabo.jp%2F20250809150325
b.hatena.ne.jp/api/my/bookmark/https%3A%2F%2Fanond.hatelabo.jp%2F20250809150325
b.hatena.ne.jp/api/my/recommended_tags?url=https%3A%2F%2Fanond.hatelabo.jp%2F20250809150325
b.hatena.ne.jp/api/entry/https%3A%2F%2Fanond.hatelabo.jp%2F20250809150325/editing_ability
b.hatena.ne.jp/api/entry/https%3A%2F%2Fanond.hatelabo.jp%2F20250809150325/editing_ability
b.hatena.ne.jp/api/my/ignore_users?limit=10000
b.hatena.ne.jp/api/my/following_bookmarks
b.hatena.ne.jp/api/my/external/share_config
o148425.ingest.sentry.io/api/4504286861066240/envelope/?sentry_key=cbbc3ab77bbb42fa8c09ca0f1b7dc3cb&sentry_version=7&sentry_client=sentry.javascript.browser%2F7.47.0
-----BEGINPGP SIGNEDMESSAGE-----Hash: SHA512https://anond.hatelabo.jp/20250809200738# -----BEGINPGP SIGNATURE-----iHUEARYKAB0WIQTEe8eLwpVRSViDKR5wMdsubs4+SAUCaJcr+wAKCRBwMdsubs4+SLTYAP4pb8fMaDacP69j8aAlqgmTDqimUmU6I6bvh/yREFo7+AEAq2ibhp1t4MwKa+5esw/9FyuZavaPZ02HmmHMmLey+Aw==kEhJ-----ENDPGP SIGNATURE-----
栄養が大事だよという至極当たり前の主張をする増田に噛みつくブコメの頭の悪さにそりゃあその脳みそじゃ精神疾患にもなるわなって納得した。1に睡眠、2に栄養(以下略)って昔から言うだろ。
精神疾患治すのに、栄養が大事だよと伝えても、伝わらないのは何でですか..栄養が大事だよという至極当たり前の主張をする増田に噛みつくブコメの頭の悪さにそりゃあその脳みそじゃ精神疾患にもなるわなって納得した。1に睡眠、2に栄養(以下略)って昔から言うだろ。2025/08/01 08:36
精神疾患治すのに、栄養が大事だよと伝えても、伝わらないのは何でですか..医者が万能だと思ってるアホはなんなんだほんとなにもわかってないんだな2025/08/01 06:16
高卒で働いてて、転職したりなんやかやで周りがほぼ大卒の環境で働いてる ..こういうのもそうだけど「クリスマスなのに男(女)同士で鬱」とか、言ってるだけだよね。別に鬱でもない。被害妄想というか、ただの常套句。もうやめた方がいいと思う。2025/07/2910:41
なんだこいつ
「選挙に行かない人」を叩く違和感権利を行使しないことは自由だけど、それを声高に言いふらすことは誉められたものではない。投票しないことで不利益生じても文句言えないよ。2025/07/13 13:12
「選挙に行かない人」を叩く違和感叩いてないよー。選挙なんて行かないとわざわざ公言するような人がいたら、残念なやつだなと思って内心見下すくらいだよ。2025/07/13 13:14
「選挙に行かない人」を叩く違和感行かないなら、政治や社会に文句言うなよ、とは思う2025/07/13 13:33
きょうだい格差のやつ見て思い出した。mkotatsu下の方が要領良いい子を育ててると、上の子それくらい一人でやれよ…て内心よく思う。多分疲れた顔してしまってる / 下の子も担任が送ってくれたかもしれんのに、実は妄想で拗ねてることに気づいてるんだろうか2025/07/09 19:31
きょうだい格差のやつ見て思い出した。タイミングの問題でしょ。中学校から先に電話がきていたら迎えに行ってたと思うよ。おかあさんが好きなのだったら、基本的に大事にされていたのでしょ。2025/07/09 07:00
きょうだい格差のやつ見て思い出した。いずれ増田に2人の娘が出来て2人揃ってインフルエンザだと両方の学校から同時に連絡があったらその時やっと増田は「選ばなければならない」ことの意味を魂で理解するのだろう2025/07/09 07:18
きょうだい格差のやつ見て思い出した。”母は妹のことは学校まで迎えに行ったんだなあって思う。”←思う?増田がそう思ってるだけなの?普段から妹ばかりという気持ちには同情するけど、インフルエンザの件は被害妄想入ってるような。2025/07/0910:20
きょうだい格差のやつ見て思い出した。先に生まれた方は自分が大事にされてる場面を物理的に見られないが、下の子のそういう場面は見る機会があるから不公平に感じてしまうのかも?2025/07/0910:21