반응형

장고 - django 1.7 tutorial 1 정리


환경 : 


참고 : https://docs.djangoproject.com/en/1.7/intro/tutorial01/



Writing your first Django app, part 1


Creating a project


1. 프로젝트를 만들고 싶은 directory 로 이동하여, 다음 명령을 입력한다.

   -- Django project 에 필요한 code 를 자동 생성한다. 

      (* project  == a collection of settings for an instance of Django, including database configuration, 

    Django-specific options and application-specific settings.)

 

$ django-admin.py startproject mysite


   --> 현재 directory 에 mysite 라는 프로젝트이름의 directory 만들어 코드 생성한다. 

        ( 주의: 프로젝트이름을 django 혹은 test 로 하지마라, 이름충돌 발생한다!)





**  아래와 같은 directory 및 file 만들어짐. 


mysite/

    manage.py

    mysite/

        __init__.py

        settings.py

        urls.py

        wsgi.py



mysite/   ---> 프로젝트명 폴더


manage.py : command-line utility  ---> 서버 기동, 앱 생성 등등 시에 필요.


mysite/   --> project package 이름 폴더

mysite/__init__.py ---> Python package 임을 나타내는 empty file


mysite/settings.py ---> 설정 관련

mysite/urls.py ---> url 관련

mysite/wsgi.py ---> WSGI-compatible web server 에서 웹서비스할때 사용.



Database setup


mysite/settings.py 를 편집하자. 

여기에는 장고 설정을 나타내는 변수들(module-level variables)이 있다


기본적으로 SQLite 를 사용한다.

 ( SQLite 는 python 에 기본 설치되어있어 따로 설치할 필요없다.)


* 다른 database 를 사용하고 싶으면, settings.py 내부의  DATABASES 'default' 항목을 바꾸면 된다.



ENGINE -- 'django.db.backends.sqlite3', 'django.db.backends.postgresql_psycopg2', 

                'django.db.backends.mysql', 'django.db.backends.oracle' 등등 에서 해당 db로 바꾼다.

NAME -- db 이름. ( SQLite 사용시에는 절대경로 사용하라.)


SQLite  이외의 db 사용시에는,  USER, PASSWORD, HOST 설정도 추가해야함. 

     참고 : https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-DATABASES


* 주의 : SQLite 이외의 db 사용한다면, 이 시점에서 "CREATE DATABASE database_name;" 와 같은 sql 문으로 database 만들어 놔야함.

   -- SQLite 는 자동 생성 하므로 걱정안해도 됨.



* 필요하면 TIME_ZONE  설정하기  -- http://freeprog.tistory.com/25

     


* INSTALLED_APPS 설정 살펴보기.

  -- INSTALLED_APPS ; 장고 프로젝트에서 사용할 모든 Django application 이름으로 구성됨.


settings.py 내부의  defalult INSTALLED_APPS 설정


django.contrib.admin - 관리자 관련

django.contrib.auth - 인증 관련

django.contrib.contenttypes  - content types

django.contrib.sessions - 세션 관련

django.contrib.messages - 메세지 관련

django.contrib.staticfiles - 정적파일 (image, javascript, css) 관련 


  ==> 흔히 사용되는 경우에 편하기위해 default 로  포함되어있음.


-- 이들  apps 중 일부는 db table 을 사용하므로, database 내에 table 생성해야한다!!!!



*** db table 생성하기

    -- v1.7 부터 migrate 로 바뀜. (이전까지는 syncdb 명령어 사용함)


$ python manage.py migrate

   



  ---> migrate 실행이후에 db.sqlite3 파일 생성과 동시에 내부에 table 10개 생성됨.

        (위에서 언급했듯이 migrate 는 table 생성용 !!!!, sqlite 만 특별히 db파일과 table 동시 생성함.)


* migrate  명령어는 INSTALLED_APPS 에 설정된 apps 에 필요한 table 들을, DATABASES 에 설정도 db 를 이용하여 만든다.




