웹 크롤링 뜯어먹기 #2 | 스크래핑 도구 비교 (bs4, selenium, scrapy)

두더지·2025년 6월 2일
post-thumbnail

전체 비교

Tool특징 요약장점단점
BeautifulSoup- HTML/XML 파싱
- 가장 쉬운 웹 크롤링 도구
배우기 쉬움
초보자에게 적합
JavaScript 미지원
느림
Selenium- 웹 브라우저 자동화 도구
- JavaScript 렌더링 처리 가능
JS 기반 사이트도 크롤링 가능
배우기 쉬움
느림 (모든 스크립트 실행)
무거움
Scrapy- 파이썬 기반 프레임워크
- 비동기 방식으로 빠르게 데이터 수집 가능
빠름
가장 완성도 높은 프레임워크
배우기 어려움
설정 복잡할 수 있음

1. Beautiful Soup

자주 사용되는 메서드 정리

메서드/속성설명반환값 형식
find()첫 번째 해당 요소Tag
find_all()모든 해당 요소ResultSet (list 유사)
select()CSS 선택자에 맞는 모든 요소list
select_one()CSS 선택자에 맞는 첫 번째 요소Tag or None
get_text()텍스트만 추출str
get()속성값 추출str or None
attrs속성 딕셔너리 반환dict
parent부모 요소 반환Tag
children자식 요소 반복자 반환generator
string텍스트 노드 반환 (하위 태그 없을 때만)str or NavigableString

자주 사용되는 메서드 코드 예시

from bs4 import BeautifulSoup

html = """
<html>
  <head><title>Example</title></head>
  <body>
    <div class="content" id="main">
      <p class="text">First paragraph.</p>
      <p class="text">Second paragraph.</p>
      <a href="https://example.com" id="link">Visit Example</a>
    </div>
  </body>
</html>
"""

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

# 1. find(tag_name, attrs)  
# - 조건에 맞는 첫 번째 요소 반환
soup.find('p')  # <p class="text">First paragraph.</p>

# 2. find_all(tag_name, attrs)
# - 조건에 맞는 모든 요소 리스트 반환
soup.find_all('p')  # [<p>...</p>, <p>...</p>]

# 3. select(css_selector)
# - CSS 선택자를 이용해 요소 리스트 반환
soup.select('div.content p.text')  # [<p class="text">...</p>, <p class="text">...</p>]

# 4. select_one(css_selector)
# - CSS 선택자를 이용해 첫 번째 요소만 반환
soup.select_one('a#link')  # <a href="...">Visit Example</a>

# 5. get_text(strip=False)
# - 태그 내부의 모든 텍스트를 추출 (하위 태그 포함)
soup.find('p').get_text()  # "First paragraph."

# 6. get(attribute_name)
# - 특정 속성(attribute)의 값을 가져옴
soup.find('a').get('href')  # "https://example.com"

# 7. attrs
# - 태그의 모든 속성 정보를 딕셔너리 형태로 반환
soup.find('a').attrs  # {'href': 'https://example.com', 'id': 'link'}

# 8. parent
# - 현재 요소의 부모 요소 반환
soup.find('a').parent.name  # 'div'

# 9. children
# - 현재 요소의 자식 요소들을 generator로 반환
list(soup.find('div').children)  # [\n, <p>...</p>, \n, <p>...</p>, \n, <a>...</a>, \n]

# 10. string
# - 해당 태그의 텍스트를 직접 반환 (자식 태그 없이 텍스트만 있을 경우)
soup.title.string  # "Example"

2. Selenium

자주 사용되는 메서드 정리

메서드설명반환값 / 효과
get(url)페이지 열기None
find_element()첫 요소 찾기WebElement
find_elements()모든 요소 리스트list[WebElement]
send_keys("text")입력값 전달None
click()클릭 이벤트None
get_attribute("attr")속성값 가져오기str
element.text텍스트 가져오기str
is_displayed()화면에 보이는지 확인True / False
implicitly_wait(초)요소 기다리기 (전역 설정)None
close() / quit()탭 종료 / 브라우저 종료None

