본문으로 바로가기

웹 스크래핑 분석 과정

1. URL 분석 (패턴이 존재하는지, query의 종류는 무엇인지)

2. URL 구성 (str, 추후 자동화 고려)

3. HTTP Response 얻기

   - urlopen(URL)

   - request.get(URL).content

4. HTML source 얻기

   - BeautifulSoup(HTTP Response, 'html.parser')

5. HTML Tag 꺼내기

   - find(~) : 첫번째 Tag

   - find_all(~) : 여러 개의 Tag를 찾은 다음 for문으로 Tag 단위를 꺼내어 활용

6. Tag로부터 Text 또는 Attribute values 꺼내기

   - Tag.get_text()

   - Tag.attrs

 


기초_실습1) 다음 사전의 단어 검색 결과 출력하기

### 설치하고 불러올 때 이름이 다른 라이브러리
# pip install beautifulsoup4  ->  from bs4 import BeautifulSoup
# pip install Pillow  ->  from PIL import ~~~   # python image library
# pip install opencv-python  ->  from cv2 import ~~~

# !pip install beautifulsoup4==4.9.3
from bs4 import BeautifulSoup 
from urllib.request import urlopen

(1/6) URL 분석
https://alldic.daum.net / search.do?q=happiness

def search.do(q=happiness):
	~~~
    return json
    
# search.do : def 함수       ==> endpoint
# ?q=happiness : parameter   ==> query: 옵션 (&로 여러 옵션 줄 수 있음)

 

(2/6) URL 구성

word = ' '
url = 'https://alldic.daum.net/search.do?q=' + word

 

 

(3/6) HTTP Response 얻기

web = urlopen(url)

 

(4/6) HTML source 얻기

# BeautifulSoup으로 web 페이지상의 HTML 구조를 파싱
web_page = BeautifulSoup(web, 'html.parser')

 

(5/6) HTML Tag 꺼내기

만약 우리가 'happiness'를 뽑아내고 싶다면 어떻게 코딩을 하면 될까?

web_page.find('span')
# > <span class="ir_wa">사전</span> 출력됨
# find 함수는 첫 번째 item을 뽑아주기 때문에 원하는 키워드가 뽑히지 않았다.

### 더 많은 옵션을 주어 'happiness'를 출력해보겠다.
box1 = web_page.find('span', {'class': 'txt_emph1'})
print(box1)
# > <span class="txt_emph1">happiness</span>
print(box1.get_text()) # 태그를 걷어내고 내부의 텍스트만 꺼내고 싶을 때
# > happiness
# 잘 출력되었음을 알 수 있다

 

'happiness'의 뜻 여러 개를 다 뽑아내고 싶다면 어떻게 할까?

# find() 대신 find_all() 함수를 사용하면 된다.
box2 = web_page.find_all('span', {'class': 'txt_search'}) 
box2

 

잘 출력된다. 우리는 다른 태그를 다 걷어내고 내부의 텍스트만 꺼내고 싶다.

하지만, find() 함수와 같이 .get_text()로 요청을 보내면 에러가 나온다.

그 이유는 출력값의 type이 다르기 때문이다. find_all() 함수는 list로 출력해주기에 key가 없다. 따라서, .get_text() 요청에는 오류가 발새하게 된다.

- type(web_page.find()) : bs4.element.Tag (Tag)

- type(web_page.find_all()) : bs4.element.ResultSet (list)

 

이를 해결하기 위해서는 for문으로 하나하나씩 .get_text() 함수를 적용해주어야 한다.

print(box1.get_text()) # get_ + Tab!
print()

for defintion in web_page.find_all('span', {'class': 'txt_search'}):
    print(defintion.get_text())

 

 


기초_실습2) 영화 제목 & 줄거리 스크래핑

(1/6) ~ (4/6) 진행

# 불러오려는 url 입력하기 (네이버영화 - Spider-Man: No Way Home (2021) )
url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=208077'
# basic.naver ? code=208077
# def basic.naver(code=208077)로 생각하면 됨

# urlopen 함수를 통해 web 변수를 생성
web = urlopen(url)

# BeautifulSoup으로 web 페이지상의 HTML 구조를 파싱
web_page = BeautifulSoup(web, 'html.parser')

 

(5/6) HTML Tag 꺼내기

- 영화 제목 출력

# 태그가 없다면 부모 태그 확인하기
# 영화 제목이 담긴 a 태그를 감싼 h3 태그를 먼저 찾고, 그 안에서 a 태그를 찾는다.
# web_page.find_all( ).find(' ') 이렇게 쓰면 list 형식에 key값을 요청하는 것이기에 에러 발생
title = web_page.find('h3', {'class':'h_movie'}).find('a') 

print('Movie Title:')
print(title.get_text())

 

- 영화 줄거리 출력

summary = web_page.find('p', {'class': 'con_tx'})

print('Movie Summary:')
print(summary.get_text())