티스토리 뷰

728x90
반응형

본격적으로 크롤링하기에 앞서...

아래는 이번에 크롤링 해볼 네이버 카페(동물의숲 포켓캠프 한국 커뮤니티 카페)의 카페소개 화면입니다.

아래 이미지에서 보이는 "카페 이름, 카페 주소, 모바일카페명 & 카페아이콘, 카페 배너, ... 등등"을 파이썬으로 가져와보겠습니다.

 

우선 카페 URL 주소를 보시면 cafe.naver.com/oooolle 이라고 되어 있습니다. 하지만 이 주소가 카페의 카페소개 URL은 아닐겁니다. 그래서 우리는 먼저 카페 소개 URL을 알아야합니다.

 

네이버 카페 소개의 URL은 일반적으로 https://cafe.naver.com/CafeProfileView.nhn?clubid=21588277 와 같은 형태로 구성되어 있습니다. 다만, 해당 카페의 고유 번호인 clubid를 알아야 정확히 원하는 카페의 카페 소개 페이지를 가져올 수 있겠죠.

 

카페의 clubid는 카페의 소스코드에서 보실 수 있습니다.

참고로 view-source: 는 크롬 브라우저에서 소스코드를 보고자하는 페이지의 URL 좌측에 붙여서 접속하면 일반적인 페이지가 아닌 소스코드 페이지를 보여줍니다. (단순히 마우스 우측 클릭 후 소스보기 하거나 개발자도구-F12 키셔서 보셔도 됩니다.)

아래 <script>태그 내부를 보시면 clubid가 있음을 알 수 있습니다.

view-source:https://cafe.naver.com/oooolle

이제 clubid를 알았으니깐, 카페 소개 페이지(cafe.naver.com/CafeProfileView.nhn?clubid=21588277)를 바로 열 수 있습니다.

 

먼저 바로 파이썬으로 크롤러를 개발하기 전에 우리가 가져오고자 하는 정보가 어떤 HTML 태그로 감싸져있는지 확인해볼 필요가 있겠죠.

우선 카페 소개는 tbl_cafe_info 클래스 테이블 태그로 감싸져있습니다. 그리고 각 항목(카페 이름, 카페 주소, 아이콘, 배너 등등)은 table 태그의 tr태그 항목과 일치하네요.

<table class="tbl_cafe_info">
	<caption></caption>
    <colgroup></colgroup>
    <tbody>
    	<tr>
        	<th scope="row">카페 이름</th>
        	<td>
            	<strong class="cafe_name">동물의 숲 포켓캠프 한국 커뮤니티 [동물의숲 모바일 ,친구,공략]</strong>
        	</td>
    	</tr>
    	<tr>...</tr>
    	<tr>...</tr>
    	<tr>...</tr>
    	<tr>...</tr>
        <tr>...</tr>
        ...
        <tr>...</tr>
    </tbody>
</table>

카페 소개의 각 항목을 가져오려면 tbl_cafe_info 테이블 태그의 각 tr 들을 모두 가져오면 되겠고, tr 태그 안에서도 th는 제목, td는 내용으로 보면 되겠네요.

 

이제 어느 정도 정리가 된 것 같으니, 바로 크롤러를 제작해보겠습니다.

 


본격적으로 크롤링 해봅시다...!

우선 제가 지금부터 사용할 모듈은 아래와 같습니다. bs4의 경우에는 없다면 별도로 설치해야합니다. (pip install bs4)

import re # 정규식
import requests as req # 웹 요청
from bs4 import BeautifulSoup # 웹 정보 추출

naver_cafe_url = "https://cafe.naver.com/" # 네이버 카페 주소
cafe_name = "oooolle" # 카페 고유 영문 이름
naver_cafe_introduce = "https://cafe.naver.com/CafeProfileView.nhn?clubid=" # 카페 소개 URL

위에 카페 소개 URL은 있지만, clubid가 없습니다. 지금부터는 clubid를 가져와야합니다. 일단 naver_cafe_url 과 cafe_name을 합친 주소인 https://cafe.naver.com/oooolle 에 requests 요청을 해서 웹 소스를 가져옵니다. 그리고 위에서도 언급했던 <script> 태그 안에 있는 clubid 값을 가져와야합니다.

<script>
  var g_sUserId = "";
  var g_sGroupId = "false";
  var g_sCafeHome = "https://cafe.naver.com/" + "oooolle";
  var g_sClubId = "21588277";
  var g_mobileWebLink = "https://m.cafe.naver.com/oooolle";

  var g_sCafeThumbUrl = 'https://cafethumb.pstatic.net';
  var g_sUpcafeUrl = 'https://up.cafe.naver.com';
  var g_sCafeUrl = "https://cafe.naver.com";
  var g_sCafeUrlOnly = "oooolle";
  var g_sCafeImgUrl = 'https://cafe.pstatic.net';
  var g_sCafeFileUrl = 'https://cafefiles.pstatic.n
  ...
  (생략)
  ...
</script>

위 코드에서는 g_sClubId가 우리가 가져와야 할 값이 됩니다. 우선 Beautifulsoup을 활용해서 script태그 안의 내용을 전부 가져오고, 우리가 원하는 부분인 g_sClubId 부분을 정규식으로 찾아서 추출해보겠습니다.

url = naver_cafe_url + cafe_name # https://cafe.naver.com/oooolle
res = req.get(url=url) # URL 요청
soup = BeautifulSoup(res.text, 'lxml') # Beautifulsoup으로 추출
p_clubid = re.compile(r'var g_sClubId = \"(\w+)\"') # 정규식 설정
clubid = p_clubid.findall(str(soup.select('script')[0]))[0] # script태그 내에서 정규식에 해당하는 정보 추출