The development server


만든 장고 프로젝트 가동시키기...


$ python manage.py runserver

       ; 장고 내장 개발용 web server 이용하여 기동시킨 것임.  실제 배포시에는 Apache 등  전문 Web server 이용하라!

       --> 위 처럼 서버 가동시키고, 웹브라우저에 http://127.0.0.1:8000/ 입력하여 접속한다.





** 장고 서버 구동시 port 사용하기


1) 로컬 컴퓨터에서 8080 포트로 접속하기위한 장고 서버 구동


    $ python manage.py runserver 8080


2) 네트워크에서 8080 포트로 접속하기위한 장고 서버 구동


    $ python manage.py runserver 0.0.0.0:8000


  참고 : https://docs.djangoproject.com/en/1.7/ref/django-admin/#django-admin-runserver

** 장고 서버 구동 상태에서 코드 수정시 자동으로 서버 재구동되어 수정사항 반영한다.





Creating models


Projects vs. apps

app -- web application ( 예: log system, 투표 app 등 )

project -- web site 를 위한 web application 들과 configuration 의 모음.

* project 는 여러개의 apps 을 포함할수있고, app 은 여러 project 에 있을수 있다.



** app 만들기


$ python manage.py startapp polls

  --> polls 라는 app 을 만들겠다!




mysite  프로젝트 폴더명 아래에 polls 라는 app 이름의 폴더 생김.

  -- polls app 내부에는 migrations 라는 폴더 생김 ( v1.7 부터 생김)



** model 만들기  

      ; model 1개  == database table 1개  라고 생각하면 될듯....


투표앱 (poll app) 에 필요한 2개의 model (table)만들자 !  -- Question, Choice 


Qustion = a question + a publication date

Choice = choice + vote tally (투표집계)

- 각각의 Choice 는 한개의 Question  과 연관됨.


* polls/models.py 파일을 아래와 같이 편집하자.

 

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
	




각각의 model 은  django.db.models.Model 을 상속받아 만든다. 

model 내부의 클래스변수 (class variable) 는 database field 에 해당한다.  ( 그러므로, model 은 table 에 해당


field (클래스변수) 는 Field class 의 instance 이다.  ( Field class --> CharField, DateTimeField , etc)

그러므로 Question 클래스에서 question_text, pub_date 는 database column name 으로 사용된다. 


CharField 같은 일부 Field class 는 database schema 혹은 유효성(validation) 검사를 위해 argument 가 필요하다.

또 일부 Field class 는 optional argument 를 설정할수있다.  ( ex: votes --> default =0 )


관계는 ForeignKey 를 사용하여 정의한다. 

장고에서는 many-to-one, many-to-many, one-to-one 의 관계를 제공한다.




Activating models


model 을 가지고 

- 투표앱을 위한 database schema (CREATE TABLE statements) 를 생성하고,

Question, Choice 객체에 접근하기위한 Python database-access API 를 생성한다.


먼저 우리 프로젝트 (mysite) 에 polls 앱이 설치되어있다고 알리는게 필요!

-- 이를위해 mysite/settings.py 파일의 INSTALLED_APPS 설정부분에 'polls' 를 추가한다.




이제 migration 파일을 만들자!  ( v1.7 에서 새로 생김, south 기능을 들여옴)


$ python manage.py makemigrations polls




- makemigration ; model 의 변화 사항을 migration 폴더에 python 파일로 저장함. 

   (위에서는 polls/migrations/  폴더내에 0001_initial.py 파일이 새로 생김)

- 아직 database 에 model table 생성된것은 아님!!!! 



** polls 앱용 table 만들기 


$ python manage.py migrate


 --> migrate 실행시 migrations 폴더내의 migration 파일을 실행시킨다는 것을 볼수 있다. 


- db 파일열어보면 polls_choice 와 polls_ question 이라는 table 이 2개 새로 생김.

   (table 명은 'app이름_소문자모델명' 으로 구성된것을 알수있다.)



** 3-step guide

1. model 을 바꾸면 ( models.py )

2. migrations 를 만들기위해, python manage.py makemigrations 실행하고,

3. database 에 적용하기위해, python manage.py migrate 를 실행하면 된다.



참고) Django 1.7 에서 database table 이름 짓는 방법

