RoNS 님의 블로그

[Web Crawling with Python] 파이썬을 이용한 정적 웹 페이지 크롤링 하기(네이버 뉴스) 본문

Crawling

[Web Crawling with Python] 파이썬을 이용한 정적 웹 페이지 크롤링 하기(네이버 뉴스)

순믹 2025. 3. 3. 20:00
728x90

이번 글에서는 Python을 사용해 네이버 뉴스 기사를 크롤링하는 방법을 다루겠습니다.

사실 특정 페이지의 정보를 수집하는 행위를 더 정확히 표현하면 '웹 스크래핑(Web Scraping)'이 맞지만, 한국에서는 '웹 크롤링(Web Crawling)'이라는 용어가 더 익숙하기 때문에 이 글에서는 크롤링이라는 표현을 사용하겠습니다.

웹 크롤링은 시장 조사, 트렌드 분석 등 데이터 수집과 분석에 꼭 필요한 과정 중 하나입니다.

크롤링을 제대로 이해하려면 컴퓨터 간 통신에 대한 기본 지식이 필요하지만, 이번 글에서는 이 부분을 생략하고 크롤링 과정을 간단히 설명한 후 바로 실습으로 넘어가겠습니다. (컴퓨터 간 통신에 대한 글은 추후 별도로 작성하겠습니다..)

크롤링의 주요 절차는 다음과 같습니다:

1️⃣ 수집하려는 데이터 정의하기 - (이번 글에서는 네이버 뉴스 기사)

2️⃣ 데이터가 있는 웹 페이지 확인하기

3️⃣ 웹 페이지의 소스 코드 가져오기

이 중 3단계를 좀 더 자세히 살펴보겠습니다.

 

1. URL을 사용해 페이지 소스 코드 다운로드 하기

 

먼저, 네이버 뉴스 페이지에서 원하는 카테고리를 선택합니다. 이번 글에서는 사회 > 교육 카테고리의 기사를 크롤링하겠습니다.

페이지에 들어간 후 해당 URL을 사용해 페이지의 소스 코드를 다운로드합니다.

이를 위해 requsets 모듈을 사용합니다:

import requests

url = "https://news.naver.com/breakingnews/section/102/250"

respone = requests.get(url)

이렇게 하면 response 객체에 서버에서 보낸 다양한 정보가 저장됩니다. 우리가 필요한 페이지의 소스 코드는 response.text에 담겨 있습니다.

 

2. 소스 코드에서 원하는 정보를 담고 있는 태그 확인 및 찾기

원하는 정보를 담고 있는 태그를 찾으려면 페이지에서 오른쪽 클릭 > 페이지 소스 보기 또는 검사를 선택합니다.

위와 같이 소스 코드가 보이면 Ctrl + F를 눌러 원하는 데이터가 어떤 태그에 들어 있는지 검색합니다.

이렇게 확인한 태그에 접근하기 위해 bs4 모듈의 BeautifulSoup 클래스를 사용합니다:

from bs4 import BeautifulSoup

bs_object = BeautifulSoup(response.text, 'lxml')

이렇게 하면 bs_object라는 객체를 통해 소스 코드에서 특정 태그에 쉽게 접글할 수 있습니다.

참고로, 이렇게 HTML 코드를 분석해 태그를 찾는 과정을 파싱(Parsing)이라고 합니다.

 

3. find() 또는 find_all() 함수를 사용하여 태그 찾기

 

BeautifulSoup은 여러 가지 방법으로 태그를 찾을 수 있는데, 그중에서 find( ) 함수와 find_all( ) 함수에 대해 다뤄보겠습니다.

  • find( ) --> 조건에 맞는 첫 번째 태그 반환
  • find_all( ) --> 조건에 맞는 모든 태그 반환(리스트 형태)

이번 글에서는 기사 제목, 링크, 본문 등 여러 요소를 가져올 것이므로 find_all( ) 함수를 먼저 사용하고 그다음 find( )를 사용해 원하는 정보를 가져오도록 하겠습니다.

 

4. 네이버 뉴스 기사 크롤링 하기

 

네이버 뉴스 기사 크롤링 실습을 통해 위의 과정을 복습해 보겠습니다.

# 필요한 모듈 불러오기
import requests
from bs4 import BeautifulSoup

# 1. URL을 사용해 페이지 소스 코드 다운로드 하기
url = 'https://news.naver.com/breakingnews/section/102/250'

response = requests.get(url)

source_code = response.text

# 2. 소스 코드에서 원하는 정보를 담고 있는 태그 확인 및 찾기
bs_object = BeautifulSoup(source_code, 'lxml')

data_list = []  # 긁어온 데이터를 저장할 빈 리스트를 생성

# 3. find() 또는 find_all() 함수를 사용하여 태그 찾기
article_list = bs_object.find_all('a', class_='sa_text_title _NLOG_IMPRESSION')  # 찾고자 하는 태그의 조건을 인자로 전달

# 4. 크롤링 하기
for article in article_list:  # find_all() 함수로 찾은 모든 태그들을 하나하나 읽으면서 기사 제목, 기사 링크, 기사 본문 추출하기
    article_title = article.find('strong', class_='sa_text_strong').text  # 해당 조건을 만족하는 태그의 텍스트만 추출 --> 기사 제목
    article_link = article['href']  # 기사 링크 추출
    
    article_response = requests.get(article_link)  # 기사 본문을 가져오기 위해서 추출한 기사 링크를 사용해 위의 과정을 반복
    article_soup = BeautifulSoup(article_response.text, 'lxml')
    
    article_body = article_soup.find('div', class_='newsct_article')  # 기사 본문이 담겨 있는 태그 찾기
    
    if article_body:  # 에러 방지를 위한 조건문
        article_body_text = article_body.get_text(strip=True)
    else:
        article_body_text = "본문을 가져올 수 없습니다."
    
    data_list.append([article_title, article_link, article_body_text])

