| 행 | 사이트 | 보드 | 시트 이슈 | 원인 한 줄 | 상태 |
|---|---|---|---|---|---|
| 42 | mediaworld.it s_seq 1100427 | MOBILE_APPLE 1103417 (동작 중) | RPA 오수집 및 "제목 없음" 수집 | 원인 확정: iPhone 18 스폰서 카드 4개에는 Item 정규식 2번째 줄이 요구하는 <button type="button"이 없어서, 정규식이 다음 카드까지 삼켜 한 상품으로 묶음 → 삼켜진 상품 누락(87→64건), 제목 없음, 판매가·정가가 다른 상품 값으로 오수집 | 완료 |
| 41 | erosdigitalhome.ae s_seq | 일부 미수집(MOBILE_MOTOROLA) | 완료 | ||
| 40 | telenor.se s_seq 1100310 | MOBILE_SAMSUNG (1102748) / MOBILE_APPLE (1102749) | 전체 미수집 및 오수집 | MOBILE_SAMSUNG의 1step Item 정규식이 Vue 컴포넌트의 scoped-CSS 해시값(6c2f030f)을 하드코딩하고 있는데, 사이트가 재배포되면서 그 해시값이 바뀌어(현재 4952cfe1/b4c0e77e/15544276) 0건(치명적에러)으로 전체 미수집됨. MOBILE_APPLE은 이미 해시에 의존하지 않는 fallback 패턴이 있어 완전히는 안 막혔지만, 날짜별로 11건/3건을 오가는 간헐적 부분수집(오수집 소지)이 있음. | 완료 |
| 41 | btech.com s_seq 1100133 | MOBILE_VIVO (1108021) | 일부 미수집(MOBILE_VIVO) | MOBILE_VIVO 1step은 browserless /function으로 VIVO 카테고리 페이지를 열어 30회 스크롤하며 로딩된 상품(a[href*="/p/"] 링크 기준)을 수집하는 커스텀 스크립트. 최근 4일간 수집 건수가 24→27→5→0(오늘, 치명적에러)으로 점점 줄다가 완전히 끊김. 에러 상세의 response_time이 0이어서(응답 자체를 못 받음) 사이트 구조변경이 아니라 browserless/proxy(proxy.realsn.com:24143) 쪽 타임아웃·장애로 추정됨. | 완료 |
| 42 | mvideo.ru s_seq 1100089 | MOBILE_VIVO (1107849) | 일부 미수집(MOBILE_VIVO) | 오수집/미수집 버그 아님. MOBILE_VIVO는 API 필터에 brand=vivo + prodavec(판매자)=mvideo(자사 직판) + sostoyanie(상태)=novyi(새상품) 3개 조건을 모두 거는데, 현재 mvideo.ru가 자사 직판으로 파는 Vivo 제품은 전부 "Восстановленный"(리퍼/재생) 상태뿐이라 "새상품" 조건과 겹치는 게 0건 → API가 204(결과없음) 응답 → Item 정규식 매칭 실패로 치명적에러 처리됨. 같은 사이트의 TECNO 보드(동일 필터 구조)는 오늘도 14건 정상 수집되는 것으로 보아 VIVO만의 특수한 재고 상황(새상품 매진)이지 스크립트/구조 문제가 아님. | 완료 |
| 51 | o2.cz s_seq 1100326 | MOBILE_SAMSUNG (1102839) | 일부 미수집(MOBILE_SAMSUNG) | 10/14 전체(4개 보드) 치명적에러(0건)는 이미 알려진 사이트 이전(eshop.o2.cz) 이슈와 동일. 10/15에는 새 URL(eshop.o2.cz)로 page 1까지는 정상 수집되지만(15건), page 2 요청에서 "예약어처리 에러(Item, NextLink)"로 멈춰 전체 112건 중 15건만 수집됨. 다만 PREG_TEST로 엔진과 동일한 서버(GB108)에서 바로 page2를 직접 호출해본 결과 Item·NextLink 정규식 모두 정상 매칭(15건+다음페이지 링크 확인됨) → 정규식/구조 문제가 아니라 그 시점의 일시적 네트워크 오류(간헐 실패)로 판단됨. | 완료 |
| 50 | samsung.com/ae(trade_in) s_seq 1100537 | TABLET_ALL_S10 FE+ (1107989) | 일부 미수집(TABLET_ALL_S10 FE+)(trade-in 활성화 상태 미수집) | 1step Script에서 재고확인 뒤에 `$stockFlag = 0;`이 다시 0으로 덮어써서 수집 블록이 항상 건너뛰어짐(10/13부터 수집 0건) | 완료 |
| 50 | apple.com/cn(trade_in) s_seq | PN B 오수집 | 엔진 스크립트가 Apple API를 조건별로 실제 호출하는 구조. B=C 항목(구형 저가 아이폰)은 API가 반환한 실제 최저가 동일값으로 정상 판단 | ✓ 확인 요청 | |
| 49 | samsung.com/in(trade_in) s_seq | TABLET_ALL_S10 FE+ 미수집 | 패턴변경 후 227/227 전부 채워짐 | ✓ 확인 요청 | |
| 48 | alza.cz s_seq | Z Fold8/Fold8 Ultra 미수집 | 패턴변경 후 전 용량 모두 수집됨 | ✓ 확인 요청 | |
| 47 | o2.cz s_seq | 전체 미수집 | URL 변경(eshop.o2.cz) 후 오늘 4개 보드 모두 15~71건 정상 수집 | ✓ 확인 요청 | |
| 46 | apple.com/tw(trade_in) s_seq | PN B 오수집 | 수정 전 B=C였으나 수정 후 분리됨 | ✓ 확인 요청 | |
| 45 | apple.com/au(trade_in) s_seq | PN B 오수집 | 수정 전 B=A였으나 수정 후 B가 고유값으로 분리됨 | ✓ 확인 요청 | |
| 44 | abenson.com s_seq | MOBILE_HUAWEI 가격 미수집 | 빈 가격 41건 전부 사이트에서 "Sold out" 확인, 채워진 24건은 "Available online" - 품절 미수집은 정상 | ✓ 확인 요청 | |
| 43 | boulanger.com s_seq | WATCH_APPLE 가격 미수집 | 55건 중 54건 채워짐(1건만 공백, 미미) | ✓ 확인 요청 | |
| 42 | samsung.com/pt(trade_in) s_seq | TABLET_ALL_S10 FE+ 미수집 | 패턴변경 후 222/222 가격 채워짐 | ✓ 확인 요청 | |
| 41 | telefonika.com s_seq | SAMSUNG/APPLE/HUAWEI 미수집 | 동일 프록시 수정, 3개 보드 모두 가격 전부 채워짐 | ✓ 확인 요청 | |
| 40 | compughana.com s_seq | MOBILE_HUAWEI 미수집 | 외부프록시 추가 후 5/5 정상 수집, 실제 사이트 상품과 일치 | ✓ 확인 요청 | |
| 57 | interdiscount.ch s_seq 1100450 | TABLET_SAMSUNG (1109013) | Tab S10+ 512GB C, Tab S10 FE/FE+/Lite 여러 용량 미수집 (6개 모델) | 오수집/미수집 아님. 신고된 Tab S10 FE(128/256GB), FE+(128/256GB), Lite(256GB)가 10/13 수집정보검색에서 전부 정상 가격 포함 수집되어 있음(29건 중 확인). "Tab S10+ 512GB C"만 색상코드(W/C)가 실제 사이트 색상(Grau/Silber)과 매칭 안 돼 확인 불가. | 완료 |
| 56 | harveynorman.com.au s_seq 1100471 | TABLET_SAMSUNG (1109071) | Tab S10+/FE/FE+/Lite 여러 용량 미수집 (7개 모델) | 실제 구조적 미수집 확인. 카테고리 페이지는 부모 상품당 1개 HTML 카드만 렌더링하고, 나머지 용량/색상 변형(Tab S10+ 256GB, FE/FE+ 128GB WiFi Blue/Grey 등)은 같은 페이지의 __NEXT_DATA__ JSON(productsData.items[].configurable_variants.variants[])에만 존재해 HTML 정규식(Item/Link Title)이 못 잡음. | 완료 |
| 54 | fravega.com s_seq | Samsung Galaxy Tab S10+ 256GB W 미수집 Samsung Galaxy Tab S10 FE 128GB 미수집 Samsung Galaxy Tab S10 FE 256GB 미수집 Samsung Galaxy Tab S10 FE+ 128GB 미수집 Samsung Galaxy Tab S10 FE+ 256GB 미수집 | 완료 | ||
| 52 | mediamarkt.com.tr s_seq | Samsung Galaxy Tab S11 128GB 미수집 Samsung Galaxy Tab S11 256GB 미수집 | 완료 | ||
| 53 | falabella.com s_seq | Samsung Galaxy Tab S10 FE 256GB 미수집 / Tab S10 FE+ 256GB 미수집 | 완료 | ||
| 51 | mxmemoxpress.com s_seq 1100176 | MOBILE_SAMSUNG(1101487) | Samsung Galaxy S26 Ultra 1024GB 미수집 | 오수집/미수집 아님. mxmemoxpress.com 1step이 WooCommerce REST API를 stock_status=instock 조건으로만 호출(재고 있는 상품만 수집하는 설계). 현재 1024GB(16GB RAM) 변형은 5개 색상(Black/Cobalt Violet/Silver Shadow/Sky Blue/White) 전부 품절 상태라 정상적으로 0건. | 완료 |
| 48 | o2.cz s_seq 1100326 | MOBILE_SAMSUNG 1102839 / MOBILE_APPLE 1102840 / MOBILE_XIAOMI 1102843 / MOBILE_HONOR 1103685 | 정의서 업데이트 (전체 미수집은 재조사 완료됨) | 사이트가 eshop.o2.cz로 이전돼 기존 API/구조 사용 불가. 보드 4개 재작성 필요 | 완료 |
| 48 | o2.cz s_seq 1100326 | MOBILE_SAMSUNG 1102839 / MOBILE_APPLE 1102840 / MOBILE_XIAOMI 1102843 / MOBILE_HONOR 1103685 | 수집원 URL 변경 (eshop.o2.cz로 재정의 요청, item 3) | 사이트가 eshop.o2.cz로 이전돼 기존 API/구조 사용 불가. 보드 4개 재작성 필요 | 완료 |
| 52 | bestbuy.ca s_seq | Samsung Galaxy Tab S11 128/256/512GB 미수집 | 완료 | ||
| 51 | interdiscount.ch s_seq | Samsung Galaxy Tab S11 128/256/512GB, Tab S11 Ultra 256/512GB 미수집 | 완료 | ||
| 50 | samsung.com/in(trade_in) s_seq | 일부 가격 미수집(TABLET_ALL_S10 FE+) | 1step 재고확인 루프가 재고 있는 첫 코드에서 break 해서 변형 1개만 수집, 나머지 유효 변형(용량/색상) 가격 미수집 | 완료 | |
| 49 | alza.cz s_seq | Samsung Galaxy Z Fold8 256/512/1024GB, Z Fold8 Ultra 256/512/1024GB 미수집 | NextLink 정규식이 "다음" 버튼의 aria-label 추가로 불일치해 1페이지만 수집 | 완료 | |
| 39 | backmarket.co.uk(Refur) s_seq 1100604 | MOBILE_SAMSUNG(1104779)/MOBILE_APPLE(1104780) | 전체 가격 미수집 | 261013 : 봇 챌린지/프록시 간헐 실패 반복, 구조변경 없음 / 재수집시 정상화 | 완료 |
| 54 | apple.com/au(trade_in) s_seq 1100289 | MOBILE_APPLE 1102672 | pn b항목 가격 오수집(a항목 가격 수집되고 있음) | Apple 트레이드인 질문 흐름이 5문항→4문항으로 바뀌면서 Plan_Name B(등급 B) URL이 존재하지 않는 5번째 파라미터를 참조해 깨짐 → B가 A와 동일한 가격으로 오수집됨 | 완료 |
| 51 | o2.cz s_seq 1100326 | MOBILE_SAMSUNG 1102839 / MOBILE_APPLE 1102840 / MOBILE_XIAOMI 1102843 / MOBILE_HONOR 1103685 | 전체 미수집 | 사이트가 eshop.o2.cz로 이전돼 기존 API/구조 사용 불가. 보드 4개 재작성 필요 | 완료 |
| 49 | samsung.com/pt(trade_in) s_seq 1100545 | TABLET_ALL_S10 FE+(1107969) | 일부 미수집(TABLET_ALL_S10 FE+) | 오수집/미수집 아님. 포르투갈 shop API 확인 결과 재고는 있으나(inStock, ON_SALE) supportedAvailableServices에 TRADE_IN이 없음(BENEFIT, ACCESSORIES만 존재) - 이 모델은 trade-in 서비스 자체를 지원하지 않아 0건 수집이 정상(established rule: trade-in 비활성화 상태는 미수집이 맞음) | 완료 |
| 48 | backmarket.es(RV) s_seq 1100848 | MOBILE_APPLE(1107934) | 일부 미수집(MOBILE_APPLE) | 스크립트 버그 발견. 1step Script에서 $proxyArr1/$proxyArr2(그리고 가격조회부의 $proxyArr)가 정의되지 않은 상태로 사용되어 "Undefined variable" PHP 경고 발생 → 프록시 값이 빈 값이 되어 browserless 호출이 매번 무응답으로 실패(10/13·10/14 전체 4회 실행 100% 동일 에러). 같은 사이트 MOBILE_SAMSUNG 보드는 동일한 변수명을 쓰는데 정상 동작 중이라 원인(어디서 정의되어야 하는지) 교차 확인 필요 | 완료 |
| 47 | telefonika.com s_seq 1100915 | MOBILE_SAMSUNG(1109393)/MOBILE_APPLE(1109394)/MOBILE_HUAWEI(1109395) | 일부 미수집(MOBILE_SAMSUNG,MOBILE_APPLE,MOBILE_HUAWEI) | 사이트 구조 변경 없음(Item 정규식 그대로 매칭됨, 직접 fetch로 Samsung 15/60 상품 확인). 서버(엔진) 요청이 일부 실행에서 무응답(error 330, response_time 0)으로 실패 - 간헐적 서버/네트워크 차단 의심 | 완료 |
| 46 | compughana.com s_seq 1100916 | MOBILE_HUAWEI (1109399) | 일부 미수집(MOBILE_HUAWEI) | 오수집/미수집 아님. compughana.com의 HUAWEI 필터 컬렉션 자체에 현재 판매 중인 상품이 0개 - 정상적인 0건 수집. | 완료 |
| 40 | telstra.com.au(RV) s_seq | MOBILE_SAMSUNG, MOBILE_APPLE (신규 2개, 수집_수집원(new) 탭 요청) | 신규 사이트 추가 (trade-in/buyback) | API 방식으로 수집 가능 확인. 정규식/HTML 파싱 불필요 - 단일 JSON 호출로 전체 기기(2,634건, Samsung 1,528/Apple 656 등) 가격 한번에 제공. | 완료 |
| 43 | backmarket.co.uk(Refur) s_seq 1100604 | MOBILE_APPLE(1104780) / MOBILE_SAMSUNG(1104779) | 전체 가격 미수집 | 간헐 실패 아님. 10/13~10/14 이틀 연속 같은 증상: SAMSUNG(1104779)은 Algolia 검색 API가 Unlocker에서 403으로 거절돼 수집 0건, APPLE(1104780)은 목록 19건은 나오지만 2step 가격이 19건 전부 빔. 이전 보고(재수집시 정상화)는 수정 필요 | 완료 |
| 49 | worten.pt s_seq 1100112 | MOBILE_SAMSUNG 1101189 (+ RC9-05에서 돈 WATCH/MOBILE_APPLE 실행) | 일부 미수집(MOBILE_SAMSUNG,WATCH_APPLE,WATCH_HUAWEI) | 스크립트 문제 아님. 10/10부터 RC9-05 서버에서 돈 실행만 전부 실패(MOBILE_SAMSUNG는 항상 RC9-05 배정 → 시작 즉시 Process Kill). 할당서버에서 RC9-05 제외 또는 서버 브라우저 프로필 정리 후 재수집 | 완료 |
| 48 | t-mobile.cz s_seq 1100125 | MOBILE_APPLE 1107534 / MOBILE_HONOR 1107535 / MOBILE_SAMSUNG 1107536 / MOBILE_XIAOMI 1107537 | 전체 미수집 | 원인: 10/10 listing API 응답 구조 변경 → 1step Item/Title/Link 0건. 수정 남은 것: HONOR·XIAOMI 정규식 추가, APPLE은 바디의 "excludeLinkedProductId":true 제거(이 값 때문에 0건). 2step은 수정 불필요(10/9 수집값과 동일하게 재현됨) | 완료 |
| 45 | mediamarkt.es s_seq 1100084 | MOBILE_GOOGLE 1108328 (MOBILE_HONOR 1101079도 같은 현상) | 일부 미수집(MOBILE_GOOGLE) | 일시적 문제. 오늘 새벽 2페이지 응답만 실패(34건 중 12건 수집)했고, 지금 할당서버(HB03)로 프리뷰 돌리면 1·2페이지 모두 정상 → 재수집하면 정상화될 건 | 완료 |
| 44 | mvideo.ru s_seq 1100089 | 전체 14개 보드 (TWS/WATCH/MOBILE 전 브랜드, 1step이 bff/products API로 전환) | 전체 미수집 | 10/12부터 mvideo bff/products API가 필수 쿠키(MVID_CITY_ID 등 7종) 없는 요청을 400으로 거절 → 1step Item 0건, 14개 보드 전부 치명적에러. 쿠키를 받아서 같이 보내도록 스크립트 수정 필요 | 완료 |
| 47 | samsung.com/in s_seq 1100041 | TWS_SAMSUNG 1108393 | 일부 미수집(TWS_SAMSUNG) | 보드 URL의 "Available to order" 필터(filter2=16s01)가 사이트에서 0건을 반환 → Item 0건(치명적에러). 실제로는 Buds4 Pro·Buds3 FE가 재고 있음. URL 필터 제거 + 스크립트에서 재고 거르기로 변경 필요 | 완료 |
| 42 | compughana.com s_seq 1100916 | MOBILE_SAMSUNG 1109397 (MOBILE_TECNO 1109400도 같은 에러) | 일부 오수집(MOBILE_SAMSUNG) | 보고된 오수집은 phones-tablets 카테고리라 삼성 태블릿(Galaxy Tab A11 등)이 MOBILE_SAMSUNG에 섞인 것. 추가로 10/8 오후부터 MOBILE_SAMSUNG·TECNO는 서버에서 빈 응답(치명적에러)으로 0건 | 완료 |
| 51 | samsung.com trade_in (28개 국가) s_seq | TABLET_ALL 계열 | 브랜드 추가(TABLET_ALL_S12 ULTRA, TABLET_ALL_S12+) | Galaxy Tab S12 Ultra·S12+ 신제품(2026-10-07 글로벌 출시) 트레이드인 보드 신규 추가 요청. 28개국 samsung.com trade_in 보드 전부에 TABLET_ALL_S12 ULTRA, TABLET_ALL_S12+ 보드가 없음(확인 보드: samsung.com/de #1100511, TABLET_ALL 계열 중 최신이 S11/S11 ULTRA까지만 있고 S12 계열 없음). | 완료 |
| 46 | trocafone.com(RV) s_seq 1100772 | 전체 | 전체 미수집 | 사이트/보드 상태는 "정상"·"동작"이지만 오늘·어제 모두 로그 자체가 없음(수집 시도 기록조차 없음) — 최근 2주 내 동일 증상 2회(260928,261002) 반복, 스케줄 실행 자체가 안 되는 인프라성 문제로 추정 | 완료 |
| 58 | samsung.com/sg(trade_in) s_seq 1100880 | S25 FE 1108728 / S25 Ultra 1108718 / S26 FE 1109392 | S25 FE 비활성화 상태 오수집 / S25 Ultra,S26 FE 활성화 상태 미수집 | 1번(S25 FE 오수집)은 해결(0건). 새 2번 S25 Ultra·S26 FE 미수집은 아직 0건 — 실제 트레이드인 가능 여부 추가 확인 필요 | 완료 |
| 56 | samsung.com/nl(trade_in) s_seq 1100621 | WATCH_ALL_7(40MM) 1107419 / WATCH_ALL_7(44MM) 1107420 | 일부 오수집(40MM/44MM, 미판매 상태 수집) | 1번(W7 40MM)은 해결(0건), 새 2번(W7 44MM)은 판매 종료인데 아직 21건 수집 → 오수집 | 완료 |
| 55 | samsung.com/be(trade_in) s_seq 1100623 | WATCH_ALL_7(40MM) 1107284 / WATCH_ALL_7(44MM) 1107285 | 일부 오수집(44MM/40MM, 미판매 상태 수집) | 1번(W7 44MM)은 해결(0건), 새 2번(W7 40MM)은 판매 종료인데 아직 21건 수집 → 오수집 | 완료 |
| 54 | fnac.com s_seq | MOBILE_SAMSUNG | 수집원교체/URL교체/URL변경 | 3번 "수집원 URL 변경" 요청(요청자 종은). 수집_수집원(new) 탭의 새 URL 확인 필요 — 다음 실행에서 처리 | 완료 |
!data-test="mms-product-card">(.*?<button type="button".*?)<[^>]+data-test="mms-search-wishlist!s
!data-test="mms-product-card">(.*?)<[^>]+data-test="mms-search-wishlist!s
!(<article.*?6c2f030f.*?</article>)!s
!(<article data.*?data-test="grid-item-heading"[^>]*>.*?</article>)!s !(<article data.*?</article>)!s
// }
$stockFlag = 0;
if ($stockFlag == 1) {// }
// $stockFlag = 0; <- 삭제 또는 주석
if ($stockFlag == 1) {<?
$responseBody = "";
$PN = "Galaxy Tab S10 FE+";
// $productCode = "SM-X626BZSEMEA";
$stockFlag = 0;
$this->arrCurlOption[CURLOPT_URL] = $this->baseURL;
$pageSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
if (preg_match('!/tablets/|/watches/!', $this->baseURL)) {
$prefixPattern = '!^(SM-[A-Z][0-9]{2})!';
} else {
$prefixPattern = '!^(SM-[A-Z][0-9]{3})!';
}
if (preg_match('!"displayName":"' . preg_quote($PN, '!') . '","englishName":"[^"]+","[^"]+":"[^"]+","modelCode":"(SM-[A-Z0-9]+)"!s', $pageSource, $tempPNCode)) {
$pnModelCode = $tempPNCode[1];
if (preg_match($prefixPattern, $pnModelCode, $tempFamily)) {
$familyPrefix = $tempFamily[1];
if (preg_match_all('!"(' . preg_quote($familyPrefix, '!') . '[A-Z0-9]+)"!s', $pageSource, $tempAllCodes)) {
$allModelCodes = array_unique($tempAllCodes[1]);
} else {
$allModelCodes = array($pnModelCode);
}
} else {
$allModelCodes = array($pnModelCode);
}
} elseif (preg_match_all('!"(SM-[A-Z0-9]+)"!s', $pageSource, $tempAllCodes)) {
$allModelCodes = array_unique($tempAllCodes[1]);
} else {
$allModelCodes = array();
}
foreach ($allModelCodes as $checkCode) {
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/tokocommercewebservices/v2/ae/servicesv2/getTradeInSimpleInfo?productCode=" . $checkCode;
$stockSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
if (!preg_match('!Service List is Empty!s', $stockSource) && !preg_match('!(?:UnknownIdentifierError|IllegalArgumentError)!s', $stockSource)) {
$stockFlag = 1;
$productCode = $checkCode;
break;
}
sleep(1);
}
if ($stockFlag == 0) {
$productCode = 'SM-A077FLVDMEA';
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/tokocommercewebservices/v2/ae/servicesv2/getTradeInSimpleInfo?productCode=" . $productCode;
$stockSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
if (preg_match('!"provider"\s*:\s*"NORTHLADDER"!s', $stockSource)) {
$stockFlag = 1;
}
}
// $productCode = 'SM-X626BZSAMEA';
$this->arrDefaultSet['CRAWLER']['TEMP']['CAT'] ='';
$this->arrDefaultSet['CRAWLER']['TEMP']['CAT'] = $productCode;
// $stockFlag = 1;
// $stockFlag = 0;
// $this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/tokocommercewebservices/v2/ae/servicesv2/getTradeInSimpleInfo?productCode=" . $productCode;
// $stockSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
// if (!preg_match('!Service List is Empty!s', $stockSource) && !preg_match('!IllegalArgumentError!s', $stockSource) && !preg_match('!UnknownIdentifierError!s', $stockSource)) {
// $stockFlag = 1;
// }
// $stockFlag = 0;
if ($stockFlag == 1) {
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$catSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
if (preg_match('!"category":"deviceType","value":"(Tablet)",!s', $catSource, $tempCategory)) {
$catId = rawurlencode($tempCategory[1]);
} else {
$catId = "";
}
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$brandSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
if (preg_match_all('!("category":"brandName","value":"[^"]+","displayName":".*?",)!s', $brandSource, $tempBrandArr)) {
foreach($tempBrandArr[1] as $tempBrandSource) {
if (preg_match('!"value":"([^"]+)"!s', $tempBrandSource, $tempBrandKey)) {
$brandKey = rawurlencode($tempBrandKey[1]);
} else {
$brandKey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempBrandSource, $tempBrand)) {
$brand = $tempBrand[1];
} else {
$brand = "";
}
if ($brand == "Samsung" || $brand == "Apple") {
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. ":brandName:" .$brandKey. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$this->arrHeader = array(
'sec-ch-ua-platform: "Windows"',
'Referer: https://www.samsung.com/',
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
'Accept: application/json, text/javascript, */*; q=0.01',
'sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
'sec-ch-ua-mobile: ?0'
);
$this->arrCurlOption[CURLOPT_HTTPHEADER] = $this->arrHeader;
$modelNameSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
$modelNameJson = json_decode($modelNameSource, true);
$modelNameSource = json_encode($modelNameJson['children'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
if (preg_match_all('!("category":".*?","value":".*?","displayName":".*?",)!s', $modelNameSource, $tempModelNameArr)) {
foreach($tempModelNameArr[1] as $tempModelNameSource) {
if (preg_match('!"category":"(.*?)",!s', $tempModelNameSource, $tempModelNameCat)) {
$modelNameCat = rawurlencode($tempModelNameCat[1]);
} else {
$modelNameCat = "";
}
if (preg_match('!"value":"(.*?)",!s', $tempModelNameSource, $tempModelNameKey)) {
$modelNameKey = rawurlencode($tempModelNameKey[1]);
} else {
$modelNameKey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempModelNameSource, $tempModelName)) {
$modelName = $tempModelName[1];
} else {
$modelName = "";
}
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. ":brandName:" .$brandKey. ":" .$modelNameCat. ":" .$modelNameKey. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$modelSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
$modelJson = json_decode($modelSource, true);
$modelSource = json_encode($modelJson['children'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
if (preg_match_all('!("category":".*?","value":".*?","displayName":".*?",)!is', $modelSource, $tempModelArr)) {
foreach($tempModelArr[1] as $tempModelSource) {
if (preg_match('!"category":"(.*?)",!s', $tempModelSource, $tempModelCat)) {
$modelCat = rawurlencode($tempModelCat[1]);
} else {
$modelCat = "";
}
if (preg_match('!"value":"(.*?)",!s', $tempModelSource, $tempModelKey)) {
$modelKey = rawurlencode($tempModelKey[1]);
} else {
$modelKey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempModelSource, $tempModel)) {
$model = $tempModel[1];
} else {
$model = "";
}
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. ":brandName:" .$brandKey. ":" .$modelNameCat. ":" .$modelNameKey. ":" .$modelCat. ":" .$modelKey. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$screenSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
$screenJson = json_decode($screenSource, true);
$screenSource = json_encode($screenJson['children'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
if (preg_match_all('!("category":".*?","value":".*?","displayName":".*?",)!is', $screenSource, $tempScreenArr)) {
foreach($tempScreenArr[1] as $tempScreenSource) {
if (preg_match('!"category":"(.*?)",!s', $tempScreenSource, $tempScreenCat)) {
$screenCat = rawurlencode(str_replace('\\', '', $tempScreenCat[1]));
} else {
$screenCat = "";
}
if (preg_match('!"value":"(.*?)",!s', $tempScreenSource, $tempScreenKey)) {
$screenKey = rawurlencode(str_replace('\\', '', $tempScreenKey[1]));
$screenParam = rawurlencode($tempScreenKey[1]);
} else {
$screenkey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempScreenSource, $tempScreen)) {
$screen = $tempScreen[1];
} else {
$screen = "";
}
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. ":brandName:" .$brandKey. ":" .$modelNameCat. ":" .$modelNameKey. ":" .$modelCat. ":" .$modelKey. ":" .$screenCat. ":" .$screenKey. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$variantSource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
$variantJson = json_decode($variantSource, true);
$variantSource = json_encode($variantJson['children'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
if (preg_match_all('!("category":".*?","value":".*?","displayName":".*?",)!is', $variantSource, $tempVariantArr)) {
foreach($tempVariantArr[1] as $tempVariantSource) {
if (preg_match('!"category":"(.*?)",!s', $tempVariantSource, $tempVariantCat)) {
$variantCat = rawurlencode(str_replace('\\', '', $tempVariantCat[1]));
} else {
$variantCat = "";
}
if (preg_match('!"value":"(.*?)",!s', $tempVariantSource, $tempVariantKey)) {
$variantKey = rawurlencode(str_replace('\\', '', $tempVariantKey[1]));
$variantParam = rawurlencode($tempVariantKey[1]);
} else {
$variantkey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempVariantSource, $tempVariant)) {
$variant = $tempVariant[1];
} else {
$variant = "";
}
$this->arrCurlOption[CURLOPT_URL] = "https://shop.samsung.com/ae/tradeinv2/filterDevices?q=deviceType:" .$catId. ":brandName:" .$brandKey. ":" .$modelNameCat. ":" .$modelNameKey. ":" .$modelCat. ":" .$modelKey. ":" .$screenCat. ":" .$screenKey. ":" .$variantCat. ":" .$variantKey. "&mainProductCode=" .$productCode. "&provider=NORTHLADDER";
$memorySource = $this->classRequestURL->getHtmlObj($this->arrCurlOption);
$memoryJson = json_decode($memorySource, true);
$memorySource = json_encode($memoryJson['children'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
if (preg_match_all('!("category":".*?","value":".*?","displayName":".*?",)!is', $memorySource, $tempMemoryArr)) {
foreach($tempMemoryArr[1] as $tempMemorySource) {
if (preg_match('!"category":"(.*?)",!s', $tempMemorySource, $tempMemoryCat)) {
$memoryCat = rawurlencode(str_replace('\\', '', $tempMemoryCat[1]));
} else {
$memoryCat = "";
}
if (preg_match('!"value":"(.*?)",!s', $tempMemorySource, $tempMemoryKey)) {
$memoryKey = rawurlencode(str_replace('\\', '', $tempMemoryKey[1]));
$memoryParam = rawurlencode($tempMemoryKey[1]);
} else {
$memoryKey = "";
}
if (preg_match('!"displayName":"(.*?)",!s', $tempMemorySource, $tempMemory)) {
$memory = $tempMemory[1];
} else {
$memory = "";
}
$responseBody .= "@#RSNSTART@#" . "Title:" . $brand . " " . $modelName . " " . $model . " " . $screen . " " . $variant . " " . $memory . "Link:" . $brand . "#" . $modelName . "#" . $model . "#" . $screen . "#" . $variant . "#" . $memory . "Param:deviceType:" .$catId. ":brandName:" .$brandKey. ":" .$modelNameCat. ":" .$modelNameKey.":" .$modelCat. ":" .$modelKey.":" .$screenCat. ":" .$screenParam. ":" .$variantCat. ":" .$variantParam. ":" .$memoryCat. ":" .$memoryParam. "@#RSNEND@#";
$this->arrCurlOption[CURLOPT_POST] = false;
unset($this->arrCurlOption[CURLOPT_POSTFIELDS]);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
$this->requestChk = true;
if( isset($this->arrDefaultSet['CRAWLER']['p_seq']) ){
$this->insertTable('PREVIEW_HISTORY', array('ph_url' => "'".changeSQL($this->baseURL)."'", 'ph_http_header' => "''", 'ph_html_source' => "'".changeSQL($responseBody)."'", 'ph_step' => $step, 'p_seq' => $this->arrDefaultSet['CRAWLER']['p_seq']));
}// 1step Script 마지막 부분
$this->requestChk = true;
// 프리뷰 보이게 하기
if( isset($this->arrDefaultSet['CRAWLER']['p_seq'])){ ... }// 1step Script 마지막 부분 뒤에 추가
if (preg_match('!<script id="__NEXT_DATA__" type="application/json">(.*?)</script>!s', $responseBody, $tempNext)) {
$nextData = json_decode($tempNext[1], true);
$items = isset($nextData['props']['pageProps']['pageProps']['pageData']['productsData']['items']) ? $nextData['props']['pageProps']['pageProps']['pageData']['productsData']['items'] : array();
$existingLinks = array();
foreach ($this->arrData as $tempRow) { $existingLinks[$tempRow['Link']] = true; }
foreach ($items as $tempItem) {
if (!isset($tempItem['configurable_variants']['variants'])) continue;
foreach ($tempItem['configurable_variants']['variants'] as $variant) {
$variantUrl = 'https://www.harveynorman.com.au/' . $variant['url_key'] . '.html';
if (isset($existingLinks[$variantUrl])) continue;
if ($variant['stock_status'] !== 'IN_STOCK') continue;
$this->arrData[] = array('Title' => $variant['name'], 'Link' => $variantUrl);
$existingLinks[$variantUrl] = true;
}
}
}
$this->requestChk = true;https://www.o2.cz/telefony-a-zarizeni/samsung -> https://eshop.o2.cz/collections/samsung https://www.o2.cz/telefony-a-zarizeni/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu -> https://eshop.o2.cz/collections/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu
Item : !"_index":"[^"]+",(.*?)"campaigns"!s Link : !"image".*?"seoUrl":"([^"]+)",!s Script: $responseBody = 'http://www.o2.cz/telefony-a-zarizeni/produkt/' . $responseBody; Title: !"model":"(.*?)",!s!"name":.*?"cs":"(.*?)"!s
Item : !(<li class="grid__item">\s*<product-card-o2 class="o2-card-wrapper">.*?</product-card-o2>)!s Link : !<a\s+href="(/products/[^"?]+)!s Script: $responseBody = 'https://eshop.o2.cz' . $responseBody; Title: !o2-card__title-link"\s*>\s*(.*?)\s*</a>!s
===== 1step 교체 부분 (CURLOPT_POST = true 줄부터 끝까지 이 내용으로) =====
$this->arrCurlOption[CURLOPT_POST] = false;
unset($this->arrCurlOption[CURLOPT_POSTFIELDS]);
$this->arrHeader = array(
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: cs',
'Referer: https://eshop.o2.cz/',
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
);
$this->arrCurlOption[CURLOPT_HTTPHEADER] = $this->arrHeader;
===== 2step 전체 소스 =====
$tempResultData = array();
$tempResultIdx = 0;
// 품절 상품 제외 (상품 페이지의 available 값)
if (preg_match('!"available":\s*true!s', $responseBody)) {
// 색상: 상품명 마지막 콤마 뒤 (예: Samsung Galaxy S26 Ultra 5G 256GB, fialová)
if (preg_match('!"title":\s*"[^"]*,\s*([^,"]+)",\s*"image"!s', $responseBody, $tempColor)) {
$color = trim($tempColor[1]);
} else {
$color = "";
}
if (preg_match('!"name":"Celková paměť \(GB\)","value":"([^"]+)"!s', $responseBody, $tempMemory)) {
$memory = $tempMemory[1]."GB";
} else {
$memory = "NA";
}
if (preg_match('!"name":"Operační paměť RAM \(MB\)","value":"([^"]+)"!s', $responseBody, $tempRam)) {
$tempRam = $tempRam[1]/1024;
$ram = $tempRam."GB";
} else {
$ram = "NA";
}
// 판매가: 코드 할인 적용가(표시가) 우선, 없으면 일반가
if (preg_match('!data-o2-displayed-price-label="([^"]+)"!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = preg_replace('![^0-9]!', '', $tempRPA[1]);
} else if (preg_match('!"price_at_add":\s*([0-9]+)!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = $tempRPA[1] / 100;
} else {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = "";
}
// 월 할부금 (MDA)
if (preg_match('!installments-o2__monthly">\s*pak\s*<strong>([^<]+)</strong>!s', $responseBody, $tempMDA)) {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = preg_replace('![^0-9]!', '', $tempMDA[1]);
} else {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = "0";
}
// 선납금 (Upfront)
if (preg_match('!installments-o2__pay-now">\s*Teď zaplatíte\s*<strong>([^<]+)</strong>!s', $responseBody, $tempUA)) {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = preg_replace('![^0-9]!', '', $tempUA[1]);
} else {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = "0";
}
$tempResultData[$tempResultIdx]['Plan_Name'] = $this->arrDefaultSet['CRAWLER']['TEMP']['PN'];
$tempResultData[$tempResultIdx]['Tariff_Actual'] = $this->arrDefaultSet['CRAWLER']['TEMP']['TA'];
$tempResultData[$tempResultIdx]['Memory'] = $memory . "/" . $ram;
$tempResultData[$tempResultIdx]['Url'] = $this->arrData[$listNumber]['Link'] . "#" . $color . "#" . $memory;
$tempResultIdx += 1;
}
if (sizeof($tempResultData) > 0) {
$responseBody = $tempResultData;
} else {
$responseBody = "";
}
===== NextLink Script (NextLink 노드 아래 Script) =====
if ($responseBody != "") {
$responseBody = 'https://eshop.o2.cz' . str_replace('&', '&', $responseBody);
}https://www.o2.cz/telefony-a-zarizeni/samsung -> https://eshop.o2.cz/collections/samsung https://www.o2.cz/telefony-a-zarizeni/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu -> https://eshop.o2.cz/collections/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu
Item : !"_index":"[^"]+",(.*?)"campaigns"!s Link : !"image".*?"seoUrl":"([^"]+)",!s Script: $responseBody = 'http://www.o2.cz/telefony-a-zarizeni/produkt/' . $responseBody; Title: !"model":"(.*?)",!s!"name":.*?"cs":"(.*?)"!s
Item : !(<li class="grid__item">\s*<product-card-o2 class="o2-card-wrapper">.*?</product-card-o2>)!s Link : !<a\s+href="(/products/[^"?]+)!s Script: $responseBody = 'https://eshop.o2.cz' . $responseBody; Title: !o2-card__title-link"\s*>\s*(.*?)\s*</a>!s
===== 1step 교체 부분 (CURLOPT_POST = true 줄부터 끝까지 이 내용으로) =====
$this->arrCurlOption[CURLOPT_POST] = false;
unset($this->arrCurlOption[CURLOPT_POSTFIELDS]);
$this->arrHeader = array(
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: cs',
'Referer: https://eshop.o2.cz/',
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
);
$this->arrCurlOption[CURLOPT_HTTPHEADER] = $this->arrHeader;
===== 2step 전체 소스 =====
$tempResultData = array();
$tempResultIdx = 0;
// 품절 상품 제외 (상품 페이지의 available 값)
if (preg_match('!"available":\s*true!s', $responseBody)) {
// 색상: 상품명 마지막 콤마 뒤 (예: Samsung Galaxy S26 Ultra 5G 256GB, fialová)
if (preg_match('!"title":\s*"[^"]*,\s*([^,"]+)",\s*"image"!s', $responseBody, $tempColor)) {
$color = trim($tempColor[1]);
} else {
$color = "";
}
if (preg_match('!"name":"Celková paměť \(GB\)","value":"([^"]+)"!s', $responseBody, $tempMemory)) {
$memory = $tempMemory[1]."GB";
} else {
$memory = "NA";
}
if (preg_match('!"name":"Operační paměť RAM \(MB\)","value":"([^"]+)"!s', $responseBody, $tempRam)) {
$tempRam = $tempRam[1]/1024;
$ram = $tempRam."GB";
} else {
$ram = "NA";
}
// 판매가: 코드 할인 적용가(표시가) 우선, 없으면 일반가
if (preg_match('!data-o2-displayed-price-label="([^"]+)"!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = preg_replace('![^0-9]!', '', $tempRPA[1]);
} else if (preg_match('!"price_at_add":\s*([0-9]+)!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = $tempRPA[1] / 100;
} else {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = "";
}
// 월 할부금 (MDA)
if (preg_match('!installments-o2__monthly">\s*pak\s*<strong>([^<]+)</strong>!s', $responseBody, $tempMDA)) {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = preg_replace('![^0-9]!', '', $tempMDA[1]);
} else {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = "0";
}
// 선납금 (Upfront)
if (preg_match('!installments-o2__pay-now">\s*Teď zaplatíte\s*<strong>([^<]+)</strong>!s', $responseBody, $tempUA)) {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = preg_replace('![^0-9]!', '', $tempUA[1]);
} else {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = "0";
}
$tempResultData[$tempResultIdx]['Plan_Name'] = $this->arrDefaultSet['CRAWLER']['TEMP']['PN'];
$tempResultData[$tempResultIdx]['Tariff_Actual'] = $this->arrDefaultSet['CRAWLER']['TEMP']['TA'];
$tempResultData[$tempResultIdx]['Memory'] = $memory . "/" . $ram;
$tempResultData[$tempResultIdx]['Url'] = $this->arrData[$listNumber]['Link'] . "#" . $color . "#" . $memory;
$tempResultIdx += 1;
}
if (sizeof($tempResultData) > 0) {
$responseBody = $tempResultData;
} else {
$responseBody = "";
}
===== NextLink Script (NextLink 노드 아래 Script) =====
if ($responseBody != "") {
$responseBody = 'https://eshop.o2.cz' . str_replace('&', '&', $responseBody);
}$stockFlag = 0; ... foreach ($allModelCodes as $checkCode) { ...; if (...유효...) { $stockFlag = 1; $productCode = $checkCode; break; } sleep(1); } if ($stockFlag == 1) { ...단일 $productCode로 offers~trade-in까지 1회만 처리... }$validProductCodes = array(); foreach ($allModelCodes as $checkCode) { ...; if (...유효...) { $validProductCodes[] = $checkCode; } sleep(1); } foreach ($validProductCodes as $productCode) { ...offers~trade-in 처리(기존과 동일 로직)를 코드마다 반복... }!class=\"next fa[^>]+id=\"pgby([0-9]+)\">!s
!class=\"next fa[^>]+id=\"pgby([0-9]+)\"[^>]*>!s
$nextUrl2 = $nextUrl . "&" . $paramArr[0] . "=2&" . $paramArr[1] . "=1&" . $paramArr[2] . "=1&" . $paramArr[3] . "=1&" . $paramArr[4] . "=2";
$nextUrl2 = str_replace('module=verify', 'module=questions', $nextUrl2);
$planName = "B"; $nextUrl2 = $nextUrl . "&" . $paramArr[0] . "=2&" . $paramArr[1] . "=1&" . $paramArr[2] . "=1&" . $paramArr[3] . "=2";
$nextUrl2 = str_replace('module=verify', 'module=questions', $nextUrl2);
$planName = "B";https://www.o2.cz/telefony-a-zarizeni/samsung -> https://eshop.o2.cz/collections/samsung https://www.o2.cz/telefony-a-zarizeni/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu -> https://eshop.o2.cz/collections/telefony?sort=RECOMMENDED&f3=samsung&f1=skladem-na-e-shopu
Item : !"_index":"[^"]+",(.*?)"campaigns"!s Link : !"image".*?"seoUrl":"([^"]+)",!s Script: $responseBody = 'http://www.o2.cz/telefony-a-zarizeni/produkt/' . $responseBody; Title: !"model":"(.*?)",!s!"name":.*?"cs":"(.*?)"!s
Item : !(<li class="grid__item">\s*<product-card-o2 class="o2-card-wrapper">.*?</product-card-o2>)!s Link : !<a\s+href="(/products/[^"?]+)!s Script: $responseBody = 'https://eshop.o2.cz' . $responseBody; Title: !o2-card__title-link"\s*>\s*(.*?)\s*</a>!s
===== 1step 교체 부분 (CURLOPT_POST = true 줄부터 끝까지 이 내용으로) =====
$this->arrCurlOption[CURLOPT_POST] = false;
unset($this->arrCurlOption[CURLOPT_POSTFIELDS]);
$this->arrHeader = array(
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: cs',
'Referer: https://eshop.o2.cz/',
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
);
$this->arrCurlOption[CURLOPT_HTTPHEADER] = $this->arrHeader;
===== 2step 전체 소스 =====
$tempResultData = array();
$tempResultIdx = 0;
// 품절 상품 제외 (상품 페이지의 available 값)
if (preg_match('!"available":\s*true!s', $responseBody)) {
// 색상: 상품명 마지막 콤마 뒤 (예: Samsung Galaxy S26 Ultra 5G 256GB, fialová)
if (preg_match('!"title":\s*"[^"]*,\s*([^,"]+)",\s*"image"!s', $responseBody, $tempColor)) {
$color = trim($tempColor[1]);
} else {
$color = "";
}
if (preg_match('!"name":"Celková paměť \(GB\)","value":"([^"]+)"!s', $responseBody, $tempMemory)) {
$memory = $tempMemory[1]."GB";
} else {
$memory = "NA";
}
if (preg_match('!"name":"Operační paměť RAM \(MB\)","value":"([^"]+)"!s', $responseBody, $tempRam)) {
$tempRam = $tempRam[1]/1024;
$ram = $tempRam."GB";
} else {
$ram = "NA";
}
// 판매가: 코드 할인 적용가(표시가) 우선, 없으면 일반가
if (preg_match('!data-o2-displayed-price-label="([^"]+)"!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = preg_replace('![^0-9]!', '', $tempRPA[1]);
} else if (preg_match('!"price_at_add":\s*([0-9]+)!s', $responseBody, $tempRPA)) {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = $tempRPA[1] / 100;
} else {
$tempResultData[$tempResultIdx]['Retail_Price_Actual'] = "";
}
// 월 할부금 (MDA)
if (preg_match('!installments-o2__monthly">\s*pak\s*<strong>([^<]+)</strong>!s', $responseBody, $tempMDA)) {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = preg_replace('![^0-9]!', '', $tempMDA[1]);
} else {
$tempResultData[$tempResultIdx]['Monthly_Device_Actual'] = "0";
}
// 선납금 (Upfront)
if (preg_match('!installments-o2__pay-now">\s*Teď zaplatíte\s*<strong>([^<]+)</strong>!s', $responseBody, $tempUA)) {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = preg_replace('![^0-9]!', '', $tempUA[1]);
} else {
$tempResultData[$tempResultIdx]['Upfront_Actual'] = "0";
}
$tempResultData[$tempResultIdx]['Plan_Name'] = $this->arrDefaultSet['CRAWLER']['TEMP']['PN'];
$tempResultData[$tempResultIdx]['Tariff_Actual'] = $this->arrDefaultSet['CRAWLER']['TEMP']['TA'];
$tempResultData[$tempResultIdx]['Memory'] = $memory . "/" . $ram;
$tempResultData[$tempResultIdx]['Url'] = $this->arrData[$listNumber]['Link'] . "#" . $color . "#" . $memory;
$tempResultIdx += 1;
}
if (sizeof($tempResultData) > 0) {
$responseBody = $tempResultData;
} else {
$responseBody = "";
}
===== NextLink Script (NextLink 노드 아래 Script) =====
if ($responseBody != "") {
$responseBody = 'https://eshop.o2.cz' . str_replace('&', '&', $responseBody);
}Item : !({[^}]+"variant".*?"tradeIn"[^}]+})!s
Title: !"productName":"(.*?)",!s
Link : !"productId":"([^"]+)"!sItem : !({"tileType":"variant".*?(?=,\{"tileType"|\],"characteristics"))!s
Title: !"name":"(.*?)"!s
Link : !"productSlug":"([^"]+)"!shttps://searchapi.samsung.com/v6/front/b2c/product/finder/newhybris?type=01040000&siteCode=in&start=1&num=12&sort=recommended&onlyFilterInfoYN=N&keySummaryYN=Y&filter2=16s01
https://searchapi.samsung.com/v6/front/b2c/product/finder/newhybris?type=01040000&siteCode=in&start=1&num=12&sort=recommended&onlyFilterInfoYN=N&keySummaryYN=Y
!<div class="card-wrapper product-card-wrapper underline-links-hover">(.*?)</li>!is
!<div class="card-wrapper product-card-wrapper underline-links-hover">((?:(?!Galaxy Tab).)*?)</li>!is