1. Introduction
- 거의 모든 웹사이트엔 stylesheet가 존재한다.
- 보통 CSS로 꾸며지게 되는데, 이 CSS는 Web Scraping할때 큰 도움이 될 수 있다.
- 우선 CSS는 HTML의 요소를 구분해서 서로 다른 스타일을 적용한다.
- 예를 들어 다음과 같은 tag가 있다고 해보자.
<span class="black"></span>
<span class="blue"></span>
- 우리는 webscraping을 할 때, class를 이용해 이 tag들을 쉽게 구별이 가능하다.
ex) black만 수집하고, blue는 제외
- 여기서 우리는 이를 구분해 가져오기 위해 findAll("tag",{"class":"ID"})를 이용할 것이다.
- tag는 말 그대로, tag이고, class와 ID는 위에 class, 색상을 의미한다.
- 이를 이용하여 https://books.toscrape.com/ 에서, tag가 p이고, 가격만 scraping해보자.
html = urlopen("https://books.toscrape.com/")
bs = BeautifulSoup(html.read(), 'lxml')
bs
nameList = bs.find_all('p', {'class':"price_color"})
nameList
for name in nameList:
print(name.get_text())
-여기서 get_text()는 tag를 제외한 나머지 부분을 출력해준다.
2. find_all() & find()
- find_all()과 find()는 BeautifulSoup에서 가장 많이 쓰이는 함수이다.
- find_all()은 조건에 맞는 모든 tag list를 return해주고,
- find() 는 조건에 맞는 첫 번째 태그 1개만 반환해준다.
<div class="book">
<h2>책 제목 1</h2>
</div>
<div class="book">
<h2>책 제목 2</h2>
</div>
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# find() - 첫 번째 div.book만 가져옴
first_book = soup.find('div', {'class' : 'book'})
# find_all() - 모든 div.book 요소를 리스트로 가져옴
all_books = soup.find_all('div', {'class' : 'book'})
- 두 함수의 parameter를 자세히 알아보자.
find_all(tag, attrs, recursive, text, limit, **kwargs)
find(tag, attrs, recursive, text, **kwargs)
- 참고로, class tag에서 2개이상의 attribute을 다음과 구할수도 있다.
.find_all('color', {'class': ['black', 'grey',...]})
3. BeautifulSoup Objects
3.1. BeautifulSoup objects
html = urlopen("https://books.toscrape.com/")
bs = BeautifulSoup(html.read(), 'lxml')
bs
- 여기서 bs가 BeautifulSoup object가 된다.
3.2. Tag objects
bs.head.h1
- 이같이 태그를 지정해주면 Tag objects가 된다.
3.3. NavigableString Objects
- 태그 안에 들어 있는 텍스트를 나타낸다.
3.4. Comment Objects
- Comment tag 안에 있는 HTML tag (<!--example>)을 찾는데 사용된다.
- 2004년부터 BeautifulSoup의 object는 4개이기 때문에, 이것만 알면 된다.
4. Navigating Tree
- HTML은 Tree로 나타내는 것이 가능하다.
- example.com의 HTML을 트리로 표현해보자.
html
├── head
│ ├── title
│ ├── meta (charset)
│ ├── meta (http-equiv)
│ ├── meta (viewport)
│ └── style
├── body
│ └── div
│ ├── h1
│ ├── p (첫 번째 문단)
│ └── p (두 번째 문단)
│ └── a (링크)
- 일반적으로 BeautifulSoup는 항상 현재 선택된 태그의 모든 하위노드를 다룬다.
- 예를 들어, bs.head.title은 head의 title tag를 선택하게 되고,
- head 바깥의 tag에 대해선 작동하지 않는다.
from bs4 import BeautifulSoup
html = '''
<html>
<body>
<div>
<p>안녕하세요</p>
<p>반가워요</p>
</div>
</body>
</html>
'''
soup = BeautifulSoup(html, 'html.parser')
div = soup.div
# 자식 태그 접근
print(div.p) # 첫 번째 <p> 태그
# .contents
print(div.contents) # 리스트 형태로 모든 자식 태그 반환
# .children
for child in div.children:
print(child)
# .parent
print(div.parent.name) # body
# .next_sibling
first_p = div.p
print(first_p.next_sibling) # 줄바꿈 문자 (\n)
print(first_p.next_sibling.next_sibling) # 다음 <p> 태그
# .descendants
for desc in div.descendants:
print(desc)
'DS Study > Web Scraping' 카테고리의 다른 글
[Web Scraping][3.3] lambda Expressions (0) | 2025.03.26 |
---|---|
[Web Scraping] [3.2] Regular Expressions (0) | 2025.03.26 |
[Web Scraping] [2.2] Introduction to BeautifulSoup (0) | 2025.03.25 |
[Web Scraping] [2.1] urllib (파이썬 라이브러리) (0) | 2025.03.25 |
[Web Scraping] [1.2] HTML,CSS (0) | 2025.03.24 |