์ง๋ 3์ ๋ง์ ๋ก๊ทธ์ธ๊น์ง๋ง ์์ ํ๊ณ , ๊ทธ ์ดํ ์์ ์ ๋ํด ์ค๋ ๊ฑธ๋ ธ์ต๋๋ค. ์์ ์ ํ์ฌ ์๋๋ฐํ์ ํ๋๋ฐ๋ ๋ณด๋๊ฐ ์ ํ์ง์ด ๊ฑธ๋ ธ์ต๋๋ค ๊ทธ๋์ ๋ ธ์ถ์๊ฐ 1/1000์ผ๋ก ์ค์ด์ ์์ํ์ง๋ง, ๋ค ์๋๊ธฐ ์ํ ๊ณผ์ ์ด๋ผ ์๊ฐํ๋ฉฐ ์ด๋ ๊ฒ ์ ๋ ๊ฒ ์๋ํ๊ณ ์์ต๋๋ค.
์ฐธ๊ณ ๋ก ์ ๋ ๊ฐ๋ฐ์๊ฐ ์๋๋ผ ๊ทธ๋ฅ ์ง๋๊ฐ๋ค ํด๋ณด๋ ์ ์ ์ ๋๋ค. ์์ค์ฝ๋๊ฐ ๊ทธ์ ๋ชฉ์ ์ด ๋์๊ฐ๊ธฐ ์ํจ์ด๋ผ ๊น๋ํ์ง ์๊ฑฐ๋ ์๋ชป๋ ๋ถ๋ถ์ด ๋ง์ ์ ์๋ ์ ์ธ์ง ๋ถํ๋๋ฆฝ๋๋ค.
๊ฐ๋ฐ ํ๊ฒฝ
Mac OS : OS ver 12.3.1
[์นด์นด์ค๋ทฐ] ๋ณด๋ ์๋ ๋ฐํ 3๋จ๊ณ. nodeJS๋ก selenium ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉํ์ฌ ์นด์นด์ค๋ทฐ - ์ฑ๋ ์๋ ๋ก๊ทธ
python๋ ์ข์ง๋ง nodejs๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด๋๋ฐํ์ ์๋ํ ํ๋ ค ํฉ๋๋ค. ์ค๋ ๋ด์ฉ์๋ ๋ก๊ทธ์ธ๊น์ง๋ง ๊ธฐ์ฌํ๊ณ , ์์์ ๋ง๋ณด๊ธฐ๋ก ์ํ ์์ ๋ก ๊ณต๊ฐ ํ๊ฒ ์ต๋๋ค ์ด๋ณด์๋ ์ด๋ ค์ธ ์ ์์ง๋ง ์ต๋ํ ๋ง์
odaily.tistory.com
1. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ธ
const {google} = require("googleapis"); //๊ตฌ๊ธ ๋ฌธ์ ๋ก๋ฉ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
const creds = require("selenium-webdriver/metal-hope-xxxxxx-xxxxxxxxx.json"); //๊ตฌ๊ธ key
const config = require("selenium-webdriver/config"); //๊ธฐ๋ณธ ์ค์ ํ์ผ
const webdriver = require('selenium-webdriver'); //์๋ํ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
const mecab = require('mecab-ya'); // ์ ๋ชฉ์ ๊ธฐ์ฌ ์ ๋ชฉ๊ณผ ์ผ์นํ์ง ์๊ธฐ ์ํ ํ๊ธ ๋ถ๋ฆฌํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
const dateUtil = require("date-utils"); //ํ์ ์ ํธ
1-1. googleapi๋ฅผ ์ฌ์ฉํ ์ด์ ๐ก
์ฐธ๊ณ ๋ก ์ค์ ๋ฐ์ดํฐ๋ ๊ธฐ์ฌ๊ฐ ๋์ผ๋ก ๋ค์ด์ค๋ ํธ์ด ์ข์์ ์ ๋ ๋ด์ค ๊ธฐ์ฌ ๋ฐ ๋ธ๋ก๊ทธ, ํฐ์คํ ๋ฆฌ๋ google spread sheet ์๋ค๊ฐ ๋ถ๋ฌ์์ต๋๋ค. api๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด metal-hope...json ํ์ผ์ด ํ์ํฉ๋๋ค.
[์นด์นด์ค๋ทฐ] ๋ณด๋ ์๋ ๋ฐํ 2๋จ๊ณ. ๊ตฌ๊ธ ์ฑ ์คํฌ๋ฆฝํธ๋ก ๋ณธ์ธ ํฐ์คํ ๋ฆฌ ํฌ์คํ ๊ธ ๊ฐ์ ธ์ค๊ธฐ(OPEN API)
๊ตฌ๊ธ ์คํ๋ ๋์ํธ๋ฅผ ์ฌ์ฉํ ์ค ์๋ ๋ถ์ด๋ฉด ๋๊ตฌ๋ ํ ์ ์์ต๋๋ค! 1๋จ๊ณ. ํฐ์คํ ๋ฆฌ API๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ฑ์ ๋ฑ๋กํฉ๋๋ค. ํฐ์คํ ๋ฆฌ API ์ฑ ๋ฑ๋ก ์ฌ์ดํธ : https://www.tistory.com/guide/api/manage/regist
odaily.tistory.com
[์นด์นด์ค๋ทฐ] ๋ณด๋ ์๋ ๋ฐํ 2๋จ๊ณ. ๊ตฌ๊ธ ์ฑ ์คํฌ๋ฆฝํธ๋ก ๋ณธ์ธ ๋ค์ด๋ฒ ๋ธ๋ก๊ทธ ํฌ์คํ ๊ธ ๊ฐ์ ธ์ค๊ธฐ(OP
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ๋ ์๊ธฐ ๋ธ๋ก๊ทธ ์ฝํ ์ธ ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ๋๋ ์ค ์์๋๋ฐ, ์ ์ฒด ๋ธ๋ก๊ทธ์์ ํน์ ๋จ์ด๋ฅผ ๊ฐ์ง๊ณ search ํ๋ open API๊ฐ ์๋ ๊ฒ์ ํ์ธํ๊ฒ ๋์์ต๋๋ค. ์ฐ์ ๋ธ๋ก๊ทธ ๋ฆฌ์คํธ๋ฅผ ์ฑ๊ฒจ
odaily.tistory.com
์ถํ description๋ ์ฌ์ฉํ๊ธฐ ์ํด์ ์ ํฌ์คํ ๊ธ์ ์กฐ๊ธ ์์ ํ์ฌ ๋ณธ๋ฌธ๋ ๊ฐ์ง๊ณ ์์ต๋๋ค.

1-2. config ํ์ผ์ด๋?
json ํํ๋ก ๋ ์ค์ ํ์ผ์
๋๋ค. ์ ๋ ๋ค์ด๋ฒ๋ด์ค, ๋ค์ ๋ด์ค, ํฐ์คํ ๋ฆฌ(๋ด ๋ธ๋ก๊ทธ), ๋ค์ด๋ฒ(๋ด ๋ธ๋ก๊ทธ), ์ ํ๋ธ ์ฝํ
์ธ ๋ก ๊ตฌ์ฑ์ ํ์์ต๋๋ค. ํน์๋ ์ฝํ
์ธ ๋ฌธ์ ๋ ์ด์๊ฐ ๋ฐ์ํ ์ ์์ด ์ ๋ถ OPEN API๋ก ๋ก๋ฉํ๊ณ ์์ต๋๋ค.
์ค์ ์ ๋ฐ๋ผ ํ๋ซํผ๋ณ ๋ณด๋ ๋ฐํ์ ์ํ ์ฝํ
์ธ ์ฌ์ฉ ์ ๋ฌด, ์์ฝ ์ค์ ์ ๋ฌด, ์์ฝ ๋ฐํ ์๊ฐ, ์นดํ
๊ณ ๋ฆฌ type์ ์ค์ ํ ์ ์์ต๋๋ค.
๋ฐํ ์๊ฐ(time)์ ์
ํ
ํ ๊ฐ์๋งํผ ๊ธฐ์ฌ๊ฐ ๋ณด๋๋ก ๋ฑ๋ก๋ฉ๋๋ค. ๋จ, isReserved : true๋ก ์ค์ ๋ ๊ฒฝ์ฐ์๋ง ์์ฝ ๋ฐํ๊ณผ ์๊ฐ ์ง์ ์ด ๋ฉ๋๋ค. ex) 18,20,23 ์ผ ๊ฒฝ์ฐ 3๊ฑด์ ๋ณด๋๊ฐ 18์, 20์, 23์ ์๊ฐ์ ์์ฝ ๋ฐํ์ผ๋ก ์
๋ฐ์ดํธ๋จ
{
"kakaoview" : {
"id" : "์นด์นด์ค์์ด๋",
"pw" : "๋น๋ฐ๋ฒํธ",
"channelID" : "์ฑ๋ID",
"bodytext" : "๋ณด๋ ๋ณธ๋ฌธ ๋ด์ฉ "
},
"google" : {
"googlesheet" : "๊ตฌ๊ธ ์คํ๋ ๋ ์ํธ ๋ฌธ์ ID",
"navernews" : "Sheet ๋ฒ์ Sheet!B3:C",
"daumnews" : "Sheet ๋ฒ์ Sheet!B3:C",
"tistory" : "Sheet ๋ฒ์ Sheet!B5:C",
"naverblog" : "Sheet ๋ฒ์ Sheet!B3:C",
"youtube" : "Sheet ๋ฒ์ Sheet!B3:C"
},
"navernews": {
"type": "naver",
"isUsed": false ,
"isReserved" : true,
"time" : "18,20,23",
"cate1" : "newsnow",
"cate2" : "issuecutating"
},
"daumnews": {
"type": "daum",
"isUsed": false,
"isReserved" : true,
"time" : "22,23",
"cate1" : "newsnow",
"cate2" : "lifestory"
},
"tistory": {
"type": "tistory",
"isUsed": false,
"isReserved" : true,
"time" : "18,19,20,21,22",
"cate1" : "career",
"cate2" : "lifestory"
},
"naverblog" : {
"type": "naverblog",
"isUsed": false,
"isReserved" : true,
"time" : "14",
"cate1" : "hobby",
"cate2" : "tech"
},
"youtube" : {
"type": "youtube",
"isUsed": true,
"isReserved" : true,
"time" : "23",
"cate1" : "hobby",
"cate2" : "contentscurating"
}
}
1-3. ์ฌ์ฉํ ๋ณ์ ์ ์ธ
By = webdriver.By
until = webdriver.until
Key = webdriver.Key
const driver = new webdriver.Builder().forBrowser('chrome').build();
const configJson = JSON.parse(JSON.stringify(config));
let client ;
let category1 ='newsnow'; //์ด๊ธฐ๊ฐ ์ผ๋ถ๋ก ์
ํ
let category2 ='issuecutating'; //์ด๊ธฐ๊ฐ ์ผ๋ถ๋ก ์
ํ
2. ํจ์ ๊ตฌํ
2-1. ๊ตฌ๊ธ api ์ธ์ฆํ์ฌ ์ฐ๋ํ๋ ์ฝํ ์ธ ๊ฐ์ ธ์ค๋ ํจ์
async function init(){
return new Promise( async function(resolve) {
client = new google.auth.JWT(
creds.client_email,
null,
creds.private_key,
[
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/spreadsheets.readonly'
]
);
await loadingData();
sleep(2000);
resolve(true);
});
}
async function loadingData(){
await client.authorize(function(err,tokens){
if(err){
console.log(err);
return;
}else {
console.log('>> google auth ok!!');
}
});
}
์ฑ๋๋ณ๋ก ์ฝํ ์ธ ๋ฅผ ๊ฐ์ ธ์ฌ ๋, ๋ณด๋ ์๋ฅผ ๋ช ๊ฐ ๋ฐํํ ์ง ๋ชฐ๋ผ config file์ Time ๊ธฐ์ค์ผ๋ก ์คํ๋ ๋์ํธ ๋ฒ์๋ฅผ ์ค์ ํ์์ต๋๋ค. ์คํ๋ ๋์ํธ์ ๋จ์ ์ ํ ๋ฒ์ ๋ก๋ฉ์ด ์๋์ด #NAME์ ๊ฐ์ด ์ ๋๋ก ๊ฐ์ ๋ชป ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๊ทธ๋ด ๊ฒฝ์ฐ๋ ํ ๋ฒ ๋ retry ํ์ฌ ๊ฐ์ ธ์ค๊ฒ ํ์์ต๋๋ค. ์ง์ง ์ค๋ฅ๊ฐ ์์ง ์๊ณ ์ ํ์ด๋ฐ ์ด์๋ ๋ฐ์ํ์ง ์๊ณ ์ ๊ฐ์ ธ์์ง๋๋ค.
async function getContent(cl, cate1,cate2, rangeVal, uploadCnt){
return new Promise( async function (resolve,reject) {
category1 = cate1;
category2 = cate2; //career
const sheets = await google.sheets({version: 'v4'});
let rangeValue = rangeChange(rangeVal, uploadCnt);
const request = {
spreadsheetId : configJson.google.googlesheet ,
range : rangeValue,
valueRenderOption: 'FORMATTED_VALUE',
auth: cl
};
sleep(2000);
try {
let response = ( await sheets.spreadsheets.values.get(request)).data;
// TODO: Change code below to process the `response` object:
sleep(2000);
//๋ก๋ฉ ์คํจ์ ๋ก๋ฉ ๋ ๋๊น์ง ๋ค์ spreadsheet ๋ถ๋ฌ์ค๊ธฐ
let tempData = JSON.parse(JSON.stringify(response.values));
while(tempData[0][0] == "#NAME?" || tempData[0][0] == "#ERROR!" || tempData[0][0] == "๋ก๋ ์ค..." )
{
console.log(">> retry getContent");
response = ( await sheets.spreadsheets.values.get(request)).data;
sleep(2000);
let tempData = JSON.parse(JSON.stringify(response.values));
if(tempData[0][0] != "#NAME?" && tempData[0][0] != "#ERROR!" || tempData[0][0] == "๋ก๋ ์ค...")
break;
}
console.log(">> data result : " , tempData);
resolve(response.values);
} catch (err) {
console.error(err);
reject(err);
}
});
}
function rangeChange(rangeval,uploadcount)
{
let start = rangeval.split(":");
startnum = start[0].substr(start[0].length-2,start[0].length);
startnum = startnum.replace("B","");
startnum = startnum.replace("F","");
let lastnum = parseInt(startnum) + uploadcount - 1;
rangeval = rangeval + lastnum;
console.log(">> data Range : " , rangeval );
return rangeval;
}
2-2. ์นด์นด์ค ๋ก๊ทธ์ธํ๋ ํจ์
configํ์ผ์ ๊ผญ ID/PW ์ค์ ํด์ผ ์ ์์ ์ผ๋ก ์ ๋ ฅ์ด ๋ฉ๋๋ค.
async function kakaoLogin(){
return new Promise( async function(resolve,reject) {
try {
let inputId = await driver.findElement(By.css('input#id_email_2'));
inputId.sendKeys(configJson.kakaoview.id);
resolve(true);
} catch (error) {
console.log("kakao ID error : ",error);
reject(err);
}
try {
let inputpw = await driver.findElement(By.css('input#id_password_3'));
inputpw.sendKeys(configJson.kakaoview.pw, Key.ENTER);
resolve(true);
} catch (error) {
console.log("kakao PW error : ", error);
reject(err);
}
});
}
2-3. ๋ณด๋ ์์ฑ
๋ณด๋ ์์ฑ์ด ๋๋ฌด ๊ธธ์ด์ ธ์.. ์ข ๋๋๋ค๊ณ ๋๋ด๋๋ฐ ์ ๋ณผํ์ด ์์ง๋ง, ๊ฒฐ๋ก ์ ์ผ๋ก ์ค์ ํ์ผ์ ์๊ฐ(time) ์
๋ ฅํ ๋งํผ ๋ณด๋๋ฅผ ์์ฑํฉ๋๋ค.
๊ตฌ๊ธ์์ ์ฝํ
์ธ ๋ถ๋ฌ์จ ๊ฒ์ ํ์ฑ ํ์ฌ ๋๊ฒจ์ค๋๋ค. ์๊ฐํด๋ณด๋ ๋ ํจ์๋ ๊ตณ์ด ๋๋ ํ์๊ฐ ์์๋ ์ถ๋ค์.
async function boardcreatebyPlatform(isUsed, type, cate1, cate2, range, isreserved, time){
if(isUsed){
console.log(">> " + type + " site!!---------------");
let content = await getContent(client,cate1,cate2,range,uploadSplit(time));
console.log(">> " + type + " loading success!");
sleep(2000);
await createBoard(type, content, isreserved, time);
sleep(2000);
}
}
async function createBoard(chflag, content, isReservation, time){
let data = await JSON.parse(JSON.stringify(content));
console.log(">> " , chflag , " data : " , data, "length : " , data.length);
let timeArr = await time.split(",")
for(i=0; i<timeArr.length; i++){
let bool = await newBoard(chflag, data[i][0],data[i][1],isReservation,i+1,timeArr[i]);
sleep(2000);
if(bool){
console.log(">> create borad : ", i + 1 , "๋ฒ์งธ ์์ฑ ์๋ฃ -----------------");
}
}
}
์ค์ ์ฝํ ์ธ ์ฑ์ ๋ฃ๋ ํจ์ : newBoard()
๋ณด๋ ํ์ดํ, ๋ณธ๋ฌธ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ , ๋ทฐ ํํ๋ฅผ ์ ํํฉ๋๋ค. ๋งํฌ ์ง์ ์ ๋ ฅ ํญ์์ ๊ตฌ๊ธ ๋ฌธ์์์ ๋ฐ์์จ ๋งํฌ๋ฅผ ๊ฒ์ํ์ฌ ๋ด๊ณ , ์ฝํ ์ธ ํ์์ ์ ๋ชฉ๊ณผ ์ ์ฌํ ๊ธฐ์ฌ๋ฅผ ๋ถ๋ฌ์ ๋ด์๋ด ๋๋ค. ์ ํ์ด 10๊ฐ๊น์ง์ธ๋ฐ ์ฑํฌ๊ฐ ์ ๋ง์์ ๋ด์ ๊ธฐ์ฌ ์๋ฅผ ๋ฎ๊ฒ ์ง์ ํ์์ต๋๋ค.