자주 사용되는 메서드 코드 예시

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

# 1. get(url)
# - 특정 웹 페이지로 이동
driver.get("https://example.com")

# 2. find_element(By.~, value)
# - 조건에 맞는 첫 번째 요소 찾기
driver.find_element(By.TAG_NAME, "h1")

# 3. find_elements(By.~, value)
# - 조건에 맞는 모든 요소 리스트 찾기
driver.find_elements(By.CLASS_NAME, "item")

# 4. send_keys(text)
# - 입력창에 텍스트 입력
search_box = driver.find_element(By.NAME, "q")
search_box.send_keys("Selenium")

# 5. click()
# - 클릭 이벤트 수행
button = driver.find_element(By.ID, "submit")
button.click()

# 6. get_attribute(attribute_name)
# - 요소의 속성값 가져오기
link = driver.find_element(By.TAG_NAME, "a")
href = link.get_attribute("href")

# 7. text
# - 요소 내부의 텍스트 추출
header = driver.find_element(By.TAG_NAME, "h1").text

# 8. is_displayed()
# - 요소가 화면에 보이는 상태인지 확인 (True/False)
driver.find_element(By.ID, "banner").is_displayed()

# 9. implicitly_wait(seconds)
# - 요소가 로드될 때까지 최대 몇 초 기다릴지 설정 (전역)
driver.implicitly_wait(5)

# 10. close() / quit()
# - close(): 현재 탭 종료, quit(): 전체 브라우저 종료
driver.close()
driver.quit()

3. Scrapy

자주 사용되는 메서드 정리

메서드/속성설명반환값
response.css(selector)CSS 선택자로 요소 찾기Selector (chainable)
response.xpath(xpath)XPath로 요소 찾기Selector (chainable)
response.follow(url)상대/절대 URL 기반 새 요청 생성Request 객체
response.url현재 페이지 URLstr
response.statusHTTP 응답 상태 코드int
response.body페이지 원문 (bytes)bytes
response.text페이지 원문 (str)str
response.meta요청 간 데이터 전달용 딕셔너리dict
scrapy.Request()새 요청 수동 생성 (callback 지정 가능)Request 객체
.get(), .getall()Selector로 추출한 값 가져오기str / list[str]

자주 사용되는 메서드 코드 예시

import scrapy

class ExampleSpider(scrapy.Spider):
    name = "example"
    start_urls = ['https://example.com']

    def parse(self, response):
        # 1. response.css() - CSS 선택자로 요소 찾기
        titles = response.css('h1::text').getall()

        # 2. response.xpath() - XPath로 요소 찾기
        paragraphs = response.xpath('//p/text()').getall()

        # 3. response.follow() - 상대 URL을 따라 새로운 요청 생성
        for href in response.css('a::attr(href)').getall():
            yield response.follow(href, callback=self.parse_detail)

        # 4. response.url - 현재 페이지의 URL
        print(response.url)

        # 5. response.status - HTTP 상태 코드
        print(response.status)

        # 6. response.body - 응답 바디 (bytes 형태)
        raw_html = response.body

        # 7. response.text - 응답 바디 (str 형태)
        raw_html_str = response.text

        # 8. response.meta - 요청 간 데이터 전달용 딕셔너리
        print(response.meta)

        # 9. scrapy.Request() - 커스텀 요청 만들기
        yield scrapy.Request(url='https://example.com/page', callback=self.parse_page)

        # 10. get(), getall() - 선택한 요소에서 텍스트 또는 속성 추출
        first_title = response.css('h1::text').get()      # 첫 번째
        all_titles = response.css('h1::text').getall()    # 전체 리스트
profile
일단 하긴 합니다.

0개의 댓글