[Tistory] guzzle, phpSpreadsheet 로 스크래핑

원글 페이지 : 바로가기

1. Guzzle 활용하기 ‘%EB%8F%99%ED%83%84+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 126.8946875%3B37.578325’,
// ‘동탄 고양이 호텔’ => ‘%EB%8F%99%ED%83%84+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 127.10504700000229%3B37.18412720000249’,
// ‘화성 동물병원’ => ‘%ED%99%94%EC%84%B1+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 127.10729150000145%3B37.16654380000182’,

$targets = [
‘화성 고양이 호텔’ => ‘%ED%99%94%EC%84%B1+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 126.83140500000144%3B37.199565000000675’,
‘용인 동물병원’ => ‘%EC%9A%A9%EC%9D%B8+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 127.10729150000094%3B37.16654380000074’,
‘용인 고양이 호텔’ => ‘%EC%9A%A9%EC%9D%B8+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 127.12444809999863%3B37.331904300000474’,
‘오산 동물병원’ => ‘%EC%98%A4%EC%82%B0+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 127.15263529999737%3B37.271100399999256’,
‘오산 고양이 호텔’ => ‘%EC%98%A4%EC%82%B0+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 127.07746199999809%3B37.14988700000025’,
‘군포 동물병원’ => ‘%EA%B5%B0%ED%8F%AC+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 127.06732260000092%3B37.169057900000354’,
‘군포 고양이 호텔’ => ‘%EA%B5%B0%ED%8F%AC+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 126.93533800000279%3B37.36152299999945’,
‘세종 동물병원’ => ‘%EC%84%B8%EC%A2%85+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 126.93498789999842%3B37.383211499998836’,
‘세종 고양이 호텔’ => ‘%EC%84%B8%EC%A2%85+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 127.28943249999855%3B36.4803512’,
‘아산 동물병원’ => ‘%EC%95%84%EC%82%B0+%EB%8F%99%EB%AC%BC%EB%B3%91%EC%9B%90, 127.22461590000336%3B36.503293900001395’,
‘아산 고양이 호텔’ => ‘%EC%95%84%EC%82%B0+%EA%B3%A0%EC%96%91%EC%9D%B4+%ED%98%B8%ED%85%94, 127.06977800000124%3B36.77321300000108’,
];

$cartegoryNames = [‘name’, ‘roadAddress’, ‘tel’, ‘telDisplay’, ‘homePage’];