๋ทฐ ๋ชจ์์ ์ ํํ์์ง๋ง, ๊ฐํน ์ธ๋ค์ผ์ด ์๋ ๊ธฐ์ฌ๊ฐ ๊ฒ์๋ผ์ ๋ทฐ์ ๋ง์ง ์๋ ๊ธฐ์ฌ๊ฐ ๋ด๊ฒจ ํ์ ์ด ๋ฐ์ํ ์ ์์ต๋๋ค. ๊ทธ๋ด ๊ฒฝ์ฐ ๋ค๋ฅธ ๋ทฐ ํํ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ์์ต๋๋ค. (๋จ, ์์ค์ ์ค๋ฅ๊ฐ ์์ด ๋ฐํ ์ ์ข ์ข ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.)
async function newBoard(chflag, title, newLink, isReserve, nCnt, uploadTime ){
return new Promise((resolve) => {
setTimeout(async()=>{
console.log(">> " + chflag + " create board ----------------------------------");
let sendTitle = getTitle(title,chflag);
let txtTitle = await driver.findElement(By.css('#boardTitle'));
let boardContent = await driver.findElement(By.css('#boardCmt'));
sleep(2000);
let idx = selectView(nCnt,chflag);
console.log(">> view select ", idx);
let view = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_editor > div:nth-child(3) > div.edit_template > ul > li:nth-child(' + idx +') > button > span'));
view.click();
sleep(2000);
boardContent.sendKeys(configJson.kakaoview.bodytext, Key.ENTER );
txtTitle.sendKeys(sendTitle);
console.log("sendtitle : ", sendTitle);
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.tab_g.tab_type2 > ul > li:nth-child(2) > a')), 40000).then( async function(){
let tab = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.tab_g.tab_type2 > ul > li:nth-child(2) > a'));
tab.sendKeys(Key.ENTER);
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.item_form.type_search > div > input')), 40000).then( async function(){
let link = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.item_form.type_search > div > input'));
link.click();
link.sendKeys(newLink, Key.ENTER);
console.log(">> search News Link : " , newLink);
sleep(3000);
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.view_contents > ul')), 50000).then( async function(){
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.view_contents > ul > li > div.wrap_util > button')), 40000).then( async function() {
let img = await driver.findElements(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.view_contents > ul > li > div.wrap_thumb > img'));
if(img == "")
{
console.log(">> no img", img); //์ธ๋ค์ผ ์์
selectView(1);
}
let sel_button = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div.view_contents > ul > li > div.wrap_util > button'));
sel_button.click();
let tab = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.tab_g.tab_type2 > ul > li:nth-child(3) > a'));
tab.sendKeys(Key.ENTER);
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div > div > input')), 40000).then( async function(){
let titleArr = regExp(removeEmojis(title)).split(" ")
console.log(">> Keyword News Search : ", titleArr[0] + '' + titleArr[1]);
link = await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > form > div > div > input'));
link.click();
link.sendKeys(titleArr[0] + '' + titleArr[1], Key.ENTER);
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.head_sort > div.tab_sort > a:nth-child(2)')), 40000).then( async function(){
driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.head_sort > div.tab_sort > a:nth-child(2)')).click();
driver.wait(until.elementLocated(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.view_contents')) ,40000).then( async function(){
sleep(2000);
let ele = await driver.findElements(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.view_contents > ul > li'));
for (var j=0; j<ele.length-1; j++){
let num = j+2;
if (num == 2)
{
let img2 = await driver.findElements(By.css(' #mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.view_contents > ul > li:nth-child(2) > a > div > img'));
if(img2 == "")
{
console.log(">> add content no img", img); //์ธ๋ค์ผ ์์
selectView(1);
}
}
sleep(2000);
await driver.findElement(By.css('#mainContent > div.editor_board > div > div.area_contents > div.cont_tab > div.view_contents > ul > li:nth-child('+ num + ') > div.wrap_util > button')).click();
sleep(2000);
console.log(">>>> add link count : " , num );
if(j > 6 || j > ele.length ) { break; }
}
await selectCategory(chflag, category1,category2 ,isReserve, uploadTime);
resolve(true);
});
},async ( err ) => {
selectView(3);
await selectCategory(chflag, category1,category2 ,isReserve, uploadTime);
resolve(true);
}
);
});
});
});
});
});
},4000);
});
}
2-4. ์นดํ ๊ณ ๋ฆฌ ์ ํ ํ ๋ฐํํ๊ธฐ(์์ฝ OR ์ฆ์)
๋ณด๋๊ฐ ์์ฑ์ด ์๋ฃ๋๊ณ [๋ฐํํ๊ธฐ] ๋ฒํผ์ ๋๋ ์ ๋ ์์ฝ ๋ฐํ๊ณผ ์๋ ๊ฒฝ์ฐ๋ฅผ ๋๋ ์ ํ๋๋ฐ ์ ๋ฆฌํ๊ณ ๋๋ฌด ๊ธธ์ด์ ์ ๋ฆฌํ๊ณ ์ถ์ง๋ง, ์์ง๋ ์ด์๊ฐ ๋ง์์ ๊ทธ๋ฅ ๋ด๋ฒ๋ ค ๋๋ ค๊ณ ํฉ๋๋ค. ์นํ์ด์ง ๋ก๋ฉ๋ผ์ ์ ์์ ์ธ ๋ element๋ฅผ ๋ถ๋ฌ์ฌ ๋๊น์ง ๋๊ธฐ๊ฐ ๋๋ฌด ๊ธธ๋ค๊ณ ์ด๋ฒ์ ๋๊ผ์ต๋๋ค. ์นดํ ๊ณ ๋ฆฌ ์ ํํ๊ณ ์ค์ ๋ณด๋๋ฅผ ๋ฐํํ ๋ ์ฌ์ฉํ๋ ํจ์์ ๋๋ค.
async function selectCategory(chflag, cate1, cate2, isReserve, reserveTime){
return new Promise( async function(resolve) {
let btnOk = await driver.findElement(By.css('#mainContent > div.wrap_btn > div.align_r > button.btn_g.btn_primary.btn_icon'));
btnOk.click();
driver.wait(until.elementLocated(By.css('#layer > div > div > div.layer_body > div > div:nth-child(3) > dl > dd > div')), 40000).then( async function(){
if(isReserve)
{
await driver.findElement(By.css('#layer > div > div > div.layer_body > div > div:nth-child(2) > dl > dd > div > div:nth-child(2) > label > span.txt_choice')).click();
driver.wait(until.elementLocated(By.css('#layer > div > div > div.layer_body > div > div:nth-child(2) > dl > dd > div > div:nth-child(5) > div > a')), 40000).then( async function(){
reserveTime = await dateUpdate(reserveTime);
await driver.findElement(By.css('#layer > div > div > div.layer_body > div > div:nth-child(2) > dl > dd > div > div:nth-child(5) > div')).click();
driver.wait(until.elementLocated(By.css('#layer > div > div > div.layer_body > div > div:nth-child(2) > dl > dd > div > div:nth-child(5) > div > div > ul')), 40000).then( async function(){
let selectBox = await driver.findElement(By.xpath('//*[@id="layer"]/div/div/div[2]/div/div[2]/dl/dd/div/div[5]/div/a'));
driver.sleep(2000);
reserveTime = parseInt(reserveTime) + 1;
let selectli = await driver.findElement(By.css('#layer > div > div > div.layer_body > div > div:nth-child(2) > dl > dd > div > div:nth-child(5) > div > div > ul > li:nth-child('+reserveTime+ ') > a > span'));
selectli.click();
driver.sleep(2000);
console.log(">> category 1: ", cate1, "category 2: ", cate2 );
await driver.findElement(By.css("label[for='"+cate1+"']")).click();
await driver.findElement(By.css("label[for='"+cate2+"']")).click();
sleep(2000);
console.log(">> category all select");
let lastBtn = await driver.findElement(By.css('#layer > div > div > div.layer_body > div > div.wrap_btn.align_r > button.btn_g.btn_primary.btn_icon'));
lastBtn.click();
driver.wait(until.elementLocated(By.css('#layer > div > div > div.layer_foot > div > button')), 40000).then( async function(){
await driver.findElement(By.css('#layer > div > div > div.layer_foot > div > button')).click();
sleep(2000);
driver.wait(until.elementLocated(By.css('#mainContent > div.wrap_tit > div > a')), 50000).then( async function(){
await driver.findElement(By.css('#mainContent > div.wrap_tit > div > a')).click();
sleep(2000);
resolve(true);
});
});
});
});
}
else {
console.log(">> category 1: ", cate1, "category 2: ", cate2 );
await driver.findElement(By.css("label[for='"+cate1+"']")).click();
await driver.findElement(By.css("label[for='"+cate2+"']")).click();
sleep(2000);
console.log(">> category all select");
let lastBtn = await driver.findElement(By.css('#layer > div > div > div.layer_body > div > div.wrap_btn.align_r > button.btn_g.btn_primary.btn_icon'));
lastBtn.click();
driver.wait(until.elementLocated(By.css('#layer > div > div > div.layer_foot > div > button')), 50000).then( async function(){
await driver.findElement(By.css('#layer > div > div > div.layer_foot > div > button')).click();
sleep(2000);
driver.wait(until.elementLocated(By.css('#mainContent > div.wrap_tit > div > a')), 50000).then( async function(){
console.log(">> new board btn click");
await driver.findElement(By.css('#mainContent > div.wrap_tit > div > a')).click();
sleep(2000);
resolve(true);
});
});
}
});
});
}
์์ฝ ๋ฐํ ์ ์๊ฐ์ด ์ง๋ฌ์ผ๋ฉด ํ์ฌ ์๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๋ ํจ์์ ๋๋ค.
async function dateUpdate(time)
{
let newDate = new Date();
let today = newDate.toFormat("YYYY-MM-DD HH24:MM");
let temptime ;
if(time.length < 2)
{
temptime = "0" + time;
}
let resevationTime = newDate.toFormat("YYYY-MM-DD") + " " + temptime + ":00"
if(Date.compare(today,resevationTime) == 1 )
{
let txt = today.split(" ");
resultTime = txt[1].split(":");
console.log(">> Change resevationTime : ", resultTime[0]);
return resultTime[0];
}
else{
return time;
}
}
์์ผ๋ก๋ ๊ณ์ ์์ ํ ๋ถ๋ถ์ ๋๋ค. ๊ธฐ์ฌ ์ ๋ชฉ์ ๊ฐ์ง๊ณ ์ ๋ณํํ๋ฉด์ ๋ณด๋ ์ ๋ชฉ์ ๋ง๋ ๋ถ๋ถ์ ๋๋ค. mecab ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ค์น ๊ณผ์ ์ด ๊ฝค๋ ๋ณต์กํด์ ๋ณ๋๋ก ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ค๋ฅธ ํฌ์คํ ๊ธ์๋ ๋ง์ด ์ฐพ์๋ณผ ์ ์์ต๋๋ค.
function getTitle(strTitle, tempChflag){
var tempTitle = removeEmojis(strTitle);
console.log(">> strTitle length :" , tempTitle.length);
if(tempTitle.length > 35)
{
console.log(">> strTitle before :" , tempTitle);
tempTitle = tempTitle.substring(0,36);
let lastidx = tempTitle.lastIndexOf(" ");
tempTitle = tempTitle.substring(0,lastidx);
console.log(">> strTitle after :" , tempTitle);
}
if(tempTitle.length == 24)
{
tempTitle = tempTitle + " ";
}
if(tempChflag == "youtube")
{
tempTitle = tempTitle.substring(0,30);
tempTitle = "[playlist]" + tempTitle;
return tempTitle;
}
sleep(1000);
if(tempChflag == "naver" || tempChflag == "daum" )
{
return new Promise((res, rej) => {
mecab.nouns(tempTitle, function(err,result){
console.log("result", result.length);
var title = "";
for(var i=0; i<result.length/2; i++)
{
title = title + result[i];
title = title + " ";
}
var endWord = "์ด์ !";
if (result.length > 3)
{
endWord = "!!!";
}
tempTitle = result[result.length-1] + " " + title + endWord;
console.log(">> strTitle return :" , tempTitle);
res(tempTitle);
});
});
}
else{
return tempTitle;
}
}
2-5. ์ค์ ์คํํ๋ Main ํจ์
์นด์นด์ค ๋ทฐ๋ฅผ ๋์ ๋ก๊ทธ์ธ ํ ํ๋ซํผ๋ณ config ์ค์ ์ ๊ฐ์ ธ์ ๋ณด๋ ์์ฑ ํธ์ถํ๋ ๋ฉ์ธ ํจ์์ ๋๋ค.
function main(){
console.log(">> kakao channel open!");
driver.get('https://creators.kakao.com/channel/'+ configJson.kakaoview.channelID + '/board/create').then( async function(){
try{
await init();
sleep(2000);
console.log(">> Google connect Success!")
await kakaoLogin();
sleep(2000);
console.log(">> Kakao login ok!");
sleep(2000);
//ํ๋ซํผ ๋ณ ํธ์ถ
await boardcreatebyPlatform(configJson.navernews.isUsed, configJson.navernews.type, configJson.navernews.cate1, configJson.navernews.cate2, configJson.google.navernews, configJson.navernews.isReserved, configJson.navernews.time);
await boardcreatebyPlatform(configJson.daumnews.isUsed, configJson.daumnews.type, configJson.daumnews.cate1, configJson.daumnews.cate2, configJson.google.daumnews, configJson.daumnews.isReserved, configJson.daumnews.time);
await boardcreatebyPlatform(configJson.tistory.isUsed, configJson.tistory.type, configJson.tistory.cate1, configJson.tistory.cate2, configJson.google.tistory, configJson.tistory.isReserved, configJson.tistory.time);
await boardcreatebyPlatform(configJson.naverblog.isUsed, configJson.naverblog.type, configJson.naverblog.cate1, configJson.naverblog.cate2, configJson.google.naverblog, configJson.naverblog.isReserved, configJson.naverblog.time);
await boardcreatebyPlatform(configJson.youtube.isUsed, configJson.youtube.type, configJson.youtube.cate1, configJson.youtube.cate2, configJson.google.youtube, configJson.youtube.isReserved, configJson.youtube.time);
}
finally{
console.log(">> close!!!!!!!!!!!!!!!!");
driver.close();
}
});
}
๊ทธ ์ธ. ๋ถ์์ ์ผ๋ก ํ์ํ๋ ํจ์
nodejs์์ drive์ sleep ์ฐ๋ ๊ธฐ๋ฅ์ ๋ชฐ๋ผ ๋ณ๋๋ก ๊ตฌํํ์ฌ ์ฌ์ฉํ์ต๋๋ค ๐ญ ์ด์ธ์๋ ์ด๋ชจ์ง ์์ ๊ธฐ, ํน์๋ฌธ์ ์์ ๋ ํจ์์ ๋๋ค.
function sleep(delay) {
var start = (new Date()).getTime();
while ((new Date()).getTime() - start < delay) {
// continue ๏ผ
continue;
}
}
async function wait(delay){
try {
await driver.wait(() => { return false; }, delay);
} catch (err) {
console.log(err);
}
}
function removeEmojis(string) {
var regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
return string.replace(regex, '');
}
function regExp(str){
var reg = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi
//ํน์๋ฌธ์ ๊ฒ์ฆ
if(reg.test(str)){
return str.replace(reg, "");
} else {
return str;
}
}
function uploadSplit(tempTime)
{
let nCount = tempTime.split(",").length;
return nCount+1;
}
์๋ง์ง์ฐฝ ํ์ฌ๋ ์ข ์ข ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง, ์ง์์ ์ผ๋ก ์์ ํ๋ฉด์ ์ฌ์ฉํด๋ณผ ์์ ์ ๋๋ค. ์๋๋ ์๋ ๋ฐํ ๊ฒฐ๊ณผ์ ๋๋ค.

