소개
시도하고자 했던 것과 그 이유 👍
스프레드 시트에 논문 검색한 내용을 정리하는 과정에서 시간 절약과 노동력을 줄이기 위해
자동화하는 방법을 모색하게 됨
진행 방법
어떤 도구를 사용 : 구글 스프레드시트, 앱스크립트, 클로드, riss API Key
어떻게 활용하셨나요?
구글 스프레드 시트에서 새 파일을 하나 열고,
확장프로그램인 앱스크립트 실행 후
클로드 AI에게 앱스크립트를 자동화할 수 있는 코드를 만들어달라고 요구함.
앱스크립트 창에서 내용을 지우고 클로드가 준 코드를 복붙함
riss.kr 사이트에 가서 API Key 신청하여 가져와야 함
저장, 실행 버튼 누르고 진행
클로드 프롬프트 :
너는 구글 앱스크립트의 전문가야/구글 스프레드 시트에 특정 주제를 검색하면 국내학술논문 정보를 받는 학술논문 분석 앱스크립트를 만들고 싶어
Tip: 클로드 AI 활용 내용
네, 국내 학술논문 정보를 검색하고 스프레드시트에 가져오는 앱스크립트를 만들어드리겠습니다. 국내 학술논문 데이터베이스는 주로 RISS(학술연구정보서비스), DBpia, KISS(한국학술정보) 등이 있습니다. 이 중 RISS는 API를 제공하므로 이를 활용하겠습니다.
```javascript
// RISS OpenAPI 키 설정
var API_KEY = '여기에_RISS_API_키를_입력하세요';
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('학술논문 검색')
.addItem('국내 학술논문 검색', 'showSearchPrompt')
.addToUi();
}
function showSearchPrompt() {
var ui = SpreadsheetApp.getUi();
var response = ui.prompt(
'국내 학술논문 검색',
'검색어를 입력하세요:',
ui.ButtonSet.OK_CANCEL
);
if (response.getSelectedButton() == ui.Button.OK) {
var searchQuery = response.getResponseText();
searchAcademicPapers(searchQuery);
}
}
function searchAcademicPapers(searchQuery) {
var sheet = SpreadsheetApp.getActiveSheet();
// 시트 초기화
sheet.clear();
// 헤더 설정
sheet.getRange('A1:I1').setValues([['논문 제목', '저자', '학술지명', '발행년도', '권호정보', '페이지', '초록', '키워드', '링크']]);
sheet.getRange('A1:I1').setFontWeight('bold');
try {
// RISS API URL
var searchUrl = 'http://api.riss.kr/search/search.do?' +
'apiKey=' + API_KEY +
'&query=' + encodeURIComponent(searchQuery) +
'&target=ARTICLE' +
'&start=1' +
'&sortby=date' +
'&displaycount=50' +
'&output=json';
var options = {
'muteHttpExceptions': true,
'headers': {
'Accept': 'application/json',
}
};
var response = UrlFetchApp.fetch(searchUrl, options);
var content = response.getContentText();
var results = JSON.parse(content);
if (!results.RESULT || !results.RESULT.items || results.RESULT.items.length === 0) {
sheet.getRange('A2').setValue('검색 결과가 없습니다.');
return;
}
var data = [];
for (var i = 0; i < results.RESULT.items.length; i++) {
var item = results.RESULT.items[i];
// 논문 제목에서 HTML 태그 제거
var title = item.title ? item.title.replace(/<\/?[^>]+(>|$)/g, "") : "제목 없음";
// 저자 정보 처리
var authors = item.author ? item.author.replace(/<\/?[^>]+(>|$)/g, "") : "저자 정보 없음";
// 학술지 정보 처리
var journal = item.journal ? item.journal.replace(/<\/?[^>]+(>|$)/g, "") : "학술지 정보 없음";
// 발행년도
var year = item.pubYear || "발행년도 정보 없음";
// 권호정보
var volume = item.volume || "";
var issue = item.issue || "";
var volumeIssue = volume + (issue ? "(" + issue + ")" : "");
// 페이지
var page = item.page || "페이지 정보 없음";
// 초록
var abstract = item.abstractDesc ? item.abstractDesc.replace(/<\/?[^>]+(>|$)/g, "") : "초록 정보 없음";
// 키워드
var keywords = item.keyword ? item.keyword.replace(/<\/?[^>]+(>|$)/g, "") : "키워드 정보 없음";
// 링크
var link = item.link_url || "링크 정보 없음";
data.push([
title,
authors,
journal,
year,
volumeIssue,
page,
abstract,
keywords,
link
]);
}
// 데이터 입력
if (data.length > 0) {
sheet.getRange(2, 1, data.length, 9).setValues(data);
// 칼럼 너비 자동 조정
sheet.autoResizeColumns(1, 9);
// 초록 열 너비 제한
sheet.setColumnWidth(7, 300);
// 링크를 클릭 가능하게 만들기
for (var i = 0; i < data.length; i++) {
if (data[i][8] && data[i][8] != "링크 정보 없음") {
var formula = '=HYPERLINK("' + data[i][8] + '", "논문 보기")';
sheet.getRange(i + 2, 9).setFormula(formula);
}
}
}
// 정렬 설정 (발행년도 기준 내림차순)
sheet.getRange(2, 1, data.length, 9).sort({column: 4, ascending: false});
} catch (e) {
Logger.log('오류 발생: ' + e.toString());
SpreadsheetApp.getUi().alert('오류가 발생했습니다: ' + e.toString() +
'\n\nRISS API 키를 확인하시고, 올바른 API 키를 입력해주세요.');
}
}
// 검색어로 학술지 정보만 검색하는 함수
function searchJournals(searchQuery) {
var sheet = SpreadsheetApp.getActiveSheet();
// 시트 초기화
sheet.clear();
// 헤더 설정
sheet.getRange('A1:F1').setValues([['학술지명', '발행기관', '등재정보', '발행주기', '주제분류', '링크']]);
sheet.getRange('A1:F1').setFontWeight('bold');
try {
// RISS API URL (학술지 검색)
var searchUrl = 'http://api.riss.kr/search/search.do?' +
'apiKey=' + API_KEY +
'&query=' + encodeURIComponent(searchQuery) +
'&target=JOURNAL' +
'&start=1' +
'&sortby=title' +
'&displaycount=50' +
'&output=json';
var options = {
'muteHttpExceptions': true,
'headers': {
'Accept': 'application/json',
}
};
var response = UrlFetchApp.fetch(searchUrl, options);
var content = response.getContentText();
var results = JSON.parse(content);
if (!results.RESULT || !results.RESULT.items || results.RESULT.items.length === 0) {
sheet.getRange('A2').setValue('검색 결과가 없습니다.');
return;
}
var data = [];
for (var i = 0; i < results.RESULT.items.length; i++) {
var item = results.RESULT.items[i];
// 학술지 정보 처리
var title = item.title ? item.title.replace(/<\/?[^>]+(>|$)/g, "") : "제목 없음";
var publisher = item.publisher || "발행기관 정보 없음";
var regist = item.regist || "등재정보 없음";
var frequency = item.frequency || "발행주기 정보 없음";
var category = item.category || "주제분류 정보 없음";
var link = item.link_url || "링크 정보 없음";
data.push([
title,
publisher,
regist,
frequency,
category,
link
]);
}
// 데이터 입력
if (data.length > 0) {
sheet.getRange(2, 1, data.length, 6).setValues(data);
// 칼럼 너비 자동 조정
sheet.autoResizeColumns(1, 6);
// 링크를 클릭 가능하게 만들기
for (var i = 0; i < data.length; i++) {
if (data[i][5] && data[i][5] != "링크 정보 없음") {
var formula = '=HYPERLINK("' + data[i][5] + '", "학술지 보기")';
sheet.getRange(i + 2, 6).setFormula(formula);
}
}
}
} catch (e) {
Logger.log('오류 발생: ' + e.toString());
SpreadsheetApp.getUi().alert('오류가 발생했습니다: ' + e.toString());
}
}
```
이 앱스크립트는 RISS(학술연구정보서비스) OpenAPI를 사용하여 국내 학술논문을 검색하고 결과를 스프레드시트에 표시합니다. 주요 기능은 다음과 같습니다:
1. 검색 기능:
- 스프레드시트 메뉴에 '학술논문 검색' 옵션 추가
- 검색어 입력 프롬프트 제공
- 최대 50개의 검색 결과 표시
2. 수집하는 정보:
- 논문 제목
- 저자
- 학술지명
- 발행년도
- 권호정보
- 페이지
- 초록
- 키워드
- 클릭 가능한 논문 링크
3. 데이터 정리:
- 자동 칼럼 너비 조정
- 발행년도 기준 내림차순 정렬
- HTML 태그 제거 기능
- 클릭 가능한 링크 형식
사용 방법:
1. RISS OpenAPI 키 발급 받기 (https://www.riss.kr/openapi/index.do에서 신청)
2. 스크립트 편집기에서 `API_KEY` 변수에 발급받은 키 입력
3. 스프레드시트 새로고침 후 '학술논문 검색' 메뉴 사용
주의사항:
- RISS OpenAPI 키가 필요합니다.
- 일일 검색 한도가 있을 수 있습니다.
- 검색 응답이 느릴 수 있습니다.
이 스크립트를 사용하시면 국내 학술논문을 쉽게 검색하고 스프레드시트에서 관리할 수 있습니다. 필요한 경우 다른 학술 데이터베이스(DBpia, KISS 등)도 추가하도록 수정할 수 있습니다.코드 전문 : (코드_클로드 생성)
// RISS OpenAPI 키 설정
var API_KEY = '여기에_RISS_API_키를_입력하세요';
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('학술논문 검색')
.addItem('국내 학술논문 검색', 'showSearchPrompt')
.addToUi();
}
function showSearchPrompt() {
var ui = SpreadsheetApp.getUi();
var response = ui.prompt(
'국내 학술논문 검색',
'검색어를 입력하세요:',
ui.ButtonSet.OK_CANCEL
);
if (response.getSelectedButton() == ui.Button.OK) {
var searchQuery = response.getResponseText();
searchAcademicPapers(searchQuery);
}
}
function searchAcademicPapers(searchQuery) {
var sheet = SpreadsheetApp.getActiveSheet();
// 시트 초기화
sheet.clear();
// 헤더 설정
sheet.getRange('A1:I1').setValues([['논문 제목', '저자', '학술지명', '발행년도', '권호정보', '페이지', '초록', '키워드', '링크']]);
sheet.getRange('A1:I1').setFontWeight('bold');
try {
// RISS API URL
var searchUrl = 'http://api.riss.kr/search/search.do?' +
'apiKey=' + API_KEY +
'&query=' + encodeURIComponent(searchQuery) +
'&target=ARTICLE' +
'&start=1' +
'&sortby=date' +
'&displaycount=50' +
'&output=json';
var options = {
'muteHttpExceptions': true,
'headers': {
'Accept': 'application/json',
}
};
var response = UrlFetchApp.fetch(searchUrl, options);
var content = response.getContentText();
var results = JSON.parse(content);
if (!results.RESULT || !results.RESULT.items || results.RESULT.items.length === 0) {
sheet.getRange('A2').setValue('검색 결과가 없습니다.');
return;
}
var data = [];
for (var i = 0; i < results.RESULT.items.length; i++) {
var item = results.RESULT.items[i];
// 논문 제목에서 HTML 태그 제거
var title = item.title ? item.title.replace(/<\/?[^>]+(>|$)/g, "") : "제목 없음";
// 저자 정보 처리
var authors = item.author ? item.author.replace(/<\/?[^>]+(>|$)/g, "") : "저자 정보 없음";
// 학술지 정보 처리
var journal = item.journal ? item.journal.replace(/<\/?[^>]+(>|$)/g, "") : "학술지 정보 없음";
// 발행년도
var year = item.pubYear || "발행년도 정보 없음";
// 권호정보
var volume = item.volume || "";
var issue = item.issue || "";
var volumeIssue = volume + (issue ? "(" + issue + ")" : "");
// 페이지
var page = item.page || "페이지 정보 없음";
// 초록
var abstract = item.abstractDesc ? item.abstractDesc.replace(/<\/?[^>]+(>|$)/g, "") : "초록 정보 없음";
// 키워드
var keywords = item.keyword ? item.keyword.replace(/<\/?[^>]+(>|$)/g, "") : "키워드 정보 없음";
// 링크
var link = item.link_url || "링크 정보 없음";
data.push([
title,
authors,
journal,
year,
volumeIssue,
page,
abstract,
keywords,
link
]);
}
// 데이터 입력
if (data.length > 0) {
sheet.getRange(2, 1, data.length, 9).setValues(data);
// 칼럼 너비 자동 조정
sheet.autoResizeColumns(1, 9);
// 초록 열 너비 제한
sheet.setColumnWidth(7, 300);
// 링크를 클릭 가능하게 만들기
for (var i = 0; i < data.length; i++) {
if (data[i][8] && data[i][8] != "링크 정보 없음") {
var formula = '=HYPERLINK("' + data[i][8] + '", "논문 보기")';
sheet.getRange(i + 2, 9).setFormula(formula);
}
}
}
// 정렬 설정 (발행년도 기준 내림차순)
sheet.getRange(2, 1, data.length, 9).sort({column: 4, ascending: false});
} catch (e) {
Logger.log('오류 발생: ' + e.toString());
SpreadsheetApp.getUi().alert('오류가 발생했습니다: ' + e.toString() +
'\n\nRISS API 키를 확인하시고, 올바른 API 키를 입력해주세요.');
}
}
// 검색어로 학술지 정보만 검색하는 함수
function searchJournals(searchQuery) {
var sheet = SpreadsheetApp.getActiveSheet();
// 시트 초기화
sheet.clear();
// 헤더 설정
sheet.getRange('A1:F1').setValues([['학술지명', '발행기관', '등재정보', '발행주기', '주제분류', '링크']]);
sheet.getRange('A1:F1').setFontWeight('bold');
try {
// RISS API URL (학술지 검색)
var searchUrl = 'http://api.riss.kr/search/search.do?' +
'apiKey=' + API_KEY +
'&query=' + encodeURIComponent(searchQuery) +
'&target=JOURNAL' +
'&start=1' +
'&sortby=title' +
'&displaycount=50' +
'&output=json';
var options = {
'muteHttpExceptions': true,
'headers': {
'Accept': 'application/json',
}
};
var response = UrlFetchApp.fetch(searchUrl, options);
var content = response.getContentText();
var results = JSON.parse(content);
if (!results.RESULT || !results.RESULT.items || results.RESULT.items.length === 0) {
sheet.getRange('A2').setValue('검색 결과가 없습니다.');
return;
}
var data = [];
for (var i = 0; i < results.RESULT.items.length; i++) {
var item = results.RESULT.items[i];
// 학술지 정보 처리
var title = item.title ? item.title.replace(/<\/?[^>]+(>|$)/g, "") : "제목 없음";
var publisher = item.publisher || "발행기관 정보 없음";
var regist = item.regist || "등재정보 없음";
var frequency = item.frequency || "발행주기 정보 없음";
var category = item.category || "주제분류 정보 없음";
var link = item.link_url || "링크 정보 없음";
data.push([
title,
publisher,
regist,
frequency,
category,
link
]);
}
// 데이터 입력
if (data.length > 0) {
sheet.getRange(2, 1, data.length, 6).setValues(data);
// 칼럼 너비 자동 조정
sheet.autoResizeColumns(1, 6);
// 링크를 클릭 가능하게 만들기
for (var i = 0; i < data.length; i++) {
if (data[i][5] && data[i][5] != "링크 정보 없음") {
var formula = '=HYPERLINK("' + data[i][5] + '", "학술지 보기")';
sheet.getRange(i + 2, 6).setFormula(formula);
}
}
}
} catch (e) {
Logger.log('오류 발생: ' + e.toString());
SpreadsheetApp.getUi().alert('오류가 발생했습니다: ' + e.toString());
}
}결과와 배운 점
Tip : riss API Key 오늘 신청했어요.
메일이 오면 실행을 해보고
이번주 토요일 오프 미팅 때 제대로 보여드리겠습니다.