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

| 메서드/속성 | 설명 | 반환값 형식 |
|---|---|---|
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"
| 메서드 | 설명 | 반환값 / 효과 |
|---|---|---|
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()
| 메서드/속성 | 설명 | 반환값 |
|---|---|---|
response.css(selector) | CSS 선택자로 요소 찾기 | Selector (chainable) |
response.xpath(xpath) | XPath로 요소 찾기 | Selector (chainable) |
response.follow(url) | 상대/절대 URL 기반 새 요청 생성 | Request 객체 |
response.url | 현재 페이지 URL | str |
response.status | HTTP 응답 상태 코드 | 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() # 전체 리스트