사용자 도구

사이트 도구


2018_07

문서의 이전 판입니다!


6일 금요일

웹 페이지를 MHTML 파일로 긁어와 저장하는 프로그램 개발.

사전에 수집해놓은 500개 페이지를 대상으로 일괄처리 시도.

Python Beautiful soup을 사용할 예정이었으나, bs4에서 .mht convert 기능 찾다 안나와서 포기.

구글링 하던 중에 python 오픈소스 개발자들이 만든 chilkat 모듈 발견.

chilkat 으로 500개 페이지 일괄 converting.

문제점: 크롬에서 mht 파일이 안열린다..




9일 월요일

chilkat 모듈을 이용하면 깨지는 페이지들이 발생.

결국 chrome extension 이용해서 다시 작업중

excel에서 읽어오는건 일단 실패했고, 파이선 chilkat 모듈로 했을때 깨지는 페이지에 대해서

크롬 익스텐션 돌려보려고 개발 중.

크롬 익스텐션 구조 익히고 popup.js 에서 background.js에 데이터 넘기는데 시간 소비.

chrome.pageCapture.saveAsMHTML 사용할때 콜백함수 사용법에 대해 더 알아봐야 함.




10일 화요일

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일 수요일

기존의 계획상으로는 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일 목요일

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일 금요일

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일 월요일

blob 객체를 장고 서버에 업로드하기 위해 기본적인 jquery ajax post 통신으로 시도해 봤지만 500에러 발생.

500에러는 보통 보내는 데이터 타입과 헤더에 명시한 타입이 맞지 않을때 발생한다고 함.

처음엔 ajax dataType 필드에 json으로 명시하고 {'data':blob} 이런식으로 보냈는데 에러가 떠서

json 안에는 blob 객체를 직접 넣는게 아닌것 같다고 판단, 아얘 dataType을 blob으로 하고

blob 객체를 직접 보내니까 여전히 같은 에러.

jquery ajax에서는 blob 전송 지원이 안되는 것일지도 모르니

잠시 내려놓고 XHR 방식으로 다시 확인하는 작업 필요.




17일 화요일

구글링을 통해 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일 수요일

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일 목요일

1개의 스레드를 돌려서 500개 mht 파일 생성하는 작업 완료.

DB에 파일 삽입하는 방법으로는 파일의 경로를 넣어두는게 가장 좋을것 같음.

그렇다면 500개 파일에 대해 각각의 파일 위치정보를 빼내서 mySQL column에 박아야 하는데

방법은 여러가지 있음.

(1) Django에서 Model 객체에 제공해주는 API 메소드 이용한다.

(2) MySQL 쿼리문을 이용해서 일괄적으로 update한다

(3) 수작업으로 복붙한다.

1번이 가장 쉬운 방법이고 3번이 가장 바보같은 방법.

나는 2번으로 하기로 함. 이유는 SQL 쿼리 작성하는법 연습도 할겸 이것저것 시도해보기 위해.

일단 쿼리로 테이블 값을 업데이트 하려면 파일 경로의 정보가 있어야 한다.

이건 윈도우 파워쉘 명령어 갖다가 근성이형이 해결해줌.

이제 쿼리 잘 만들어서 update sql문 잘 날려주면 됨.

내일은 이 작업 마무리하고 논문 리딩 시작.

2018_07.1531986646.txt.gz · 마지막으로 수정됨: 2021/04/13 06:54 (바깥 편집)