컴퓨터/Python

Python (9) - BeautifulSoup를 이용하여 디시인사이드에 웹 크롤링을 해보자

달서비 2023. 1. 3. 23:57

카타르 월드컵이 끝나고 커뮤니티를 실시간으로 볼 수 있는 웹 크롤러가 있으면 어떨까 생각해 보았습니다. F5를 주기적으로 눌러보는 방법도 있으나 크롤링으로 화면이 보이게 하였습니다. 그래서 먼저는 데이터를 크롤링하는 방법에 대하여 알아보겠습니다.

 

크롤링

먼저 크롤링은 웹상에 존재하는 정보를 수집해 오는 작업입니다. 데이터 수집 방법에는 크게 3가지 방법이 있습니다.

  1. HTML 페이지를 가져와 필요한 데이터만 수집하는 방법
  2. OpenAPI를 호출하여 받은 데이터 중 필요한 데이터만 수집하는 방법
  3. 프로그램을 이용하여 브라우저를 조작하여 필요한 데이터를 수집하는 방법

여기서 1번 방법을 사용하여 HTML 페이지를 가져오는 방법을 진행하려고 합니다.

 

디시인사이드 크롤링을 하는 과정

※ 크롤링 같은 경우 사용 방법에 따라 처벌이 있을 수 있습니다. 불이익은 사용자가 책임져야 합니다.

 

1. 제작하기에 앞서 패키지를 설치합니다. (파이썬 3.7 이상 버전 필요)

pip install requests
pip install bs4
pip install lxml

 

2. requests 패키지를 이용하여 파이썬에 데이터를 가져옵니다.

import requests
from bs4 import BeautifulSoup

url = "https://gall.dcinside.com/board/lists/?id=tree"
webpage = requests.get(url)

print(webpage)

일반적으로는 위에 소스코드 같이 url을 가지고 웹페이지를 여는 경우에 웹페이지의 정보를 얻을 수 있습니다. 나중에 다른 갤러리까지 쉽게 정보를 얻기 위하여 파라미터를 따로 두었습니다.

 

또한 디시인사이드에는 헤더에 접속자 정보를 작성하여야 크롤링을 할 수 합니다.

(개발자도구 - Network 를 통하여 user-agent 정보를 복사한다)

(230829) 유저정보에다가 ""으로 두어도 작동되는 것을 확인했습니다.

import requests
from bs4 import BeautifulSoup

url = "https://gall.dcinside.com/board/lists"
params = {'id' : 'tree'}
headers = {"User-Agent" : "유저정보"}

webpage = requests.get(url, params=params, headers=headers)

복사한 데이터들을 두어 위와 같이 구성하였습니다.

 

3. BeautifulSoup를 사용하여 정보를 가공한다.

requests로 HTML페이지를 가져왔습니다. 이제 가져온 정보들을 BeautifulSoup로 가공하겠습니다.

soup = BeautifulSoup(webpage.content, "lxml")
article = soup.select(".us-post")

먼저 웹페이지를 lxml 형식으로 가공합니다. 그리고 게시글에서  한개의 정보가 담아 us-post 클래스까지 지정하였습니다.이제 각 줄의 정보들을 분해하여 한페이지 게시글에 대한 정보를 for문을 이용하여 출력하도록 합니다.

for i in article:
    link = "https://gall.dcinside.com/" + i.select("a")[0]['href'].strip() #웹사이트 링크
    num = i.select(".gall_num")[0].text #게시글 번호
    title = i.select(".ub-word > a")[0].text #게시글 제목
    reply = i.select(".ub-word > a.reply_numbox > .reply_num") #게시글 댓글 갯수
    if reply:
        reply = reply[0].text
    else:
        reply = ""
    nickname = i.select(".ub-writer")[0].text.strip() #닉네임
    timestamp = i.select(".gall_date")[0].text #시간
    refresh = i.select(".gall_count")[0].text #조회수
    recommend = i.select(".gall_recommend")[0].text #추천
    print(link, num, title, reply, nickname, timestamp, refresh, recommend)

 

소스코드

위의 소스코드에서 모든 정보를 가지고 올 수 있으나 몇 가지 정보는 필요 없어 주석처리 하였습니다.

import requests
from bs4 import BeautifulSoup
import os
import time

#init
url = "https://gall.dcinside.com/board/lists"
param = {'id' : 'tree'}
header = {"User-Agent" : "유저정보"}

#process
webpage = requests.get(url, params=param, headers=header)
soup = BeautifulSoup(webpage.content, "lxml")
article = soup.select(".us-post")

for i in article:
    #link = "https://gall.dcinside.com/" + i.select("a")[0]['href'].strip()
    num = i.select(".gall_num")[0].text
    title = i.select(".ub-word > a")[0].text
    reply = i.select(".ub-word > a.reply_numbox > .reply_num")
    if reply:
        reply = reply[0].text
    else:
        reply = ""
    nickname = i.select(".ub-writer")[0].text.strip()
    timestamp = i.select(".gall_date")[0].text
    #refresh = i.select(".gall_count")[0].text
    #recommend = i.select(".gall_recommend")[0].text
    print(num, title, reply, nickname, timestamp)

 

마지막으로

BeautifulSoup가 다양한 사용에서 사용할 수 있는 것을 봤습니다. 다음에는 다른 상황에서 한번 게시글을 작성해 보겠습니다.