您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自動滾動頁面,點擊"続きを読む"、"スタンプページへ"、"スタンプ/ポイント確認"、"戻る"按鈕,並在特定首頁點擊第一個文章連結。
// ==UserScript== // @name NewsFan.jp 自動翻頁和點擊 // @namespace http://tampermonkey.net/ // @version 1.5 // @description 自動滾動頁面,點擊"続きを読む"、"スタンプページへ"、"スタンプ/ポイント確認"、"戻る"按鈕,並在特定首頁點擊第一個文章連結。 // @author lchanc3 // @homepage https://github.com/lchanc3/userscript // @supportURL https://github.com/lchanc3/userscript/issues // @match *://*.trepy.jp/* // @match *://*.life-n.jp/* // @match *://*.point-news.jp/* // @grant none // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // --- 配置 --- const SCROLL_INTERVAL = 200; const BUTTON_CHECK_INTERVAL = 300; const MAX_SCROLL_ATTEMPTS = 10; const STAMP_PAGE_BUTTON_CHECK_INTERVAL = 500; // Page 2 按鈕檢查頻率 const END_PAGE_BUTTON_CHECK_INTERVAL = 500; const HOMEPAGE_LINK_CHECK_INTERVAL = 1000; // 首頁連結檢查頻率 const HOMEPAGE_CHECK_TIMEOUT = 15000; // 首頁連結檢查超時 (15秒) // 目標首頁域名列表 const TARGET_HOMEPAGE_HOSTS = [ 'www.trepy.jp', 'www.life-n.jp', 'point-news.jp' ]; const TARGET_HOMEPAGE_PATH = '/sp/'; // --- 輔助函數 --- function log(message, ...args) { console.log(`[AutoScript v0.8] ${message}`, ...args); } // --- 頁面 1: 滾動頁面邏輯 (article/?article_id=...) --- function handleScrollingPage() { log("正在處理滾動頁面 (article)..."); let lastHeight = 0; let scrollAttempts = 0; let scrollLoop = null; let clickLoop = null; function stopScrollLoop() { if (scrollLoop) { clearInterval(scrollLoop); scrollLoop = null; log("滾動檢查已停止。"); } } function stopClickLoop() { if (clickLoop) { clearInterval(clickLoop); clickLoop = null; log("按鈕/連結檢查已停止 (滾動頁面)。"); } } function autoScroll() { if (scrollLoop) return; // 防止重複創建 log("啟動滾動檢查..."); scrollLoop = setInterval(() => { let currentHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); window.scrollTo(0, currentHeight); if (currentHeight === lastHeight) { scrollAttempts++; if (scrollAttempts >= MAX_SCROLL_ATTEMPTS) { log("已達滾動底部或無法再滾動 (嘗試次數: " + scrollAttempts + ")。"); stopScrollLoop(); if (!clickLoop) { // 如果按鈕檢查也停了,重啟以查找 stampLink findAndClickButtons(); } } } else { // log("滾動中...", currentHeight); scrollAttempts = 0; } lastHeight = currentHeight; }, SCROLL_INTERVAL); } function findAndClickButtons() { if (clickLoop) return; // 防止重複創建 log("啟動按鈕/連結檢查 (滾動頁面)..."); clickLoop = setInterval(() => { // 1. 檢查 "続きを読む" 按鈕 let readMoreButton = document.querySelector('[class^="btnNext"]'); if (readMoreButton && readMoreButton.offsetParent !== null) { log("發現按鈕「続きを読む」,正在點擊...", readMoreButton.className); readMoreButton.click(); scrollAttempts = 0; // 重置滾動嘗試 if (scrollLoop === null) { // 如果滾動已停止,重新啟動 log("重新啟動滾動檢查 (因點擊続きを読む)。"); autoScroll(); } // 不需要停止 clickLoop,因為可能還有多個 "続きを読む" return; } // 2. 檢查 "スタンプページへ" 連結 // 只有在滾動確實停止後才尋找此連結 if (scrollLoop === null) { let stampLink = document.querySelector('.button_stamp a'); if (stampLink && stampLink.offsetParent !== null) { log("滾動結束,找到「スタンプページへ」連結,準備跳轉...", stampLink.href); stopClickLoop(); // 找到目標,停止此頁所有檢查 log("停止計時器,執行頁面跳轉至 Stamp 頁。"); window.location.href = stampLink.href; return; } } // 如果滾動停止了,但 "続きを読む" 和 "スタンプページへ" 都沒找到 (或 "スタンプページへ" 時機未到) if (scrollLoop === null && !readMoreButton) { // stampLink 的檢查已包含在 scrollLoop === null 條件內 log("滾動結束且未找到目標按鈕/連結「続きを読む」或「スタンプページへ」,停止按鈕檢查。"); stopClickLoop(); } }, BUTTON_CHECK_INTERVAL); } autoScroll(); findAndClickButtons(); } // --- 頁面 2: Stamp/Point Action 頁面邏輯 (article/page/?article_id=...) --- function handleStampPage() { log("正在處理 Stamp/Point Action 頁面 (article/page)..."); let checkPageButtonLoop = null; function findAndClickPageButton() { checkPageButtonLoop = setInterval(() => { // **優先檢查** 新的 Point 按鈕 (btn_point.png) const pointImage = document.querySelector('.btn_area img[src*="btn_point.png"]'); const pointButtonLink = pointImage ? pointImage.closest('a') : null; if (pointButtonLink && pointButtonLink.offsetParent !== null) { log("發現 Point 按鈕/連結 (btn_point.png),準備點擊...", pointButtonLink.href); clearInterval(checkPageButtonLoop); log("停止計時器,執行點擊 (Point)。"); pointButtonLink.click(); return; } // 如果沒找到 Point 按鈕,再檢查原始的 Stamp 按鈕 (btn_stamp.png) const stampImage = document.querySelector('.btn_area img[src*="btn_stamp.png"]'); const stampButtonLink = stampImage ? stampImage.closest('a') : null; if (stampButtonLink && stampButtonLink.offsetParent !== null) { log("發現 Stamp 確認按鈕/連結 (btn_stamp.png),準備點擊...", stampButtonLink.href); clearInterval(checkPageButtonLoop); log("停止計時器,執行點擊 (Stamp)。"); stampButtonLink.click(); return; } // log("未找到 Point 或 Stamp 按鈕,繼續檢查..."); }, STAMP_PAGE_BUTTON_CHECK_INTERVAL); setTimeout(() => { if (checkPageButtonLoop) { clearInterval(checkPageButtonLoop); log("Stamp/Point 頁面按鈕檢查超時,已停止。"); } }, 30000); // 30 秒 } findAndClickPageButton(); } // --- 頁面 3: 結束頁面邏輯 (article/page-end/?article_id=...) --- function handleEndPage() { log("正在處理結束頁面 (article/page-end)..."); let checkEndButtonLoop = null; function findAndClickEndButton() { checkEndButtonLoop = setInterval(() => { const endButtonImage = document.querySelector('.btn_com img[src*="btn_return.png"]'); const endButtonLink = endButtonImage ? endButtonImage.closest('a') : null; if (endButtonLink && endButtonLink.offsetParent !== null) { log("發現結束頁面按鈕/連結 (btn_return.png),準備點擊...", endButtonLink.href); clearInterval(checkEndButtonLoop); log("停止計時器,執行點擊。"); endButtonLink.click(); } else { // log("未找到結束頁面按鈕,繼續檢查..."); } }, END_PAGE_BUTTON_CHECK_INTERVAL); setTimeout(() => { if (checkEndButtonLoop) { clearInterval(checkEndButtonLoop); log("結束頁面按鈕檢查超時,已停止。"); } }, 30000); } findAndClickEndButton(); } // --- 新功能: 首頁邏輯 (特定網站的 /sp/ 路徑) --- function handleHomepage() { log("正在處理首頁 (特定網站 /sp/)..."); let checkHomepageLinkLoop = null; let homepageCheckTimeoutTimer = null; function findAndClickFirstArticle() { // 更新後的選擇器: // 選擇 div 元素且 class 為 "pon_article_inner",然後選擇其直接子元素 a, // 且 a 標籤的 href 包含 "/sp/article/?article_id=" const firstArticleLink = document.querySelector('div.pon_article_inner > a[href*="/sp/article/?article_id="]'); if (firstArticleLink && firstArticleLink.offsetParent !== null) { log("在首頁找到第一個文章連結,準備點擊:", firstArticleLink.href); if (checkHomepageLinkLoop) clearInterval(checkHomepageLinkLoop); if (homepageCheckTimeoutTimer) clearTimeout(homepageCheckTimeoutTimer); log("停止計時器,執行點擊首頁文章連結。"); firstArticleLink.click(); } else { log("首頁未找到可見的文章連結 (div.pon_article_inner > a),繼續檢查..."); } } // 使用 setInterval 進行檢查,因為元素可能延遲載入 checkHomepageLinkLoop = setInterval(findAndClickFirstArticle, HOMEPAGE_LINK_CHECK_INTERVAL); // 設定超時,如果在一定時間内未找到連結,則停止檢查 homepageCheckTimeoutTimer = setTimeout(() => { if (checkHomepageLinkLoop) { clearInterval(checkHomepageLinkLoop); log("首頁文章連結檢查超時,已停止。"); } }, HOMEPAGE_CHECK_TIMEOUT); // 立即執行一次檢查,避免等待第一個 interval findAndClickFirstArticle(); } // --- 主邏輯:根據當前 URL 決定執行哪個函數 --- const currentHref = window.location.href; const currentHostname = window.location.hostname; const currentPath = window.location.pathname; const currentSearch = window.location.search; log("腳本啟動。當前 URL:", currentHref); // 判斷頁面類型 if (TARGET_HOMEPAGE_HOSTS.includes(currentHostname) && currentPath === TARGET_HOMEPAGE_PATH) { handleHomepage(); // 首頁處理 } else if (currentPath.includes('/sp/article/') && currentSearch.startsWith('?article_id=')) { if (currentPath.includes('/page-end/')) { handleEndPage(); // Page 3 } else if (currentPath.includes('/page/')) { handleStampPage(); // Page 2 (處理 Stamp 或 Point) } else if (currentPath === '/sp/article/') { // 確保是 /sp/article/ 而不是 /sp/article/page/ handleScrollingPage(); // Page 1 } else { log("當前頁面路徑包含 /sp/article/ 但不完全匹配已知規則,不執行操作。路徑:", currentPath); } } else { log("當前頁面不符合任何已定義的處理規則。"); } })();