{
  "version": "1.0.0",
  "exported_at": "2026-05-31T23:55:00.000Z",
  "project": {
    "name": "Yahoo News Comments Scraper",
    "description": "Best-effort Yahoo!ニュース comments scraper equivalent to the Octoparse Yahoo News Comments template. Accepts multiple Yahoo News article URLs, redirects valid article pages to /comments, attempts to expand Japanese load-more/next controls, then exports article title, URL, parent comment author/time/text/reactions, and reply author/time/text/reactions. The attached sample URLs currently return Yahoo 404/deleted article pages; for those cases the template exports a diagnostic row instead of silently producing no CSV.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 220,
      "config": {
        "urls": [
          "https://news.yahoo.co.jp/articles/48b080831b4df67a25de7f8f918f06d6f7829205",
          "https://news.yahoo.co.jp/articles/af81fce4eba55e79dd002a21acb8b81989681e9c"
        ],
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 456,
      "position_y": 220,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 792,
      "position_y": 220,
      "config": {
        "jsCode": "(function(){var p=location.pathname;if(/^\\/articles\\/[^\\/]+$/.test(p)){location.href=location.origin+p+'/comments';}return true;})();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1128,
      "position_y": 220,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 1464,
      "position_y": 220,
      "config": {
        "timeout": 30
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1800,
      "position_y": 220,
      "config": {
        "selector": "body",
        "timeout": 30,
        "visible": true
      }
    },
    {
      "block_id": "scroll-1",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll the page or element",
      "position_x": 2136,
      "position_y": 220,
      "config": {
        "direction": "down",
        "amount": 1400
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2472,
      "position_y": 220,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2808,
      "position_y": 220,
      "config": {
        "selector": "(//button[not(@disabled) and (contains(normalize-space(.), 'もっと見る') or contains(normalize-space(.), 'さらに表示') or contains(normalize-space(.), '次へ'))] | //a[(contains(normalize-space(.), 'もっと見る') or contains(normalize-space(.), 'さらに表示') or contains(normalize-space(.), '次へ')) and not(contains(@aria-disabled, 'true')) and not(contains(@class, 'disabled'))])[1]"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 3144,
      "position_y": 520,
      "config": {
        "selector": "(//button[not(@disabled) and (contains(normalize-space(.), 'もっと見る') or contains(normalize-space(.), 'さらに表示') or contains(normalize-space(.), '次へ'))] | //a[(contains(normalize-space(.), 'もっと見る') or contains(normalize-space(.), 'さらに表示') or contains(normalize-space(.), '次へ')) and not(contains(@aria-disabled, 'true')) and not(contains(@class, 'disabled'))])[1]",
        "timeout": 10
      }
    },
    {
      "block_id": "sleep-3",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3480,
      "position_y": 520,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 2808,
      "position_y": 520,
      "config": {
        "jsCode": "(function(){document.querySelectorAll('[data-uscraper-comment-row=\"1\"]').forEach(function(e){e.remove();});var clean=function(s){return (s||'').replace(/\\s+/g,' ').trim();};var meta=function(sel){var e=document.querySelector(sel);return e?e.getAttribute('content')||'':'';};var article=clean((document.querySelector('h1')||{}).textContent)||clean(meta('meta[property=\"og:title\"]'))||clean(document.title);var url=location.href.replace(/\\/comments(?:[?#].*)?$/,'');var bodyText=clean(document.body?document.body.innerText:'');var isNotFound=/指定されたURLは存在しません|URLが正しく入力されていない|ページが削除/.test(bodyText);var labels=['共感した','なるほど','うーん'];var timeRe=/(たった今|[0-9０-９]+\\s*(分|時間|日|週間|か月|ヶ月|年)前|昨日|一昨日)/;var navRe=/トップ|速報|ライブ|エキスパート|オリジナル|ランキング|ログイン|プライバシー|Yahoo!ニューストップへ|ヘルプ|利用規約/;function visible(el){var r=el.getBoundingClientRect();var st=getComputedStyle(el);return r.width>0&&r.height>0&&st.display!=='none'&&st.visibility!=='hidden';}function hasSignals(el){var t=clean(el.innerText||el.textContent);return t.length>35&&t.length<8000&&timeRe.test(t)&&labels.some(function(l){return t.indexOf(l)>-1;})&&!navRe.test(t);}var raw=Array.from(document.querySelectorAll('li, article, [role=\"article\"], section, div')).filter(function(el){return visible(el)&&hasSignals(el);});var nodes=raw.filter(function(el){return !raw.some(function(other){return other!==el&&el.contains(other)&&hasSignals(other)&&clean(other.innerText||other.textContent).length>35;});});function parse(el){var rawText=el.innerText||el.textContent||'';var text=clean(rawText);var lines=rawText.split(/[\\n\\r]+/).map(clean).filter(Boolean);var tm=text.match(timeRe);var time=tm?tm[0]:'';var author='';for(var i=0;i<lines.length;i++){var ln=lines[i];if(ln!==time&&ln.length>0&&ln.length<=40&&!labels.some(function(l){return ln.indexOf(l)>-1;})&&!/返信|表示|もっと見る|シェア|報告|コメント/.test(ln)&&!/^[0-9０-９,，]+$/.test(ln)){author=ln;break;}}var reactions={};labels.forEach(function(l){var m=text.match(new RegExp(l+'\\\\s*([0-9０-９,，]+)'));if(!m){m=text.match(new RegExp('([0-9０-９,，]+)\\\\s*'+l));}reactions[l]=m?m[1].replace(/[，,]/g,''):'';});var commentLines=lines.filter(function(ln){return ln!==author&&ln!==time&&!labels.some(function(l){return ln.indexOf(l)>-1;})&&!/返信|表示|もっと見る|さらに表示|シェア|報告|コメントを書く/.test(ln)&&!/^[0-9０-９,，]+$/.test(ln);});var comment=clean(commentLines.join(' '));return {author:author,time:time,comment:comment,like:reactions['共感した'],naruhodo:reactions['なるほど'],uun:reactions['うーん']};}var rows=[];nodes.forEach(function(n){var parent=null;var p=n.parentElement;while(p){if(nodes.indexOf(p)>-1){parent=p;break;}p=p.parentElement;}if(parent){rows.push({main:parse(parent),reply:parse(n)});}else{rows.push({main:parse(n),reply:null});}});var seen={};rows=rows.filter(function(r){var k=[r.main.author,r.main.time,r.main.comment,r.reply?r.reply.author:'',r.reply?r.reply.comment:''].join('|');if(seen[k]){return false;}seen[k]=true;return r.main.comment||r.reply;});if(rows.length===0){rows.push({main:{author:'',time:'',comment:isNotFound?'NO_COMMENTS_FOUND: Yahoo returned a deleted/not-found article page for this URL.':'NO_COMMENTS_FOUND: No visible Yahoo News comments were detected; comments may be disabled, behind CAPTCHA/login, or markup changed.',like:'',naruhodo:'',uun:''},reply:null});}var root=document.createElement('div');root.id='uscraper-normalized-comments';root.style.display='none';rows.forEach(function(o){var d=document.createElement('div');d.setAttribute('data-uscraper-comment-row','1');var attrs={article:article,url:url,id:o.main.author,time:o.main.time,comment:o.main.comment,like:o.main.like,naruhodo:o.main.naruhodo,uun:o.main.uun,reply_id:o.reply?o.reply.author:'',reply_time:o.reply?o.reply.time:'',reply:o.reply?o.reply.comment:'',reply_like:o.reply?o.reply.like:'',reply_naruhodo:o.reply?o.reply.naruhodo:'',reply_uun:o.reply?o.reply.uun:''};Object.keys(attrs).forEach(function(k){d.setAttribute('data-'+k,clean(attrs[k]));});root.appendChild(d);});document.body.appendChild(root);return rows.length;})();",
        "waitForCompletion": true,
        "timeout": 10
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 3312,
      "position_y": 800,
      "config": {
        "rowSelector": "[data-uscraper-comment-row=\"1\"]",
        "fileName": "yahoo-news-comments-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "Article",
            "selector": "",
            "attribute": "data-article"
          },
          {
            "name": "URL",
            "selector": "",
            "attribute": "data-url"
          },
          {
            "name": "ID",
            "selector": "",
            "attribute": "data-id"
          },
          {
            "name": "Time",
            "selector": "",
            "attribute": "data-time"
          },
          {
            "name": "Comment",
            "selector": "",
            "attribute": "data-comment"
          },
          {
            "name": "共感した",
            "selector": "",
            "attribute": "data-like"
          },
          {
            "name": "なるほど",
            "selector": "",
            "attribute": "data-naruhodo"
          },
          {
            "name": "うーん",
            "selector": "",
            "attribute": "data-uun"
          },
          {
            "name": "Reply_ID",
            "selector": "",
            "attribute": "data-reply_id"
          },
          {
            "name": "Reply_Time",
            "selector": "",
            "attribute": "data-reply_time"
          },
          {
            "name": "Reply",
            "selector": "",
            "attribute": "data-reply"
          },
          {
            "name": "Reply_共感した",
            "selector": "",
            "attribute": "data-reply_like"
          },
          {
            "name": "Reply_なるほど",
            "selector": "",
            "attribute": "data-reply_naruhodo"
          },
          {
            "name": "Reply_うーん",
            "selector": "",
            "attribute": "data-reply_uun"
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 3648,
      "position_y": 800,
      "config": {}
    }
  ],
  "connections": [
    {
      "from_block_id": "navigate-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-1",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-page-load-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-page-load-2",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-1",
      "from_connector_id": "right",
      "to_block_id": "scroll-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "element-exists-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "true",
      "to_block_id": "click-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-1",
      "from_connector_id": "right",
      "to_block_id": "sleep-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-3",
      "from_connector_id": "right",
      "to_block_id": "scroll-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "inject-javascript-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-2",
      "from_connector_id": "right",
      "to_block_id": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "loop-continue-1",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 48,
      "position_y": 116,
      "width": 3680,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "sleep-1",
          "wait-for-page-load-2",
          "wait-for-element-1",
          "sleep-2",
          "sleep-3"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 720,
      "position_y": 116,
      "width": 2336,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "scroll-1",
          "inject-javascript-2"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 2736,
      "position_y": 116,
      "width": 1160,
      "height": 876,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 3240,
      "position_y": 696,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Yahoo!ニュース comments scraper equivalent to the Octoparse Yahoo News Comments template. Accepts multiple Yahoo News article URLs, redirects valid article pages to /comments, attempts to expand Japanese load-more/next controls, then exports article title, URL, parent comment author/time/text/reactions, and reply author/time/text/reactions. The attached sample URLs currently return Yahoo 404/deleted article pages; for those cases the template exports a diagnostic row instead of silently producing no CSV.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(function(){var p=location.pathname;if(/^\\/articles\\/[^\\/]+$/.test(p)){location.href=location.origin...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 992,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `(//button[not(@disabled) and (contains(normalize-space(.), 'もっと見る') or contains(normalize-space(.), 'さらに表示') or contains`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 200,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-inject-javascript-2",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(function(){document.querySelectorAll('[data-uscraper-comment-row=\"1\"]').forEach(function(e){e.remov...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 3008,
      "position_y": 500,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-2"
      }
    },
    {
      "id": "note-block-loop-continue-1",
      "element_type": "note",
      "title": "Note: Loop Continue",
      "content": "Loop Continue advances a multi-URL or multi-text loop. Place at the end of the loop body with a clear back-edge to the loop start.",
      "color": "#ee5396",
      "position_x": 3848,
      "position_y": 780,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}