BeautifulSoup 라이브러리의 다양한 메소드들 중에서 크롤링을 위해 자주 사용하는 메소드는 find 메소드와 select 메소드라고 합니다. 두 가지의 메소드를 이용하면 앞서 requests를 이용하여 가져온 HTML 문서에서 원하는 부분을 추출할 수 있습니다. 하지만 추출하는 방법에는 조금 차이가 있습니다.
참고로 BeautifulSoup의 더 다양한 메소드나 설명은 공식문서에서 찾아볼 수 있습니다. 물론, 영어입니다..😅
find 메소드는 태그를 이용하여 원하는 부분을 추출합니다.
태그는 이름(name), 속성(attribut), 값(value)로 구성되어 있기 때문에 find로 해당 이름이나 속성, 값을 특정하여 태그를 찾을 수 있습니다.
tag = "<p class='example' id='test01'> Hello World! </p>"
soup = BeautifulSoup(tag)
# 태그 이름만 특정
soup.find('p')
# 태그 속성만 특정
soup.find(class_='example')
soup.find(attrs = {'class':'exmaple'})
# 태그 이름과 속성 모두 특정
soup.find('p', class_='example')
한편 select 메소드의 경우, CSS Selector로 tag 객체를 찾아 반환합니다.
이는 CSS에서 HTML을 태깅하는 방법을 활용한 메소드입니다. 다음과 같이 다양하게 select()를 사용할 수 있습니다.
#태그 찾기
soup.select("title")
#특정 태그 아래에 있는 태그 찾기
soup.select("div a") #div 태그 아래에 있는 a 태그 찾기
#특정 태그 바로 아래에 있는 태그 찾기
soup.select("head > title")
soup.select("head > #link1") #아이디로 태그 찾음
#태그들의 형제 태그 찾기
soup.select("#link1 ~ .sister")
soup.select("#link1 + .sister")
#CSS class로 태그 찾기
soup.select(".sister")
#ID값으로 태그 찾기
soup.select("#link1")
더 자세한 설명이나 이 것보다 더 다양한 활용사례는 공식문서를 참고하세요:)
select()와 select_one()의 차이점은 무엇일까요?
간단히 말해서 select_one()은 추출된 태그들 중에 첫번째 값만 반환하고 select()는 리스트에 추출된 태그들을 모두 담아 해당 리스트를 반환한다는 점이 다릅니다. 다음의 예시를 보면 더 이해가 쉽게 될 거라 생각합니다.
#sister라는 class를 가진 태그들을 모두 찾을 때
print(soup.select(".sister"))
>> [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
#sister라는 class를 가진 태그들 중에 첫 번째 값만 추출할 때
print(soup.select_one(".sister"))
>> <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
한 가지 더 덧붙이자면, find_all()는 select()와 같이 전체 결과를 리스트로 반환하고, 이와 달리 find()는 select_one()과 동일하게 가장 첫 번째 결과만 반환합니다.
find 메소드와 select 중에 무엇을 사용하는 것이 좋을까요?
find와 select는 태그 이름, 속성, 속성값을 특정하는 방식은 같다고 합니다. 하지만 CSS는 이 외에도 다양한 선택자(selector)를 갖기 때문에 여러 요소를 조합하여 태그를 특정하기 쉽습니다. 예를 들어 트정 경로의 태그를 객체로 반환하고 싶을 때, find의 경우 아래와 같이 반복적으로 코드를 작성해야 하는 반면 select는 직접 하위 경로를 지정할 수 있습니다.
#find
soup.find('div').find('p')
#select
soup.select_one('div > p')
그러므로 더 다양한 조건을 이용하여 더 직관적인 방법으로 태그를 찾기 위해서는 find보다는 select를 사용하는 게 적합합니다.
여기서 잠깐!
CSS Selector(선택자)란?
CSS 선택자는 특정한 HTML 태그를 선택할 때 사용하는 기능으로 선택자를 이용하여 특정 HTML 태그를 선택하면 해당 태그에 원하는 스타일이나 기능을 적용할 수 있게 됩니다.
선택자의 종류는 다양하지만 가장 대표적으로는 태그 선택자, 클래스 선택자, 하위 선택자, 그룹 선택자 등이 있다고 합니다. 각 선택자에 대한 간단하고 직관적인 설명은 이 페이지를 참고해주세요:)
준우의 오류노트
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
https://miyakita.tistory.com/14