{
  "version": "1.0.0",
  "exported_at": "2026-05-31T00:00:00.000Z",
  "project": {
    "name": "Xiaohongshu Scraper",
    "description": "Best-effort Xiaohongshu / RedNote scraper for xiaohongshu.com search/listing results. Extracts post title, cover image URL, post URL, author/account name, author profile URL, and like count, matching the Octoparse Xiaohongshu search/hashtag template descriptions. Xiaohongshu frequently requires login, CAPTCHA, trusted browser state, or blocks automated browsing. This template loads a generic Xiaohongshu search URL, performs finite infinite-scroll loading, checks whether post cards/links are present, exports post rows when available, and otherwise writes a diagnostic row to xiaohongshu-scraper.csv explaining that the page was likely blocked or empty.",
    "color": "bg-[#ff832b]",
    "template_id": "ai-generated"
  },
  "blocks": [
    {
      "block_id": "set-window-size-1",
      "block_type": "process",
      "title": "Set Window Size",
      "description": "Set browser window dimensions",
      "position_x": 120,
      "position_y": 180,
      "config": {
        "width": 1920,
        "height": 1080,
        "color": "bg-[#4589ff]"
      }
    },
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 480,
      "position_y": 180,
      "config": {
        "url": "https://www.xiaohongshu.com/search_result?keyword=%E6%97%85%E8%A1%8C",
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "wait-for-page-load-1",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 840,
      "position_y": 180,
      "config": {
        "timeout": 45,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1200,
      "position_y": 180,
      "config": {
        "selector": "body",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1560,
      "position_y": 180,
      "config": {
        "duration": 6,
        "color": "bg-[#08bdba]"
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript",
      "position_x": 1920,
      "position_y": 180,
      "config": {
        "jsCode": "(() => {\n  window.scrollTo(0, 0);\n  const possibleButtons = Array.from(document.querySelectorAll('button, [role=\"button\"], .close, [class*=\"close\"], [class*=\"Close\"]'));\n  for (const el of possibleButtons) {\n    const txt = (el.innerText || el.textContent || el.getAttribute('aria-label') || '').trim().toLowerCase();\n    if (txt === 'accept' || txt === 'close' || txt.includes('同意') || txt.includes('关闭') || txt.includes('知道了')) {\n      try { el.click(); } catch (e) {}\n    }\n  }\n  return true;\n})()",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#a56eff]"
      }
    },
    {
      "block_id": "scroll-1",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll page or element",
      "position_x": 2280,
      "position_y": 520,
      "config": {
        "direction": "down",
        "amount": 1800,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 2640,
      "position_y": 520,
      "config": {
        "duration": 4,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "scroll-2",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll page or element",
      "position_x": 3000,
      "position_y": 520,
      "config": {
        "direction": "down",
        "amount": 1800,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "sleep-3",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3360,
      "position_y": 520,
      "config": {
        "duration": 4,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "scroll-3",
      "block_type": "process",
      "title": "Scroll",
      "description": "Scroll page or element",
      "position_x": 3720,
      "position_y": 520,
      "config": {
        "direction": "down",
        "amount": 1800,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "sleep-4",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 4080,
      "position_y": 520,
      "config": {
        "duration": 4,
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 4440,
      "position_y": 360,
      "config": {
        "selector": "a[href*=\"/explore/\"], section.note-item, div.note-item, .feeds-container [class*=\"note\"], [class*=\"NoteItem\"]",
        "color": "bg-[#ff832b]"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 4800,
      "position_y": 180,
      "config": {
        "rowSelector": "a[href*=\"/explore/\"], section.note-item, div.note-item, .feeds-container [class*=\"note\"], [class*=\"NoteItem\"]",
        "fileName": "xiaohongshu-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "create",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "post_title",
            "selector": "(() => { const root = ROW.closest?.('section, article, div[class*=\"note\"], div[class*=\"Note\"], div[class*=\"card\"], div[class*=\"Card\"]') || ROW; const el = root.querySelector?.('.title, .note-title, [class*=\"title\"], [class*=\"Title\"], span, img[alt]'); const val = el?.getAttribute?.('alt') || el?.innerText || el?.textContent || ROW.getAttribute?.('title') || ROW.getAttribute?.('aria-label') || root.innerText || ''; return val.trim().split('\\n').map(s => s.trim()).filter(Boolean)[0] || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "post_url",
            "selector": "(() => { const a = ROW.matches?.('a[href*=\"/explore/\"]') ? ROW : ROW.querySelector?.('a[href*=\"/explore/\"]') || ROW.closest?.('a[href*=\"/explore/\"]'); const href = a?.getAttribute?.('href') || ''; try { return href ? new URL(href, location.origin).href : ''; } catch(e) { return href; } })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "image_url",
            "selector": "(() => { const root = ROW.closest?.('section, article, div[class*=\"note\"], div[class*=\"Note\"], div[class*=\"card\"], div[class*=\"Card\"]') || ROW; const img = root.querySelector?.('img'); const src = img?.currentSrc || img?.src || img?.getAttribute?.('data-src') || img?.getAttribute?.('src') || ''; try { return src ? new URL(src, location.origin).href : ''; } catch(e) { return src; } })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "author_name",
            "selector": "(() => { const root = ROW.closest?.('section, article, div[class*=\"note\"], div[class*=\"Note\"], div[class*=\"card\"], div[class*=\"Card\"]') || ROW; const el = root.querySelector?.('.author-wrapper .name, .author .name, a[href*=\"/user/profile/\"] span, a[href*=\"/user/profile/\"], .name, [class*=\"author\"], [class*=\"Author\"], [class*=\"user\"], [class*=\"User\"]'); return (el?.innerText || el?.textContent || el?.getAttribute?.('title') || '').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "author_url",
            "selector": "(() => { const root = ROW.closest?.('section, article, div[class*=\"note\"], div[class*=\"Note\"], div[class*=\"card\"], div[class*=\"Card\"]') || ROW; const a = root.querySelector?.('a[href*=\"/user/profile/\"], a[href*=\"/profile/\"]'); const href = a?.getAttribute?.('href') || ''; try { return href ? new URL(href, location.origin).href : ''; } catch(e) { return href; } })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "like_count",
            "selector": "(() => { const root = ROW.closest?.('section, article, div[class*=\"note\"], div[class*=\"Note\"], div[class*=\"card\"], div[class*=\"Card\"]') || ROW; const candidates = Array.from(root.querySelectorAll?.('.like-wrapper .count, .like .count, .count, [class*=\"like\"], [class*=\"Like\"], [class*=\"count\"], [class*=\"Count\"]') || []); for (const el of candidates) { const t = (el.innerText || el.textContent || '').trim(); if (/^\\d+(\\.\\d+)?[万kK]?$/.test(t) || /赞|like/i.test(t)) return t; } const all = (root.innerText || '').split('\\n').map(s => s.trim()).filter(Boolean); return all.find(t => /^\\d+(\\.\\d+)?[万kK]?$/.test(t)) || ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "structured-export-2",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 4800,
      "position_y": 660,
      "config": {
        "rowSelector": "body",
        "fileName": "xiaohongshu-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "create",
        "color": "bg-[#42be65]",
        "columns": [
          {
            "name": "post_title",
            "selector": "(() => document.title || 'No Xiaohongshu post cards found')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "post_url",
            "selector": "(() => location.href)()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "image_url",
            "selector": "(() => { const img = document.querySelector('img'); return img?.currentSrc || img?.src || img?.getAttribute('data-src') || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "author_name",
            "selector": "(() => '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "author_url",
            "selector": "(() => '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "like_count",
            "selector": "(() => '')()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "extraction_status",
            "selector": "(() => { const text = (document.body.innerText || '').slice(0, 3000); if (/验证码|captcha|验证/i.test(text)) return 'Blocked by CAPTCHA or verification page; log in or use a trusted browser profile.'; if (/登录|login|sign in/i.test(text)) return 'Login prompt detected; Xiaohongshu requires authentication or trusted session before post cards are visible.'; if (/安全|异常|risk|blocked|访问受限/i.test(text)) return 'Access appears restricted by Xiaohongshu anti-bot controls.'; return 'No Xiaohongshu post card selectors were found after scrolling; page may be empty, changed, geo-blocked, or dynamically blocked.'; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "page_text_sample",
            "selector": "(() => (document.body.innerText || '').replace(/\\s+/g, ' ').trim().slice(0, 500))()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 5160,
      "position_y": 180,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    },
    {
      "block_id": "end-2",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 5160,
      "position_y": 660,
      "config": {
        "color": "bg-[#8d8d8d]"
      }
    }
  ],
  "connections": [
    {
      "from_block_id": "set-window-size-1",
      "from_connector_id": "right",
      "to_block_id": "navigate-1",
      "to_connector_id": "left"
    },
    {
      "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": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-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": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "inject-javascript-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": "scroll-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-2",
      "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-3",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "scroll-3",
      "from_connector_id": "right",
      "to_block_id": "sleep-4",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-4",
      "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": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "structured-export-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "from_connector_id": "right",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-2",
      "from_connector_id": "right",
      "to_block_id": "end-2",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-entry",
      "element_type": "group",
      "title": "Entry & Setup",
      "color": "#4589ff",
      "position_x": 48,
      "position_y": 76,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "set-window-size-1"
        ]
      }
    },
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 408,
      "position_y": 76,
      "width": 3920,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "sleep-1",
          "sleep-2",
          "sleep-3",
          "sleep-4"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1848,
      "position_y": 76,
      "width": 2120,
      "height": 636,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "scroll-1",
          "scroll-2",
          "scroll-3"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 4368,
      "position_y": 256,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 4728,
      "position_y": 76,
      "width": 380,
      "height": 776,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1",
          "structured-export-2"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 5088,
      "position_y": 76,
      "width": 380,
      "height": 776,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1",
          "end-2"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Best-effort Xiaohongshu / RedNote scraper for xiaohongshu.com search/listing results. Extracts post title, cover image URL, post URL, author/account name, author profile URL, and like count, matching the Octoparse Xiaohongshu search/hashtag template descriptions. Xiaohongshu frequently requires login, CAPTCHA, trusted browser state, or blocks automated browsing. This template loads a generic Xiaohongshu search URL, performs finite infinite-scroll loading, checks whether post cards/links are present, exports post rows when available, and otherwise writes a diagnostic row to xiaohongshu-scraper.csv explaining that the page was likely blocked or empty.",
      "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: `(() => {\n  window.scrollTo(0, 0);\n  const possibleButtons = Array.from(document.querySelectorAll('bu...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 2120,
      "position_y": 160,
      "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 `a[href*=\"/explore/\"], section.note-item, div.note-item, .feeds-container [class*=\"note\"], [class*=\"NoteItem\"]`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 4640,
      "position_y": 340,
      "width": 340,
      "height": 166,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (post_title, post_url, image_url, author_name, author_url). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 5000,
      "position_y": 160,
      "width": 340,
      "height": 132,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-structured-export-2",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (post_title, post_url, image_url, author_name, author_url). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 5000,
      "position_y": 640,
      "width": 340,
      "height": 132,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-2"
      }
    }
  ]
}