댓글 검색 목록

[javascript] 웹 페이지 메타 데이터를 스크래핑하는 서버리스 기능 만들기

페이지 정보

작성자 운영자 작성일 21-06-13 15:17 조회 1,567 댓글 0

오늘날 대부분의 웹 사이트는 HTML 마크 업에서 콘텐츠에 대한 메타 데이터를 직접 제공합니다. 이 게시물은 Metascraper를 사용하여 이 데이터를 스크레이핑 하는 Vercel 서버리스 기능을 만드는 방법을 보여줍니다.


Metascraper 개요 


Metascraper는 일련의 규칙에 따라 웹 사이트 콘텐츠를 검색 할 수 있는 규칙 기반 시스템입니다. 오픈 소스 Node.js 라이브러리로 배포됩니다.


Metascraper는 브라우저 자동화 제품에서 내부적으로 사용하는 Microlink에 의해 구워졌습니다. 


프로젝트 개요 


모든 Node.js 애플리케이션에서 Metascraper를 사용할 수 있습니다. 

제 생각에 가장 편리한 사용 방법은 입력 URL이 주어지면 대상 웹 페이지에 대한 구조화 된 메타 데이터를 출력으로 반환하는 작은 Node.js 서버 내에 있는 것입니다.

아이디어는 다음과 같은 API를 만드는 것입니다.

  • 웹 사이트 메타 데이터를 스크랩 하는 데 사용할 수 있는 경로를 노출합니다 (예 : api / scrape).
  • 유효한 URL이 매개 변수로 전달되었는지 확인합니다 (예 :? url 쿼리 매개 변수로).
  • 웹 사이트의 콘텐츠를 가져옵니다.
  • 메타 데이터를 추출하기 위해 웹 사이트 콘텐츠와 함께 Metascraper를 호출합니다.
  • 응답 본문에 json으로 인코딩 된 메타 데이터를 반환합니다.

Vercel API 프로젝트 설정 


이 Node.js 서버의 목표는 범위가 매우 넓고 요청 실행에 오랜 시간이 걸리지 않을 것으로 예상되므로 서버리스 / 람다 기능으로 배포하는 데 매우 적합합니다. 

Vercel을 사용하여 서버리스 기능을 배포하지만 Node.js를 지원하는 다른 서버리스 API 공급자 (예 : AWS Lambda, Firebase, Netlify 등)에서도 동일한 작업을 수행 할 수 있습니다. 프로젝트 디렉토리를 만들고 cd로 시작하여 npm을 사용하여 초기화합니다.


mkdir url-metadata-scraper && cd url-metadata-scraper
npm init

다음으로 vercel을 devDependency로 설치합니다.


npm install -D vercel 

그리고 package.json의 시작 스크립트를 "start": "vercel dev"로 업데이트하여 서버리스 기능을 로컬에서 실행하십시오.


마지막으로 api 디렉토리와 그 안에 scrape.js 파일을 만듭니다.


mkdir api && touch api/scrape.js
// api/scrape.js
// In Vercel, any file inside the folder "/api" is mapped to "/api/*" and 
// will be treated as an API endpoint.


// For an API route to work, you need to export a function as default (a.k.a request handler),
// which then receives the following parameters:
// - req: The request object.
// - res: The response object.
// See https://vercel.com/docs/serverless-functions/supported-languages#node.js for details.
export default async function handler(req, res) {
  res.status(200).send(`Hello world!`)
}

이제 코드 배포를 Vercel에 실행할 수 있습니다 (물론 api / scrape.js에 "실제"로직을 추가하지 않았으므로 지금은 아무 작업도 수행하지 않습니다). 이러한 경우에 필자의 접근 방식은 GitHub 리포지토리를 만들고 Vercel에 연결하여 각 커밋에 프로젝트를 자동으로 배포하도록 하는 것입니다.하지만 원하는 경우 수동으로 수행 할 수도 있습니다.


스크래핑 로직 만들기 


스크래핑 로직에 대한 작업을 시작하겠습니다.


먼저 got npm 패키지를 사용하여 웹 사이트 콘텐츠를 가져오고 (다른 가져 오기 라이브러리를 자유롭게 사용) 메타 스크래퍼 npm 패키지를 사용하여 메타 데이터를 추출합니다.


npm i got metascraper

Metascraper는 "규칙 번들"을 사용하여 메타 데이터를 추출합니다. 규칙 번들은 결정 속성 주위의 HTML 선택기 모음입니다. metascraper npm 패키지에는 기본적으로 규칙 번들이 포함되어 있지 않으므로 필요한 각 번들을 수동으로 설치해야 합니다. 메타 스크래퍼 문서의 "규칙 번들"섹션에서 사용 가능한 번들 목록을 확인할 수 있습니다. 가능한 한 많은 메타 데이터를 추출 할 수 있도록 거의 모든 메타 데이터를 추가하겠습니다.


npm i metascraper-amazon metascraper-audio metascraper-author metascraper-clearbit metascraper-date metascraper-description metascraper-image metascraper-instagram metascraper-lang metascraper-logo metascraper-logo metascraper-publisher metascraper-readability metascraper-soundcloud metascraper-spotify metascraper-telegram metascraper-title metascraper-url metascraper-video metascraper-youtube

