{
  "version": "1.0.0",
  "exported_at": "2026-06-03T07:20:00.000Z",
  "project": {
    "name": "Google Ads Scraper by Urls",
    "description": "Extracts Google Ads Transparency Center ad detail data by URL list, including advertiser, page URL, last shown date, format, variation number, region, impressions, image/video URLs, headline, description, and error status. Uses navigate.urls[] plus loop-continue to process all supplied URLs, and a variation pagination loop to click the next creative variation when an enabled next arrow is present. Best-effort: Google may require sign-in, rate-limit, remove creatives, render ad text inside images/media, or change its Angular DOM; when headline/description are not exposed in the DOM, the Error column explains the limitation.",
    "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://adstransparency.google.com/advertiser/AR12174930187514806273/creative/CR05909607835150319617?region=SI",
          "https://adstransparency.google.com/advertiser/AR12174930187514806273/creative/CR05909607835150319617?region=PL",
          "https://adstransparency.google.com/advertiser/AR12174930187514806273/creative/CR03063857217439531009?region=IE"
        ],
        "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": 480,
      "position_y": 220,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-text-1",
      "block_type": "process",
      "title": "Wait for Text",
      "description": "Wait until text appears",
      "position_x": 840,
      "position_y": 220,
      "config": {
        "text": "Ad details",
        "timeout": 45,
        "selector": "body"
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 1200,
      "position_y": 220,
      "config": {
        "duration": 2
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1560,
      "position_y": 220,
      "config": {
        "waitForCompletion": true,
        "timeout": 10,
        "jsCode": "(function(){const norm=s=>String(s||'').replace(/[\\u2066\\u2069]/g,'').replace(/\\s+/g,' ').trim();const bodyText=norm(document.body.innerText||'');const pick=re=>{const m=bodyText.match(re);return m?norm(m[1]):'';};const advertiser=pick(/FAQ Ad details (.*?) The information about this ad may vary/i)||pick(/keyboard_arrow_right (.*?) keyboard_arrow_right Ad details/i);const region=pick(/Shown in (.*?) close First shown/i)||pick(/Shown in (.*?) First shown/i);const lastShown=pick(/Last shown(?: on or before)?:\\s*([A-Za-z]{3,9}\\s+\\d{1,2},\\s+\\d{4})/i);const format=pick(/Format:\\s*([A-Za-z]+)/i);const variation=pick(/(\\d+\\s+of\\s+\\d+\\s+variations)/i)||(document.querySelector('material-fab.variation-right-arrow, [aria-label*=\"Next\" i]')?'1 of multiple variations':'0 variations');const impressions=pick(/once\\.\\s*([0-9.,KkMm\\s\\u2013\\u2014-]+)\\s+info\\s+target/i)||pick(/Times shown.*?once\\.\\s*([0-9.,KkMm\\s\\u2013\\u2014-]+)/i);const reportSegment=norm((bodyText.match(/Report this ad\\s+(.*?)(?:visibility\\s+Times shown|Times shown)/i)||[])[1]||'');const removed=/Removed for a policy violation|Sorry, we(?:'|’)?re not able to show you this ad|Our ad policies/i.test(bodyText)||/Removed for a policy violation|Sorry, we(?:'|’)?re not able to show you this ad|Our ad policies/i.test(reportSegment);let imageUrl='';let videoUrl='';const imgObj=Array.from(document.images).map(i=>({src:i.currentSrc||i.src||'',w:i.naturalWidth||i.width||0,h:i.naturalHeight||i.height||0})).find(o=>/^https?:/i.test(o.src)&&!/logo|favicon|googlelogo|branding/i.test(o.src)&&((o.w>80&&o.h>80)||/tpc\\.googlesyndication|encrypted-tbn|googleusercontent|ytimg|ggpht/i.test(o.src)));if(imgObj)imageUrl=imgObj.src;const vid=document.querySelector('video source[src],video[src]');if(vid)videoUrl=vid.currentSrc||vid.src||vid.getAttribute('src')||'';const bad=s=>{s=norm(s);return !s||s.length<3||s===advertiser||s===region||s===variation||/chevron_|keyboard_arrow|hide_image|visibility|target|flag|info|close|arrow_forward|arrow_back/i.test(s)||/Removed for a policy violation|Sorry, we(?:'|’)?re not able to show you this ad|Our ad policies/i.test(s)||/Go to Ads Transparency Center|Region selection filter|Sign in|Google Account|Google apps/i.test(s)||/^(Home|FAQ|Ad details|Privacy|Terms|Ads Policies|Principles|Ads Blog|See more ads|Report this ad|Protecting Users|Key|View examples|Learn more)$/i.test(s)||/^(First shown|Last shown|Format|Topic|Times shown|Audience selection|Shown in|A range of the number|The information about this ad|Criteria from this category|Learn more about audience selection)/i.test(s)||/^\\d+\\s+of\\s+\\d+\\s+variations$/i.test(s)||/^https?:\\/\\//i.test(s)||/[{}<>]/.test(s);};let lines=[];if(!removed){let creativeTexts=[];document.querySelectorAll('.creative-container,.html-container,.creative-bounding-box,.ad-preview,[class*=\"creative\"]').forEach(el=>{const cloned=el.cloneNode(true);cloned.querySelectorAll('material-icon,button,[role=\"button\"],.material-icon-i,.material-icons-extended,.touch-target,.focus-ring').forEach(n=>n.remove());const t=norm(cloned.innerText||cloned.textContent||'');if(t)creativeTexts.push(t);});if(reportSegment)creativeTexts.unshift(reportSegment);lines=creativeTexts.join('\\n').split(/\\n| {2,}|\\s\\|\\s/).map(norm).filter(s=>!bad(s));lines=[...new Set(lines)];}let headline='';let description='';if(lines.length){headline=lines.find(s=>s.length>=4&&s.length<=160)||'';const idx=lines.indexOf(headline);description=lines.slice(idx+1).find(s=>s.length>=12&&s.length<=320&&s!==headline)||'';}let error='';if(!/Ad details/i.test(bodyText))error='Ad details content not detected; page may be blocked, logged out, or not fully loaded.';else if(removed)error='Creative removed or unavailable due to policy violation; headline/description are not visible.';else if(!headline&&!description)error='Creative headline/description not available in the page DOM; Google may render it as image/video media or block access.';let row=document.querySelector('#uscraper-ad-row');if(!row){row=document.createElement('div');row.id='uscraper-ad-row';row.style.display='none';document.body.appendChild(row);}const data={advertiser:advertiser,page_url:location.href,last_shown:lastShown,format:format,variations:variation,regions:region,number_of_impressions:impressions,image_url:imageUrl,video_url:videoUrl,headline:headline,description:description,error:error};Object.entries(data).forEach(([k,v])=>row.setAttribute('data-'+k.replace(/_/g,'-'),norm(v)));})();"
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1920,
      "position_y": 220,
      "config": {
        "rowSelector": "#uscraper-ad-row",
        "fileName": "google_ads_scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "advertiser",
            "selector": "",
            "attribute": "data-advertiser"
          },
          {
            "name": "page_url",
            "selector": "",
            "attribute": "data-page-url"
          },
          {
            "name": "last_shown",
            "selector": "",
            "attribute": "data-last-shown"
          },
          {
            "name": "format",
            "selector": "",
            "attribute": "data-format"
          },
          {
            "name": "variations",
            "selector": "",
            "attribute": "data-variations"
          },
          {
            "name": "regions",
            "selector": "",
            "attribute": "data-regions"
          },
          {
            "name": "number_of_impressions",
            "selector": "",
            "attribute": "data-number-of-impressions"
          },
          {
            "name": "image_url",
            "selector": "",
            "attribute": "data-image-url"
          },
          {
            "name": "video_url",
            "selector": "",
            "attribute": "data-video-url"
          },
          {
            "name": "headline",
            "selector": "",
            "attribute": "data-headline"
          },
          {
            "name": "description",
            "selector": "",
            "attribute": "data-description"
          },
          {
            "name": "error",
            "selector": "",
            "attribute": "data-error"
          }
        ]
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2280,
      "position_y": 220,
      "config": {
        "selector": "material-fab.variation-right-arrow:not([disabled]):not([aria-disabled=\"true\"]):not(.is-disabled):not(.disabled), [aria-label*=\"Next\" i]:not([disabled]):not([aria-disabled=\"true\"]):not(.is-disabled):not(.disabled)"
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 2640,
      "position_y": 540,
      "config": {
        "selector": "material-fab.variation-right-arrow:not([disabled]):not([aria-disabled=\"true\"]):not(.is-disabled):not(.disabled), [aria-label*=\"Next\" i]:not([disabled]):not([aria-disabled=\"true\"]):not(.is-disabled):not(.disabled)",
        "timeout": 10
      }
    },
    {
      "block_id": "sleep-2",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3000,
      "position_y": 540,
      "config": {
        "duration": 1.5
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2280,
      "position_y": 860,
      "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": "wait-for-text-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-text-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": "structured-export-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "structured-export-1",
      "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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-2",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "element-exists-1",
      "from_connector_id": "false",
      "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": 3200,
      "height": 616,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-text-1",
          "sleep-1",
          "sleep-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1488,
      "position_y": 116,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1"
        ]
      }
    },
    {
      "id": "group-extract",
      "element_type": "group",
      "title": "Data Extraction",
      "color": "#42be65",
      "position_x": 1848,
      "position_y": 116,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "structured-export-1"
        ]
      }
    },
    {
      "id": "group-pagination",
      "element_type": "group",
      "title": "Pagination Loop",
      "color": "#ff832b",
      "position_x": 2208,
      "position_y": 116,
      "width": 680,
      "height": 936,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1",
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Extracts Google Ads Transparency Center ad detail data by URL list, including advertiser, page URL, last shown date, format, variation number, region, impressions, image/video URLs, headline, description, and error status. Uses navigate.urls[] plus loop-continue to process all supplied URLs, and a variation pagination loop to click the next creative variation when an enabled next arrow is present. Best-effort: Google may require sign-in, rate-limit, remove creatives, render ad text inside images/media, or change its Angular DOM; when headline/description are not exposed in the DOM, the Error column explains the limitation.",
      "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(){const norm=s=>String(s||'').replace(/[\\u2066\\u2069]/g,'').replace(/\\s+/g,' ').trim();con...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1760,
      "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 `material-fab.variation-right-arrow:not([disabled]):not([aria-disabled=\"true\"]):not(.is-disabled):not(.disabled), [aria-l`. True / False branches control which path runs next. Keep enough space between branches so both connector lines are visible.",
      "color": "#ee5396",
      "position_x": 2480,
      "position_y": 200,
      "width": 340,
      "height": 170,
      "z_index": 22,
      "data": {
        "block_id": "element-exists-1"
      }
    },
    {
      "id": "note-block-click-1",
      "element_type": "note",
      "title": "Note: Click",
      "content": "Pagination click — add waits after this block; the page reloads asynchronously.",
      "color": "#ee5396",
      "position_x": 2840,
      "position_y": 520,
      "width": 316,
      "height": 106,
      "z_index": 22,
      "data": {
        "block_id": "click-1"
      }
    },
    {
      "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": 2480,
      "position_y": 840,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}