[Laravel] Goutte를 활용한 웹크로링(Web Scraper) 만들기

[Laravel] Goutte를 활용한 웹크로링(Web Scraper) 만들기 updated_at: 2024-01-30 17:53

Goutte를 활용한 웹크로링(Web Scraper) 만들기

참조

Install

composer require fabpot/goutte

간단한 사용법

use Goutte\Client;
................
public function WebScraper($code=null) {
  $client = new Client();
  $crawler = $client->request('GET', [target url]);
  $crawler->filter('#summary_info > p')->each(function ($node) {
    echo $node->text();
  });
}

Symfony\Component\HttpClient\HttpClient 와 병행하여 사용하기

http를 가져올때 다양한 옵션을 함께 줄 수 있어 활용법이 다양하다.

use Goutte\Client;
use Symfony\Component\HttpClient\HttpClient;
................
public function WebScraper($code=null) {
  $client = new Client(HttpClient::create(['timeout' => 60]));
  $crawler = $client->request('GET', [target url]);
  $crawler->filter('#summary_info > p')->each(function ($node) {
    echo $node->text();
  });
}

GuzzleHttp\Client 와 Crawler 를 사용하기

이 부분도 상당히 활용도가 높다. naver 크롤링시 문자 깨짐이 발생하여 이 방식을 사용하여 해결하였다.

GuzzleHttp 사용법

use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;
................
public function WebScraper($code=null) {
  $client = new Client();
  $response = $client->request('GET', [target url]);
  $body = iconv( "euc-kr", "utf-8", $response->getBody());;// 문자 깨짐이 발생하여 전체 페이지를 iconv 시킴

  $crawler = new Crawler($body); // Crawler를 이용하여  crawler 시킴
  $crawler->filter('#summary_info > p')->each(function ($node) {
    echo $node->text();
  });
}

로그인 처리

  • login.html
<form action=''>
  <input type='text' name='login_id'>
  <input type='password' name='login_password'>
  <button type="submit">Login</button>
</form>
$client = new Client();
$crawler = $client->request('GET', 'https://onstory.fun/login.html');
$form = $crawler->selectButton('Login')->form();
$crawler = $client->submit($form, ['login_id' => 'UserID', 'login_password' => 'UserPWD']);

Filter 예제

jquery의 selector와 유사함으로 그 부분을 참조하시면 됩니다.

div#view // id select
div.view // class select
table tr > td.subject:not(.notice) a // > 가 있으면 바로 아래 없으면 현재 엘리먼트(table)의 아래에 있는 모든 child의 tr
li:not(.notice):not(.ad) > div.subject // sudo 가 가능하고 여러개를 사용해도 된다.

Read

text 및 attribute 읽기

$crawler->filter('body > div')->innerText(); // div 내부 텍스트 읽기
$crawler->filter('div')->attr('user-data'); // div 의 user-data attribute 읽기 
$crawler->filter('a.link')->attr('href'); // a tag href 읽기
$crawler->filter('a.link')->innerText(); // a tag 안의 내용 읽기

link 관련 속성

$link = $crawler->filter('a.link')->link();
echo $link->getUri(); // 위의 attr('href') 와 유사
echo $link->getMethod(); // GET

node삭제

$crawler = new Crawler($html);
$parentNode = $crawler->filter('body > div')->getNode(0);
$childNode = $crawler->filter('div.inner')->getNode(0);
$parentNode->removeChild($childNode);
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1