메인 콘텐츠로 건너뛰기

개요

revolution/laravel-fullfeed는 피드 리더용으로 웹 페이지에서 본문을 추출하는 Laravel 패키지입니다.
사이트별 룰(JSON)을 사용하여 각 기사에 필요한 콘텐츠를 추출합니다.
원래는 프라이빗한 피드 리더 앱에서 사용되던 기능이 분리되어 공개 패키지화되어 있습니다.

요구 사항

  • PHP >= 8.4(Dom\HTMLDocument를 이용)
  • Laravel >= 12.x

설치

composer require revolution/laravel-fullfeed
개발 버전을 사용하는 경우:
composer require revolution/laravel-fullfeed:dev-main

설정 파일과 사이트 정의 공개

php artisan vendor:publish --tag=fullfeed
이 명령어로 다음이 생성됩니다.
  • config/fullfeed.php
  • resources/fullfeed

정의 파일 자동 갱신(composer post-update-cmd)

composer update 시에 사이트 정의를 자동으로 재공개하려면 composer.json에 다음을 추가합니다.
{
  "scripts": {
    "post-update-cmd": [
      "@php artisan vendor:publish --tag=laravel-assets --ansi --force",
      "@php artisan vendor:publish --tag=fullfeed-site --ansi --force"
    ]
  }
}

기본적인 사용법

use Revolution\Fullfeed\Facades\FullFeed;

$html = FullFeed::get($url);

테스트

FullFeed::expects()로 Facade를 스텁할 수 있습니다.
use Revolution\Fullfeed\Facades\FullFeed;

FullFeed::expects('get')
    ->with('https://example.com/article/1')
    ->andReturn('<div>Main content</div>');

사이트 룰 파일

items_all.json

items_all.json은 LDRFullFeed(wedata) 형식의 룰을 가져오기 위한 베이스입니다.
Livedoor Reader는 일본에서 유명한 서비스였지만 서비스 자체는 종료되었으며, 현재는 룰 데이터가 주로 자산으로 남아 있습니다. FullFeed는 이 역사적인 데이터 형식을 활용합니다.

plus.json

plus.json은 자체 룰 추가용 샘플입니다.
{
  "name": "note",
  "data": {
    "url": "^https://note\\.com/",
    "selector": "div[data-name=\"body\"]",
    "xpath": "//div[@data-name=\"body\"]",
    "enc": "UTF-8",
    "callable": "App\\FullFeed\\CustomExtractor"
  }
}

룰 설정 필드

  • url: 대상 URL에 매칭시키는 정규 표현식
  • selector: CSS 셀렉터(xpath보다 우선)
  • xpath: XPath 지정
  • enc: 문자 코드 변환이 필요한 경우의 인코딩 지정
  • callable: 전처리로 실행할 자체 Extractor 클래스(단일/배열)
  • after_callable: 후처리로 마지막에 실행할 Extractor 클래스

Pipeline 패턴으로서의 Extractor 실행 순서

FullFeed는 Laravel의 Pipeline 패턴으로, Extractor를 순서대로 흘려보냅니다.
  1. callable에서 지정한 클래스
  2. XPathExtractor
  3. SelectorExtractor
  4. after_callable에서 지정한 클래스
단순한 XPath/CSS 추출 전후에 자체 처리를 삽입할 수 있으므로, 사이트별 특이 사항에 대응하기 쉬운 설계입니다.

내장 Extractor

RemoveElements

지정한 셀렉터의 요소를 삭제합니다.
{
  "after_callable": ["Revolution\\Fullfeed\\Extractor\\RemoveElements"],
  "remove": ["svg", "button", "script"]
}

ReplaceMatches

정규 표현식으로 일치한 문자열을 치환합니다(HTML 문자열에 대해 처리).
{
  "after_callable": ["Revolution\\Fullfeed\\Extractor\\ReplaceMatches"],
  "replace": [
    {
      "pattern": "/ data-(h-)?index=\"[0-9]+\"/",
      "replace": ""
    }
  ]
}

StripTags

strip_tags() 상당으로 태그를 제거합니다.
{
  "after_callable": ["Revolution\\Fullfeed\\Extractor\\StripTags:a,img"]
}

Squish

Str::squish()로 여분의 공백을 제거합니다.
{
  "after_callable": ["Revolution\\Fullfeed\\Extractor\\Squish"]
}

자체 룰 추가

  1. resources/fullfeed에 JSON 파일을 추가
  2. config/fullfeed.phppaths에 추가
data.url에 가장 먼저 매칭한 룰이 사용되므로, 추가 파일은 paths의 맨 앞에 두는 것을 권장합니다.
마지막 수정일 2026년 7월 13일