-
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를 씁니다. ^^
수고 많으셨습니다. 부족하거나 잘못된 부분은 말씀해주시면 수정토록하겠습니다.
반응형