파이썬으로 네이버 뉴스 제목과 링크 수집하기
파이썬으로 네이버 뉴스 제목과 링크 수집하기
뉴스 크롤링을 처음 만들 때는 많은 기사를 저장하는 것보다 한 페이지에서 제목과 링크를 안정적으로 읽는 것부터 확인하는 편이 좋습니다. 이 글에서는 요청, HTML 분석, 결과 검증, 실패 처리까지 하나의 작은 예제로 연결합니다.
먼저 확인해야 할 범위
웹페이지에 접속할 수 있다고 해서 모든 내용을 자유롭게 수집하거나 재배포할 수 있는 것은 아닙니다. 실행 전에 대상 사이트의 이용약관과 robots.txt를 확인하고, 기사 본문을 복제하지 말고 필요한 최소 정보만 다루십시오. 반복 실행 시에는 요청 간격을 두고 서버에 부담을 주지 않아야 합니다.
requests와 BeautifulSoup 설치
python -m pip install requests beautifulsoup4
requests는 페이지를 내려받고, BeautifulSoup은 HTML에서 원하는 요소를 찾습니다. 가상환경을 사용하면 프로젝트별 패키지 충돌을 줄일 수 있습니다.
제목과 링크를 읽는 최소 예제
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
url = "https://search.naver.com/search.naver"
params = {"where": "news", "query": "파이썬"}
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(
url, params=params, headers=headers, timeout=10
)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
items = []
for link in soup.select("a.news_tit"):
title = link.get_text(" ", strip=True)
href = urljoin(response.url, link.get("href", ""))
if title and href:
items.append({"title": title, "url": href})
for item in items[:5]:
print(item["title"])
print(item["url"])
선택자 a.news_tit은 사이트 개편으로 달라질 수 있습니다. 결과가 0개라면 먼저 브라우저 개발자 도구에서 현재 HTML 구조를 확인해야 합니다. 선택자를 무작정 여러 개 추가하면 잘못된 링크까지 섞일 수 있습니다.
실패를 정상적으로 다루기
try:
response = requests.get(url, params=params, headers=headers, timeout=10)
response.raise_for_status()
except requests.RequestException as error:
print(f"요청 실패: {error}")
else:
print("응답 크기:", len(response.content))
운영용 수집기에는 타임아웃, 제한된 재시도, 중복 URL 제거, 요청 간격, 실패 로그가 필요합니다. 로그인 우회나 차단 회피 코드는 넣지 않는 것이 좋습니다.
결과를 저장하기 전에 검증하기
첫 실행에서는 전체 결과 수, 비어 있는 제목 수, 중복 링크 수를 출력해 보십시오. HTML을 저장해 두면 선택자가 실패했을 때 원인을 재현하기 쉽습니다. CSV로 저장할 때는 엑셀 한글 깨짐을 피하려고 encoding="utf-8-sig"를 사용할 수 있습니다.
선택자가 깨졌는지 확인하는 진단 순서
수집 결과가 없다고 바로 차단으로 판단하지 마십시오. 먼저 response.status_code가 200인지, response.url이 예상 주소인지, 응답 앞부분에 실제 검색 결과가 있는지 확인합니다. 상태 코드는 정상이지만 결과가 없다면 브라우저에서 보는 HTML과 requests가 받은 HTML이 다른지 살펴봅니다.
print("상태:", response.status_code)
print("최종 주소:", response.url)
print("선택 결과:", len(soup.select("a.news_tit")))
print(response.text[:200])로그인 화면이나 오류 안내가 보인다면 선택자 문제가 아닙니다. 사이트 구조가 바뀌었다면 현재 요소의 안정적인 속성을 다시 찾고, 테스트 결과가 확인되기 전까지 자동 실행을 멈추는 편이 안전합니다.
연습: 중복 없는 다섯 개 링크 만들기
같은 URL이 여러 번 등장해도 한 번만 출력하도록 코드를 바꿔 보십시오. 힌트는 이미 본 URL을 set에 저장하는 것입니다. 제목이 비어 있는 항목도 제외하고, 최종적으로 수집 수·중복 제외 수·빈 제목 수를 각각 출력하면 수집 품질을 확인할 수 있습니다.
정리
좋은 크롤러는 많이 가져오는 프로그램이 아니라, 필요한 정보만 천천히 수집하고 구조 변경과 네트워크 실패를 알아차리는 프로그램입니다. 먼저 한 페이지와 다섯 개 결과로 검증한 뒤 범위를 늘리십시오.