pupperteer를 이용한 화면 캡처 기능 개발

이번에 개발하는 기능중에 화면을 캡처해서 다운로드를 제공해야 하는 기능이 있다.

처음 시도한 방법은 html2canvas을 이용한 방법 이었는데... 실패 했다.

화면에 보여주는 부분은 잘 캡쳐가 되지만, 스크롤에 숨겨진 부분이 캡쳐가 되지 않았다.

하루를 날리고, 다음으로 시도한 방법은 pupperteer를 이용해서 요청이 오면 내부에서 새로운 페이지를 띄우고 해당 페이지를 로딩해서 캡쳐 하는 방식이다.

만든 코드는 다음과 같다.

router.post('/capture', async (req, res, next) => {
  const file_name = `${shortid.generate()}.png`;
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setViewport({ width: 1366, height: 768, });
  await page.goto(CAPTURE_URL+Buffer.from(JSON.stringify(req.body)).toString('base64'), {waitUntil: 'domcontentloaded'});
  await page.waitFor(1000);
  await page.waitForSelector('#endarea');
  await page.screenshot({fullPage: true, path: `public/images/${file_name}`});
  await browser.close();
  res.json({image_url:`/images/${file_name}`})
});

요청이 들어오면 해당 페이지로 넘어온 파라메터를 다시 전달해서 화면을 캡쳐 한다.

await page.screenshot({fullPage: true, path: public/images/${file_name}});이 부분에 보이는 부분을 전체 화면으로 캡쳐를 해서 저장을 하는 기능을 수행한다.

저장된 이미지를 웹에서 다운로드를 하는 코드는 다음과 같다.

function forceDownload(url, fileName){
        var xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.responseType = "blob";
        xhr.onload = function(){
            var urlCreator = window.URL || window.webkitURL;
            var imageUrl = urlCreator.createObjectURL(this.response);
            var tag = document.createElement('a');
            tag.href = imageUrl;
            tag.download = fileName;
            document.body.appendChild(tag);
            tag.click();
            document.body.removeChild(tag);
        }
        xhr.send();
    }

이와 같이 실행하면 fileName으로 다운로드가 진행된다.

인터넷과 함께면 난 못하는게 없다.

참고자료

Posted by lahuman

MongoDB aggregate 사용

다음과 같은 형식의 여러 ROW의 데이터를 하나의 데이터로 표현 하고 싶었다.

# DATA
{
    "_id" : ObjectId("5c864b1e1cd4038eed5b5633"),
    "link_tag" : [ 
        "#핫앤쿨", 
        "#마스크팩", 
        "#홈케어", 
        "#리뉴메디", 
        "#젊줌마", 
        "#예뻐지는시간"
    ],
    "name" : "홈케어",
    "text" : "젊어지는시간\n. .\n\n#핫앤쿨 #마스크팩 #홈케어\n#리뉴메디 #젊줌마 #예뻐지는시간",
    "owner" : "10961953345",
    "shortcode" : "Bu3eX2iHIFG",
    "display_url" : "https://scontent-icn1-1.cdninstagram.com/vp/c330b55401b96aca266acca202386b42/5D08D97D/t51.2885-15/e35/54446467_181108306201409_5180562059450456961_n.jpg?_nc_ht=scontent-icn1-1.cdninstagram.com",
    "is_video" : false,
    "accessibility_caption" : "Image may contain: 1 person",
    "writed_date" : ISODate("2019-03-11T11:44:00.000Z"),
    "hash" : "086e2b6a65b823c887ef1afc19734f67",
    "createdAt" : ISODate("2019-03-11T11:48:46.276Z"),
    "updatedAt" : ISODate("2019-03-11T12:22:43.532Z"),
    "__v" : 3
}