print(clubid)

우리가 요청한 페이지에는 script태그가 여러개 있습니다. 그 중에서 가장 첫번째 태그에 우리가 원하는 정보인 clubid가 있습니다. 그래서 [0] 번째 인덱스에서 가져왔습니다.

 

그리고 clubid를 잘 가져왔는 지 출력해보면, 잘 가져와진 것을 알 수 있습니다.

C:\Users\Domdom>python naver_cafe_intro_crawler.py
21588277

이제 다시 이 clubid와 네이버 카페 소개 URL을 합쳐서 다시 페이지를 요청해야되겠죠.

# https://cafe.naver.com/CafeProfileView.nhn?clubid=21588277
introduce_url = naver_cafe_introduce+clubid
info_res = req.get(url=introduce_url)
soup = BeautifulSoup(info_res.text, 'lxml')

요청이 잘 되었다면, soup로 우리가 원하는 정보만 추출해야합니다. 아까도 봤지만, 우리가 원하는 정보는 table태그의 tr들에 있었습니다. 그리고 제목에 해당하는 내용은 th 태그에 있고, 내용에 해당하는 것은 td 태그에 있다고 했죠.

<table class="tbl_cafe_info">
	<caption></caption>
    <colgroup></colgroup>
    <tbody>
    	<tr>
        	<th scope="row">카페 이름</th>
        	<td>
            	<strong class="cafe_name">동물의 숲 포켓캠프 한국 커뮤니티 [동물의숲 모바일 ,친구,공략]</strong>
        	</td>
    	</tr>
    	<tr>...</tr>
    	<tr>...</tr>
    	<tr>...</tr>
    	<tr>...</tr>
        <tr>...</tr>
        ...
        <tr>...</tr>
    </tbody>
</table>

위 tbl_cafe_info 클래스의 table 태그 안의 모든 th 태그들의 내용물을 가져와 보겠습니다.

ths = soup.select('table.tbl_cafe_info th')
for th in ths:
    print(th.text)

위 코드를 실행하게 되면 아래와 같습니다.

C:\Users\Domdom>python naver_cafe_intro_crawler.py
카페 이름
카페 주소
모바일카페명 &카페아이콘
카페 배너
카페 매니저
카페 스탭
카페 설립일
카페 설명
카페 검색어
카페 성격
가입 방식
글쓰기 조건
카페 활동
카페 랭킹
멤버 관리

이번에는 tbl_cafe_info 클래스의 table 태그 안의 모든 td 태그들의 내용물을 가져와 보겠습니다.

tds = soup.select('table.tbl_cafe_info td')
for td in tds:
    print(td.text.strip())

위 코드를 실행하게 되면 아래와 같습니다. strip 함수를 쓴 이유는 내용물의 경우에는 공백이 다수 있어, 제거 해줘야 했습니다. 하지만 완벽히 깔끔하게 보이지는 않습니다. 사실 이번 거는 td 태그 내용을 한번에 가져와서 그렇지, td에도 각 항목별로 태그 모양새가 다릅니다. 그런 부분을 일일이 고려해줘야지, 깔끔하게 우리가 원하는 형태가 나오겠지요.

C:\Users\Domdom>python naver_cafe_intro_crawler.py
동물의숲 포켓캠프 한국 커뮤니티 [동물의숲 모바일,친구,공략]
https://cafe.naver.com/oooolle
☆포켓캠프 커뮤니티
동물의숲 포켓캠..
+ 카페경로복사
동물의숲 포켓캠..
+ 카페경로복사

포켓캠프장
포켓캠프장
부매니저 : 부캠프장




                                            스탭 : 동물스탭
Since 2010.10.06.카페연혁보기
주제
게임 > 모바일게임
★동물의숲 포켓캠프 공식카페 - 모바일 친구 산리오 주민 공략 초보 동숲 모동숲 모여봐요 닌텐도 스위치
동물의숲
                                    ,

                                    포켓캠프
                                    ,

                                    모여봐요
                                    ,

                                    모동숲
                                    ,

                                    동숲
                                    ,

                                    모바일
                                    ,

                                    포켓캠프친구
                                    ,

                                    포켓캠프얼굴
                                    ,

                                    포켓캠프친구다운
                                    ,

                                    포켓캠프친구시간

공개(검색, 카페 주소 등을 통해 카페에 방문할 수 있습니다.)
가입 신청 시 바로 가입
카페방문 2회, 댓글작성 5회
카페멤버 : 108205명     
                                전체 게시글 : 272158개     
                                총 방문자 : 14069956명
현재랭킹 : 열매4단계
별명 사용

그리고 각 항목별로 가져오는 소스코드는 아래와 같습니다.

intro = soup.select('table.tbl_cafe_info td') # 카페 소개 전체
name = intro[0].text.strip() # 카페 이름
print(name) # 동물의숲 포켓캠프 한국 커뮤니티 [동물의숲 모바일,친구,공략]
link = intro[1].select('a')[0].attrs.get('href') # 카페 링크 주소
print(link) # https://cafe.naver.com/oooolle
mobile_name = intro[2].select('.mcafe_name')[0].text.strip() # 카페 모바일 이름
print(mobile_name) # ☆포켓캠프 커뮤니티

...

이렇게 다른 항목들도 위와 같이 똑같이 가져올 수 있겠죠?

 

- 끝 -

728x90
반응형
댓글