웹 스크래핑은 인터넷상의 웹 페이지에서 데이터를 마이닝하는 행위를 말합니다. 웹 스크래핑의 다른 동의어는 웹 크롤링 또는 웹 데이터 추출입니다.
PHP는 동적 웹 사이트 및 웹 응용 프로그램을 만드는 데 널리 사용되는 백엔드 스크립팅 언어입니다. 일반 PHP 코드를 사용하여 웹 스크레이퍼를 구현할 수 있습니다.
그러나 우리는 바퀴를 재발 명하고 싶지 않기 때문에 쉽게 사용할 수 있는 오픈 소스 PHP 웹 스크래핑 라이브러리를 활용할 수 있습니다.
그건 그렇고, 우리는 또한 Nodejs를 사용한 웹 스크래핑과 Python을 사용한 웹 스크래핑에 관한 몇 가지 훌륭한 기사를 게시했습니다. 확인해보세요.
이 가이드에서는 웹 페이지를 스크랩 하기 위해 PHP와 함께 사용할 수 있는 다양한 도구와 서비스에 대해 설명합니다. 논의 할 도구에는 Guzzle, Goutte, Simple HTML DOM, Headless 브라우저 Symfony Panther,
시작하기 전에 코드를 따라 해보고 싶다면 개발 환경을 위한 몇 가지 전제 조건은 다음과 같습니다.
위의 전제 조건을 완료했으면 프로젝트 디렉터리를 만들고 디렉터리로 이동합니다.
mkdir php_scrapercd php_scraper
터미널에서 다음 두 명령을 실행하여 composer.json 파일을 초기화합니다.
composer init — require=”php >=7.4" — no-interactioncomposer update
시작하자.
1. Guzzle, XML, XPath를 사용한 PHP 웹 스크래핑
Guzzle은 HTTP 요청을 쉽게 보낼 수 있는 PHP HTTP 클라이언트입니다. 쿼리 문자열 작성을 위한 간단한 인터페이스를 제공합니다. XML은 사람이 읽을 수 있고 기계가 읽을 수 있는 형식으로 문서를 인코딩하기 위한 마크업 언어입니다. XPath는 XML 노드를 탐색하고 선택하기 위한 쿼리 언어입니다. 이 세 가지 도구를 함께 사용하여 웹 사이트를 스크랩 하는 방법을 살펴 보겠습니다.
터미널에서 다음 명령을 실행하여 composer를 통해 Guzzle을 설치하여 시작하십시오.
composer require guzzlehttp/guzzle
Guzzle이 설치된 상태에서 코드를 추가 할 새 PHP 파일을 생성 해 보겠습니다. 이름은 guzzle_requests.php입니다.
이 데모에서는 Books to Scrape 웹 사이트를 스크랩합니다. 여기에서 정의한 것과 동일한 단계를 따라 원하는 웹 사이트를 스크랩 할 수 있습니다.
Books to Scrape 웹 사이트는 다음과 같습니다.
책의 제목을 추출하여 단말기에 표시하려고 합니다. 웹 사이트 스크래핑의 첫 번째 단계는 HTML 레이아웃을 이해하는 것입니다. 이 경우 목록의 첫 번째 제품 바로 위에 있는 페이지를 마우스 오른쪽 버튼으로 클릭하고 검사를 선택하여 이 페이지의 HTML 레이아웃을 볼 수 있습니다.
다음은 페이지 소스의 스니펫을 보여주는 스크린 샷입니다.
목록이 <ol class =”row”> 요소 안에 포함되어 있음을 알 수 있습니다. 다음 직계 자식은 <li> 요소입니다.
원하는 것은 책 제목, 즉 <a> 내부, <h3> 내부, <article> 내부, 마지막으로 <li> 요소 내부에 있습니다.
Guzzle, XML 및 Xpath를 초기화하려면 guzzle_requests.php 파일에 다음 코드를 추가하세요.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \GuzzleHttp\Client();$response = $httpClient->get(‘https://books.toscrape.com/');$htmlString = (string) $response->getBody();//add this line to suppress any warningslibxml_use_internal_errors(true);$doc = new DOMDocument();$doc->loadHTML($htmlString);$xpath = new DOMXPath($doc);
위의 코드 조각은 웹 페이지를 문자열로 로드합니다. 그런 다음 XML을 사용하여 문자열을 파싱하고 $xpath 변수에 할당합니다.
다음으로 원하는 것은 <a> 태그 내부의 텍스트 콘텐츠를 타겟팅하는 것입니다. 파일에 다음 코드를 추가합니다.
$titles = $xpath->evaluate(‘//ol[@class=”row”]//li//article//h3/a’);$extractedTitles = [];foreach ($titles as $title) {$extractedTitles[] = $title->textContent.PHP_EOL;echo $title->textContent.PHP_EOL;}
위의 코드 스니펫에서 // ol [@ class =”row”]는 전체 목록을 가져옵니다.
목록의 각 항목에는 책의 실제 제목을 추출하기 위해 타겟팅하는 <a> 태그가 있습니다. <a>를 포함하는 <h3> 태그가 하나뿐이므로 직접 타겟팅하기가 더 쉽습니다.
foreach 루프를 사용하여 텍스트 콘텐츠를 추출하고 터미널에 에코합니다. 이 단계에서 추출 된 데이터로 작업을 수행하거나 데이터를 배열 변수에 할당하거나 파일에 쓰거나 데이터베이스에 저장하도록 선택할 수 있습니다. 아래 명령을 실행하여 터미널에서 PHP를 사용하여 파일을 실행할 수 있습니다. 강조 표시된 부분은 파일 이름을 지정하는 방법입니다.
php guzzle_requests.php
다음과 같이 표시되어야 합니다.
자, 우리가 책의 가격도 알고 싶다면?
가격은 <div> 태그의 <p> 태그 안에 있습니다. 보시다시피 하나 이상의 <p> 태그와 하나 이상의 <div> 태그가 있습니다. 올바른 타겟을 찾기 위해 우리는 운 좋게도 각 태그에 대해 고유 한 CSS 클래스 선택기를 사용할 것입니다. 다음은 가격표를 가져 와서 제목 문자열에 연결하는 코드 스니펫입니다.
$titles = $xpath->evaluate(‘//ol[@class=”row”]//li//article//h3/a’);$prices = $xpath->evaluate(‘//ol[@class=”row”]//li//article//div[@class=”product_price”]//p[@class=”price_color”]’);foreach ($titles as $key => $title) {echo $title->textContent . ‘ @ ‘. $prices[$key]->textContent.PHP_EOL;}
터미널에서 코드를 실행하면 다음과 같은 내용이 표시됩니다.
전체 코드는 다음과 같아야 합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \GuzzleHttp\Client();$response = $httpClient->get(‘https://books.toscrape.com/');$htmlString = (string) $response->getBody();//add this line to suppress any warningslibxml_use_internal_errors(true);$doc = new DOMDocument();$doc->loadHTML($htmlString);$xpath = new DOMXPath($doc);$titles = $xpath->evaluate(‘//ol[@class=”row”]//li//article//h3/a’);$prices = $xpath->evaluate(‘//ol[@class=”row”]//li//article//div[@class=”product_price”]//p[@class=”price_color”]’);foreach ($titles as $key => $title) {echo $title->textContent . ‘ @ ‘. $prices[$key]->textContent.PHP_EOL;}
물론 이것은 기본적인 웹 스크레이퍼이며 확실히 더 좋게 만들 수 있습니다. 다음 라이브러리로 이동하겠습니다.
2. Goutte로 PHP 웹 스크래핑
Goutte는 웹 스크래핑을 위해 특별히 제작 된 또 다른 훌륭한 PHP 용 HTTP 클라이언트입니다. Symfony Framework의 제작자가 만들었으며 웹 사이트의 HTML / XML 응답에서 데이터를 스크랩 할 수 있는 멋진 API를 제공합니다. 다음은 웹 크롤링을 간단하게 만들기 위해 포함 된 몇 가지 구성 요소입니다.
터미널에서 다음 명령을 실행하여 composer를 통해 Goutte를 설치합니다.
composer require fabpot/goutte
Goutte 패키지를 설치했으면 코드 용 새 PHP 파일을 생성합니다. 이름을 goutte_requests.php로 지정하겠습니다.
이 섹션에서는 첫 번째 섹션에서 Guzzle 라이브러리로 수행 한 작업에 대해 설명합니다. Google은 Goutte를 사용하여 Books to Scrape 웹 사이트에서 책 제목을 스크랩합니다. 또한 가격을 배열 변수에 추가하고 코드 내에서 변수를 사용하는 방법도 보여줍니다. goutte_requests.php 파일에 다음 코드를 추가합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \Goutte\Client();$response = $httpClient->request(‘GET’, ‘https://books.toscrape.com/');$titles = $response->evaluate(‘//ol[@class=”row”]//li//article//h3/a’);$prices = $response->evaluate(‘//ol[@class=”row”]//li//article//div[@class=”product_price”]//p[@class=”price_color”]’);// we can store the prices into an array$priceArray = [];foreach ($prices as $key => $price) {$priceArray[] = $price->textContent;}// we extract the titles and display to the terminal together with the pricesforeach ($titles as $key => $title) {echo $title->textContent . ‘ @ ‘. $priceArray[$key] . PHP_EOL;}
터미널에서 다음 명령을 실행하여 코드를 실행합니다.
php goutte_requests.php
출력은 다음과 같습니다.
위에서 살펴본 것은 Goutte로 웹 스크래핑을 달성하는 한 가지 방법입니다.
Goutte와 함께 제공되는 CSSSelector 구성 요소를 사용하는 다른 방법에 대해 알아 보겠습니다. CSS 선택기는 이전 방법에 표시된 XPath를 사용하는 것보다 더 간단합니다.
다른 PHP 파일을 만들고 이름을 goutte_css_requests.php로 지정하겠습니다. 파일에 다음 코드를 추가합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \Goutte\Client();$response = $httpClient->request(‘GET’, ‘https://books.toscrape.com/');// get prices into an array$prices = [];$response->filter(‘.row li article div.product_price p.price_color’)->each(function ($node) use (&$prices) {$prices[] = $node->text();});// echo titles and prices$priceIndex = 0;$response->filter(‘.row li article h3 a’)->each(function ($node) use ($prices, &$priceIndex) {echo $node->text() . ‘ @ ‘ . $prices[$priceIndex] .PHP_EOL;$priceIndex++;});
보시다시피 CSSSelector 구성 요소를 사용하면 코드가 더 깔끔하고 읽기 쉬워집니다. & 연산자를 사용한 것을 눈치 채 셨을 것입니다. 이렇게 하면 변수 값뿐만 아니라 '각'루프에서 변수 참조를 가져옵니다. & $ prices가 루프 내에서 수정되면 루프 외부의 실제 값도 수정됩니다. PHP 공식 문서에서 참조로 할당에 대해 자세히 알아볼 수 있습니다.
다음 명령을 실행하여 터미널에서 파일을 실행하십시오.
php goutte_css_requests.php
이전 스크린 샷과 유사한 출력이 표시되어야 합니다.
PHP와 Goutte를 사용한 웹 스크레이퍼는 지금까지 잘 진행되고 있습니다. 좀 더 자세히 살펴보고 링크를 클릭하여 다른 페이지로 이동할 수 있는지 살펴 보겠습니다.
데모 웹 사이트에서. 스크랩 할 책, 책 제목을 클릭하면 다음과 같은 책의 세부 정보를 보여주는 페이지가 로드됩니다.
도서 목록에서 링크를 클릭하고 도서 세부 정보 페이지로 이동하여 설명을 추출 할 수 있는지 확인하려고 합니다. 페이지를 검사하여 우리가 타겟팅 할 대상을 확인하십시오.
대상 흐름은 <div class =”content”> 요소, <div id =”content_inner”>, 한 번만 표시되는 <article> 태그, 마지막으로 <p> 태그 순입니다. 여러 개의 <p> 태그가 있으며 설명이 있는 태그는 <div class =”content”> 부모 내 4 번째 태그입니다. 배열은 0에서 시작하므로 세 번째 색인에서 노드를 가져옵니다.
이제 우리가 무엇을 목표로 삼고 있는지 알았으니 코드를 작성해 보겠습니다.
먼저 HTML5 구문 분석에 도움이 되는 다음 composer 패키지를 추가합니다.
composer require masterminds/html5
다음으로 goutte_css_requests.php 파일을 다음과 같이 수정합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \Goutte\Client();$response = $httpClient->request(‘GET’, ‘https://books.toscrape.com/');// get prices into an array$prices = [];$response->filter(‘.row li article div.product_price p.price_color’)->each(function ($node) use (&$prices) {$prices[] = $node->text();});// echo title, price, and description$priceIndex = 0;$response->filter(‘.row li article h3 a’)->each(function ($node) use ($prices, &$priceIndex, $httpClient) {$title = $node->text();$price = $prices[$priceIndex];//getting the description$description = $httpClient->click($node->link())->filter(‘.content #content_inner article p’)->eq(3)->text();// display the resultecho “{$title} @ {$price} : {$description}\n\n”;$priceIndex++;});
터미널에서 파일을 실행하면 제목, 가격 및 설명이 표시됩니다.
Goutte CSS 선택기 구성 요소와 페이지 클릭 옵션을 사용하면 여러 페이지가 있는 전체 웹 사이트를 쉽게 크롤링하고 필요한 만큼 데이터를 추출 할 수 있습니다.
3. Simple HTML DOM을 사용한 PHP 웹 스크랩
Simple HTML DOM은 웹 사이트를 크롤링 하는 데 사용할 수 있는 또 다른 최소한의 PHP 웹 스크래핑 라이브러리입니다. 이 라이브러리를 사용하여 웹 사이트를 스크래핑 하는 방법에 대해 논의하겠습니다. 이전 예에서와 마찬가지로 Books to Scrape 웹 사이트를 스크랩 할 것입니다.
패키지를 설치하기 전에 composer.json 파일을 수정하고 버전 관리 오류가 발생하지 않도록 require : {} 블록 바로 아래에 다음 코드 줄을 추가하세요.
“minimum-stability”: “dev”,“prefer-stable”: true
이제 다음 명령을 사용하여 라이브러리를 설치할 수 있습니다.
composer require simplehtmldom/simplehtmldom
라이브러리가 설치되면 새 PHP 파일을 만들고 이름을 simplehtmldom_requests.php라고 합니다.
이전 섹션에서 스크랩하는 웹 페이지의 레이아웃에 대해 이미 논의했습니다. 그래서 우리는 코드로 바로 갈 것입니다. 다음 코드를 simplehtmldom_requests.php 파일에 추가합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = new \simplehtmldom\HtmlWeb();$response = $httpClient->load(‘https://books.toscrape.com/');// echo the titleecho $response->find(‘title’, 0)->plaintext . PHP_EOL . PHP_EOL;// get the prices into an array$prices = [];foreach ($response->find(‘.row li article div.product_price p.price_color’) as $price) {$prices[] = $price->plaintext;}// echo titles and pricesforeach ($response->find(‘.row li article h3 a’) as $key => $title) {echo “{$title->plaintext} @ {$prices[$key]} \n”;}
터미널에서 코드를 실행하면 결과가 표시됩니다.
공식 API 문서에서 간단한 HTML DOM 라이브러리를 사용하여 웹 페이지를 크롤링 하는 더 많은 방법을 찾을 수 있습니다.
4. 헤드리스 브라우저 (Symfony Panther)로 PHP 웹 스크래핑
헤드리스 브라우저는 그래픽 사용자 인터페이스가 없는 브라우저입니다. 헤드리스 브라우저를 사용하면 터미널을 사용하여 웹 브라우저와 유사한 환경에서 웹 페이지를 로드 할 수 있습니다. 이를 통해 이전 단계에서 수행 한 것처럼 탐색을 제어하는 코드를 작성할 수 있습니다. 왜 이것이 필요한가요?
현대 웹 개발에서 대부분의 개발자는 JavaScript 웹 프레임 워크를 사용합니다. 이러한 프레임 워크는 브라우저 내부에서 HTML 코드를 생성합니다. 다른 경우에는 AJAX를 사용하여 콘텐츠를 동적으로 로드합니다. 이전 예제에서는 정적 HTML 페이지를 사용했기 때문에 출력이 일관되었습니다. HTML을 생성하는 데 JavaScript와 AJAX가 사용되는 동적인 경우 DOM 트리의 출력이 크게 다를 수 있으므로 스크레이퍼가 실패 할 수 있습니다. 최신 웹 사이트에서 이러한 문제를 처리하기 위해 헤드리스 브라우저가 등장합니다.
헤드리스 브라우저에 사용할 수 있는 라이브러리는 Symfony Panther PHP 라이브러리입니다. 라이브러리를 사용하여 웹 사이트를 스크랩하고 실제 브라우저를 사용하여 테스트를 실행할 수 있습니다. 또한 Goutte 라이브러리와 동일한 방법을 제공하므로 Goutte 대신 사용할 수 있습니다. 이 자습서에서 설명한 이전 웹 스크래핑 라이브러리와 달리 Panther는 다음을 수행 할 수 있습니다.
우리는 이미 스크래핑을 많이 해왔으니 다른 것을 시도해 봅시다. HTML 페이지를 로드하고 페이지의 스크린 샷을 찍습니다.
다음 명령을 사용하여 Symfony Panther를 설치합니다.
composer require symfony/panther
새 PHP 파일을 만들고 이름을 panther_requests.php로 지정하겠습니다. 파일에 다음 코드를 추가합니다.
<?php# scraping books to scrape: https://books.toscrape.com/require ‘vendor/autoload.php’;$httpClient = \Symfony\Component\Panther\Client::createChromeClient();// for a Firefox client use the line below instead//$httpClient = \Symfony\Component\Panther\Client::createFirefoxClient();// get response$response = $httpClient->get(‘https://books.toscrape.com/');// take screenshot and store in current directory$response->takeScreenshot($saveAs = ‘books_scrape_homepage.jpg’);// let’s display some book titles$response->getCrawler()->filter(‘.row li article h3 a’)->each(function ($node) {echo $node->text() . PHP_EOL;});
이 코드를 시스템에서 실행하려면 코드에서 사용한 클라이언트에 따라 Chrome 또는 Firefox 용 드라이버를 설치해야 합니다. 다행히 Composer가 자동으로 이 작업을 수행 할 수 있습니다. 터미널에서 다음 명령을 실행하여 드라이버를 설치하고 감지하십시오.
composer require — dev dbrekelmans/bdi && vendor/bin/bdi detect drivers
이제 터미널에서 PHP 파일을 실행할 수 있으며 웹 페이지의 스크린 샷을 찍고 현재 디렉토리에 저장 한 다음 웹 사이트의 제목 목록을 표시합니다.
결론
이 자습서에서는 웹 사이트를 스크랩 하는 데 사용할 수 있는 다양한 PHP 오픈 소스 라이브러리에 대해 설명했습니다. 튜토리얼을 따라했다면 기본 스크레이퍼를 만들어 한 두 페이지를 크롤링 할 수 있었습니다. 이것은 입문 기사 였지만 라이브러리에서 사용할 수 있는 대부분의 방법을 다루었습니다. 이 지식을 바탕으로 수천 페이지를 크롤링 할 수 있는 복잡한 웹 스크래퍼를 만들 수 있습니다. 이 가이드의 코드는 이 GitHub 저장소에서 제공됩니다.
https://www.scrapingdog.com/blog/web-scraping-with-php
등록된 댓글이 없습니다.