아 그게 뭐더라

우리학교에서 푼 문제 크롤링하기 (in 백준) 본문

프로젝트

우리학교에서 푼 문제 크롤링하기 (in 백준)

뭐더라토 2019. 6. 2. 22:12

백준에서는 우리 학교 친구들이 풀지 않은 문제를 풀어야 학교 랭킹이 올라간다. 따라서 우리 학교 구성원들이 어떤 문제를 풀어 두었는지 확인하는 과정이 필요한 때가 있다. (과제하기 싫어서) 한번 만들어 보았다.

 

python2에서 이것 저것 import 할 수 있는 것은 전부 가져다 썼다. 먼저 크롤링 해 오는 부분의 소스코드이다.

https://github.com/friendship1/ps_dgist/blob/master/ps_dgist/parse_and_insert/parse.py

(허전한 github를 채울 절호의 기회라고 생각해서 급조했다)

 

아주 간단하게 보면,

requests로 html를 받아와서,

유명한 html 크롤링 모듈인 BeautifulSoup로 파싱한 후,

이를 pymysql로 (이미 mysql 명령어로 만들어 놓은) mysql database의 테이블에 집어넣는 코드이다.

dgist 구성원이 나온 페이지에서 구성원들 id를 긁어온 후, id를 통해 각 개인 페이지에 들어가서 푼 문제를 긁어온다. 

"baekjoon_dgist" 데이터베이스에 만들어 놓은 table은 "solved" 와 "wronged"(맑은물은 wrong의 과거형이 뭔지 모른다) 두 개로, 각각 맞춘 문제와 틀린 문제에 대해,

(사용자 아이디(user) VARCHAR(32), 문제 번호(pnum) (INT), 테이블에 쓴 날짜(updated_date) (DATE))

이렇게 세가지 칼럼을 저장한다. primary key는 (user, pnum) 두 칼럼을 합친 것.

 

 

이제 띄워주는 부분을 보자.

https://github.com/friendship1/ps_dgist/blob/master/ps_dgist/show_in_web/server.py

시간소모가 너무 커서 그냥 Flask라는 웹서버 만드는데 아주 좋은 모듈을 가져다 붙여놓고, sql 결과를 때려 넣었다.

http://www.dgrang.com:8000/ac

http://www.dgrang.com:8000/wa

(80번 포트는 열심히 아파치가 일하고 있는지라 8000번 포트이다)

위 두 개에 들어가면 "solved" 와 "wronged" 테이블을 "select *" 한 것을 뿌리도록 해 두었다. (updated_date는 뺐다)

사용자가 문제 번호를 입력하면 검색해 주는 기능은 나중에 하는걸로... (그냥 사기기술인 Ctrl + F 를 쓰자...)

 

 

서버 파일은 nohup을 이용해 계속 돌고 있으며, 크롤링 해주는 부분은 매일 새벽 04:30에 한 번씩 크롤링 하도록 crontab을 이용해 설정해 두었다.(잘 되는지는 내일이 되어야 안다) 구사과 백준 크롤링 사이트가 백준 정책 위반으로 막혔던데, 나도 잡혀가려나...

 

 

 

헤맨 지점 :

 - Flask에 host 번호를 0.0.0.0 으로 적어주지 않으면 외부에서 접속이 안된다. 디폴트가 127.0.0.1 같던데 127.0.0.1은 외부 접속이 안되는건가. (맑은물 인증. 두 개는 분명히 다른 것이었다.  https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost )

 - pimary key가 (user, pnum)이라 매번 크롤링 해서 insert하면 알아서 무시할 줄 알았는데 에러가 뜬다. INSERT 뒤에 IGNORE을 붙여주어야 중복을 무시하고 넘어간다. 그런데 이렇게해도 warning은 떠서, 화면이 지저분해진다.

 - 내 mysql 비밀번호를 따로 저장해두고 싶어서 모듈로 뺐는데, private 폴더를 import를 못하는게 아닌가. 찾아보니 폴더 안에 __init__.py 를 껍데기라도 넣어두어야 하위폴더를 import할 수 있는 것으로 인식한다고.

 - BeautifulSoup로 parse할 때, text="" 기능과, find_parent 기능을 몰라서 한참 헤맸다.

 - 고인물의 상징 re.compile(). 맑은물인 나에게는 버거운 기능이다. 한참 검색했다.

 - mysql에서는 DATE와 DATETIME 자료형이 있다. 딩굴이 만들때는 몰라서 1900년 이후로 흐른 초를 썼는데... NOW()를 넣어주면 알아서 값도 넣어준다.

 - github 웹에서 파일을 올렸더니 빈 파일이었던 __init__.py는 안올려주네. 그래서 따로 직접 만들어줬다.

'프로젝트' 카테고리의 다른 글

나의 키보드 연대기  (3) 2022.11.16
키보드 배열  (0) 2021.10.21
Comments