| 행 | 사이트 | 보드 | 시트 이슈 | 원인 한 줄 | 상태 |
|---|---|---|---|---|---|
| 42 | mediaworld.it s_seq 1100427 | MOBILE_APPLE 1103417 (동작 중) | RPA 오수집 및 "제목 없음" 수집 | iPhone 18 카드에 button 태그가 없어 Item 정규식이 카드를 삼킴(87→64건) | 완료 |
| 41 | erosdigitalhome.ae s_seq | 일부 미수집(MOBILE_MOTOROLA) | 완료 | ||
| 40 | telenor.se s_seq 1100310 | MOBILE_SAMSUNG (1102748) / MOBILE_APPLE (1102749) | 전체 미수집 및 오수집 | Item 정규식에 하드코딩된 CSS 해시가 바뀌어 0건. 해시 의존 제거 필요 | 완료 |
| 41 | btech.com s_seq 1100133 | MOBILE_VIVO (1108021) | 일부 미수집(MOBILE_VIVO) | 브라우저 응답 자체를 못 받음. 구조 변경이 아닌 browserless/proxy 장애 추정 | 완료 |
| 42 | mvideo.ru s_seq 1100089 | MOBILE_VIVO (1107849) | 일부 미수집(MOBILE_VIVO) | 미수집 아님. 자사 직판 Vivo가 리퍼뿐이라 새상품 조건과 겹치는 게 0건 | 완료 |
| 51 | o2.cz s_seq 1100326 | MOBILE_SAMSUNG (1102839) | 일부 미수집(MOBILE_SAMSUNG) | 사이트 이전 이슈와 동일. 2페이지 요청 실패는 일시적 오류, 정규식은 정상 | 완료 |
| 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 오수집 | 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 확인, 품절 미수집은 정상 | ✓ 확인 요청 | |
| 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개 모델) | 미수집 아님. 신고된 모델은 10/13 정상 수집됨. W/C 색상코드만 확인 불가 | 완료 |
| 56 | harveynorman.com.au s_seq 1100471 | TABLET_SAMSUNG (1109071) | Tab S10+/FE/FE+/Lite 여러 용량 미수집 (7개 모델) | 변형 상품이 __NEXT_DATA__ JSON에만 있어 HTML 정규식이 못 잡음 | 완료 |
| 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 미수집 | 오수집 아님. 재고 있는 상품만 수집하는데 해당 변형이 전부 품절이라 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+) | 재고 루프가 첫 코드에서 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항목 가격 수집되고 있음) | 질문이 4개로 줄어 Plan B URL이 깨짐, 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+) | 미수집 아님. 해당 모델은 트레이드인 서비스 미지원이라 0건이 정상 | 완료 |
| 48 | backmarket.es(RV) s_seq 1100848 | MOBILE_APPLE(1107934) | 일부 미수집(MOBILE_APPLE) | 1step의 $proxyArr1/$proxyArr2 미정의 오류로 매 실행 실패. 정의 위치 확인 필요 | 완료 |
| 47 | telefonika.com s_seq 1100915 | MOBILE_SAMSUNG(1109393)/MOBILE_APPLE(1109394)/MOBILE_HUAWEI(1109395) | 일부 미수집(MOBILE_SAMSUNG,MOBILE_APPLE,MOBILE_HUAWEI) | 구조 변경 없음. 일부 실행에서 서버 요청이 무응답(간헐적 차단 의심) | 완료 |
| 46 | compughana.com s_seq 1100916 | MOBILE_HUAWEI (1109399) | 일부 미수집(MOBILE_HUAWEI) | 오수집 아님. HUAWEI 컬렉션에 판매 상품이 0개라 0건이 정상 | 완료 |
| 40 | telstra.com.au(RV) s_seq | MOBILE_SAMSUNG, MOBILE_APPLE (신규 2개, 수집_수집원(new) 탭 요청) | 신규 사이트 추가 (trade-in/buyback) | 단일 JSON API로 전체 기기 수집 가능. 정규식 파싱 불필요 | 완료 |
| 43 | backmarket.co.uk(Refur) s_seq 1100604 | MOBILE_APPLE(1104780) / MOBILE_SAMSUNG(1104779) | 전체 가격 미수집 | 간헐 실패 아님. SAMSUNG은 검색 API 403, APPLE은 2step 가격이 전부 빔 | 완료 |
| 49 | worten.pt s_seq 1100112 | MOBILE_SAMSUNG 1101189 (+ RC9-05에서 돈 WATCH/MOBILE_APPLE 실행) | 일부 미수집(MOBILE_SAMSUNG,WATCH_APPLE,WATCH_HUAWEI) | 스크립트 문제 아님. RC9-05 서버 실행만 실패, 서버 제외 또는 프로필 정리 필요 | 완료 |
| 48 | t-mobile.cz s_seq 1100125 | MOBILE_APPLE 1107534 / MOBILE_HONOR 1107535 / MOBILE_SAMSUNG 1107536 / MOBILE_XIAOMI 1107537 | 전체 미수집 | listing API 응답 구조 변경으로 Item/Title/Link 0건. 정규식 교체와 APPLE 바디 수정 필요 | 완료 |
| 45 | mediamarkt.es s_seq 1100084 | MOBILE_GOOGLE 1108328 (MOBILE_HONOR 1101079도 같은 현상) | 일부 미수집(MOBILE_GOOGLE) | 일시적 실패. 프리뷰는 1·2페이지 정상, 재수집하면 정상화 | 완료 |
| 44 | mvideo.ru s_seq 1100089 | 전체 14개 보드 (TWS/WATCH/MOBILE 전 브랜드, 1step이 bff/products API로 전환) | 전체 미수집 | mvideo API가 필수 쿠키 없는 요청을 400 거절. 쿠키를 받아 보내도록 수정 필요 | 완료 |
| 47 | samsung.com/in s_seq 1100041 | TWS_SAMSUNG 1108393 | 일부 미수집(TWS_SAMSUNG) | URL의 재고 필터가 0건을 반환. 필터 제거 후 스크립트에서 재고 거르기 | 완료 |
| 42 | compughana.com s_seq 1100916 | MOBILE_SAMSUNG 1109397 (MOBILE_TECNO 1109400도 같은 에러) | 일부 오수집(MOBILE_SAMSUNG) | phones-tablets 컬렉션이라 삼성 태블릿이 섞임. 서버 빈 응답은 BrightData로 해결 | 완료 |
| 51 | samsung.com trade_in (28개 국가) s_seq | TABLET_ALL 계열 | 브랜드 추가(TABLET_ALL_S12 ULTRA, TABLET_ALL_S12+) | Tab S12 Ultra·S12+ 트레이드인 보드 신규 추가 요청(28개국, 보드 없음) | 완료 |
| 46 | trocafone.com(RV) s_seq 1100772 | 전체 | 전체 미수집 | 로그 자체가 없음. 스케줄 실행 안 된 인프라성 문제 추정(2주 내 2회 반복) | 완료 |
| 58 | samsung.com/sg(trade_in) s_seq 1100880 | S25 FE 1108728 / S25 Ultra 1108718 / S26 FE 1109392 | S25 FE 비활성화 상태 오수집 / S25 Ultra,S26 FE 활성화 상태 미수집 | S25 FE 오수집은 해결. S25 Ultra·S26 FE 미수집은 트레이드인 가능 여부 확인 필요 | 완료 |
| 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변경 | 수집원 URL 변경 요청, 새 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