2022년 11주차 기록
2022.03.14
google-sheets-formula recipe wiki-setting
03/14 (월) ~ 03/20 (일)
- 구글 시트 함수 레시피 한 개 추가
- 개인위키에서 태그 검색시에 조합 태그를 사용할 수 있을까? (2022-03-14)
-
용어정리 필요 - React를 CDN으로 사용할 경우 권장하는
crossorigin
속성에 대해 - 구글시트 에서 직접 스크레이핑 하기
- GCP에 대해 아라보자 (2022-03-17)
- IT문서에서 사용되는 영어 표현 (2022-03-18)
- (질문) Commander.js 와 Pkg는 같은 개념의 Library인가?
- 축구 경기일정 calendar에 추가하기
- 윈도우즈 이모지 선택하기
- 클립보드로 복사히기 버튼 만들기
- CSS로 그림그리기
- Naver Cloud Platform
구글 시트 함수 레시피 한 개 추가
- 태그 연관성: #google-sheets-formula, #recipe
Recipe, 특정 범위에서 12번째 컬럼의 모든 열을 범위로 받고 싶다
INDEX 사용
- INDEX 함수 설명, 구글
- INDEX는 보퉁 참조된 범위 내에서 특정 행과 열에 해당하는 값만 반환 한다
- INDEX는 때문에 행, 열의 INDEX는 보통 1이상의 정수가 입력되는데..
- 하지만 행이나 열 부분에
0
이 입력될 경우 0이 아닌 값을 가진 행이나 열의 전체 배열을 반환하게 된다 - 사용례
=INDEX(이름이지정된범위, 0, 12)
- 이름이지정된범위의 12번째 컬럼 배열이 반환됨
OFFSET 사용
- OFFSET 함수 설명, 구글
- OFFSET은 원래 범위 참조를 반환하는 함수다
- 첫번째 argument인 셀 참조 에는 보통
A2
와 같이 지정된 셀주소를 넣지만-
이름이지정된범위
를 넣으면 해당 범위의 LeftTop 지점이 OFFSET을 계산할 기준으로 설정된다
-
- 행 수를 계산하기 위해
ROWS()
를 사용했다 - 때문에 위의 INDEX 와 같은 결과를 반환하려면 아래와 같이 사용한다
=OFFSET(이름이지정된범위,0,11,ROWS(이름이지정된범위),1)
- 이름이지정된범위의 12번째 컬럼의 범위 참조가 반환된다
차이점 ?
- 반환하는 값의 명치이 배열과 범위 참조로 차이가 있다
- 배열과 범위 참조에 어떤 실질적 차이가 있는지는 아직 발견하지 못했다
Plus Recipe, 특정 범위에서 특정 컬럼을 기준으로 Filtering 하고 싶다
- FILTER 함수 설명, 구글
- 위의 Recipe 결과를 반환받아 다음과 같이 응용할 수 있다
- 12번째 컬럼이
B02
값을 갖는 행만 필터링해서 보고 싶다=FILTER(이름이지정된범위,INDEX(이름이지정된범위,0,12) = 'B02')
개인위키에서 태그 검색시에 조합 태그를 사용할 수 있을까? (2022-03-14)
- 태그 연관성: #wiki-setting
- 스택 오버플로의 태그 페이지를 보면 여러태그의 조합으로 질문 필터링을 할 수 있다
- 개인 위키 태그 페이지는 한 개의 태그를 선택하면 그 태그에 해당하는 포스팅만 나오는 구조라 조합 태그를 사용할 수 없다
- 조합 태그를 사용할 수 있도록 구조를 바꿔보자
- 필요성 ?
- 위 섹션의 구글 시트 함수 레시피 에 두 개의 태그를 쓰고 싶다
- #google-sheets-formula, #recipe
- 두 개의 태그 조합시 이 태그 두개가 붙은 포스팅이 모두 검색되면 좋겠다
- 여유가 있을 때 해보자
- 관련 링크
용어정리 필요 - React를 CDN으로 사용할 경우 권장하는 crossorigin
속성에 대해
관련 링크
- crossorigin 속성이 필요한 이유, React
- HTML attribute: crossorigin, 모질라
- Cross-Origin Resource Sharing (CORS), 모질라
- CORS는 왜 이렇게 우리를 힘들게 하는걸까?, EvansLibrary
꼽사리 .. Evans Libary 정리가 잘된 개인 블로그 인듯
구글시트 에서 직접 스크레이핑 하기
-
How to Use IMPORTHTML Function to Pull Data From a Website Into Google Sheets, coupler.io : IMPORTHTML로 스크레이핑 하기 ( table 과 list만 가능함 )
- console 에 직접 JavaScript를 입력하여 table이나 list 순서를 print하는 구문이 쓸만함
1 2
/* 아래 구문을 직접 console 창에 입력 */ var index = 1; [].forEach.call(document.getElementsByTagName("table"), function(elements) { console.log("Index: " + index++, elements); });
- console 에 직접 JavaScript를 입력하여 table이나 list 순서를 print하는 구문이 쓸만함
-
Use Google Sheets’ ImportXML function to scrape and visualize data, geckoboard : IMPORTXML로 스크레이핑 하기
- Extract value of attribute node via XPath, stackoverflow : XPath로 태그 프로퍼티 값 읽어오기
GCP에 대해 아라보자 (2022-03-17)
- #google-cloud-platfrom #google-cloud-functions
- Google-apps-script에서 Puppeteer를 이용하는 방법 : GCF로 Puppeteer를 써서 페이지를 로딩한후 Apps Script가 HTTP API를 읽어오게 할수 있다.
How to puppeteer on Google Cloud Functins - Youtube
- Tech Youtube 따라해보기
- 0:59 , Kickstart 등장
- create-react-app 같은 것인줄 알았는데.. 그런 공식적인 것은 아니고..
- 아래와 같이 그냥 만든 generic batch function
1 2 3 4
kickstart () { mkdir $1 && cd $1 && git init && npm init -y $$ code . echo "You're awesome 🤟" }
Creating a Puppeteer microservice to deploy to Google Cloud Functions
- 작성일 : 2021.10.14, 제목에 원본 링크함
- 이 기사에서는 GitHub에서 키워드를 검색해서 첫번째 결과에서 title을 fetch해오는 예제를 만들어볼것 이다
- 이것은 순전히 예제를 위한것이며 굳이 Puppeteer를 사용하지 않아도 된다
- keyword는 URL에 있고 Github의 페이지에 페이지 목록이 있기 때문에 결과로 바로 navigating 할 수 있다
- 하지만, web page와 interaction이 page URL에 반영되지 않고 이 데이타를 fetch해올수 있는 API가 없다고 가정하자
- 이 경우 Puppeteer를 통한 자동화가 필요해질것이다
Setting up Puppeteer and Node.js
- Puppeteer 프로젝트를 처음 시작하기
- node.js 프로젝트를 시작하고 puppeteer 설치하기
- 가장 기본적인 템플릿으로 puppeteer가 동작하는지 확인
1 2 3 4 5 6 7 8
import puppeteer from 'puppeteer'; const browser = await puppeteer.lauch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.github.com');
- 실행방법
- package.json의 script 에
"run": "node ./src/service.mjs",
를 추가하고npm run-script run
을 실행 - 아니면 그냥
node ./src/service.mjs
를 실행
- package.json의 script 에
Using automation with Puppeteer
- Puppeteer로 다음 동작을 자동화하여 실행해봄
- github.com 을 접속하여 ‘react’로 keyword 검색
- 프로젝트 리스트중 첫번째 프로젝트의 title을 가져옴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
import puppeteer from 'puppeteer'; const service = async (keyword) => { const browser = await puppeteer.launch({ headless: true, defaultViewport: { width: 1920, height: 1080 } }); const inputField = '.header-search-input'; const repoList = '.repo-list'; try { const page = await browser.newPage(); await page.goto('https://www.github.com'); await page.waitForSelector(inputField); await page.focus(inputField); await page.keyboard.type(keyword); await page.keyboard.press('Enter'); await page.waitForNavigation(); await page.waitForSelector(repoList); const title = await page.evaluate((repoList) => ( document .querySelector(repoList) .querySelectorAll('li')[0] .querySelector('.f4.text-normal') .innerText ), repoList); await browser.close(); return title; } catch (e) { throw e; } } export default service;
- 위 과정중 알게된 knowledge
-
page.waitxxx
method로 로딩이 끝나길 기다려 실행할 수 있음-
page.waitForNavigation
,page.waitForSelector
등을 사용해봄
-
-
page.evalute
method로 실제 scrape 를 실행할 수 있음
-
- 위 작업의 결과물을 다른 파일에서도 사용할 수 있게 function으로 wrap하고 export 함
- service.mjs의 최종 결과물은 keyword를 입력받는 async function 임
- 혹시 에러가 발생하면 알 수 있도록
try..catch
블럭을 사용함 - 작업이 끝난후
browser.close
를 호출하여 용무가 끝난 browser 를 닫음
Creating an Express server
- 우선 다음 명령으로 express 설치한다
1
$ npm install express --save
- 서버코드는 다음과 같다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// server.mjs import express from 'express'; import service from './service.mjs'; const app = express(); app.listen(5000); app.get('/:keyword', async (req, res) => { const { keyword } = req.params; try { const response = await service(keyword); res.status(200).send(response); } catch (e) { res.status(500).send(e); } });
- 이 섹션에서는 express로 간이 서버를 만들고 service.mjs를 서비스한다
- express 서버에 접속하면 우리는 contents로 우리가 scraping 해온 title을 얻을수 있다
- 본문에서는
curl localhost:5000/react
형식으로 실행했는데- windows10의 Powershell에서는 다음과 같이
Invoke-WebRequest
명령으로 실행한다.Contest
에facebook/react
를 가져온 것이다1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
❯ Invoke-WebRequest -Uri http://localhost:3000/react StatusCode : 200 StatusDescription : OK Content : facebook/react RawContent : HTTP/1.1 200 OK Connection: keep-alive Keep-Alive: timeout=5 Content-Length: 14 Content-Type: text/html; charset=utf-8 Date: Sat, 19 Mar 2022 06:08:16 GMT ETag: W/"e-snvGvaecsCpaaBiKy352NKIUZX0"... Forms : {} Headers : {[Connection, keep-alive], [Keep-Alive, timeout=5], [Content-Length, 14], [Content-Type, text/html; charset=ut f-8]...} Images : {} InputFields : {} Links : {} ParsedHtml : mshtml.HTMLDocumentClass RawContentLength : 14
- 위 Invke-WebRequest 호출에서 keyword를 다른 것으로 바꿔보며 테스트해보자
- windows10의 Powershell에서는 다음과 같이
- 이 예제는 최소한으로 동작을 확인하기 위한것이다
- 실제 사용시에는 endpoint에 보안작업이 필요하며
- 서버가 아닌 브라우저로부터 request를 send할경우 CORS 설정도 필요하다
Deploying to Google Cloud Functions
- 드디어.. 이제 이 서비스를 serverless cloud function에 배포해보자
- cloud function 과 서버의 차이점은 ?
- cloud function : request 오는 순간 깨어나서 후속 request가 있을동안 깨어있음
- server : 항상 깨어있는 상태
- Google Cloud Function에 배포하는 것은 매우 간단하지만
- Puppeteer가 성공적으로 실행되기 위해서 몇가지 알아둬야할 설정이 있다
- 첫째로 충분한 메모리를 cloud function에 할당해야 한다
- 내 경험으로는 512MB 정도면 Puppeteer를 돌릴수 있었는데
- 혹시 memory-related 문제를 만나게 되면 좀더 할당해라
-
package.json
내용은 다음과 같아야 한다1 2 3 4 5 6 7 8 9
{ "name": "puppeteer-example", "version": "0.0.1", "type": "module", "dependencies": { "puppeteer": "^10.2.0", "express": "^4.17.1" } }
- dependencies 에
puppeteer
와express
를 추가하고 ES6 문법을 사용하기 위해module
로 설정했다
- 첫째로 충분한 메모리를 cloud function에 할당해야 한다
IT문서에서 사용되는 영어 표현 (2022-03-18)
due in part to
- #english-idiom
- 발견한 곳 : Creating a Command-line App … 에서 본문 첫번째 paragraph
This is due in no small part to the fact that command-line apps tend to be efficient, fast, and powerful.
- due in part to , collins dict : 콜린즈 사전의 예문들
- due in part vs. in part due: 비슷한 다른 표현과의 예문 비교
- 의미는 “partly because”
- 나의 추론은…
- This is
due
to the fact .. (100% 그 사실 때문이다) - This is due
in part
to the fact .. (100%는 아니지만 부분적으로는 그 사실 때문이다) - This is due in
no small
part to the fact .. (100%는 아니지만 결코 작지않은 부분이 그 사실 때문이다)
- This is
(질문) Commander.js 와 Pkg는 같은 개념의 Library인가?
- Commander.js 소개 : node.js 프로그램에 CLI 인터페이스를 지원
-
Pkg 소개 : node.js 애플리케이션을 바이너리 컴파일 하여 nodejs가 없는곳에서도 실행할수 있게 만듬
- 생각해보니 pkg로 만든 바이너리가 꼭 Command line Interface일 필요는 없겠다고 생각됨
- 다른게 당연 ?
축구 경기일정 calendar에 추가하기
울버햄턴
- 울버햄턴 홈페이지 접속
- 아래로 스크롤하여 중간쯤에 NEVER MISS A FIXTURE CHANGE 항목에서
DOWNLOAD
버튼 클릭
윈도우즈 이모지 선택하기
- 페이지를 하나 만들까 했는데..이미 인터넷상에 있음
클립보드로 복사히기 버튼 만들기
- #jekyll #liquid #javascript #wiki-setting
- 개인위기의 사용자 경험을 개선시키는 도구
-
How to Add a Copy-to-clipboard Button to Jekyll
- 이 블로그의 Dark 모드 버튼이 참신하다
CSS로 그림그리기
- HowTo …
Naver Cloud Platform
- 사용자 아이디 만듬 롱텀 지메일아이디로..
- cloud function 지원함