data_list  # 결과를 보기 위해 리스트 출력

 

해당 코드를 돌리게 되면 아래와 같이 기사 제목, 기사 링크, 기사 본문이 추출되는 것을 확인할 수 있습니다!

[['2026학년도 의대 정원도 4월 말까지 ‘오리무중’',
  'https://n.news.naver.com/mnews/article/005/0001760711',
  '교육-복지부 ‘증원’ 놓고 엇박자수험생들, 2년째 입시 혼란 우려최현규 기자의·정 갈등 해소의 실마리를 찾지 못하면서 2026학년도 의대 정원도 다음 달 말까지 오리무중이란 관측이 나온다. 교육부가 ‘증원 0명’ 의사를 내비치고, 보건복지부가 이에 공개 반대하는 등 정부 내 엇박자까지 노출되며 올해 정원 논의는 더 꼬이는 모습이다. 대입 수험생들은 지난해에 이어 2년 연속 ‘의대발 불확실성’에 시달릴 가능성이 커지고 있다.‘의료인력 수급 추계위원회’(추계위) 설치를 담은 보건의료기본법 개정안은 지난달 27일 국회 보건복지위 법안심사 제1소위원회를 통과했다. 의대 정원 조정 시 과학적 근거를 제공하는 추계위를 통해 정부와 의사 단체들이 수긍하는 증원 규모를 결정한다는 게 법안의 골자다.개정안은 복지위 전체회의, 법제사법위원회, 본회의를 남겨뒀다. 절차대로 진행되면 이달 초 혹은 중순 본회의 의결이 이뤄질 수 있다. 국무회의를 거쳐 관보 게재를 마치면 법안은 효력을 갖는다. 추계위 위원 추천 및 구성 절차 등을 서둘러 진행하면 추계위 첫 회의는 3월 말 혹은 다음 달 초쯤 이뤄질 전망이다.문제는 올해 고3이 치르는 2026학년도 대입이다. 의대 모집인원 결정 시한은 다음 달 말이다. 추계위가 빠르게 구성되더라도 2026학년도 의대 정원을 결정하기 어렵다는 관측이 많다. 여야는 이를 고려해 개정안에 2026학년도에 한해 각 대학 총장이 정해진 범위에서 자율적으로 모집인원을 정하도록 하는 특례조항을 뒀다.대학별로 의대 모집인원을 정하면 대학 본부와 의대가 갈등을 빚을 가능성이 크다. 의대 측은 증원 규모를 줄이기 위해 의사 단체들과 대학 본부를 압박할 것으로 보인다. 의대 교육 인프라에 투자를 해놓은 상태에서 신입생이 줄면 타격이 큰 만큼 대학본부 역시 물러서기 쉽지 않다.의대 모집인원 결정이 늦어지면 대입 현장의 혼란은 가중된다. 의대 입시는 의대뿐 아니라 전체 대입에 연쇄적으로 영향을 끼친다. 임성호 종로학원 대표는 “지난해 의대 모집정원이 증가하면서 수시와 정시 모두 의대 지원자가 크게 늘었다. 또 변화가 생기면서 입시 예측성이 2년 연속 ‘제로’인 상태가 된다”고 말했다.'],
 ['전쟁은 왜 일어날까?',
  'https://n.news.naver.com/mnews/article/015/0005101297',
  '이번주 주니어 생글생글주니어 생글생글 제150호 커버스토리 주제는 ‘전쟁’이다. 개전 3년을 넘긴 러시아·우크라이나 전쟁을 비롯해 지금 이 시각에도 지구촌 곳곳에서 무력 분쟁이 벌어지고 있다. 아랍·이스라엘 분쟁 등 주요 국제 분쟁을 살펴봤다. 전쟁이 일어나는 이유는 무엇이며, 전쟁에서 어떤 교훈을 얻을 수 있는지 알아봤다. 국제 관계 이론의 핵심 개념인 안보 딜레마도 설명했다. 꿈을 이룬 사람들의 주인공은 이국종 국군대전병원장이다. 중증 외상 분야 권위자인 이 병원장의 삶을 조명했다.'],
 ['무역장벽의 정치경제학',
  'https://n.news.naver.com/mnews/article/015/0005101296',
  '이번주 생글생글제885호 생글생글 커버스토리 주제는 한한령과 비관세 장벽이다. 중국 내 한류 콘텐츠 유통을 금지하는 한한령이 오는 5월께 해제될 수 있다는 보도가 나왔다. 한한령은 무역 장벽 중 비관세 장벽의 일종이다. 비관세 장벽을 두는 이유는 무엇이며 국제 무역과 국내 경제에 어떤 영향을 끼치는지 살펴봤다. 또 다른 무역 장벽인 관세 장벽을 알아봤다. 대입 전략에선 서울대 정시 합격자의 출신 고등학교를 분석했다. 최근 10년간 일반고 비중이 높아지고 자사고 비중이 낮아진 것으로 나타났다'],
 .
 .
 .
 ['동덕여대 재단 규탄 집회 연 재학생 연합',
  'https://n.news.naver.com/mnews/article/001/0015242892',
  '(서울=연합뉴스) 서대연 기자 = 동덕여자대학교 재학생연합 회원들이 3일 서울 종로구 북인사마당 앞에서 동덕여대 재단을 규탄하는 집회를 열고 있다. 2025.3.3dwise@yna.co.kr']]

 

 

728x90