개발

[Crawling] BeautifulSoup 예제

소혼 2022. 8. 11. 09:59
반응형

오픈 채팅방에서 Beautiful soup 예제에 대한 설명을 원하는 분이 계셔서 간단히 공부하고 작성해 봅니다.
(BeautifulSoup 처음 써봄)

BeautifulSoup은 HTML/XML 데이터를 가져와서 간단히 파싱을 해서 보여주는 python 라이브러리입니다.
https://www.crummy.com/software/BeautifulSoup/bs4/doc/

PIP로 설치할 수 있습니다. https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup

간단한 예제는 다음과 같습니다.
이 블로그의 목록을 가져와 제목과 요약을 출력해보았습니다.

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.141 Safari/537.36'}
data = requests.get('https://bunhere.tistory.com/',headers=headers)

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

articles = soup.select('.area-main > .area-common > article')
for article in articles:
    title = article.select_one('.title')
    summary = article.select_one('.summary')
    print(title.text, summary.text)

코딩을 거의 모른다고 전제하고 하나씩 설명해 보겠습니다.

처음 두 줄은 python에서 외부 라이브러리(또는 모듈)를 가져오는 부분입니다.
우리가 직접 작성하지 않은 코드들을 가져와 사용하고 싶을 때 파이썬에서는 import라는 키워드를 사용합니다.

첫번째 줄은 requests라는 외부모듈을 가져옵니다. 이걸로 네트워크를 통해 웹페이지를 가져올 겁니다.
두번째 줄은 bs4 라는 외부 모듈에서 BeautifulSoup을 가져옵니다. 부분적으로 가져오기 위해 from 이라는 키워드를 사용했습니다.

그 다음 코드 블럭 4-5줄은 네트워크를 통해 html을 가져오는 부분입니다.
requests라는 모듈은 get이라는 함수를 가지고 있습니다. 웹에서 어떤 정보를 요청하는 가장 기본적인 두가지 메소드(get과 post)중 get을 이용해 웹페이지 정보를 가져오는 일을 수행합니다.

우리가 브라우저를 통해 주소를 전달할때 브라우저는 주소외에 다른 정보들을 추가로 전달합니다.
이 것을 request header라고 합니다.

브라우저의 인스펙터를 통해 Request header 정보를 볼 수 있습니다.

이렇게 전달된 request header 정보들은 url과 함께 웹서버가 적절히 판단하여 결과를 보내주게 됩니다. 이 중 웹 서버들이 확인하는 주요 정보중 하나인 User-Agent는 이 요청이 누구에게서 왔는지 알려주는 역할을 수행합니다.

브라우저에서 요청한 것처럼 해야 하기 때문에 유명한 브라우저의 User-Agent 정보를 임의로 하나 header에 넣어 전달하였습니다.

7줄은 beatiful soup을 객체를 만듭니다.
requests 모듈의 get 함수를 통해 받은 html data를 넘겨주고, html.parser를 사용할 것을 선언합니다
https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup

그 뒤로 beautiful soup을 이용하여 html의 특정 요소들의 내용을 찾아 꺼내와야 합니다.

이것을 수행하려면 html 과 CSS 선택자에 대해 이해가 필요합니다.

일반적으로 웹 페이지는 HTML, CSS, JavaScript 이렇게 세가지 요소로 이루어져 있습니다.
크롤링을 위해 꼭 필요한 기본 적인 정보만 설명해보겠습니다.