foreach ($targets as $key => $value) {
$resultLists = [];
$pageNumber = 1;
$totalCount = 0;

$target = explode(‘, ‘, $value);

// 새로운 시트 생성
$sheet = $spreadsheet->createSheet();
$sheet->setTitle($key); // 시트의 이름을 키 값으로 설정

while (true) {
try {
// 요청을 보낼 URL을 정의합니다.
$url = “https://”;

echo “현재 request url = {$url}” . PHP_EOL;

// HTTP GET 요청을 보냅니다.
$response = $client->request(‘GET’, $url, [
‘headers’ => [
‘Accept’ => ‘application/json, text/plain, */*’,
‘Accept-Encoding’ => ‘gzip, deflate, br’,
‘Accept-Language’ => ‘ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4’,
‘Cache-Control’ => ‘no-cache’,
‘Expires’ => ‘Sat, 01 Jan 2000 00:00:00 GMT’,
‘User-Agent’ => ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36’,
‘Cookie’ => ‘NNB=; nx_ssl=2; page_uid=’,
‘Pragma’ => ‘no-cache’,
‘Referer’ => “https://”,
‘Sec-Ch-Ua’ => ‘”Chromium”;v=”116″, “Not)A;Brand”;v=”24″, “Google Chrome”;v=”116″‘,
‘Sec-Ch-Ua-Mobile’ => ‘?0’,
‘Sec-Ch-Ua-Platform’ => ‘”Windows”‘,
‘Sec-Fetch-Dest’ => ’empty’,
‘Sec-Fetch-Mode’ => ‘cors’,
‘Sec-Fetch-Site’ => ‘same-origin’,
],
]);

// 응답 본문을 문자열로 가져옵니다.
$responseBody = (string) $response->getBody();
$jsonData = json_decode($responseBody, true);

// 결과를 출력합니다.
dump($jsonData);

$lists = $jsonData[‘result’][‘place’][‘list’];
} catch (RequestException $e) {
echo “{$key} HTTP 요청 중 오류 발생: ” . $e->getMessage() . PHP_EOL;
break;
}
$totalCount = $jsonData[‘result’][‘place’][‘totalCount’];
foreach ($lists as $list) {
$resultList = [];
foreach ($cartegoryNames as $name) {
$resultList[$name] = $list[$name];
}
$resultLists[] = $resultList;
}
if (count($lists) < 20) { break; } $pageNumber++; sleep(60); } // 엑셀 데이터 추가 $row = 2; // 데이터 행 시작 foreach ($resultLists as $resultList) { $col = 'A'; // 열 초기화 (첫 번째 열) $sheet->setCellValue($col . $row, $row – 1); // No. 추가

// 나머지 데이터 추가
foreach ($resultList as $value) {
$col++;
$sheet->setCellValue($col . $row, $value);
}

$row++; // 다음 행
}

echo “{$key} 완료 / 리스트 총 개수 : {$totalCount}” . PHP_EOL;
dump($resultLists);

// Excel 파일로 저장
$writer = new Xlsx($spreadsheet);
$writer->save(“exceldata/{$key}.xlsx”);

sleep(15);
} Guzzle의 Client() 기능을 생성하고 $response = $client->request(‘GET’, $url, [
‘headers’ => [

],
]); request를 할 수 있다. 이 때 headers에 넣을 데이터는 request headers 를 복사해서 PostMan의 Bulk Edit을 활용해서 필요한 헤더 데이터를 찾도록 하자 $responseBody = (string) $response->getBody();
$jsonData = json_decode($responseBody, true); 받아온 $response는 처음에 객체 형태이기 때문에 getBody() 메서드로 내용을 가져오고, (string) 형태로 선언해준 다음 json으로 변경해서 사용할 수 있다. 2. phpSpreadsheet json형태의 데이터로 잘 만들었다면, 눈으로 확인하기 쉽게 엑셀에 담아서 보관할 수 있다 php8.1 버전에서 phpSpreadsheet 를 활용해서 excel파일을 읽고, 쓰는 방법을 알아보자 (버전에 따라 지원하는 excel 편집 라이브러리가 다르다) getAllSheets();

foreach ($worksheets as $worksheet) {
// 워크시트를 선택합니다.
$worksheetTitle = $worksheet->getTitle();

// G 열 데이터를 기준으로 행을 그룹화합니다.
$groupedRows = [];
foreach ($worksheet->getRowIterator() as $row) {
$cellG = $worksheet->getCell(‘F’ . $row->getRowIndex());
$groupKey = $cellG->getValue();

if (!isset($groupedRows[$groupKey])) {
$groupedRows[$groupKey] = [];
}

$rowData = $worksheet->rangeToArray(“B{$row->getRowIndex()}:F{$row->getRowIndex()}”)[0];
$groupedRows[$groupKey][] = $rowData;
}

dump($groupedRows);

// 각 그룹마다 새로운 Excel 파일을 생성하고 데이터를 추가합니다.
foreach ($groupedRows as $groupKey => $groupedRowData) {
$newSpreadsheet = new Spreadsheet();
$newWorksheet = $newSpreadsheet->getActiveSheet();

$headerRow = [‘Name’, ‘Address’, ‘Phone’, ‘Homepage’, ‘SearchKeyWord’];
$newWorksheet->fromArray([$headerRow], null, ‘A1’);
$newWorksheet->fromArray($groupedRowData, null, ‘A2’); // 데이터를 워크시트에 추가

// 새로운 Excel 파일로 저장합니다.
$outputFileName = ‘exceldata/’. $groupKey . ‘.xlsx’;
$writer = IOFactory::createWriter($newSpreadsheet, ‘Xlsx’);
$writer->save($outputFileName);
}
} 위의 코드는 중복 데이터가 삭제 된 excel 파일을 불러와서 특정 열의 값을 비교해서 중복이 발생하는 행을 삭제하고, 특정 열의 값이 같은 요소들 끼리 excel 파일로 나누는 중복 제거 기능을 수행한다. IOFactory, SpreadSheet를 활용한다. getRowIterator() 로 워크시트를 행으로 나누고 getRowIndex()로 각 행의 인덱스를 설정한 후, getCell()을 이용해서 워크시트에 존재하는 모든 F열 값을 cellG에 저장한다. $groupedRows 배열에 groupKey값과 배열을 선언해주고 원하는 범위의 엑셀 데이터를 배열에 넣어주고 Spreadsheet의 기능들로 스프레드 시트를 제작한 뒤 IOFactory로 엑셀 파일을 생성하자.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다