ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 7. selenium 과 BeautifulSoup으로 daum 카페 크롤링 - 댓글편
    Python/파이썬 웹 크롤러 2019. 5. 18. 01:45
    반응형

    깃헙에서 예제가 잘 보이지 않을 때는 raw를 클릭하시던지 저장해서 보시면 될 것 같습니다. 

     

    예제 주소:

    https://github.com/pycrawling/crawling-tutorial/blob/master/daum-cafe-mobile-crawler-reply.ipynb

     

    * 크롤링 + db 저장까지 하겠습니다. 

    본문편에서 설명한 부분은 제외합니다. 

    1. import sqlite 

    파이썬의 기본 내장 DB인 sqlite를 사용하겠습니다. 

    import sqlite3

    2. 데이터베이스 초기화

    sqlite는 IF NOT EXISTS 조건을 사용해서 테이블을 생성할 수 있습니다. 편합니다. ^^

    conn = sqlite3.connect(DB) 
    cur = conn.cursor() 
    
    sql = 'CREATE TABLE IF NOT EXISTS "' + BOARD_NAME + \ 
      '"("num" INTEGER NOT NULL UNIQUE, "subject" TEXT, ' \ 
      '"nick" TEXT, "write_time" TEXT, "views" INTEGER, ' \ 
      '"url" TEXT, "contents" TEXT, PRIMARY KEY("num"));' 
    cur.execute(sql) # 본문들을 저장할 테이블
    conn.commit() 
    
    sql = 'CREATE TABLE IF NOT EXISTS "' + BOARD_NAME + \ 
    '_cmt" ("cmt_num" TEXT NOT NULL UNIQUE, "cmt_reply" INTEGER, ' \
    '"cmt_writer" TEXT, "cmt_time" TEXT, "cmt_txt" TEXT, PRIMARY KEY("cmt_num"));' 
    cur.execute(sql) # 댓글들을 저장할 테이블
    conn.commit() 
    
    conn.close()

    2. 본문 DB 저장

    sqlite는 'repalce into'가 됩니다. 덮어쓰기죠.

    크롤링을 하다보면 중간에 멈추는 경우가 꽤 있습니다. 

    이럴 때 일일히 어디까지 저장이 되었는지 확인하고 거기서부터 재시작한다면 아주 불편합니다. 

    적당히 여유있게 재시작해서 덮어쓰기하면 아주 편합니다. 

    conn = sqlite3.connect(DB) 
    cur = conn.cursor() 
    sql = "replace into %s(num,subject,nick,write_time,views,url,contents) values (?,?,?,?,?,?,?)" % BOARD_NAME cur.execute(sql, (num, subject, nick, write_time, views, url, contents)) 
    conn.commit() 
    conn.close()

    3. 댓글을 크롤링하자. 

        # 댓글 페이지로 이동 
        driver.get('http://m.cafe.daum.net/{0}/{1}/{2}/comments'.format(CAFE_NAME,BOARD_NAME,inp_num)) 
        time.sleep(1) 
    
        # 댓글 페이지 
        html = driver.page_source 
        soup = BeautifulSoup(html, 'html.parser')     
    
        # for문을 이용 댓글 페이지를 역순으로 크롤링 
    
        for i in range(cmt_page_max): 
            j = cmt_page_max-i       
    
            # 캡쳐
            html = driver.page_source 
            soup = BeautifulSoup(html, 'html.parser') 
    
            # 페이지 내의 코멘트들을 모두 찾자.  
            cmt_all = soup.body.find('ul' ,id="commentList").find_all('li') 
    
            # 찾은 코멘트들을 언패킹하자.  
            for k in cmt_all: 
                if k.div.span.find_all('span', class_="txt_bar"): 
                    if k['class'] == ['reply_on']: 
                        cmt_reply = True 
                        print('ㄴ', end='') # 댓글에 댓글을 단 걸 어떻게 처리할까 잠시 고민했으나 그냥 넘기기로.. 
                    else: 
                        cmt_reply = False 
    
                    cmt_num = inp_num +'_'+ k['id'].split('comment_')[1] 
                    cmt_writer = k.div.find('span', class_='sr_only').next_sibling 
                    cmt_time = k.div.span.find('span', class_="num_info").get_text() 
                    cmt_txt = k.div.find('span', class_='txt_detail').get_text(strip=True) 
    
                    # 언패킹한 결과물을 화면 출력하고.. 
                    print(cmt_num, '[', cmt_writer, ']', cmt_time, cmt_txt) 
                     
                    # DB에 저장하자.  
                    conn = sqlite3.connect(DB) 
                    cur = conn.cursor() 
                    sql = "replace into '%s_cmt'(cmt_num,cmt_reply,cmt_writer,cmt_time,cmt_txt) values (?,?,?,?,?)" % BOARD_NAME 
                    cur.execute(sql, (cmt_num,cmt_reply,cmt_writer,cmt_time,cmt_txt)) 
                    conn.commit() 
                    conn.close() 
    
            # 페이지가 0으로 넘어가지 않도록 if 문을 작성...   
    
            if j > 1: 
                # 페이지를 이동..  
                driver.get('http://m.cafe.daum.net/{0}/{1}/{2}/comments?prev_page={3}&mode=regular&cdepth={4}&page={5}'.format(CAFE_NAME,BOARD_NAME,inp_num,j,'0002100000',(j-1))) 
    
                time.sleep(2)

    3. 저장된 db를 볼 때는 DB Browser for SQLite 를 사용하자. 

    여러 가지를 써봤는데 최종적으로 DB Browser for SQLite를 씁니다. ^^

     

    https://sqlitebrowser.org

     

    개인정보 보호를 위해 내용은 공개하지 않습니다. 

     

    개인정보 보호를 위해 내용은 공개하지 않습니다. 

    수고 많으셨습니다. 부족하거나 잘못된 부분은 말씀해주시면 수정토록하겠습니다. 

    반응형
Designed by Tistory.