BeautifulSoup 맛 보기

2023. 12. 19. 15:15Portfolio/kakao X goorm 군 장병 AI·SW 교육

Contents 접기

BeautifulSoup로 웹 스크래핑

다음 사전에서 happiness 검색



단어와 단어의 의미만을 출력해보고 싶다면?
또, 여러 단어들의 의미들도 출력하고 싶다면?

BeautifulSoup를 이용하여 웹 스크래핑 하면 쉽게 출력할 수 있다.


https://semlog.tistory.com/4

에서 설명한 웹 스크래핑 프로세스를 떠올려보자.

 

Web Scraping Process

URL 분석

https://alldic.daum.net/search.do?q=happiness



다음 사전에서 'happiness'를 검색했을 때의 URL이다.

 

? 를 기준으로

searh_do는 Daum's server-side script의 함수 중 하나를 나타내고,
q=happiness는 (Web) Query를 의미하고, searh_do 함수의 parameter에 해당한다.

 

다음과 같이 이해하면 쉬울 듯 하다.

def search_do(q)
    ~~~
    return ~~~


Query

쿼리(Query)란 쉽게 이야기해서 데이터베이스에 정보를 요청하는 것

웹 서버에 특정한 정보를 보여달라는 웹 클라이언트 요청(주로 문자열을 기반으로 한 요청)에 의한 처리

 

URL 구성

다음 사전 URL에 `string` 타입의 word 변수를 합쳐서 url 변수를 생성한다.

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

 

 

HTTP Response 얻기

HTTP에 요청을 했으니, 서버로부터 요청한 내용을 얻어야 한다.

이때 urlopen 함수를 통해 web 변수를 생성한다.

web = urlopen(url)

 

 

HTTP Source 얻기

BeautifulSoup으로 Web 페이지 상의 HTML 구조를 파싱(Parsing)할 수 있다.

web_page = BeautifulSoup(web, 'html.parser')

 

다음 어학사전 Parsing 결과


파싱(Parsing)

- HTML이나 XML, JavaScript 등으로 쓰여진 소스들을 각 요소별로 나누는 것
- 이 때, 이러한 parsing을 진행해주는 것을 parser라고 부른다.

 

 

HTTP Source 얻기

HTML Tag를 꺼내는 방법에는 두 가지의 함수를 사용할 수 있다.

#### - .find(~)

# 찾는 단어 (대상이 하나일 때)

box1 = web_page.find('span', {'class': 'txt_emph1'}) # attribute 종류에는 제약 없음. 아무거나 써도 됨.
# class 이름이 'txt_emph1'인 Tag 중 'span'이 들어간 Tag 1개를 찾아라!

print(box1)
print(box1.get_text()) # .get_text() #태그를 걷어내고 내부의 텍스트만 꺼내고 싶을 때


.find(~)는 1개의 Tag를 꺼낼 수 있다.
조건이 동일한 Tag가 여러 개일 경우에는 첫 번째 Tag를 출력!

 

 .find_all(~) : 여러개의 Tag를 찾을 때 사용한다.

for p_tag in web_page.find_all('p'):
    print(p_tag.get_text())
    # Tag 이름이 'p'인 HTML Tag를 하나씩 p_tag에 저장해라!

 

 

 Tag로부터 텍스트 or Attribute values 꺼내기

우리가 궁극적으로 알고 싶은 것은 Tag가 아닌,
Tag가 가리키는 텍스트Attribute values이다.

#텍스트를 출력해주는 함수
Tag.get_text()

#attribute values를 출력해주는 함수
Tag.attrs


다만 여기서 주의해야 할 점은,
HTML Tag를 꺼내는 과정에서 반드시 1개의 Tag를 함수에 대입해야 출력된다는 것이다.



위 예시를 보면 .find_all 함수를 사용했지만,
for문을 이용하여 Tag를 1개씩 출력하여, 텍스트를 꺼냈다.

내가 실습 중 가장 많이 실수 했던 부분이다. .ㅠ

 


그럼 이제 여러 단어의 의미를 찾아보자.

찾을 단어: 'state', 'character', 'emotion', 'content', 'intense'

words = ['state', 'character', 'emotion', 'content', 'intense']

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

    http_response = urlopen(url)
    html_source = BeautifulSoup(http_response, 'html.parser')

    print(html_source.find_all('span', {'class': 'txt_search'})[0].get_text())


결과는!

국가
캐릭터
감정
콘텐츠
강렬한

 


아직은 너무 기초이지만, 일일이 검색하지 않아도 되는 것이 너무 재밌다.