{
  "version": "1.0.0",
  "exported_at": "2026-06-01T00:00:00.000Z",
  "project": {
    "name": "Best Buy Reviews Scraper",
    "description": "Scrapes BestBuy product reviews equivalent to the Octoparse Best Buy Reviews Scraper. Extracts product title, model, SKU, overall rating, number of reviews, recommendation/rating fields, reviewer account, review rating, post time, comment, recommendation flag, helpful/unhelpful counts, and page URL. Navigation strategy: multi-URL BestBuy review endpoint loop plus JavaScript-driven API pagination for each SKU; products with unavailable/blocked review API data render an empty visible container and are skipped without failing. Best-effort: BestBuy may block scraping, return CAPTCHA/anti-bot responses, or change its internal review API.",
    "color": "bg-[#4589ff]",
    "template_id": "ai-generated-best-buy-reviews-scraper"
  },
  "blocks": [
    {
      "block_id": "navigate-1",
      "block_type": "process",
      "title": "Navigate",
      "description": "Go to a URL",
      "position_x": 120,
      "position_y": 240,
      "config": {
        "urls": [
          "https://www.bestbuy.com/ugc/v2/reviews?skuId=6319978&page=1&pageSize=20&sort=MOST_RECENT",
          "https://www.bestbuy.com/ugc/v2/reviews?skuId=BCKVZQ48PC&page=1&pageSize=20&sort=MOST_RECENT"
        ],
        "color": "bg-[#4589ff]",
        "tags": [
          "bestbuy",
          "reviews",
          "multi-url",
          "api"
        ]
      }
    },
    {
      "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": 240,
      "config": {
        "timeout": 45
      }
    },
    {
      "block_id": "wait-for-element-1",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 840,
      "position_y": 240,
      "config": {
        "selector": "body",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "inject-javascript-1",
      "block_type": "process",
      "title": "Inject JavaScript",
      "description": "Execute custom JavaScript",
      "position_x": 1200,
      "position_y": 240,
      "config": {
        "jsCode": "(async()=>{const sleep=ms=>new Promise(r=>setTimeout(r,ms));const clean=v=>v==null?'':String(v).replace(/\\s+/g,' ').trim();const skuMeta={6319978:{title:'ASUS - 14\" Laptop - AMD A6-Series - 4GB Memory - AMD Radeon R4 - 500GB Hard Drive',model:'X441BA-CBA6A',sourceUrl:'https://www.bestbuy.com/site/reviews/asus-14-laptop-amd-a6-series-4gb-memory-amd-radeon-r4-500gb-hard-drive/6319978?variant=A&skuId=6319978'},BCKVZQ48PC:{title:'Ray-Ban Meta Wayfarer - Green Lenses - Capture Photos/Video, Listen to Music, Ask Meta AI for Answers - Shiny Black',model:'',sourceUrl:'https://www.bestbuy.com/product/ray-ban-meta-wayfarer-green-lenses-capture-photos-video-listen-to-music-ask-meta-ai-for-answers-shiny-black/BCKVZQ48PC#tabbed-customerreviews'}};const pick=(obj,paths)=>{for(const path of paths){try{let cur=obj;for(const part of path.split('.')){if(cur==null)break;cur=cur[part];}if(cur!==undefined&&cur!==null&&cur!=='')return cur;}catch(e){}}return '';};const parseJson=()=>{const txt=(document.body.innerText||'').trim();try{return JSON.parse(txt);}catch(e){const pre=document.querySelector('pre');if(pre){try{return JSON.parse(pre.textContent.trim());}catch(e2){}}return {};}};function arrayScore(arr){if(!Array.isArray(arr)||!arr.length||typeof arr[0]!=='object'||arr[0]===null)return 0;const s=JSON.stringify(arr[0]).toLowerCase();let score=0;['review','rating','comment','submission','nickname','author','helpful','recommended','text','body'].forEach(k=>{if(s.includes(k))score++;});return score;}function findReviewArrays(obj,out=[]){if(!obj)return out;if(Array.isArray(obj)){const score=arrayScore(obj);if(score>=2)out.push({arr:obj,score});obj.slice(0,3).forEach(v=>findReviewArrays(v,out));return out;}if(typeof obj==='object'){Object.keys(obj).forEach(k=>findReviewArrays(obj[k],out));}return out;}function getReviews(d){if(Array.isArray(d))return d;const known=[d&&d.reviews,d&&d.reviewList,d&&d.review_list,d&&d.results,d&&d.items,d&&d.data&&d.data.reviews,d&&d.data&&d.data.reviewList,d&&d.data&&d.data.results,d&&d.payload&&d.payload.reviews,d&&d.response&&d.response.reviews].filter(Array.isArray);if(known.length)return known.sort((a,b)=>arrayScore(b)-arrayScore(a))[0];const found=findReviewArrays(d).sort((a,b)=>b.score-a.score||b.arr.length-a.arr.length);return found.length?found[0].arr:[];}function findValueByKey(obj,regex){let ans='';const seen=new Set();function walk(o){if(ans!==''||!o||typeof o!=='object'||seen.has(o))return;seen.add(o);if(Array.isArray(o)){o.slice(0,5).forEach(walk);return;}for(const k of Object.keys(o)){if(regex.test(k)&&o[k]!=null&&typeof o[k]!=='object'){ans=o[k];return;}walk(o[k]);if(ans!=='')return;}}walk(obj);return ans;}const params=new URLSearchParams(location.search);const sku=params.get('skuId')||params.get('sku')||params.get('skus')||(location.href.match(/(?:skuId=|sku=|skus=|\\/sku\\/)([A-Z0-9-]+)/i)||[])[1]||'';const meta=skuMeta[sku]||{};const pageSize=20;async function fetchJson(url){try{const res=await fetch(url,{credentials:'include',headers:{'accept':'application/json,text/plain,*/*','x-requested-with':'XMLHttpRequest'}});const txt=await res.text();try{return JSON.parse(txt);}catch(e){return {__error:txt,status:res.status,url};}}catch(e){return {__error:String(e),url};}}async function fetchBestPage(page){const sorts=['MOST_RECENT','NEWEST','BEST_MATCH','MOST_HELPFUL'];const urls=[];for(const sort of sorts){urls.push(`/ugc/v2/reviews?skuId=${encodeURIComponent(sku)}&page=${page}&pageSize=${pageSize}&sort=${sort}`);urls.push(`/ugc/v2/reviews?sku=${encodeURIComponent(sku)}&page=${page}&pageSize=${pageSize}&sort=${sort}`);}urls.push(`/ugc/v2/reviews?skus=${encodeURIComponent(sku)}&page=${page}&pageSize=${pageSize}`);urls.push(`/ugc/v2/reviews/${encodeURIComponent(sku)}?page=${page}&pageSize=${pageSize}`);let best=null,bestArr=[];for(const u of urls){const j=await fetchJson(u);const arr=getReviews(j);if(arr.length>bestArr.length){best=j;bestArr=arr;}if(arr.length>=pageSize)break;}return best||{};}let first=parseJson();let firstArr=getReviews(first);if(!firstArr.length){first=await fetchBestPage(1);firstArr=getReviews(first);}const all=[];const seen=new Set();function addReviews(arr){arr.forEach(r=>{const key=pick(r,['id','reviewId','review_id','submissionId'])||clean((pick(r,['userNickname','nickname','reviewer.nickname','author.name'])||'')+'|'+(pick(r,['submissionTime','submissionDate','date'])||'')+'|'+(pick(r,['comment','reviewText','text','body','content'])||'')).slice(0,300);if(!seen.has(key)){seen.add(key);all.push(r);}});}addReviews(firstArr);let total=Number(String(pick(first,['totalReviewCount','totalReviews','totalResults','count','total','reviewStatistics.totalReviewCount','statistics.totalReviewCount','summary.totalReviewCount','data.totalReviewCount','data.totalResults'])||findValueByKey(first,/^(totalReviewCount|totalReviews|totalResults|reviewCount|count|total)$/i)||'').replace(/[^0-9]/g,''))||firstArr.length;let maxPages=Math.min(Math.max(Math.ceil(total/pageSize)||1,1),50);if(maxPages<3&&firstArr.length>=pageSize)maxPages=50;for(let p=2;p<=maxPages;p++){const d=await fetchBestPage(p);const arr=getReviews(d);if(!arr.length)break;const before=all.length;addReviews(arr);if(all.length===before)break;if(arr.length<pageSize)break;await sleep(150);}const product=pick(first,['product','productDetails','data.product','payload.product','products.0'])||{};const title=clean(meta.title||pick(product,['name','title','productName','displayName'])||pick(first,['productName','data.productName']));const model=clean(meta.model||pick(product,['model','modelNumber','model_number'])||pick(first,['model','modelNumber','data.modelNumber'])||findValueByKey(first,/^(model|modelNumber)$/i));const overall=clean(pick(first,['averageOverallRating','averageRating','overallRating','reviewStatistics.averageOverallRating','statistics.averageOverallRating','summary.averageOverallRating','data.reviewStatistics.averageOverallRating'])||findValueByKey(first,/^(averageOverallRating|averageRating|overallRating)$/i));const numReviews=clean(total||pick(first,['reviewStatistics.totalReviewCount','statistics.totalReviewCount','summary.totalReviewCount'])||findValueByKey(first,/^(totalReviewCount|totalReviews|reviewCount)$/i));const recommendRate=clean(pick(first,['recommendationPercentage','recommendedPercent','reviewStatistics.recommendationPercentage','statistics.recommendationPercentage','summary.recommendationPercentage'])||findValueByKey(first,/^(recommendationPercentage|recommendedPercent)$/i));document.body.innerHTML='';const style=document.createElement('style');style.textContent='#uscraper-reviews-container{display:block!important;visibility:visible!important;min-height:28px;padding:8px;background:#fff;color:#111}.uscraper-review-row{display:block!important;visibility:visible!important;min-height:18px;margin:2px;padding:2px}.uscraper-review-row span{display:inline-block;margin-right:4px}.uscraper-no-review-message{display:block!important;min-height:24px;color:#444}';document.head.appendChild(style);const status=document.createElement('div');status.id='uscraper-render-status';status.textContent=`Rendered ${all.length} review rows for SKU ${sku}`;document.body.appendChild(status);const container=document.createElement('div');container.id='uscraper-reviews-container';container.setAttribute('data-sku',sku);document.body.appendChild(container);function val(r,paths){return clean(pick(r,paths));}function add(row,cls,value){const el=document.createElement('span');el.className=cls;el.textContent=clean(value);row.appendChild(el);}all.forEach((r,i)=>{const row=document.createElement('div');row.className='uscraper-review-row';row.setAttribute('data-index',String(i+1));const reviewer=val(r,['reviewer.name','reviewer.nickname','reviewer.userName','author.name','userNickname','nickname','author','account','name']);const rating=val(r,['rating','overallRating','reviewRating','stars','score']);const post=val(r,['submissionTime','submittedDate','submissionDate','createdDate','date','postTime','post_time']);const comment=val(r,['comment','reviewText','text','body','content','description','review']);let rec=val(r,['isRecommended','recommended','wouldRecommend','recommend']);if(/^true$/i.test(rec))rec='√';else if(/^false$/i.test(rec))rec='×';const helpful=val(r,['helpfulVotes','positiveFeedbackCount','helpfulCount','helpfulness.positive','feedback.positive','helpful']);const unhelpful=val(r,['unhelpfulVotes','negativeFeedbackCount','unhelpfulCount','helpfulness.negative','feedback.negative','unhelpful']);add(row,'title',title);add(row,'model',model);add(row,'sku',sku);add(row,'overall_rating',overall);add(row,'number_of_reviews',numReviews);add(row,'recommendation_rate',recommendRate);add(row,'value_rating',val(r,['secondaryRatings.Value.value','secondaryRatings.value.value','secondaryRatings.Value','valueRating']));add(row,'quality_rating',val(r,['secondaryRatings.Quality.value','secondaryRatings.quality.value','secondaryRatings.Quality','qualityRating']));add(row,'ease_of_use_rating',val(r,['secondaryRatings.EaseOfUse.value','secondaryRatings.Ease of Use.value','secondaryRatings.easeOfUse.value','secondaryRatings.EaseOfUse','easeOfUseRating']));add(row,'account',reviewer);add(row,'rating',rating?`${rating} out of 5 stars`:'');add(row,'post_time',post);add(row,'comment',comment);add(row,'whether_to_recommend',rec);add(row,'helpful',helpful);add(row,'unhelpful',unhelpful);add(row,'page_url',meta.sourceUrl||location.href);container.appendChild(row);});if(!all.length){const empty=document.createElement('div');empty.className='uscraper-no-review-message';empty.textContent=`No review rows found for SKU ${sku}; skipping this product.`;container.appendChild(empty);}return true;})()",
        "waitForCompletion": true,
        "timeout": 120
      }
    },
    {
      "block_id": "wait-for-element-2",
      "block_type": "process",
      "title": "Wait for Element",
      "description": "Wait until element appears",
      "position_x": 1560,
      "position_y": 240,
      "config": {
        "selector": "#uscraper-reviews-container",
        "timeout": 45,
        "visible": true
      }
    },
    {
      "block_id": "structured-export-1",
      "block_type": "process",
      "title": "Structured Export",
      "description": "Export data with custom columns",
      "position_x": 1920,
      "position_y": 240,
      "config": {
        "rowSelector": ".uscraper-review-row",
        "fileName": "best-buy-reviews-scraper.csv",
        "saveLocation": "C:\\Users\\theskd\\Documents\\UScraper\\templates",
        "includeHeaders": true,
        "fileMode": "append",
        "columns": [
          {
            "name": "title",
            "selector": ".title",
            "attribute": "text"
          },
          {
            "name": "model",
            "selector": ".model",
            "attribute": "text"
          },
          {
            "name": "sku",
            "selector": ".sku",
            "attribute": "text"
          },
          {
            "name": "overall_rating",
            "selector": ".overall_rating",
            "attribute": "text"
          },
          {
            "name": "number_of_reviews",
            "selector": ".number_of_reviews",
            "attribute": "text"
          },
          {
            "name": "recommendation_rate",
            "selector": ".recommendation_rate",
            "attribute": "text"
          },
          {
            "name": "value_rating",
            "selector": ".value_rating",
            "attribute": "text"
          },
          {
            "name": "quality_rating",
            "selector": ".quality_rating",
            "attribute": "text"
          },
          {
            "name": "ease_of_use_rating",
            "selector": ".ease_of_use_rating",
            "attribute": "text"
          },
          {
            "name": "account",
            "selector": ".account",
            "attribute": "text"
          },
          {
            "name": "rating",
            "selector": ".rating",
            "attribute": "text"
          },
          {
            "name": "post_time",
            "selector": ".post_time",
            "attribute": "text"
          },
          {
            "name": "comment",
            "selector": ".comment",
            "attribute": "text"
          },
          {
            "name": "whether_to_recommend",
            "selector": ".whether_to_recommend",
            "attribute": "text"
          },
          {
            "name": "helpful",
            "selector": ".helpful",
            "attribute": "text"
          },
          {
            "name": "unhelpful",
            "selector": ".unhelpful",
            "attribute": "text"
          },
          {
            "name": "page_url",
            "selector": ".page_url",
            "attribute": "text"
          }
        ]
      }
    },
    {
      "block_id": "loop-continue-1",
      "block_type": "process",
      "title": "Loop Continue",
      "description": "Continue multi-input loop",
      "position_x": 2280,
      "position_y": 240,
      "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-element-1",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-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-2",
      "to_connector_id": "left"
    },
    {
      "from_block_id": "wait-for-element-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": 136,
      "width": 1760,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "navigate-1",
          "wait-for-page-load-1",
          "wait-for-element-1",
          "wait-for-element-2"
        ]
      }
    },
    {
      "id": "group-interaction",
      "element_type": "group",
      "title": "Interaction",
      "color": "#a56eff",
      "position_x": 1128,
      "position_y": 136,
      "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": 136,
      "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": 136,
      "width": 380,
      "height": 296,
      "z_index": 20,
      "data": {
        "memberBlockIds": [
          "loop-continue-1"
        ]
      }
    },
    {
      "id": "note-overview",
      "element_type": "note",
      "title": "Overview",
      "content": "Scrapes BestBuy product reviews equivalent to the Octoparse Best Buy Reviews Scraper. Extracts product title, model, SKU, overall rating, number of reviews, recommendation/rating fields, reviewer account, review rating, post time, comment, recommendation flag, helpful/unhelpful counts, and page URL. Navigation strategy: multi-URL BestBuy review endpoint loop plus JavaScript-driven API pagination for each SKU; products with unavailable/blocked review API data render an empty visible container and are skipped without failing. Best-effort: BestBuy may block scraping, return CAPTCHA/anti-bot responses, or change its internal review API.",
      "color": "#f1c21b",
      "position_x": 80,
      "position_y": 20,
      "width": 480,
      "height": 160,
      "z_index": 22,
      "data": {}
    },
    {
      "id": "note-block-navigate-1",
      "element_type": "note",
      "title": "Note: Navigate",
      "content": "Multi-URL loop over 2 pages. Pair with loop-continue at the end of each iteration.",
      "color": "#ee5396",
      "position_x": 320,
      "position_y": 220,
      "width": 328,
      "height": 107,
      "z_index": 22,
      "data": {
        "block_id": "navigate-1"
      }
    },
    {
      "id": "note-block-inject-javascript-1",
      "element_type": "note",
      "title": "Note: Inject JavaScript",
      "content": "Runs custom JavaScript in the page: `(async()=>{const sleep=ms=>new Promise(r=>setTimeout(r,ms));const clean=v=>v==null?'':String(v).repl...` Verify in browser if results are empty.",
      "color": "#ee5396",
      "position_x": 1400,
      "position_y": 220,
      "width": 340,
      "height": 140,
      "z_index": 22,
      "data": {
        "block_id": "inject-javascript-1"
      }
    },
    {
      "id": "note-block-structured-export-1",
      "element_type": "note",
      "title": "Note: Structured Export",
      "content": "Extracts rows matching `.uscraper-review-row`. Confirm row count > 0 before running at scale.",
      "color": "#ee5396",
      "position_x": 2120,
      "position_y": 220,
      "width": 340,
      "height": 111,
      "z_index": 22,
      "data": {
        "block_id": "structured-export-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": 220,
      "width": 340,
      "height": 123,
      "z_index": 22,
      "data": {
        "block_id": "loop-continue-1"
      }
    }
  ]
}