/* 2 */
{
    "_id" : ObjectId("5c864b1e1cd4038eed5b5632"),
    "link_tag" : [ 
        "#토니슈어", 
        "#다낭까지와서", 
        "#이러고있다", 
        "#간절한걸어떡함", 
        "#플라즈마", 
        "#갈바닉", 
        "#너네둘만믿는다", 
        "#동안피부", 
        "#얼굴마사지기", 
        "#피부개선", 
        "#탄력", 
        "#피부미용기기", 
        "#미용", 
        "#홈케어", 
        "#피부미인", 
        "#데일리", 
        "#뷰티", 
        "#살균", 
        "#셀프", 
        "#피부질환", 
        "#플라즈마", 
        "#트러블케어", 
        "#피부", 
        "#피부과", 
        "#선물", 
        "#물광피부", 
        "#보습", 
        "#안티에이징", 
        "#led마스크", 
        "#미백", 
        "#콜라겐"
    ],
    "name" : "홈케어",
    "text" : "토니느님~ 제 피부를 10년전으로 돌려주세요\n\n제발요....♡ .\n\n#토니슈어 #다낭까지와서 #이러고있다 #간절한걸어떡함 #플라즈마 #갈바닉 #너네둘만믿는다 #동안피부 가즈앙~ \n#얼굴마사지기 #피부개선 #탄력 #피부미용기기 #미용 #홈케어 #피부미인 #데일리 #뷰티 #살균 #셀프 #피부질환 #플라즈마 #트러블케어 #피부 #피부과 #선물 #물광피부 #보습 #안티에이징 #led마스크 #미백 #콜라겐",
    "owner" : "10698447319",
    "shortcode" : "Bu3e2n_jrrE",
    "display_url" : "https://scontent-icn1-1.cdninstagram.com/vp/97d840dbdea55753d2a976302f90002b/5D065CE9/t51.2885-15/fr/e15/s1080x1080/53176269_319394038719034_3474616797099883761_n.jpg?_nc_ht=scontent-icn1-1.cdninstagram.com",
    "is_video" : false,
    "accessibility_caption" : "Image may contain: outdoor and water",
    "writed_date" : ISODate("2019-03-11T11:48:12.000Z"),
    "hash" : "c9a418d8295391c1c83553f0316d1127",
    "createdAt" : ISODate("2019-03-11T11:48:46.266Z"),
    "updatedAt" : ISODate("2019-03-11T12:22:43.527Z"),
    "__v" : 3
}

원하는 결과 데이터

[
    { "tag" : "#미백", "count" : 3},
    { "tag" : "#물광", "count" : 4},
    { "tag" : "#보습", "count" : 10},
    ...
]

구글을 검색하니 $push명령어를 찾았다.

내가 처리한 Query는 다음과 같다.

db.hashtag.aggregate([
    { $match: { $and: [{ name: "테그명" }, { "createdAt": { $gte: (new Date()), $lt: (new Date()) } }] } },
    {$unwind: "$link_tag"},
    {$group:{_id:null, clrs: {$push: {name: "$link_tag", count:1}}}},
    {$unwind: "$clrs"},
    {$group:{_id:"$clrs.name", size: {$sum:"$clrs.count"}}},
    { $sort: { size:-1} },
    { $limit : 5 },
    {$project: {_id:1, size:1 }
  ]);

이렇게 처리 하면 다음과 같은 결과를 받을 수 있다.

[
    { _id:"#물광", size:15 },
    { _id:"#홈케어", size:13 }
    { _id:"#대일리", size:12 }
]

다음은 매 시간별로 수집된 데이터를 counting 하는 query 이다.
내가 원하는 결과는 다음과 같다.

[
    {"date": "2018-03-14 10", "count":30},
    {"date": "2018-03-14 11", "count":20},
    {"date": "2018-03-14 12", "count":33},
    {"date": "2018-03-14 13", "count":34}
]

다행이 이번 QUERY는 한방에 처리 하였다.

db.hashtag.aggregate([
    { $match: { $and: [{ name: "태그명" }, { "createdAt": { $gte: (new Date()), $lt: (new Date()) } }] } },
    {
      $group:
      {
        _id:
        {
          hour: { $hour: "$createdAt" },
          day: { $dayOfMonth: "$createdAt" },
          month: { $month: "$createdAt" },
          year: { $year: "$createdAt" }
        },
        value: { $sum: 1 },
        date: { $first: "$createdAt" },
        sortDate: { $first: "$createdAt" }
      }
    },
    {
      $project:
      {
        date:
        {
          $dateToString: { format: "%Y-%m-%d %H", date: "$date" }
        },
        sortDate: 1,
        value: 1,
        _id: 0
      }
    },
    { $sort: { sortDate: 1 }}
  ])

분명히 많은 기능을 Mongodb에서 제공해주고 있는데, 잘 쓰지 못하고 있다...

노력하자.

참고 자료

Posted by lahuman

puppeteer를 설치하고 구동하기

설치는 아주 간단하다. npm 을 이용해서 설치 하면 바로 되는데, 문제는 설치후 기동하면 오류가 난다.

# 설치
npm install --save puppeteer

# 실행
node app.js

# error 발생

에러 메시지에서는 puppeteer troubleshooting를 보라고 하지만, 내게 도움되는 내역이 없었다.

구글의 도움을 받아 찾은 puppeteer not working on Ubuntu 16.04 but works on 14.04에서 다음 라이브러리를 설치하라는 메시지를 확인하였다.

sudo apt-get install libpangocairo-1.0-0 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 libgconf2-4 libasound2 libatk1.0-0 libgtk-3-0

설치를 하고 나서 실행하면 문제 없이 잘된다.

그러하다~

참고 주소

Posted by lahuman