http://freeprog.tistory.com/50




====================================================================================

                       이상으로  장고 기본 설정 완료함....


                       아래부터는 추가 조작 사항들... 

=====================================================================================



*** migration 파일 SQL 확인하기


$ python manage.py sqlmigrate polls 0001

   --> polls 앱 폴더내 migrations 폴더안에 있는 0001_initial.py 를 SQL 로 표현 출력한다. ????

         SQL 문을 실행시키는 것은 아님.

         사용하는 database 에 따라 SQL 문은 다를 수 있다.




- Primary key (ID) 는 자동생성됨을 알 수 있다.

foreign key field name 에는 _id 가 자동 추가됨. ( ex: question_id )




*** Playing with the API


* Django interactive Python shell 실행하기.

   -- DJANGO_SETTINGS_MODULE 환경변수 설정하여 사용가능하게 하는 장점이 있어 편하다. 


$ python manage.py shell




>>> from polls.models import Question, Choice   # 투표 앱 model import



# db 에 저장된 모든 question 출력함. -- 처음 생성시에는 아무것도 없다. 

# all()  ---> Returns a copy of the current QuerySet (or QuerySet subclass). 

https://docs.djangoproject.com/en/1.7/ref/models/querysets/#django.db.models.query.QuerySet.all

# http://stackoverflow.com/a/22806277


>>> Question.objects.all()

[]




>>> from django.utils import timezone  # 장고 내장 timezone 이용...


# new Question 생성.

>>> q = Question(question_text="What's new?", pub_date=timezone.now())


# database 에 저장

>>> q.save()




# 저장하면서 id 자동 생성됨.  db 에 따라  1 or 1L 로 보일수 있다.

>>> q.id

1


# python 속성을 이용하여 model field value 접근

>>> q.question_text

"What's new?"

>>> q.pub_date

datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)


# 속성을 바꾸후 save() 를 이용하여 원래의 값을 바꿀수 있다.

>>> q.question_text = "What's up?"

>>> q.save()




# objects.all() -- db 에 있는 모든 question 출력함.

>>> Question.objects.all()

[<Question: Question object>]   # 가독성 떨어져 보임...


==> 가독성 향상위해 polls/models.py 파일의 model class 에 __unicode__() method 추가한다.





* Django shell 을 다시 시작하여 확인해보자 !


>>> Question.objects.all()

실행했을때, Question object  대신에  해당 내용을 보여주어 가독성 좋아짐....




- polls/models.py 를 아래와 같이 수정 저장해 보자.





*** Djnago python shell 로 이상의 것을 가지고 테스트 해보자!!!


python manage.py shell




==> field 검색시에 장고 자체의 Lookup 방법을 따른다. 



참고)  Field lookups    

http://freeprog.tistory.com/49



# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
[]

# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()



참고)  Manager 명명법 ; _set 사용법    

http://freeprog.tistory.com/55





반응형
Posted by 자유프로그램
,

django 설치, 버전 확인

python 2014. 10. 14. 15:55
반응형

django 설치, 버전 확인


환경 : ubuntu 14.04.1 LTS, python 2.7.6, django 1.7


참고 : https://docs.djangoproject.com/en/1.7/topics/install/#installing-official-release



** 설치 명령어

sudo pip install Django





** 설치 버전 확인 (python shell 에서)













반응형
Posted by 자유프로그램
,

ubuntu 버전 정보 확인

Linux 2014. 10. 14. 15:35
반응형

ubuntu 버전 정보 확인