์๋๋ฐํ ์ดํ๋ก ๋ณด๋๊ฐ ์ ํ์ง์ด ๋์ด ๋ ธ์ถ ์๊ฐ 1/1000์ผ๋ก ๊ฐ์ํ๋๋ฐ์. ๋ณด๋ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์ฃผ๊ธฐ์ ์ผ๋ก ์์ ํด๋ณด๋ฉด์ ๋ฐํํ์ฌ ์ํฉ์ ์ง์ผ๋ณผ ์์ ์ ๋๋ค.


์ถ๊ฐ์ ์ผ๋ก ๋ฆ๊ฒ ์์ํ์ฌ ๋ณด๋ ์ ์ฒด ์์ฝ ๋ฐํํ๋ ๋ถ ์ค ์ง๋๋ฌ 150๋ง ์ ์์ต ๋ ๋ถ์ด ์์ด์ ์์ฝ ๋ณด๋ ๋ฐํ์ ์ ํ์ง์ด๋ ๋ ธ์ถ์ด ์ ๋๋ ์ฌ์ ๋ ์๋๋ผ๋ ํผ๋๋ฐฑ์ ๋ฐ์์ต๋๋ค. ๊ทธ๋ผ์ ๋ฐ์๋ ๋ฐ์ ํ๋ ์ฌํ์ธ๋ฐ ์์ฝ๋ง์ผ๋ก ์ ํ์ง์ด๋ฉด ๋๋ฌด ์ต์ธํ ๊ฒ ๊ฐ์์.
์ ๋ ์๋์ผ๋ก ๋ฐํํ๋ ์๊ฐ์ด ๋๋ฌด ์ค๋ ๊ฑธ๋ ค ๊ธธ๊ฒ ์นด์นด์ค ๋ทฐ๋ฅผ ํ ์๊ฐ์ผ๋ก ์๋๋ฐํ ๊ตฌํํ๊ธฐ ์ํด ๋ ธ๋ ฅํ ์ง๋๊ฐ๋ ์ ์ ์ ๋๋ค. ์ค์ ์นด์นด์ค ๋ทฐ ๋ ธ์ถ ๋ฐ ์์ต ๋ ธํ์ฐ๋ ์๋ ์นดํ์์ ๋ง์ ์ ๋ณด๊ฐ ์์ผ๋ ์ฐธ๊ณ ๋ถํ๋๋ฆฝ๋๋ค.
๊ฒ์๋ฌ๋ ๋๋ฒJob : ๋ค์ด๋ฒ ์นดํ
๋์งํธ๋ ธ๋ง๋๋ก ๊ฒฝ์ ์ ์์ ๋ฅผ ๋๋ฆฌ๋ ค๋ ์นดํ ๊ฒ์๋ฌ๋ ๊พธ์คํ๊ฒ ๋๋ฒ ๊ธฐํ๋ฅผ ์ฐพ์๋ณด๋ ์นดํ
cafe.naver.com
'๋์งํธ ๊ฟํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
curl ์ค์น ๋ฐ ์ฌ์ฉ๋ฒ (0) | 2022.05.18 |
---|---|
์ปดํจํฐ์ ์ ์ฅ ์ฉ๋ ๋จ์ (๋นํธ, ๋ฐ์ดํธ, ๊ธฐ๊ฐ, ํ ๋ผ, ํํ, ์์ฌ, ์ ํ, ์ํ) (0) | 2022.05.16 |
RAID ์ ํ๊ณผ ์ฉ๋ ๊ณ์ฐํ๊ธฐ (RADI, JBOD) (0) | 2022.05.16 |
๋๊ธ
์ผ์์ ๊ณต์ ํฉ๋๋ค๋์
๊ธ์ด ์ข์๋ค๋ฉด ์์์ ๋ณด๋ด์ฃผ์ธ์!
์ด ๊ธ์ด ๋์์ด ๋๋ค๋ฉด, ์์ ๋๊ธ์ ์จ๋ณด์ธ์. ๋ธ๋ก๊ฑฐ์๊ฒ ์ง๊ธ๋๋ ์์๊ธ์ ์๋ก์ด ์ฐฝ์์ ํฐ ํ์ด ๋ฉ๋๋ค.
์์ ๋๊ธ์ ๋ง 14์ธ ์ด์ ์นด์นด์ค๊ณ์ ์ด์ฉ์๋ผ๋ฉด ๋๊ตฌ๋ ํธํ๊ฒ ์์ฑ, ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
๊ธ ๋ณธ๋ฌธ, ๋๊ธ ๋ชฉ๋ก ๋ฑ์ ํตํด ์์ํ ํฌ๊ณผ ์์ ๋๊ธ, ์์๊ธ์ ๊ฐ์กฐํด ๋ณด์ฌ์ค๋๋ค.
์์๊ธ์ ์ฑ์์๋ ์ธ์ฑ๊ฒฐ์ , ์น์์๋ ์นด์นด์คํ์ด ๋ฐ ์ ์ฉ์นด๋๋ก ๊ฒฐ์ ํ ์ ์์ต๋๋ค.