{
  "version": "1.0.0",
  "exported_at": "2026-06-01T00:00:00.000Z",
  "project": {
    "name": "Yellow Pages Latin ScraperProduct Details",
    "description": "Scrapes Páginas Amarillas Argentina business details for the Octoparse-style input keyword/city: Farmacia + Buenos Aires. Uses a direct results URL known to load listing pages, waits for /fichas/ detail links, marks only real business rows whose card/name/detail URL contains the pharmacy keyword stem 'farmac', then exports name, site URL, detail URL, address, website, WhatsApp, and phone. Pagination is handled with a click-next loop until no enabled Siguiente/next control remains. CAPTCHA may require manual solving.",
    "color": "bg-[#f1c21b]",
    "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": {
        "url": "https://www.paginasamarillas.com.ar/buscar/farmacia/buenos-aires",
        "color": "bg-[#4589ff]",
        "tags": [
          "entry",
          "paginas-amarillas",
          "farmacia",
          "buenos-aires"
        ]
      }
    },
    {
      "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": 30,
        "color": "bg-[#08bdba]",
        "tags": [
          "page-load"
        ]
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 840,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { const buttons = Array.from(document.querySelectorAll('button, a')); const accept = buttons.find(el => /aceptar|accept|entiendo|ok/i.test((el.innerText || el.textContent || '').trim())); if (accept) accept.click(); return true; })();",
        "waitForCompletion": true,
        "timeout": 5,
        "color": "bg-[#a56eff]",
        "tags": [
          "cookie",
          "best-effort"
        ]
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1200,
      "position_y": 220,
      "config": {
        "selector": "a[href*=\"/fichas/\"]",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]",
        "tags": [
          "results",
          "raw-detail-links"
        ]
      }
    },
    {
      "block_id": "inject-javascript-2",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Run custom JavaScript on the page",
      "position_x": 1560,
      "position_y": 220,
      "config": {
        "jsCode": "(() => { const links = Array.from(document.querySelectorAll('a[href*=\"/fichas/\"]')); links.forEach(a => a.removeAttribute('data-uscraper-business-row')); const seen = new Set(); let count = 0; const getCard = (a) => { let el = a; for (let i = 0; i < 8 && el; i++) { const t = (el.innerText || '').trim(); if (el.querySelector('a[href*=\"/fichas/\"]') && t.length > 60) return el; el = el.parentElement; } return a.closest('article, li, .card, .resultado, .result, .listing, .item') || a.parentElement || a; }; for (const a of links) { const text = (a.innerText || a.textContent || '').replace(/\\s+/g, ' ').trim(); const href = a.href || a.getAttribute('href') || ''; if (!text || text.length < 2) continue; if (/^\\+\\s*\\d+/.test(text)) continue; if (/chatear|whatsapp|tel[eé]fono|contactar|ver m[aá]s|c[oó]mo llegar/i.test(text)) continue; if (!/\\/fichas\\//.test(href)) continue; const card = getCard(a); const cardText = (card && (card.innerText || card.textContent || '')) || ''; const haystack = (text + ' ' + href + ' ' + cardText).toLowerCase(); if (!/farmac/.test(haystack)) continue; let key = href; try { key = new URL(href, location.href).pathname; } catch (e) {} if (seen.has(key)) continue; seen.add(key); a.setAttribute('data-uscraper-business-row', '1'); count++; } return count; })();",
        "waitForCompletion": true,
        "timeout": 10,
        "color": "bg-[#a56eff]",
        "tags": [
          "dedupe",
          "keyword-filter",
          "mark-business-rows"
        ]
      }
    },
    {
      "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": "a[data-uscraper-business-row=\"1\"]",
        "fileName": "paginas_amarillas_latin_detalles_scraper_farmacia.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "color": "bg-[#42be65]",
        "tags": [
          "business-details",
          "lead-generation",
          "farmacia",
          "deduplicated"
        ],
        "columns": [
          {
            "name": "Sitio_web",
            "selector": "location.origin",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Palabra_clave",
            "selector": "'Farmacia'",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Ciudad",
            "selector": "'Buenos Aires'",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Nombre",
            "selector": "(() => { return (ROW.innerText || ROW.textContent || '').replace(/\\s+/g, ' ').trim(); })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Página_URL",
            "selector": "location.origin",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Detalles_URL",
            "selector": "(() => { try { return new URL(ROW.getAttribute('href') || ROW.href || '', location.href).pathname; } catch (e) { return ROW.getAttribute('href') || ''; } })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Domicilio",
            "selector": "(() => { const clean = s => (s || '').replace(/https?:\\/\\/\\S+/gi, '').replace(/(?:www\\.)?[a-z0-9-]+\\.[a-z]{2,}(?:\\.[a-z]{2,})?/gi, '').replace(/\\b(?:Chatear|WhatsApp|Tel[eé]fono|Ver m[aá]s|Cómo llegar|Contactar)\\b/gi, '').replace(/\\s+/g, ' ').trim(); const getCard = () => { let el = ROW; for (let i = 0; i < 8 && el; i++) { const t = (el.innerText || '').trim(); if (el.querySelector('a[href*=\"/fichas/\"]') && t.length > 60) return el; el = el.parentElement; } return ROW.closest('article, li, .card, .resultado, .result, .listing, .item') || ROW.parentElement || ROW; }; const card = getCard(); const direct = card.querySelector('[itemprop=\"streetAddress\"], [class*=\"direccion\" i], [class*=\"domicilio\" i], [class*=\"address\" i]'); if (direct) return clean(direct.innerText || direct.textContent || ''); const name = clean(ROW.innerText || ROW.textContent || ''); const lines = (card.innerText || '').split(/\\n+/).map(clean).filter(Boolean).filter(l => l !== name); const found = lines.find(l => !/^\\+\\s*\\d+$/.test(l) && !/chatear|whatsapp|tel[eé]fono|contactar|ver m[aá]s/i.test(l) && (/\\b(Av|Av\\.|Avenida|Calle|Ruta|San|Gral|Dr|Pje|Boulevard|Bv|Moreno|Belgrano|Rivadavia|Mitre|Sarmiento|Peralta|Luro|Plaza|Octubre)\\b/i.test(l) || /\\d{2,5}/.test(l))); return found || ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Página_web",
            "selector": "(() => { const getCard = () => { let el = ROW; for (let i = 0; i < 8 && el; i++) { const t = (el.innerText || '').trim(); if (el.querySelector('a[href*=\"/fichas/\"]') && t.length > 60) return el; el = el.parentElement; } return ROW.closest('article, li, .card, .resultado, .result, .listing, .item') || ROW.parentElement || ROW; }; const card = getCard(); const links = Array.from(card.querySelectorAll('a[href]')); const web = links.find(a => /^https?:/i.test(a.href) && !/paginasamarillas\\.com\\.ar/i.test(a.href) && !/whatsapp|wa\\.me/i.test(a.href) && !/^tel:/i.test(a.getAttribute('href') || '')); if (web) return web.href.replace(/^https?:\\/\\//i, '').replace(/\\/$/, ''); const text = card.innerText || ''; const m = text.match(/(?:www\\.)?[a-z0-9-]+\\.[a-z]{2,}(?:\\.[a-z]{2,})?/i); return m ? m[0] : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Contacto_WhatsApp",
            "selector": "(() => { const getCard = () => { let el = ROW; for (let i = 0; i < 8 && el; i++) { const t = (el.innerText || '').trim(); if (el.querySelector('a[href*=\"/fichas/\"]') && t.length > 60) return el; el = el.parentElement; } return ROW.closest('article, li, .card, .resultado, .result, .listing, .item') || ROW.parentElement || ROW; }; const card = getCard(); const wa = card.querySelector('a[href*=\"whatsapp\"], a[href*=\"wa.me\"]'); if (wa) { const href = wa.href || ''; const m = href.match(/(?:phone=|wa\\.me\\/)(\\d+)/i) || href.match(/(54\\d{8,15})/); if (m) return m[1]; return href; } const text = card.innerText || ''; const line = text.split(/\\n+/).find(l => /whatsapp|chatear/i.test(l)); if (!line) return ''; const m = line.match(/\\+?\\d[\\d\\s().-]{7,}\\d/); return m ? m[0].replace(/[^\\d]/g, '') : ''; })()",
            "attribute": "text",
            "isJs": true
          },
          {
            "name": "Telefono",
            "selector": "(() => { const getCard = () => { let el = ROW; for (let i = 0; i < 8 && el; i++) { const t = (el.innerText || '').trim(); if (el.querySelector('a[href*=\"/fichas/\"]') && t.length > 60) return el; el = el.parentElement; } return ROW.closest('article, li, .card, .resultado, .result, .listing, .item') || ROW.parentElement || ROW; }; const card = getCard(); const tel = card.querySelector('a[href^=\"tel:\"]'); if (tel) return (tel.getAttribute('href') || '').replace(/^tel:/i, '').trim() || (tel.innerText || '').trim(); const text = card.innerText || ''; const candidates = text.match(/\\(?0?\\d{2,5}\\)?[\\s-]*\\d{3,5}[\\s-]*\\d{3,5}/g); return candidates && candidates.length ? candidates[0].trim() : ''; })()",
            "attribute": "text",
            "isJs": true
          }
        ]
      }
    },
    {
      "block_id": "element-exists-1",
      "block_type": "process",
      "title": "Element Exists",
      "description": "Check if element exists",
      "position_x": 2280,
      "position_y": 220,
      "config": {
        "selector": "(//a[@rel='next' and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //a[(contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente') or contains(translate(@aria-label, 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente')) and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //button[(contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente') or contains(translate(@aria-label, 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente')) and not(@disabled)])[1]",
        "color": "bg-[#ff832b]",
        "tags": [
          "pagination",
          "xpath"
        ]
      }
    },
    {
      "block_id": "click-1",
      "block_type": "process",
      "title": "Click",
      "description": "Click on element",
      "position_x": 2640,
      "position_y": 520,
      "config": {
        "selector": "(//a[@rel='next' and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //a[(contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente') or contains(translate(@aria-label, 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente')) and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //button[(contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente') or contains(translate(@aria-label, 'ABCDEFGHIJKLMNOPQRSTUVWXYZÁÉÍÓÚ', 'abcdefghijklmnopqrstuvwxyzáéíóú'), 'siguiente')) and not(@disabled)])[1]",
        "timeout": 10,
        "color": "bg-[#ff832b]",
        "tags": [
          "pagination",
          "next-page"
        ]
      }
    },
    {
      "block_id": "wait-for-page-load-2",
      "block_type": "process",
      "title": "Wait for Page Load",
      "description": "Wait for page to finish loading",
      "position_x": 3000,
      "position_y": 520,
      "config": {
        "timeout": 30,
        "color": "bg-[#08bdba]",
        "tags": [
          "pagination",
          "page-load"
        ]
      }
    },
    {
      "block_id": "sleep-1",
      "block_type": "process",
      "title": "Sleep",
      "description": "Wait for specified time",
      "position_x": 3360,
      "position_y": 520,
      "config": {
        "duration": 2,
        "color": "bg-[#8d8d8d]",
        "tags": [
          "pagination",
          "ajax-buffer"
        ]
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 3720,
      "position_y": 520,
      "config": {
        "selector": "a[href*=\"/fichas/\"]",
        "timeout": 30,
        "visible": true,
        "color": "bg-[#08bdba]",
        "tags": [
          "pagination",
          "raw-detail-links"
        ]
      }
    },
    {
      "block_id": "end-1",
      "block_type": "output",
      "title": "End",
      "description": "Terminate execution flow",
      "position_x": 2280,
      "position_y": 840,
      "config": {
        "color": "bg-[#8d8d8d]",
        "tags": [
          "end"
        ]
      }
    }
  ],
  "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": "wait-for-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-1",
      "from_connector_id": "right",
      "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": "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": "element-exists-1",
      "from_connector_id": "false",
      "to_block_id": "end-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "click-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": "sleep-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "sleep-1",
      "from_connector_id": "right",
      "to_block_id": "wait-for-element-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-2",
      "from_connector_id": "right",
      "to_block_id": "inject-javascript-2",
      "to_connector_id": "left"
    }
  ],
  "canvas_elements": [
    {
      "id": "group-load",
      "element_type": "group",
      "title": "Page Load",
      "color": "#08bdba",
      "position_x": 48,
      "position_y": 116,
      "width": 3920,
      "height": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "wait-for-page-load-2",
          "sleep-1",
          "wait-for-element-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 768,
      "position_y": 116,
      "width": 1040,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "inject-javascript-1",
          "inject-javascript-2"
        ]
      }
    },
    {
      "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": 596,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "element-exists-1",
          "click-1"
        ]
      }
    },
    {
      "id": "group-control",
      "element_type": "group",
      "title": "Control Flow",
      "color": "#8d8d8d",
      "position_x": 2208,
      "position_y": 736,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "end-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes Páginas Amarillas Argentina business details for the Octoparse-style input keyword/city: Farmacia + Buenos Aires. Uses a direct results URL known to load listing pages, waits for /fichas/ detail links, marks only real business rows whose card/name/detail URL contains the pharmacy keyword stem 'farmac', then exports name, site URL, detail URL, address, website, WhatsApp, and phone. Pagination is handled with a click-next loop until no enabled Siguiente/next control remains. CAPTCHA may require manual solving.",
      "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: `(() => { const buttons = Array.from(document.querySelectorAll('button, a')); const accept = buttons....` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1040,
      "position_y": 200,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-inject-javascript-2",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(() => { const links = Array.from(document.querySelectorAll('a[href*=\"/fichas/\"]')); links.forEach(a...` 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-2"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Structured export with JS columns (Sitio_web, Palabra_clave, Ciudad, Nombre, Página_URL). These selectors are fragile — update if the site layout changes.",
      "color": "#ee5396",
      "position_x": 2120,
      "position_y": 200,
      "width": 340,
      "height": 131,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-1"
      }
    },
    {
      "id": "note-block-element-exists-1",
      "element_type": "note",
      "title": "Note: Element Exists",
      "content": "Condition block: checks `(//a[@rel='next' and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //a[(contains(translate(n`. 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": "Uses XPath `(//a[@rel='next' and not(contains(concat(' ', normalize-space(@class), ' '), ' disabled '))] | //a[(`. XPath breaks easily if DOM structure changes.",
      "color": "#ee5396",
      "position_x": 2840,
      "position_y": 500,
      "width": 340,
      "height": 133,
      "z_index": 22,
      "data": {
        "block_id": "click-1"
      }
    }
  ]
}