참고 : http://www.cyberciti.biz/faq/howto-upgrade-to-ubuntu-14-04-from-ubuntu-13-10-or-12-04/

         http://forum.falinux.com/zbxe/index.php?document_srl=785099&mid=lecture_tip




방법 2 가지


1. lsb_release -a




2. cat /etc/issue





** 기타  ; 32 bit or 64 bit 구분하기 

uname -mrs




반응형
Posted by 자유프로그램
,
반응형

python -- ffmpeg 이용한 video, audio capture 


환경 : windows 7 32bit, python 2.7.8, 

         FFmpeg version: 2014-09-28 git-3edb9aa

         webcam : Logitech HD Webcam C510

         windows  화면 캡쳐 프로그램 : Setup Screen Capturer Recorder v0.12.8.exe  


참고사이트  : http://nerdlogger.com/2011/11/03/stream-your-windows-desktop-using-ffmpeg/

                   https://www.ffmpeg.org/ffplay-all.html#gdigrab

                   https://github.com/rdp/screen-capture-recorder-to-video-windows-free




<< 준비 작업 >>


** FFmpeg 다운로드.

 http://ffmpeg.zeranoe.com/builds/

-- FFmpeg 32-bit Static 다운로드함.

   -> 다운받은 ffmpeg-20140928-git-3edb9aa-win32-static.7z  파일 압축을 풀면,

        bin 폴더에 ffmpeg.exe 존재

   -> 사용의 편의를 위해 ffmpeg.exe 를 python 설치된 폴더 ( ex: C:\Python27\ )로 복사함.



** Screen Capture Recorder  다운로드.

 http://sourceforge.net/projects/screencapturer/files/?source=navbar

 소스 및 설명 : https://github.com/rdp/screen-capture-recorder-to-video-windows-free




<< 본격적인 시작하기 >>


** directshow devices 목록 보기.

ffmpeg -list_devices true -f dshow -i dummy      



   ---> "留덉씠??HD Webcam C510)"  ; 요것이 뭔가??? 

  ==> 확인 하기위해 python으로 코드 짬.. 


 

# -*- coding: utf-8 -*-
 
import subprocess
import re

p = subprocess.Popen(["ffmpeg","-list_devices","true","-f","dshow","-i","dummy"],
    stdout=subprocess.PIPE,stderr=subprocess.PIPE)

out, err = p.communicate()

print err

tt = err.splitlines()
dshow_devices = []

for i, x in enumerate(tt):
    result = re.search('"(.+)"',x)
    if result:
        b = result.groups()
        print b[0]
        dshow_devices.append(b[0])
	



<결과>


 

==> 즉. "留덉씠??HD Webcam C510)" 는  "마이크(HD Webcam C510)"  인데 , 한글 깨진것임...



** webcam video 녹화.

ffmpeg -f dshow -i video="Logitech HD Webcam C510" out.mp4



 ** webcam video , audio(마이크) 녹화.

ffmpeg -f dshow -i video="Logitech HD Webcam C510" -f dshow -i audio="마이크(HD Webcam C510)" -r 30 out2.mp4



** 전체화면 녹화 , webcam 마이크 소리 녹화

ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="마이크(HD Webcam C510)" -r 30 out3.mp4



** 전체화면 녹화 , 컴퓨터 사운드 녹화

ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -r 30 out4.mp4





Logitech HD Webcam C510 녹화 해상도 옵션 구하기.

ffmpeg -list_options true -f dshow -i video="Logitech HD Webcam C510"





** ffmpeg 자체 내장된 "gdigrab" 화면 video 만 저장하기 >

   https://www.ffmpeg.org/ffplay-all.html#gdigrab


- 전체화면 저장

ffmpeg -f gdigrab -framerate 6 -i desktop out6.mp4


- 시작점 (10,20) 부터 시작하여 vga 크기 (640x480) 만큼만 녹화하기.

