웹 스크래핑(Web Scraping) 또는 웹 크롤링(Web Crawling)은 웹 페이지로부터 원하는 정보를 추출하는 기법입니다. 어떤 서비스에서 API가 별도로 제공되고 있지 않지만 웹 페이지로는 정보가 제공되고 있을 때, 웹 스크래핑 기법을 이용하면 원하는 정보를 획득할 수 있습니다.
웹 스크래핑의 원리에 대해서는 이전 글인 웹 스크래핑(웹 크롤링)의 원리에서 다루었습니다. 이번 글에서는 PHP에서 몇 가지 패키지를 조합하여 손쉽게 구현한 웹 스크래핑 함수 예제코드를 소개합니다.
패키지 설치
이전 글을 토대로 웹 스크래핑의 원리에 대해서는 이해할 수 있었으나, 실제 그 과정을 직접 구현하는 것은 번거로운 일입니다. 그러나 PHP에서 Composer를 통해 설치할 수 있는 패키지 몇 가지만 있으면, 이 원리를 손쉽게 소스코드로 구현할 수 있습니다. 제가 구현시에 사용한 패키지는 아래 3가지입니다.
guzzle은 더 말할 필요가 없는 HTTP 통신 패키지의 대표주자로, 열기 과정에서 curl 대신에 사용할 수 있습니다. 이렇게 HTTP 통신으로 가져온 HTML을 dom-crawler 패키지를 사용하면, 찾기 과정에서 DOM 단위로 탐색할 수 있습니다. 마지막으로 css-selector는 dom-crawler에서 CSS 선택자를 사용할 수 있게 하는 패키지로, 보기 과정을 CSS 선택자로 한 번에 해결합니다.
composer require guzzlehttp/guzzle
composer require symfony/dom-crawler
composer require symfony/css-selector
각 패키지는 위와 같이 composer로 설치해주어야 합니다.
구현 함수
이 3가지 패키지를 통해 스크래핑 함수를 구현하면 아래와 같습니다. 함수는 먼저 $url 인자로 입력한 URL을 Guzzle 패키지를 통해 열어 HTML 소스코드를 받아옵니다. 이어서 입력한 CSS 선택자를 통해 DOM Crawler가 받아온 HTML 소스코드에서 해당하는 요소를 찾습니다. 마지막으로 찾은 내용을 배열 $res에 담아 최종적으로 반환합니다.
require_once(__DIR__ . '/../vendor/autoload.php');
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\DomCrawler\Crawler;
function scrapWebpage(string $url, string $selector): array
{
$res = [];
// 열기
try {
$client = new GuzzleClient();
$response = $client->request('GET', $url);
} catch (GuzzleException $e) {
die('Exception');
}
if ($response->getStatusCode() == 200) {
// 찾기
$html = strval($response->getBody());
$crawler = new Crawler($html);
$crawler = $crawler->filter($selector);
// 보기
foreach ($crawler as $domElement) {
$res[] = $domElement->nodeValue;
}
}
return $res;
}
실제로 위 함수를 사용하는 예는 아래와 같습니다. 스크래핑할 URL와 스크래핑할 부분의 CSS 선택자를 넣어 간단하게 사용할 수 있습니다. 반환하는 값은 배열이기 때문에, 입력한 선택자에 여러 개의 요소가 해당하더라도 문제없이 정보를 수집할 수 있습니다.
$res = scrapWebpage('http://dev.epiloum.net/', 'h1.entry-title a');
위 코드는 간단한 소개를 위해서 네임스페이스 등이 생략되어 있으며, 전체 소스코드는 Github 저장소에서 확인하실 수 있습니다. 필요하신 분은 참고하여 주시기 바랍니다.