===== 06일 금요일 =====
[Develop]
웹 페이지를 MHTML 파일로 긁어와 저장하는 프로그램 개발.
사전에 수집해놓은 500개 페이지를 대상으로 일괄처리 시도.
Python Beautiful soup을 사용할 예정이었으나, bs4에서 .mht convert 기능 찾다 안나와서 포기.
구글링 하던 중에 python 오픈소스 개발자들이 만든 chilkat 모듈 발견.
chilkat 으로 500개 페이지 일괄 converting.
문제점: 크롬에서 mht 파일이 안열린다..
\\
\\
\\
===== 09일 월요일 =====
[Develop]
chilkat 모듈을 이용하면 깨지는 페이지들이 발생.
결국 chrome extension 이용해서 다시 작업중
excel에서 읽어오는건 일단 실패했고, 파이선 chilkat 모듈로 했을때 깨지는 페이지에 대해서
크롬 익스텐션 돌려보려고 개발 중.
크롬 익스텐션 구조 익히고 popup.js 에서 background.js에 데이터 넘기는데 시간 소비.
chrome.pageCapture.saveAsMHTML 사용할때 콜백함수 사용법에 대해 더 알아봐야 함.
\\
\\
\\
===== 10일 화요일 =====
[Develop]
Chrome Extension 사용하여 mhtml 파일 저장하는 작업 완료.
chrome.pageCapture.saveAsMHTML 사용하는 방법은 이해했으나, 크롬 엔진이 API를 찾지 못하는 문제 발생.
manifest에 pageCapture, download 아무리 추가해도 해결 안됨.
크롬 flag 권한을 enable로 바꾸니까 해결 됨. (근성이형 도움 받음)
Python Chilkat으로 다운 받았을 때 발생했었던 문제 2가지
(1) 깨지는 페이지 존재했다.
(2) mht 파일이 ie에서만 열리고 chrome에서 안열렸다.
2가지 모두 해결 됨.
내일부터는 xlsl 파일에 들어있는 data set 읽어와서 일괄처리 작업 진행.
\\
\\
\\
===== 11일 수요일 =====
[Develop]
기존의 계획상으로는 xlsl 파일로부터 500개 dataSet 읽어와서 mht 파일로 변환하는 작업을 진행하려고 했으나,
chrome extension에서 mht 파일을 변환할 경우 브라우저에서 보안 점검한다고 뜨는 팝업때문에 문제가 생김.
이 말은 즉 프로그램을 자동화시킬 수 없고 사용자가 개입해야한다는 의미. (팝업 메시지를 클릭해야 함)
내가 이 짓을 하고 있는 이유는 DataSet의 신뢰성을 증명하기 위해 수집 process를 누구나 재현할 수 있도록
하기 위함이므로 이 문제를 해결하지 않으면 안 됨.
대충 고안한 해결 전략으로는
(1) chrome extension의 pageCapture 모듈을 뒤져본다.
(2) 서버를 만들어서 ajax로 던져준다.
chrome extension의 pageCapture 모듈에서 팝업을 무시해주는 특정 function을 찾아볼 수도 있었지만,,
어차피 DataSet을 DB화 해야하고, Visualization을 통해 검증할 수 있어야 교수님이 좋아하기 때문에
서버를 구축하기로 함. 서버는 Django로 구축했고 DBMS는 MySQL 사용함.
Django를 오랜만에 만져봐서 pip도 말썽이고 특히 python-Mysql 모듈이 파이썬 버젼업 되면서 엉망돼버림.
결국 PyMySQL 모듈 가져와서 setting.py에 pymysql.install_as_MySQLdb() 추가하니까 해결 됨.
(오늘 Django 서버 configuration 하는데 시간 거의 다 씀.)
장고 서버 환경설정 대충 마무리하고
Page Model, View 만들어서 엑셀에 모아놓았던 DataSet을 아얘 DB로 옮겨버리는 작업까지 완료.
MySQL에서 Data import 하는데도 인코딩 타입 에러나서 한시간 정도 해맴.
앞으로의 작업 계획은,,
(1) Chrome extension에서 MySQL Data 빼오는 작업
(2) MySQL에서 빼온 Data를 이용해서 각각 페이지마다 mht 또는 blob 파일 생성하는 작업
(3) 생성해낸 mht 또는 blob 을 서버에 전송하는 작업 (ajax)
(4) Django 서버에서 DB 안에 들어있는 mht 정보 찍어보는 작업 (Temlate, View)
그리고 데이터셋 보존 작업 빨리 마무리하고 scoring 방법도 생각해봐야 됨..
\\
\\
\\
===== 12일 목요일 =====
[Develop]
Django 서버에 mainpage 만들어서 DB에 모아두었던 모든 DataSet들 화면에 찍어봄.
temlates 만들고, view 에서 mysql 커넥트 함수 사용법 알아보는데 약간의 시간 소비.
html template에 찍어보니까 모든 필드 정상적으로 출력.
되는줄 알았는데,, 몇개 raw에서 필드가 잘리기도하고 아얘 안들어간 raw 3개 발견.
이유를 알아보니까 dataSet csv 파일을 mysql에 import 할때 세미콜론(;) 을 기준으로 자르게 되는데,
url에 자체적으로 세미콜론이 포함된 경우가 있었음. 그런 애들 때문에 뒤에 raw도 영향을 받아 문제가 생김.
문제있는 데이터들 제대로 수정해주고, 어제 계획했던 chrome extension 에서의 mysql 접근방법 알아봄.
근데 이 작업은 바보같은 생각이었다는 것을 깨달음. ajax 사용해서 서버에 request 하면 훨씬 빠르고 쉽기 때문.
뿐만 아니라 client에서 DB에 접근한다는 것 자체가 굉장히 비효율적인 작업. google에도 관련정보 거의 안나옴.
그래서 client (chrome extension) 에서 django 서버에 ajax 보내는 작업 시작.
근데 또 문제가 client의 background에서 jquery import가 안됨. 원인 찾는데 약간의 시간 소비.
manifest 계속 수정해도 jquery 못찾는다는 에러 뜸. 결국 chrome extension 프로젝트 다시 로드하니까 해결됨.
굉장히 허무했음. 원래 manifest 수정했을 때는 프로젝트 다시 로드해야한다고 함. (민우형 조언)
그래서 ajax 문제 해결하고 Django 서버에 get 메시지 보내는 부분 성공.
Django 서버에서는 접근 url이름을 url(r'^getSites', views.getSites) 로 설정해주고
veiw에서 mysql 빼내서 json으로 전송해 주는 작업 완료.
여기서도 DB에서 빼온 데이터가 json으로 전송이 안되는 문제가 발생했는데,
쿼리셋은 non serializble 하기 때문이라고 함. 장고 core에서 제공하는 serializers 모듈 사용하여 해결.
개발을 하다보니 너무 멀리 와버렸는데 본래의 작업 목적을 다시 한번 상기시키자면,,
(1) client의 background에서 DB에 있는 DataSet을 빼와야했고,
(2) 각각의 url에 대해 mht/blob 파일 생성하여
(3) 다시 서버로 보내줘야 함.
지금까지 (1),(2) 는 진행 완료된 것 같고 3번을 진행해야하는데,
서버 내부에 blob 파일을 저장하는 부분은 좀 더 생각해봐야하는 이슈임.
\\
\\
\\
===== 13일 금요일 =====
[Develop]
client에서 생성했던 blob 파일을 다시 서버로 보내기 위해 ajax 의 POST request를 구현하던 중 문제가 발생.
이상하게 GET은 문제없이 잘 날라가는데, POST는 403 forbidden error가 발생.
POST type으로 ajax 통신할때 필요한 attribute를 빼먹은 줄 알고 한참 돌아다니며 찾아봐도 없음.
googling 해보니 CSRF Token 문제라고 함. CSRF Token은 Cross-site request forgery Token
이라고 해서 다른 사이트의 client에서 request를 보낼 때 서버에서 발행해준 코드를 의미.
이 토큰을 request 호출 주최측에서 헤더에 실어 보내야 권한을 주겠단 소리.
즉, 내가 request를 보낼때 쿠키에서 서버로부터 생성된 토큰을 꺼내 헤더에 넣어야 한다는 것이며
현재 내 개발 실력으로는 거의 불가능에 가까움.
한참 헤매고 있던 중에 태화 선배가 사기캐같은 능력으로 문제를 해결해 줌.
django 미들웨어에 csrf.CsrfViewMiddleware 추가해서 쿠키에 값을 넣을 수 있도록 설정해 주었고,
chrome extension mainfest에 "cookies" permission 추가하여 client에서 쿠키에 올라와 있는 데이터
접근 가능하도록 뜯어 고침. 이렇게 해놓으니까 chrome.cookies.get 함수를 이용하여
cookie 안에 있는 CSRF Token 값을 빼올 수 있게 됐고, 클라이언트에서 post 방식으로 ajax request 할 때
header에 X-CSRFToken 값을 넣어 요청이 가능해졌음.
이렇게 해놓으니까 거짓말처럼 403 forbidden error 없어지고 데이터 값 넘어가짐.
이 문제 해결하는데 하루 다 쓰고, 체력 다 방전 됨. 구글에도 정확한 설명이 있는 자료가 거의 없었는데
감으로 따라가서 결국 문제를 해결하신 태화선배의 개발 능력 보면서 매우 감탄함.
잠시 정신 고르고 개발을 다시 진행.
post 방식으로 ajax 통신이 가능해졌으니 클라이언트에서 생성한 blob 파일 500개를 서버에 전송하려 시도.
근데 또 문제가 생김. ajax 통신에서는 string, general object, jason 등의 타입은 전송 가능한데
blob 같이 대용량 바이너리 파일은 전송이 안됨..
여기서 다시 원점으로 돌아가 blob을 ajax로 전송할 수 있는 방법 또는 blob 파일을 전송 할 수 있는
ajax가 아닌 다른 통신 방법이 있는지 탐색. 알아본 결과 FormData 타입의 객체를 사용할 경우 ajax로도
전송이 가능하다고 함. 다음주에는 이 방법 사용해서 blob 파일 넘겨 DB에 넣는 작업 진행.
개발 어렵다..
\\
\\
\\
===== 16일 월요일 =====
[Develop]
blob 객체를 장고 서버에 업로드하기 위해 기본적인 jquery ajax post 통신으로 시도해 봤지만 500에러 발생.
500에러는 보통 보내는 데이터 타입과 헤더에 명시한 타입이 맞지 않을때 발생한다고 함.
처음엔 ajax dataType 필드에 json으로 명시하고 {'data':blob} 이런식으로 보냈는데 에러가 떠서
json 안에는 blob 객체를 직접 넣는게 아닌것 같다고 판단, 아얘 dataType을 blob으로 하고
blob 객체를 직접 보내니까 여전히 같은 에러.
jquery ajax에서는 blob 전송 지원이 안되는 것일지도 모르니
잠시 내려놓고 XHR 방식으로 다시 확인하는 작업 필요.
\\
\\
\\
===== 17일 화요일 =====
[Develop]
구글링을 통해 XHR (XML Http Request) 방식으로 ajax 다시 보내봄.
이번에는 쿠키 문제 해결했으니 문제없이 잘 동작.
결과는 에러가 안남.
기쁜 마음으로 Django에서 콘솔에 찍어보니 [Object Blob] 이라고 잘 뜬다.
근데 원래 blob 객체를 프린트하면 저렇게 나오나 의심되어 getsizrof() 함수로 blob 객체의 크기 찍어보니까..
62 바이트라고 함. type 찍어보니 string 타입..
그러니까, XHR로 blob 객체 잘 넘어온줄 알았는데 알고보니 string 타입으로 '[Object Blob]' 만 넘어온것
객체의 toString 같은 개념인가보다.
이 방법은 아닌것 같아 포기하고 다시 구글링해보니 FormData 객체의 append 함수 사용하면
blob 객체도 json 안에 담아서 넘길 수 있다고 함.
FormData 객체 생성하고 append() 함수로 blob 담아서 send(formData) 날려보니까
여전히 에러 발생. 근데 이번엔 500에러가 아니라 문법 에러가 나는걸 봐선
FormData 객체를 못찾는것 같음.
FormData 객체 사용하는 방법에 대해 더 찾아봐야 함.
\\
\\
\\
===== 18일 수요일 =====
[Develop]
FormData 객체가 잘 생성되고 있는지 확인하기 위해 append 함수로 string 값 넣어놓고
콘솔에 찍어보니까 문제없이 잘 출력됨. FomrData가 문제가 아니였음.
그래서 blob 객체를 append하고 나서 다시 찍어보니까 브라우저상에는 잘 찍힘.
근데 서버로 넘긴 후에 찍어보니까 string 값으로 append 했던 element들은 잘 찍히는데
blob 객체는 맴버에 안보임. 이 부분을 파고들어서 더 자세히 알아보니까,
django에서 ajax로 blob을 get 할때는 request.POST가 아니라 request.FILES를 통해
꺼내야 한다고 함. 그렇게 시도해보니까 문제없이 잘 열림.
혹시나 이번에도 str 값으로 들어온걸 보고 낚였을 수 있으니 size를 확인해보니까
정확히 일치함. 이틀간 해맸던 blob 객체 전송을 성공했으니 쭉쭉 진도 빼는것 가능해짐.
가장 먼저, 서버측에서 넘겨 받은 Blob 객체를 디스크에 write하기 위해 python defalt_storage
모듈 이용하여 내려받았고, 현제 프로젝트 폴더에 files 폴더를 만들어 그 위치에 저장 성공.
이제 500개 페이지에 대해서 loop 돌면서 client 프로그램을 실행시켜놓니까
잘 진행되는것 같다가도 네트워크 에러 발생.
javascript는 비동기적으로 function을 call 하기 때문에 거의 500개의 페이지가 동시에
서버에 requst 메시지를 보내게 됨. 네트워크 트래픽에 병목현상 일어나고 내 컴퓨터가 감당 못함.
즉 이런식으로 프로그래밍 하면 안된다는것을 깨달음 (컴퓨터가 슈퍼 사양이라면 상관없지만)
그래서 처음에는 tap 객체를 생성할때 마다 일정 시간의 delay를 주기 위해 setInterval() 함수를
사용해 보았지만, 시뮬레이션 돌려보니 이것 역시 네트워크가 느려서 결국 tab 생성 및 mht 다운로드
속도가 따라잡혀버림. 결국 마지막 대안 방법으로 생각해낸 것이 스레드를 풀어서 tap 객체를 독립적으로
동작하게 하고, tap 객체가 작업이 끝난 후에 다음 페이지에 대한 작업을 시작하도록 해야 함.
결국 tap 객체를 5개만 생성하고 작업이 끝났을때 다음 url로 이동해주는 함수를 콜백으로 호출하도록
하여 구현. 근데 여기서 운영체제 시간에 배웠던 shared memory 접근시 발생하는 문제가 발생.
특정 tap이 공유 변수를 수정하는 사이에 몇개의 tap이 접근해버려서 결국 몇몇 page는 놓쳐버림.
이 문제를 해결하기 위해 결국 tap마다 처리하는 page 번호의 범위를 나누고 독립적으로 작업하도록 변경
잘 돌아가긴 하지만, 속도가 너무 느림.
5개의 스레드 잘 처리하는 방법과 네트워크 트래픽 문제로 어쩔 수 없이 에러가 발생하는 경우의
예외처리, 저장해놓은 mht 파일을 DB에 저장하는 방법에 대해 더 진행해야 함.
\\
\\
\\
===== 19일 목요일 =====
[Develop]
1개의 스레드를 돌려서 500개 mht 파일 생성하는 작업 완료.
DB에 파일 삽입하는 방법으로는 파일의 경로를 넣어두는게 가장 좋을것 같음.
그렇다면 500개 파일에 대해 각각의 파일 위치정보를 빼내서 mySQL column에 박아야 하는데
방법은 여러가지 있음.
(1) Django에서 Model 객체에 제공해주는 API 메소드 이용한다.
(2) MySQL 쿼리문을 이용해서 일괄적으로 update한다
(3) 수작업으로 복붙한다.
1번이 가장 쉬운 방법이고 3번이 가장 바보같은 방법.
나는 2번으로 하기로 함. 이유는 SQL 쿼리 작성하는법 연습도 할겸 이것저것 시도해보기 위해.
일단 쿼리로 테이블 값을 업데이트 하려면 파일 경로의 정보가 있어야 한다.
이건 윈도우 파워쉘 명령어 갖다가 근성이형이 해결해줌.
이제 쿼리 잘 만들어서 update sql문 잘 날려주면 됨.
내일은 이 작업 마무리하고 논문 리딩 시작.
\\
\\
\\
===== 20일 금요일 =====
[Develop]
쿼리 만들어서 파일 경로 DB에 update하는 작업 진행하다 시간이 너무 많이 소요돼서
결국 django 에서 제공해주는 함수 이용하여 작업.
view 단에 setMhtFiles() 메소드 만들고 os 모듈 안에 있는 listdor() 함수 사용하여
files 폴더 안에 모아놓은 모든 파일의 이름 빼옴.
현재 디렉터리의 경로를 알기 위해 os.path.realpath() 함수 사용하였고, 앞에서 구한
파일명 앞에 붙여서 500개의 절대경로 만들어냄.
각각의 경로들을 DB에 update 하기 위해 모듈 클래스의 save() 함수 이용하여 작업 완료.
추가 작업으로 클라이언트에서 시뮬레이션 할때마다 변수값들 바꿔주는 시간 줄이기 위해
소스코드 정리한번 하고, startDownload() 함수 안에 strat, end, numberOfTabs, isDownload
파라미터 만들어서 쉽게 옵션 변경 가능하도록 함.
마지막으로 클라이언트 프로그램 아이콘 만들어서 추가하는 작업 완료.
\\
\\
\\
===== 23일 월요일 =====
[Study]
개발 잠시 접어두고, 인공지능 (Deep Learning) 공부 방법에 대해 알아 봄.
일단, 인공지능 공부를 하는 목적을 명확히 하자면 내 연구의 비교 알고리즘으로
구현할 필요가 있을 수 있고, 추후에 있을 CRC 과제에서 딥러닝을 사용한 개발을
진행 할 수 도 있기 때문. 그때 가서 공부하기에는 너무 늦기 때문에 지금부터 조금씩
진행해 놓을 계획. 공부할 material은 많이 있었지만 나는 실무 위주의 개념이 필요하므로
홍콩과기대 김성훈 교수님이 youtube와 github에 공유해 놓으신 강의로 결정.
이 강의에는 tensorflow를 실제로 사용하는 예제가 있어서 좋음.
오늘은 기본적인 개론과 tensorflow configuration 정도 진행하고,
machine learning 의 맨 처음으로 나오는 linear regression 은 수업시간에 하도 많이 했으므로
빠르게 진도 뺌. tensorflow 사용해보면서 호기심이 많이 생겼고, 이걸로 뭔가 만들어보고 싶다는
욕구가 생겼고 익숙하지는 않았지만 오랜만에 좌뇌를 많이 사용한 것 같아서 쫄깃한 재미가 있었음.
\\
\\
\\
===== 24일 화요일 =====
[Research]
하루종일 논문세미나와 CRC 그룹1 미팅 및 회식하느라 개인시간 거의 없었음. 개발이나 공부는 거의
못하고 조만간 있을 논문세미나 준비를 조금 진행. 일단 논문 선정을 어떻게할까 고민했는데, 처음엔
비교 알고리즘으로 제시할 Automatic Web Content Extraction by Combination of Learning and Grouping
논문을 발표할까 하다가,, Content extraction에서 scoring 방법론과 관련한 논문을 survey 해서 발표하는
것이 좋을것 같다고 판단. 이유는 어차피 내 연구를 진행하려면 조사해야하는 부분이기도 하고, (무엇보다
이 논문을 미리 발표하면 교수님의 기대치가 너무 높아질 것 같기때문에.) 내일은 괜찮은 논문 찾아서
서베이 진행해야 함.
\\
\\
\\
===== 25일 수요일 =====
[Research]
Web Content Extraction 에서의 Scoring 방법론 관련 논문을 찾아보니 생각보다 많이 나오지는 않음.
google scholar 에서 2개 정도 논문 찾음
(1) Evaluating Web Content Extraction Algorithm
(2) Evaluation Content Extraction on HTML Documents
첫 번째 논문은 스로베니아의 류블랴나 대학교에서 쓴 학위논문이고, 처음 abstrict에서는 web content
extraction algorithm을 평가하는 방법에 대해 서베이한다는 것처럼 말하고 있어서 기대했는데
막상 읽어보니 서베이라기보단 자신들의 한 가지 방법론을 제시하고 있고 다양한 알고리즘들에 대해서
실험해보는 내용임. 여기서 제안하고있는 평가 방법은 Longest Common Subsequence (LCS)
즉 HTML code 끼리 text 일치성을 비교하겠다는 의미. python으로 구현했고, 평가는 잘 된다고 나와있음.
몇가지 아쉬웠던 점은 아이디어가 그닥 신선하지는 않았고, 정답 Set 만드는 과정이 명확하게 제시돼있지
않음. 그리고 여기서 제시하는 것처럼 단순히 text로만 비교를 한다면 생기는 논리적 모순이 발생할 것 같음.
예를들어 비슷한 구조를 갖고있는 생뚱맞은 2개의 영역이 있다고한다면 그 2개는 코드가 비슷할테고
일치성이 높게 판단될 것. 단순한 LCS 비교로는 이러한 문제를 잡지 못할것임.
영역과 면적을 비교한다던지 DOM Tree 를 비교하는 등 구조적인 특징을 잡아야 함.
\\
\\
\\
===== 26일 목요일 =====
[Research]
content extraction evaluating 논문 중 두번째 논문 읽음.
이 논문은 독일의 마인츠 대학교에서 쓴 논문이고 content extraction 분야에서 유명한 논문들이
reference 했음. 이전 논문에 비해서 좋았던 점은 정답 Set을 정한 기준과 방법에 대해 명확히 제시하고
있고, 자신들이 개발한 프레임워크를 설명하는 부분도 있음.
아직 다 읽어보지는 못했지만 여기서는 어떤 아이디어를 냈나 대충 읽어보니 여기도 역시
text 비교를 하는것 같음. 이전 논문처럼 LCS를 사용했는지는 아직 모르겠지만 비교 단위를 characters,
sequence of words, bag of words, set of words 등으로 분류하는것을 보아 LCS는 아닌것 같음.
text를 비교한다는 내용 보고 솔직히 기대는 안되지만 뒤에 실험부분이나 output format 같은 부분은
도움이 될 것 같음.
\\
\\
\\
===== 27일 금요일 =====
[Research]
Evaluation Content Extraction on HTML Documents 논문 읽음.
어제 대충 읽어봤던대로 이 논문은 content extraction 알고리즘을 평가하는 방법론에 대해 제시하고 있음.
인상깊었던 점은 date set을 저장하는 방식이 html 방식이였고, 구체적인 내용을 정의하고있는 meta data를
따로 만들었음. 그리고 정답 set을 정의하는 포맷은 text 형식이었음. recall과 precision을 계산하는
metric이 text이기 때문에 정답 set 역시 text로 저장해도 무방함.
나같은 경우에는 xpath로 저장했었는데 나도 만약 text 비교로 성능을 측정한다면 이와 같이 해도
좋겠다는 생각을 함.
프레임워크의 아키텍쳐같은 경우는 내가 만들고 있는 방식이랑 거의 유사했음. 다만 이 논문에서는
알고리즘별로 연산시간도 뽑아내고 있으므로 단순한 server가 아닌 proxy server를 사용하고 있음.
baseline으로 제시한 알고리즘은 Plain, BTE, Crunch, DSC, LQF 로 총 5가지.
plain같은 경우는 저자가 proxy 서버에 남아있는 정보를 이용한다는 간단한 아이디어로 구현한것이고
나머지 4가지는 기존에 제시된 CE 알고리즘들임.
성능은 데이터셋의 종류에 따라 제각각이지만 대부분의 경우에서 DSC가 높게 측정됨.
related work로 제시된 논문들은 몇가지 있었으나 딱히 흥미로운 것은 없었음.
이 분야에서 성능을 측정하는 방법론에 대해 제시된게 거의 없는 것 같음.
사실 이 논문의 저자도 CE 에서의 성능 측정을 IR 에서의 정보 검색률로 생각한 것임.
\\
\\
\\
===== 30일 월요일 =====
휴가
\\
\\
\\
===== 31일 화요일 =====
휴가
\\
\\
\\