[Python] Html 및 XML에서 데이터를 가져오는 모듈(Beautiful Soup)


Development note/Python  2020. 2. 12. 09:00

안녕하세요. 명월입니다.


이 글은 Python에서 Html 및 XML에서 데이터를 가져오는 모듈(Beautiful Soup)에 대한 설명입니다.


이전에 제가 requests(http connector) 와 xml를 다루는 글을 작성한 적이 있습니다.

링크 - [Python] IO - XML 다루기

링크 - [Python] HttpConnection(requests 모듈)로 웹 서버에 접속하는 방법


requests 모듈의 경우는 http 프로토콜을 이용해서 웹에 접속하고 데이터를 가져오는 (html 파일) 역할을 하는 모듈입니다만, html 파일을 파싱해서 데이터를 추출하는 기능은 없습니다.

또 XML를 다루는 lxml의 경우는 정확히는 xml를 데이터를 파싱해서 가져오기는 하지만 html 파싱을 하는 것은 아니고, 또 css selector(Sizzle Selector) 기능이 없기 때문에 사용하기가 까다롭습니다.


Beautiful Soup모듈의 경우는 html데이터를 파싱해서 selector 기능으로 보다 쉽고 빠르게 필요한 데이터를 추출하는 모듈입니다.

import requests;
from bs4 import BeautifulSoup;

with requests.Session() as session:
  session.trust_env = False;
  # 블로그에 접속한다.
  session.headers["Host"] = "nowonbun.tistory.com";
  # Tistory에서 User-Agent를 체크
  session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/82.0.4054.2 Safari/537.36";
  # Tistory 메인 화면 접속
  with session.get("https://nowonbun.tistory.com" , proxies=proxies) as response:
    # File Encoding을 설정한다.
    response.encoding = 'UTF-8';
    
    print("***********response text***********");
    # Response body를 콘솔에 출력한다.
    print(response.text);
    print("***********response text***********");
    # BeautifulSoup로 파싱한다.
    soup = BeautifulSoup(response.text, "lxml");
    # a태그를 모두 출력한다.
    for tag in soup.find_all('a'):
      print(tag);
    print("************function************");
    # a 태그의 class가 navbar-brand인 것을 찾는다. (id도 가능)
    item = soup.find('a', class_="navbar-brand");
    # find는 한 개의 요소를 가져오고, find_all는 해당되는 모든 요소를 리스트로 가져온다. 
    # find에서 여러 요소의 조건일 경우, 첫번째 요소를 가져온다.
    print(item);
    # 요소의 태그 명
    print(item.name);
    # 요소의 속성
    print(item.attrs);
    # 요소의 href 속성
    print(item["href"]);
    print(item.get("href"));
    # 요소의 innerText
    print(item.string);
    print(item.get_text());
    # 요소의 파생 요소
    for child in item.children:
      print(child);
      # 재파싱을 한다. prettify 함수는 사실 html를 재 정렬하는 함수입니다.
      sub = BeautifulSoup(child.prettify(), "lxml");
      # 파생 요소의 span 태그를 찾는다.
      print(sub.find("span"));
    # 부모 태그를 찾는다.
    #for parent in item.parents:
    #  print(parent);
    
    # css selector와 같이 css select 표현식으로 태그를 찾는다.
    items = soup.select("#leftside > h2");
    
    # 리스트 형식으로 가져온다.
    for child in items:
      print(child);

위 에제에서 find와 find_all이 있습니다만, 필자는 사실 select 밖에 안 씁니다.예전에는 xPath도 많이 사용했던 걸로 기억하는데. 이젠 기억이 가물가물하네요.

최근에는 javascript나 CSS, 여러가지 xml형식 등은 css select 표현식(Sizzle Selector)이 가장 편하고 자주 사용되는 문법이지 않나 싶습니다.


참조 - https://www.crummy.com/software/BeautifulSoup/bs4/doc/


여기까지 Python에서 Html 및 XML에서 데이터를 가져오는 모듈(Beautiful Soup)에 대한 설명이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.