본문 바로가기

TIL/Node.js, express

node.js로 웹페이지 스크래핑하기 (feat. cheerio)

cheerio를 사용한 스크래핑

node.js에서 웹페이지의 html을 파싱하여 스크래핑하기 위해서는 cheerio라는 툴을 사용해야 한다.

 

const cheerio = require(”cheerio”)로 불러와서 사용하면 되고,

 

일반적인 웹사이트에는 SEO를 위해 다음과 같이 메타 태그가 적용되어 있기 때문에, 이를 이용하여 cheerio로 관련 정보를 불러올 수 있다.

 

const html = await axios({
            url: req.body.url,
            method: "GET",
          });
const $ = cheerio.load(html.data);
crawledData = {
  image: $('head meta[property="og:image"]').attr("content"),
  desc: $('head meta[property="og:description"]').attr("content"),
  title: $('head meta[property="og:title"]').attr("content"),
};

 

페이스북 스크래핑

페이스북의 경우 허가되지 않은 도메인에서의 스크래핑을 보안 상 막아 두었다.

 

따라서 페이스북 개발자 계정으로 앱 승인을 받은 후, 페이스북의 graph API를 사용해야 한다.

 

앱 검수 요청은 Meta for Developers에서 받을 수 있으며, 스크래핑에 필요한 권한은 oembed_read이다.

 

본 포스팅에서는 해당 권한에 대한 승인을 받았다고 가정한다.

 

Graph API Reference v15.0: Oembed Post - Documentation - Meta for Developers

 

그래프 API 참고 자료 v15.0: Oembed Post - 문서 - Meta for Developers

 

developers.facebook.com

위 링크에 자세한 api 정보가 나와있다.

 

결론적으로 다음과 같이 스크래핑하고자 하는 사이트의 url과 승인된 계정의 앱키를 매개변수로 담아 사용할 api 엔드포인트(/oembed_post)로 요청을 보내면, 응답 객체 속에서 html 정보를 활용할 수 있다.

 

case "facebook":
  const response = await axios.get(
    "<https://graph.facebook.com/oembed_post>",
    {
      params: {
        access_token: process.env.FACEBOOK_APP_KEY,
        url: req.body.url,
      },
    }
  );
  const data = await response.data;
  const fbhtml = await data.html;

  $ = cheerio.load(fbhtml);

  const text = $("blockquote.fb-xfbml-parse-ignore p").text();

  crawledData = {
    desc: text,
  };

  break;

 

 

 

++

인스타그램 스크래핑

Graph API Reference v15.0: Instagram Oembed - Documentation - Meta for Developers

 

그래프 API 참고 자료 v15.0: Instagram Oembed - 문서 - Meta for Developers

 

developers.facebook.com

인스타그램의 경우엔 대개의 경우 메타 태그로 스크래핑이 가능하지만, 가끔 유저 접속 환경에 따라 스크래핑이 되지 않는 경우가 있다.

 

이 때에도 역시 미리 승인받은 권한에 한하여 facebook의 graph API를 사용하면 된다.

 

인스타그램용 엔드포인트(instagram_oembed)가 따로 존재하며, Oembed Read 권한을 승인받은 계정이라면 사용 가능하다.

 

intagram_oembed의 경우 url외에 액세스 토큰을 매개변수로 보내줘야 하고, 자바스크립트 태그(<script>)를 스크래핑 값에서 제거하고 싶다면 omitscript: true를 매개변수로 보내면 된다.

 

instagram_oembed는 oembed_post와 달리 응답 데이터에 thumbnail_url이 존재하여, 이미지 소스를 스크래핑해올 수 있다.

 

const response = await axios.get(
  "https://graph.facebook.com/instagram_oembed",
  {
    params: {
      access_token: process.env.INSTAGRAM_TOKEN,
      url: req.body.url,
      omitscript: true,
    },
  }
);
crawledData = {
  image: await response.data.thumbnail_url,
  desc: $("title").text(),
  title: $("title").text(),
};