이제 api / scrape.js에서 API 로직을 설정할 준비가 되었습니다. 단순화를 위해 다음은 전체 코드 (주석 포함)입니다.


// api/scrape.js
// In Vercel, any file inside the folder "/api" is mapped to "/api/*" and 
// will be treated as an API endpoint.

const { parse } = require("url");
const got = require("got");
// Initialize metascraper passing in the list of rules bundles to use.
const metascraper = require("metascraper")([
  require("metascraper-amazon")(),
  require("metascraper-audio")(),
  require("metascraper-author")(),
  require("metascraper-date")(),
  require("metascraper-description")(),
  require("metascraper-image")(),
  require("metascraper-instagram")(),
  require("metascraper-lang")(),
  require("metascraper-logo")(),
  require("metascraper-clearbit-logo")(),
  require("metascraper-logo-favicon")(),
  require("metascraper-publisher")(),
  require("metascraper-readability")(),
  require("metascraper-spotify")(),
  require("metascraper-title")(),
  require("metascraper-telegram")(),
  require("metascraper-url")(),
  require("metascraper-logo-favicon")(),
  require("metascraper-amazon")(),
  require("metascraper-youtube")(),
  require("metascraper-soundcloud")(),
  require("metascraper-video")(),
]);


// For an API route to work, you need to export a function as default (a.k.a request handler),
// which then receives the following parameters:
// - req: The request object.
// - res: The response object.
// See https://vercel.com/docs/serverless-functions/supported-languages#node.js for details.
export default async function handler(req, res) {
  // Parse the "?url" query parameter.
  const targetUrl = parse(req.url, true).query?.url;

  // Make sure the provided URL is valid.
  if (!targetUrl) {
    res
      .status(401)
      .send('Please provide a valid URL in the "url" query parameter.');
    return;
  }

  try {
    // Use the got library to fetch the website content.
    const { body: html, url } = await got(targetUrl);
    // Extract the metadata from the website content.
    const metadata = await metascraper({ html, url });
    // The Vercel Edge Network can cache the response at the edge in order to 
    // serve data to your users as fast as possible.
    // Here we're caching the response at the edge for 1 hour.
    // See https://vercel.com/docs/edge-network/caching for details.
    res.setHeader("Cache-Control", "s-maxage=3600");
    // Return the metadata as JSON
    res.status(200).json(metadata);
  } catch (err) {
    console.log(err);
    res.status(401).json({ error: `Unable to scrape "${url}".` });
  }
}

그게 다입니다. 

npm start를 실행 (또는 코드 배포)하고 url 쿼리 매개 변수의 유효한 URL을 사용하여 / api / scrape 엔드 포인트를 호출하면 웹 페이지 메타 데이터가 포함 된 JSON 응답을 받아야 합니다.


예를 들어 http : // localhost : 3000 / api / scrape? url = https : //google.com은 다음을 반환해야 합니다.


{
  "lang": "en",
  "author": null,
  "title": "Google",
  "publisher": null,
  "image": "https://www.google.com/images/branding/googleg/1x/googleg_standard_color_128dp.png",
  "audio": null,
  "date": null,
  "description": "Search the world’s information, including webpages, images, videos and more. Google has many special features to help you find exactly what you’re looking for.",
  "video": null,
  "logo": "https://logo.clearbit.com/www.google.com",
  "url": "https://www.google.com/"
}

GitHub에서 이 프로젝트의 전체 소스 코드를 찾을 수 있습니다. 자유롭게 포크하거나 사용해보세요!


보너스 : m3u8 지원 


metascraper-video 패키지는 태그에 유효한 동영상 URL이 포함되어 있는지 확인하기 위해 is-video 패키지에 의존하고, is-video는 유효한 동영상 확장 목록을 보유하는 동영상 확장 패키지에 의존합니다.


안타깝게도 동영상 확장 패키지는 한동안 업데이트 되지 않았기 때문에 m3u8 동영상 확장 (요즘 웹에서 인기 있는 동영상 확장)을 지원하지 않습니다. 이 pull 요청이 릴리스되고 is-video가 최신 버전의 video-extensions를 사용하도록 업데이트 될 때까지 다음 diff와 함께 patch-package를 사용하여 m3u8 지원을 비디오 확장에 수동으로 패치 할 수 있습니다 (패치 / 비디오에 추가). -extensions + 1.1.0.patch).


diff --git a/node_modules/video-extensions/video-extensions.json b/node_modules/video-extensions/video-extensions.json
index 0ad84d7..a115959 100644
--- a/node_modules/video-extensions/video-extensions.json
+++ b/node_modules/video-extensions/video-extensions.json
@@ -8,6 +8,7 @@
  "drc",
  "flv",
  "m2v",
+ "m3u8",
  "m4p",
  "m4v",
  "mkv",


https://mmazzarolo.com/blog/2021-06-06-metascraper-serverless-function/



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.