0%

PyCrawler

What is PyCrawler

이번에 회사에서 Python을 이용하여 Daum Cafe를 크롤링하는 업무를 잠깐 진행하였다.
업무를 진행하면서 했던 내용을 정리할 겸 해서 github에 등록하였다.

자세한 코드는 PyCrawler Github에 등록하였다.

프로젝트를 간단하게 요약하면 특정 다음 카페의 게시판 정보, 게시판의 게시글 리스트, 본문을 크롤링 하고, 데이터를 가공하여 Django를 통해 Rest API 형식으로 제공하는 기능을 제공한다.
기타 참고사항은 아래와 같다.

  • Chrome Driver : Chrome/76.0.3809.100
  • Python 3.x
  • Django 2.2.4
  • BeatuifulSoup 4.8.0
  • Selenium 3.141.0
  • FBV 방식 사용

설명에 앞서 아직 기능이 많이 부족하다.
프로젝트는 완료되었지만…시간이 될 때마다 조금씩 업데이트를 해볼 수 있도록 노오려억을…


주요 기능

주요 기능은 크게 세 가지이며 아래에서 좀 더 자세하게 다루겠다.

게시판 리스트 정보 api

특정 카페의 게시판 리스트 정보를 가져오는 기능을 제공한다.
호출 시 아래와 같은 Json 정보를 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"title": "카페 제목",
"board_cnt": "게시판 갯수",
"board_url": [
{
"name": "[공지사항]",
"url": "http://m.cafe.daum.net/...."
},
{
"name": "[기타사항]",
"url": "http://m.cafe.daum.net/..."
},
....
]
}

먼저 다음 카페의 ID를 알아야 한다.
다음 카페의 모바일 페이지로 이동을 한다. (모바일 사이트가 좀 더 크롤링하기 편하기 때문에…)

http://m.cafe.daum.net/

로그인을 한 다음에 카페 메인 페이지 화면에서, 각 브라우저의 소스보기 등으로 열어본다.
그리고 아래와 같은 부분을 찾아본다.

1
2
3
4
5
....

<a href="/[Daum Cafe ID]?nil=cafes" class="link_cafe #join_cafe_list">

....

위와 같이 class의 link_cafe 요소를 검색하면 알 수 있다.
찾은 Cafe id를 crawling.py 파일 상단의 Config 영역에 적어준다.
이 때 로그인할 계정과 암호도 입력해준다.

크롤링 코드의 경우 cafe_daum.py 코드의 get_board_list 함수를 참고한다.
워낙 간단하 코드라서 코드의 주석을 참고하면 파악하는데 큰 어려움은 없을 것이다.


특정 게시판의 게시글 리스트 조회 API

특정 게시판의 게시글 리스트를 가져오는 기능을 제공한다.
호출 시 아래와 같은 Json 정보를 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"totalPage": "2",
"data": [
{
"name": "게시글 01",
"url": "http://m.cafe.daum.net/..."
},
{
"name": "게시글 02",
"url": "http://m.cafe.daum.net/..."
},
....
]
}

응답된 값에서 totalPage는 해당 게시판의 총 페이지 갯수를 의미하며, data에는 게시글 리스트와 게시글 url 값을 제공한다.

위 API를 호출하여 동작하는 함수는 cafe_daum.py 코드의 get_board_content_list 함수를 참고한다.
이 api를 호출할 때는 Request Header에 두 가지 값을 전달한다.

  • url-code
    • 이 값은 첫 번째 api에서 호출할 때 해당 게시판의 url을 넣어준다.
  • page
    • 게시판의 페이지 값을 입력한다.

해당 Header 값을 정상적으로 넣어줘야 파싱을 처리할 수 있다.


게시글 상세 조회 API

게시글의 상세 정보를 가져오는 기능을 제공한다.
호출 시 아래와 같은 Json 정보를 제공한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"content_body": "<p>안녕하세요</p> <p>게시글 테스트 입니다.</p>",
"attach_file": {
"attach_cnt": "2",
"attach_file": [
{
"name": "테스트01.JPG",
"url": "http://pd.cafe.daum.net/download.php?grpid=111&fldid=aas&dataid=11&fileid=1&disk=30&.JPG"
},
{
"name": "테스트02.JPG",
"url": "http://pds.cafe.daum.net/download.php?grpid=111&fldid=zzzz&dataid=11&fileid=2&disk=29&.JPG"
}
]
},
"write_user": "작성자",
"write_date": "06.04.18"
}

응답 Json의 형태는 아래와 같다.

  • content_body
    • 게시글 정보를 나타낸다.
    • 일반 태그는 다 제거하고 p, img, br 세 가지 태그만 추려서 가져온다.
  • attach_file
    • 첨부파일이 있는 경우 첨부파일을 담는 부분
      • attach_cnt
        • 첨부파일의 갯수
      • attach_file
        • 첨부파일의 이름과 다운로드 url을 담는다.
  • write_user
    • 작성자 닉네임
  • write_date
    • 작성 시각

위 API를 호출하여 동작하는 함수는 cafe_daum.py 코드의 get_board_content 함수를 참고한다.
이 api를 호출할 때는 Request Header에 아래의 값을 전달한다.ㄴ

  • url-code
    • 이 값은 두 번째 api에서 호출할 때 해당 게시판의 url을 넣어준다.

해당 Header 값을 정상적으로 넣어줘야 파싱을 처리할 수 있다.


정리

아직 기능이 많이 부족한 편이지만, 업무가 끝난 뒤에도 크롤링 관련 내용을 조금씩 추가해볼 예정이다.
이번 포스팅에서는 Daum cafe를 대상으로 하였지만, 다음에는 Naver cafe도 크롤링을 다뤄볼 예정이다.