HTML은 hypertext markup language의 줄임말로 HTML 파일은 HTML 태그라고 불리는 마크업들을 텍스트 문서로 나열한 것입니다.
태그들은 <body> ... </body> 와 같이 대체로 여는 태그와 닫는 태그로 구성되어 있습니다.
이 태그들을 중첩해서 웹페이지가 담으려는 정보들의 구조를 잡게 됩니다.
크롤링을 위해 알아야 하는 HTML의 또 다른 중요한 요소는 어트리뷰트(attribute)입니다. 어트리뷰트는 태그에 추가적인 속성을 제공합니다. 그렇게 제공되는 속성 가운데 id와 class가 크롤링을 위해 많이 사용됩니다.
id ( https://www.w3schools.com/html/html_id.asp )는 특정 태그를 유일하게 구분할 수 있게 해주며,
class ( https://www.w3schools.com/html/html_classes.asp )는 특정 태그들의 묶음을 구분할 수 있게 해줍니다.

<body> ... <a href="..." id="link_axxx" class="title">인터넷 익스플로러</a> ... </body>

위 예제에서는 a 태그중에 id가 link_axxx class가 title인 값을 보여주고 있습니다. 이 페이지에서 id가 link_axxx인 값은 위 태그말고는 없어야 합니다.(가끔 잘못 만드는 경우 있을 수 있습니다만 오동작할 가능성이 있습니다.) 반면, class가 title인 다른 태그들은 여럿이 있을 수 있습니다.

CSS는 cascading style sheet의 줄임말로 HTML 파일에 스타일(화면에 어떻게 표시되어야 할지)을 제공해줍니다.
이를 위해 CSS의 중요한 요소는 지금 크롤링을 위해 필요하지 않아 생략하고 크롤링에서 사용되는 요소는 CSS 선택자입니다.

CSS 선택자는 CSS가 HTML의 특정 태그 또는 태그들을 선택할 수 있도록 하는 CSS의 문법입니다.
https://developer.mozilla.org/ko/docs/Web/CSS/CSS_Selectors

 

CSS 선택자 - CSS: Cascading Style Sheets | MDN

CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.CSS 선택자는 CSS 규칙을 적용할 요소를 정의합니다.

developer.mozilla.org

자세한 내용은 위 문서를 꼼꼼히 읽어보시길 추천드립니다.

CSS 선택자 가운데 위에서 이야기한 id는 #을 붙여서, 클래스는 .을 붙이면 됩니다.
위 예제에서 #link_axxx 를 하거나 .title을 사용하면 위 a 태그가 선택될 것입니다.

크롤링을 하려면 웹페이지가 HTML 태그들과 어트리뷰트들을 어떻게 쓰고 있는지 분석이 필요합니다.

이를 위해 브라우저를 띄워서 인스펙터를 실행해보겠습니다.
인스펙터는 크롬/웨일 기준 Ctrl + Shift + i 또는 F12를 누르시거나 메뉴에서 개발자도구를 선택하시면 됩니다.

인스펙터의 이 버튼을 클릭하거나 Ctrl + Shift + C를 누르면 마우스가 이동하는 곳이 푸른색으로 변합니다.
아무글이나 선택해보면 다음과 같이 변합니다.

인스펙터 창이 Elements라는 항목으로 바뀌면서 HTML 태그들이 트리 구조로 보입니다.

대충 보면 이 페이지는 area-main이라는 클래스를 가진 div 태그 안에 area-common 클래스를 가진  div태그 안에 article이라는 태그들이 반복적으로 나타나는 것을 알 수 있습니다. (HTML tag 마지막을 보시거나 직접 실행해보세요)

따라서 코드의 9번줄에서는 beautiful soup의 select 함수에 .area-main > .area-common > article 라는 CSS 선택자를 전달해주었습니다.
A > B 는 CSS 선택자 가운데 A의 직접 자식들 중에서 B를 선택하도록 하는 선택자입니다.

결과로 반환되는 articles는 여러개의 article 태그집합을 가르키고 있을 것입니다.
article 내부를 보면 a 태그, article-content라는 클래스를 갖는 div 태그가 있고 그 div 태그 내에 title이라는 클래스를 갖는 strong태그가 제목을, summary 클래스를 갖는 p 태그가 요약을 가지고 있습니다.

for loop를 만들어 각각의 article 태그 집합을 순회하며 select_one 함수를 이용해 해당하는 값들을 꺼내 출력해주면 제목과 요약 정보들을 크롤링하는데 성공한 것을 볼 수 있습니다. (아래는 보기 좋게 하려고 제목만 출력했습니다.)

인터넷 익스플로러 종료 미리하기
[웨일] 모바일에서 전송한 url/사진 등이 PC에서 안보일때
chrome/whale등에서 파일 다운로드 안될때 확인
[초프만2022] 1. 안드로이드 스튜디오 설치하기
원격에서 듀얼부팅할때 순서 바꾸는 법
flutter 따라해보기 - 첫번째 앱 1
참조된 계정이 현재 잠겨있으므로 그 계정으로 로그온 할 수 없습니다
[C++] 소스코드에서 컴파일러 구분하기?
DART 대충 빠르게 훝어본 C++과 다른점
[C++11] std::enable_shared_from_this
반응형