ffmpeg -f gdigrab -framerate 6 -offset_x 10 -offset_y 20 -video_size vga -i desktop out7.mp4


- 시작점 (100,200) 부터 시작하여 svga 크기 (800x600) 만큼만 녹화하기.

ffmpeg -f gdigrab -framerate 6 -offset_x 100 -offset_y 200 -video_size svga -i desktop out8.mp4


- 윈도우 title 이  "Calculator" 인 화면만 녹화하기. (???)

ffmpeg -f gdigrab -framerate 6 -i title=Calculator out9.mp4






시작점 (100,200) 부터 시작하여 svga 크기 (800x600) 만큼만 녹화  + "마이크(HD Webcam C510)"  이용한 audio 녹화

ffmpeg -f gdigrab -framerate 6 -offset_x 10 -offset_y 20 -video_size svga -i desktop -f dshow -i audio="마이크(HD Webcam C510)" out10.mp4


시작점 (100,200) 부터 시작하여 svga 크기 (800x600) 만큼만 녹화  + 컴퓨터 사운드 녹화

ffmpeg -f gdigrab -framerate 6 -offset_x 100 -offset_y 200 -video_size svga -i desktop -f dshow -i audio="virtual-audio-capturer" out11.mp4


시작점 (100,200) 부터 시작하여 720x405 (youtube) 크기 만큼만 녹화  + 컴퓨터 사운드 녹화

ffmpeg -f gdigrab -framerate 6 -offset_x 100 -offset_y 200 -video_size 720x405 -i desktop -f dshow -i audio="virtual-audio-capturer" out9.mp4







반응형
Posted by 자유프로그램
,
반응형

beautiful Soup, PhantomJS 사용한 javacript web scraping


환경 : windows 8 64bit, python 2.7.5 64bit, pycharm 3.4


참고 사이트 : 

    http://kochi-coders.com/2014/05/06/scraping-a-javascript-enabled-web-page-using-beautiful-soup-and-phantomjs/

    http://stackoverflow.com/questions/814757/headless-internet-browser


    http://coreapython.hosting.paran.com/etc/beautifulsoup4.html    --> beautiful Soup 4 한글문서

    http://www.crummy.com/software/BeautifulSoup/bs4/doc/#    --> beautiful Soup 4 영어문서


    http://phantomjs.org/quick-start.html    ---> PhantomJS quick start!



<< 미션 >>  

 Pubmed 사이트에서 검색한 논문의 인용횟수 구하기...



< 분석 >

1. chrome 으로 pubmed 에서 찾고자 하는 논문을 검색한다. 

    ex) http://www.ncbi.nlm.nih.gov/pubmed/17708774


  

     ---> 화면 우측 하단에 있는 Cited by 62 PubMed Central articles  부분의 정보를 가져오면 됨!



2. 찾은 논문 페이지에서 F12 눌러서 '개발자 도구' 열어서, html 소스 분석하기.



      --->  id 는 유일하므로 <div id="disc_col"> 을 먼저 찾고,

             -> class 는 여러개 가능하므로 <div class="portlet_title"> 를 모두 찾아서,

             -> 하위의 <h3> , 또 그 하위의 <span> 까지 찾아들어간후,

             -> 'Cited by' 문자가 있으면 정규식으로 62 추출하자!!!

             

 



* 준비 : beautiful Soup 4 설치하기





< 1차 시도 > 

 

# -*- coding: utf-8 -*-
 
from bs4 import BeautifulSoup
import urllib
 
urlstr = 'http://www.ncbi.nlm.nih.gov/pubmed/23256168'

f = urllib.urlopen(urlstr)
tt = f.read()


pp = BeautifulSoup(tt)

# pp 내용중에서, div tag 이면서 id = 'disc_col' 인 element를 list 로 가져온다
tmp = pp.find_all('div', attrs={'id':'disc_col'})[0]

print tmp.prettify()

url2 =  tmp.a.get('href')

url2 = 'http://www.ncbi.nlm.nih.gov/' + url2

