Seongwon Lim

[Python] CSS selector를 이용하여 Daum 뉴스기사 제목 크롤링하기 본문

Python

[Python] CSS selector를 이용하여 Daum 뉴스기사 제목 크롤링하기

limsw 2022. 5. 8. 16:43
반응형

CSS selector란?

CSS selector는 직역하면 CSS 선택자이며 의미는 특정 요소를 선택하여 스타일을 적용할 수 있도록 도와준다.

위 그림을 보면 선택자로 p태그에 정의되어 있으며 해당 태그를 여러 속성을 주어 스타일을 적용했다.

이처럼 { 기호가 나오기 이전의 부분을 선택자(selector) 라고 표현하며 파이썬에서 크롤링을 할 때 HTML에 정의되어 있는 많은 selector를 이용하여 데이터를 추출할 수 있다.

 

  • 쉽게 생각하면 CSS selector는 태그의 연속으로 이루어진 문자열 이라고 생각할 수 있다.

(태그 말고도 클래스명, 아이디값 등 다양한 값이 올 수 있으며 아래에서 다룰 예정이다.)

사용방법

기존에는 find(), findAll() 등의 함수를 사용했다면 CSS Selector를 이용할 때에는 select() 를 사용한다.
결과는 리스트 형태로 반환되며 select_one() 메서드를 이용한다면 1개의 결과만을 객체로 반환한다.

예시로 살펴보기

다음 홈페이지의 뉴스 탭에 있는 뉴스의 제목과 해당 뉴스의 링크를 크롤링 해보고자 한다. 먼저 다음과 같이 코드를 구성했다.

import requests
from bs4 import BeautifulSoup

res = requests.get("https://news.daum.net/")

soup = BeautifulSoup(res.content, 'html.parser')

items = soup.select('div strong a')
for item in items:
    print(item.text.strip() + '\t' + item.attrs['href'])

위 코드를 보면 리스트를 반환할 때 select() 메서드를 이용했고 그 안에는 3개의 태그가 나열된 것을 볼 수 있다. 이제 위와 같이 div strong a 형태로 작성한 이유를 알아보고자 한다.

먼저 다음뉴스 페이지에서 검사 창을 연다. (F12를 누르거나 오른쪽 마우스 클릭 후 검사 창을 연다.)

위와 같이 나온다면 검사창의 왼쪽 상단에 있는 아이콘을 누른다.

해당 탭에서 맨 왼쪽에 위치하는 화살표 모양의 아이콘을 누른다. 그 다음으로 마우스를 기사 제목에 가져간 뒤 클릭을 해보면 검사창의 위치가 해당 기사 제목의 HTML 코드가 작성된 곳으로 이동한다.

이렇게 구성된 것을 확인할 수 있는데 a태그의 내용을 보면 기사 제목인 것을 확인할 수 있다.

이 때 해당 태그를 추출하고자 한다면 CSS selector를 위 코드에서 정의한 div strong a 처럼 정의할 수 있는 것이다.

 

해당 selector가 의미하는 것은 div태그 아래에 strong태그를 찾고 그 strong태그 아래에 a태그를 찾아서 반환하는 것이다. 그리고 select() 메서드는 리스트 형태로 값이 반환되므로 해당 CSS selector 조건에 맞는 모든 데이터를 반환한다.

조금 더 상세하게 선택자 지정하기

div strong a 처럼 선택자를 선언하는 것보다 더 상세하게 선택자를 사용할 수 있다. 바로 > 기호를 이용하는 것이다. > 기호는 바로 자식 태그에 대해서 검색한 뒤 해당 태그로 들어가는 것을 의미한다.

<div>
	<strong>
		<b>
			<a>...</a>
		</b>
	</strong>
</div>

예를 들어 위와 같은 HTML 구조가 있다고 가정해보자. 이 때에는 div strong a 로 선택자를 주어도 원하는 데이터를 추출할 수 있다. >가 아니라 공백을 사용했기 때문에 바로 자식 태그가 아니더라도 후손 태그에 조건에 부합하는 태그가 있다면 해당 데이터를 추출한다.

그러나 만약에 div > strong > a 형태로 선택자를 선언한다면 데이터를 가져올 수 없다. > 부호는 바로 자식 태그를 확인하는 것이기 때문에 strong태그의 바로 밑 태그는 b태그 이기 때문이다. 따라서 알맞게 선택자를 수정한다면 div > strong > b > a 처럼 선택자를 선언해야 한다.

 

따라서 우리 코드도 조금 더 상세하게 CSS Selector를 선언하고 싶다면 다음과 같이 코드를 수정할 수 있다.

data = soup.select('div > strong > a')

CSS Selector에 class, id 이용하기

태그를 이용하여 선택자를 선언할 수도 있지만 태그와 클래스, 아이디를 이용해서도 선택자를 선언할 수 있다.
위 예시에서 div > strong > a 로 선언을 했는데 HTML 코드를 보면

div태그는 cont_thumb 라는 클래스명을 가지고 있으며 strong태그는 tit_g 라는 클래스명을 가지고 있다.

이제 클래스를 사용하여 선택자를 선언하면 다음과 같이 코드를 작성할 수 있다.

# 모두 같은 결과이다.
items1 = soup.select('.cont_thumb > .tit_g > a')
items2 = soup.select('div.cont_thumb > strong.tit_g > a')
items3 = soup.select('.cont_thumb strong.tit_g a')

태그와 클래스명을 조합해도 되며 클래스명만 사용해서도 나타낼 수 있고 이처럼 다양하게 정의할 수 있다.

결과 확인하기

위의 예제에서 살펴본 모든 items 객체에는 다음과 같이 결과가 나올 것이다.

 
Comments