print '------------------------------------------- \n'
print url2
        
f2 = urllib.urlopen(url2)
tt2 = f2.read()

pp = BeautifulSoup(tt2)

print '------------------------------------------- \n'
print pp.prettify()
	


-- 출력 결과 --




***  예상과는 다른 결과 나옴!

개발자 도구에서   <div id="disc_col"> 을 찾으면 다음을 쉽게 진행할수 있으리라 생각했으나, 

href 에 새로운 url 이 나오고, 새로운 url 을 추적하였으나, javascript 에 연결되어 있고 원하는 결과 안보임 !!!


====>  새로운 해결책 필요!!!

        javascript를 실행해서 우리가 원하는 결과를 가져올수 있는 뭔가가 필요하다....


        그래서..    PhantomJS  찾음. (다른 도구 사용하고 싶으면  참고사이트를 참고하시라!)




<<  PhantomJS 사용법  >>


1. http://phantomjs.org/download.html   에서 zip 파일 다운로드함.


2. zip 파일 압축풀면. phantomjs.exe 단독 실행 파일 존재함. (추가 설치 작업 필요없다.)


3. javascript 를 포함하고있는 목표 url 을, 분석하여 html로 변환하여, 로컬에 저장한다.

  -> 이를 위해 js 파일을 만든다. (test.js)

  -> phantomjs.exe 로 위에서 만든 js 파일(test.js)을 실행시킴.

  -> javascript 로 된 url 구문이 html 구문으로 변환되고, 이를 로컬에 저장한다.

  -> 이후에 저장된 html 파일을 분석하여 원하는 결과 가져오면됨.



* 메모장으로 test.js 라는 이름으로 텍스트파일을 만들어 아래 내용 입력(복사) 한다. (phantomjs 에서 사용하기 위함)


var page = require('webpage').create();
system = require('system');
var fs = require('fs');// File System Module

var args = system.args;
var url = args[1];    // 대상 webpage url
var output = args[2]; // 저장할 파일이름, path for saving the local file 

page.open( url, function() { // open the file 
  fs.write(output,page.content,'w'); // Write the page to the local file using page.content
  phantom.exit(); // exit PhantomJs
});
	



* python 에서 편하게 사용하기위해, phantomjs.exe 파일만 python 설치한 폴더로 복사함.


** phantomjs 실행 화면


---> javascript 를 포함한 http://www.ncbi.nlm.nih.gov/pubmed/17708774 를 html 로 변환하여 test.html 로 저장하라.




*** 최종 코드 ***

 

# -*- coding: utf-8 -*-
 
from bs4 import BeautifulSoup
import re
 
html_file = 'test.html'     # phantomJS 로 만든 대상 web page의 html 파일
 
f = open(html_file)
tt = f.read()
 
pp = BeautifulSoup(tt)
 
# pp 내용중에서, div tag 이면서 id = 'disc_col' 인 element를 list 로 가져온다
data = pp.find_all('div', attrs={'id': 'disc_col'})[0]
 
# print data.prettify()
 
# data 내용중에서, div tag 이면서 class = 'portlet_title' 인 element들을 list 로 가져온다
d2 = data.find_all('div', attrs={'class': 'portlet_title'})
# print len(d2)

citation = '0'
 
for x in d2:
    tmp = x.h3.span.contents    # x  -> h3 tag  -> span tag  contents
    if tmp and u'Cited by' in tmp[0]:
        # print tmp[0]
        citation = re.search('\d+', tmp[0]).group()    # string
        
print u'인용횟수 = ' , citation
	






성공 !!!

 

**  추가로.. 예외처리, 기타 자동화는 개인적으로 수정해서 사용하세요!!!!

     --- 모든 경우를 확인 한것 아니므로 , 에러 발생시 chrome 개발자도구로  html 분석해서 알고리즘 추가하세요!


반응형
Posted by 자유프로그램
,