웹 크롤러를 만들거나 html에서 필요한 정보를 검색할 때, BeautifulSoup 라이브러리를 사용하여 편리하게 코딩할 수 있습니다.

설치

$ pip3 install beautifulsoup4

beautifulsoup에는 기본적으로 파이썬 표준라이브러리인 html 파서를 지원하지만, lxml이라는 모듈이 더 빠르게 동작하므로 lxml 모듈도 설치해 줍니다.

$ pip3 install lxml


아래는 beautifulsoup에서 사용할 수 있는 파서의 장단점을 보여주는 테이블 입니다.

Parser선언방법장점단점
파이썬 html.parserBeautifulSoup(markup, 'html.parser')

설치할 필요 없음

적당한 속도


lxml HTML parserBeautifulSoup(markup, 'lxml')매우 빠름lxml 추가 설치 필요
lxml XML parser

BeautifulSoup(markup, 'lxml-xml')

BeautifulSoup(markup, 'xml')

매우 빠름

유일하게 지원되는 xml parser

lxml 추가 설치 필요
html5libBeautifulSoup(markup, 'html5lib')

웹 브라우저와 같은 방식으로 페이지를 파싱

유효한 HTML5 생성

html5lib 추가 설치 필요

매우 느림

사용법

기본 선언 및 테스트 HTML은 아래와 같습니다.

from bs4 import BeautifulSoup

html = """
<!DOCTYPE html>
<html>

<head>
   <title>Page title</title>
</head>

<body>
   <div>
      <p>a</p>
      <p>b</p>
      <p>c</p>
   </div>
   <div class="ex_class">
      <p>d</p>
      <p>e</p>
      <p>f</p>
   </div>
   <div id="ex_id">
      <p>g</p>
      <p>h</p>
      <p>i</p>
   </div>
   <h1>This is a heading</h1>
   <p>This is a paragraph.</p>
   <p>This is another paragraph.</p>
   <a href="http://brownbears.tistory.com" class="a"/>
</body>

</html>
"""


bs = BeautifulSoup(html, 'lxml')

find(name, attrs, recursive, string, **kwargs)

조건에 맞는 태그를 가져옵니다. 만약 조건에 맞는 태그가 1개 이상이면 가장 첫 번째 태그를 가져옵니다.

result = bs.find('p')
print(result)


# <p>a</p>

find_all(name, attrs, recursive, string, limit, **kwargs)

조건에 맞는 모든 태그들을 가져옵니다.

result = bs.find_all('p')
print(result)

# [<p>a</p>, <p>b</p>, <p>c</p>, <p>d</p>, <p>e</p>, <p>f</p>, <p>g</p>, <p>h</p>, <p>i</p>, <p>This is a paragraph.</p>, <p>This is another paragraph.</p>]

class 명으로 찾기

result = bs.find('div', class_='ex_class')
print(result)


# <div class="ex_class">
# <p>d</p>
# <p>e</p>
# <p>f</p>
# </div>

id 명으로 찾기

result = bs.find('div', id='ex_id')
print(result)


# <div id="ex_id">
# <p>g</p>
# <p>h</p>
# <p>i</p>
# </div>

해당 태그명 출력

result = bs.find('div', id='ex_id')
print(result.name)

# div

해당 id명 출력

result = bs.find('div', id='ex_id')
print(result['id'])

# ex_id

해당 class명 출력

result = bs.find('div', class_='ex_class')
print(result['class'])


# ex_class

태그 사이에 있는 내용 출력

result = bs.find('div', class_='ex_class')
print(result.p.text)

# d

result = bs.find('div', class_='ex_class')


# 검색된 div 태그 내의 모든 p태그를 조회
for tag in result.find_all('p'):
    print(tag.text)

# d
# e
# f

태그 내의 속성값 출력

result = bs.find('a', class_='a')
print(result.get('href'))
# http://brownbears.tistory.com


위에서 설명한 방법만으로 충분히 HTML을 파서할 수 있습니다. 더 자세한 내용은 https://www.crummy.com/software/BeautifulSoup/bs4/doc/ 에서 확인할 수 있습니다.

파이썬 스크립트를 개발할 때, 호출 당시 인자값을 줘서 동작을 다르게 하고 싶은 경우가 있습니다. 이때, 파이썬 내장함수인 argparse 모듈을 사용하여 원하는 기능을 개발할 수 있습니다.

아래 설명은 파이썬 3.7 버전 기준으로 작성했습니다.

사용법

간단하게 인자값을 받아 처리하는 로직은 아래와 같습니다.

import argparse

# 인자값을 받을 수 있는 인스턴스 생성
parser = argparse.ArgumentParser(description='사용법 테스트입니다.')

# 입력받을 인자값 등록
parser.add_argument('--target', required=True, help='어느 것을 요구하냐')
parser.add_argument('--env', required=False, default='dev', help='실행환경은 뭐냐')

# 입력받은 인자값을 args에 저장 (type: namespace)
args = parser.parse_args()

# 입력받은 인자값 출력
print(args.target)
print(args.env)


위와 같이 코드를 작성한 다음, 터미널에서 해당 파일을 인자값 없이 실행시키면 아래와 같이 노출이 됩니다.

$ python3 argparse_test.py
usage: argparse_test.py [-h] --target TARGET [--env ENV]
argparse_test.py: error: the following arguments are required: --target

$ python3 argparse_test.py -h
usage: argparse_test.py [-h] --target TARGET [--env ENV]

사용법 테스트입니다.

optional arguments:
  -h, --help       show this help message and exit
  --target TARGET  어느 것을 요구하냐
  --env ENV        실행환경은 뭐냐


다음은 인자값을 target, env에 인자값을 주고 실행시킨 결과입니다.

$ python3 argparse_test.py --target=테스트 --env=local
테스트
local

$ python3 argparse_test.py --target=테스트
테스트
dev

$ python3 argparse_test.py --env=qa
usage: argparse_test.py [-h] --target TARGET [--env ENV]
argparse_test.py: error: the following arguments are required: --target

인자값 설명

위에서 설명한 기능으로도 원하는 동작을 충분히 커버할 수 있습니다. 아래는 객체와 메서드에 어떤 인자가 있는지 간략하게 설명하겠습니다.

ArgumentParser()

해당 객체에는 아래와 같이 입력받고 있습니다.

  • prog: 프로그램의 이름 (기본값: sys.argv[0])
    • 기본값으로 실행한 스크립트파일명을 노출. 작성 시 스크립트 파일 대신 입력한 값이 노출
  • usage: 프로그램 사용법을 설명하는 문자열 (기본값: 파서에 추가된 인자로부터 만들어지는 값)
    • 사용방법을 노출.  기본값으로 실행한 파일 + 입력한 인자값들을 노출
  • description: 인자 도움말 전에 표시할 텍스트 (기본값: none)
    • 스크립트에 -h 옵션을 주어 실행 시, usage 아래에 노출
  • epilog: 인자 도움말 후에 표시할 텍스트 (기본값: none)
  • parents: ArgumentParser 객체들의 리스트이고, 이 들의 인자들도 포함
  • formatter_class: 도움말 출력을 사용자 정의하기 위한 클래스
  • prefix_chars: 선택 인자 앞에 붙는 문자 집합 (기본값: '-').
  • fromfile_prefix_chars: 추가 인자를 읽어야 하는 파일 앞에 붙는 문자 집합 (기본값: None).
  • argument_default: 인자의 전역 기본값 (기본값: None)
  • conflict_handler: 충돌하는 선택 사항을 해결하기 위한 전략 (일반적으로 불필요함)
  • add_help: 파서에 -h/--help 옵션을 추가 (기본값: True)
  • allow_abbrev: 약어가 모호하지 않으면 긴 옵션을 축약할 수 있도록 함. (기본값: True)

add_argument()

해당 메서드는 아래와 같이 입력받고 있습니다.

  • name or flags: 옵션 문자열의 이름이나 리스트, 예를 들어 foo 또는 -f, --foo.
  • action: 명령행에서 이 인자가 발견될 때 수행 할 액션의 기본형.
  • nargs: 소비되어야 하는 명령행 인자의 수.
  • const: 일부 action 및 nargs 를 선택할 때 필요한 상숫값.
  • default: 인자가 명령행에 없는 경우 생성되는 값.
  • type: 명령행 인자가 변환되어야 할 형.
  • choices: 인자로 허용되는 값의 컨테이너.
  • required: 명령행 옵션을 생략 할 수 있는지 아닌지 (선택적일 때만).
  • help: 인자가 하는 일에 대한 간단한 설명.
  • metavar: 사용 메시지에 사용되는 인자의 이름.
  • dest: parse_args() 가 반환하는 객체에 추가될 어트리뷰트의 이름.


해당 인자들과 추가적인 기능에 대한 자세한 설명은 https://docs.python.org/ko/3.7/library/argparse.html 에서 확인할 수 있습니다.

  1. Hoguz 2019.06.26 10:36 신고

    매번 많은 도움 받고 갑니다. 감사합니다

  2. 지나가다 2019.08.06 11:13

    도움 많이 되었습니다 감사합니다!

샤딩(sharding)과 파티셔닝(partitioning)의 차이

파티셔닝이란 퍼포먼스(performance), 가용성(availability) 또는 정비용이성(maintainability)를 목적으로 논리적인 데이터 엘리먼트들을 다수의 table로 쪼개는 행위를 뜻하는 일반적인 용어입니다.

샤딩은 수평 파티셔닝(horizontal partitioning)과 동일합니다. 데이터베이스를 샤딩하게 되면 기존에 하나로 구성될 스키마를 다수의 복제본으로 구성하고 각각의 샤드에 어떤 데이터가 저장될 지를 샤드 키를 기준으로 분리합니다. 

수평 파티셔닝 (horizontal partitioning) = 샤딩


위 예시를 보면 1 ~ 5 번 고객의 정보는 하나의 샤드에 저장하고 6 ~ 10 번 고객의 정보는 다른 샤드에 저장하기로 한 예시 입니다. DBA는 데이터 엑세스 패턴과 저장 공간 이슈(로드의 적절한 분산 , 데이터의 균등한 저장)를 고려하여 적절한 샤드 키를 결정하게 됩니다.

수직 파티셔닝 (vertical partitioning)


수직 파티셔닝(vertical partitioning)은 하나의 테이블에 저장된 데이터들을 공간이나 퍼포먼스의 이유로 다수의 테이블로 분리하는것을 말합니다. 이러한 작업을 하는 이유는 DB의 3정규화(Normalization)로 접근하면 편합니다.

'DB' 카테고리의 다른 글

샤딩(sharding), 파티셔닝(partitioning)  (0) 2018.12.23
[DB] ETL이란  (0) 2018.12.22
[DB] CDC란  (0) 2018.12.22
[DB]Connection Pool  (0) 2017.02.11
[SQL] WHERE절에서 IF문처럼 AND 사용  (0) 2017.02.02
[DB] 클러스터  (0) 2016.11.18

SSR 이란?

Server Side Rendering 의 약어로써 단어 그대로 서버에서 렌더링을 작업합니다. 기존에 존재하던 방식으로 사용자가 웹페이지에 접근할 때, 서버에 페이지에 대한 요청을 하며 서버에서는 html, view 와 같은 리소스들을 어떻게 보여질지 해석하고 렌더링하여 사용자에게 반환합니다. 

웹에서 제공하는 정보량이 많아지고 데스크탑보다 성능이 다소 떨어지는 스마트폰의 웹에 대한 요구가 커지면서 새로운 기법이 탄생했습니다.

CSR 이란?

Client Side Rendering의 약어로써 최초에 1번 서버에서 전체 페이지를 로딩하여 보여주고 이후에는 사용자의 요청이 올 때마다, 리소스를 서버에서 제공한 후 클라이언트가 해석하고 렌더링을 하는 방식입니다. 여기에 Angular JS, Backbone JS같이 SPA 개발에 쉬운 JS 프레임워크가 등장했습니다. 여기에 점점 클라이언트가 무거워지자 다시 view만 관리하자는 철학으로 React JS가 등장하게 됩니다.

주의점

기존 웹에서 사용하는 방식이 모두 SSR이 아닌 것 처럼 SPA 방식이 모두 CSR이 아닙니다.

차이점

차이점은 크게 초기 렌더링 속도, SEO, 보안으로 볼 수 있습니다.

초기 렌더링 속도


CSR의 경우, 사용자의 행동에 따라 필요한 부분만 다시 읽어들이기 때문에 서버 측에서 렌더링하여 전체 페이지를 다시 읽어들이는 것보다 빠른 반응속도를 기대할 수 있습니다. SSR을 한다 하더라도 Ajax 기능을 위해 클라이언트 렌더링 요소가 포함될 수 밖에 없습니다. 이러한 점으로 미루어보아 클라이언트 측에서 렌더링을 하게 되면 서버 사이드 렌더링이 따로 필요하지 않기 때문에 일관성있는 코드를 작성할 수 있습니다.

CSR은 페이지를 읽어들이는 시간, 자바스크립트를 읽어들이는 시간, 그리고 자바스크립트가 화면을 그리는 시간까지 모두 마쳐야 콘텐츠가 사용자에게 보여집니다. 여기에 웹 서버에서 콘텐츠 데이터라도 가져와야 한다면 그 시간은 더욱 길어집니다. 즉, 초기 구동속도가 느립니다. 초기 구동속도를 제외하고는 빠른 반응을 보여줍니다.



이와 반대로 SSR의 경우 서버에서 view를 렌더링하여 가져오기 때문에 view를 보기까지 초기 구동속도가 빠릅니다. 물론 JS파일을 전부 다운로드 받기 전까지는 제대로 동작하지 않지만 사용자 측면에서는 빠르다 느낄 수 있습니다. 

SEO

SEO는 Search Engine Optimization의 약어입니다.

대부분의 웹 크롤러, 봇들이 자바스크립트 파일을 실행시키지 못하고 HTML에서만 컨텐츠를 수집합니다. 때문에 CSR 방식으로 개발된 페이지를 빈 페이지로 인식하게 됩니다. 검색엔진에 제대로 노출이 되지 않는 다면 웹페이지의 유입이 줄어드는 악순환이 반복됩니다.

SSR은 view를 서버에서 전부 렌더링하여 내려주므로 HTML에 모든 컨텐츠가 저장되어 있기 때문에 SEO 적용에 큰 문제가 없습니다.

보안

기존의 SSR에서는 사용자에 대한 정보를 서버 측에서 세션으로 관리를 하지만 CSR 방식은 클라이언트 측의 쿠키말고는 사용자에 대한 정보를 저장할 공간이 마땅치 않습니다.

'' 카테고리의 다른 글

SOP, JSONP란?  (0) 2019.09.13
GraphQL이란?  (0) 2019.09.13
서버 사이드 렌더링(SSR), 클라이언트 사이드 렌더링(CSR)  (0) 2018.12.23
CDN이란  (0) 2018.12.22
SPA (Single Page Application)  (0) 2018.12.22
Phantom JS란?  (0) 2017.10.22

ETL은 Extract, Transform, Load 의 앞글자를 딴 용어입니다. 즉 데이터를 추출, 변환, 적재를 한다는 것입니다. 내용은 그렇게 어렵지가 않습니다.

예를 들어, calendar라는 테이블에 년/월/일/시/분/초 형태로 각 컬럼이 존재합니다. 이러한 데이터를 사용하여 통계를 내는 어떤 프로그램을 실행하려고 확인 했더니 해당 프로그램은 년월일/시분초 와 같은 컬럼형태를 요구하고 있을 때 작업을 하는 것을 ETL이라 합니다.

예시

Extract

대상이 되는 calendar 테이블에서 년/월/일/시/분/초 형태의 데이터를 전부 추출합니다.

Transform

추출한 데이터를 요구하는 형태인 년월일/시분초 형태로 변경을 합니다.

Load

변경이 된 데이터를 새로운 테이블에 적재합니다.

요약

간단하게 위와 같은 단계를 거치는 것이 ETL이라 합니다. ETL은 저장된 데이터를 변형하여(요구사항에 맞게) 다른 곳으로 이동하는 것 이라 볼 수 있습니다. 위 예제처럼 컬럼 개수를 변형할 수도 있고 데이터의 형태나 컬럼 개수를 변형하지 않는 작업이 될수도 있습니다. 예를 들어 MSSQL을 사용하다가 PostgreSQL로 데이터를 이전하고 싶을 경우, 데이터의 형태와 컬럼 개수는 유지하면서 테이블의 스키마를 조금 변형하는 작업이 될 수도 있습니다.

'DB' 카테고리의 다른 글

샤딩(sharding), 파티셔닝(partitioning)  (0) 2018.12.23
[DB] ETL이란  (0) 2018.12.22
[DB] CDC란  (0) 2018.12.22
[DB]Connection Pool  (0) 2017.02.11
[SQL] WHERE절에서 IF문처럼 AND 사용  (0) 2017.02.02
[DB] 클러스터  (0) 2016.11.18

Change Data Capture의 약어로 마지막으로 추출한 이후 변경된 데이터만 골라내는 기술을 의미합니다. 흔히 데이터 백업이나 통합 작업을 할 경우 방대한 데이터를 다뤄야 하는데 원본 소스 데이터 가운데 최근 변경된 데이터들만 골라 다른 시스템으로 옮기게 되면 시스템 로드도 줄이고 전체적인 작업 생산성을 향상시킬 수 있습니다.  특히 한 시스템에 있는 대량의 데이터를 정기적으로 추출해 다른 시스템으로 이동하는 데이터 통합이나 데이터 웨어하우스 업무의 경우 CDC 기술을 이용하면 데이터를 추출, 이동하는 시간을 크게 줄일 수 있습니다. 또한 24시간 운영해야 하는 필수적인 업무 시스템의 경우 CDC 기술을 이용하면 다운타임 없이 실시간 백업과 데이터 통합이 가능합니다.


'DB' 카테고리의 다른 글

샤딩(sharding), 파티셔닝(partitioning)  (0) 2018.12.23
[DB] ETL이란  (0) 2018.12.22
[DB] CDC란  (0) 2018.12.22
[DB]Connection Pool  (0) 2017.02.11
[SQL] WHERE절에서 IF문처럼 AND 사용  (0) 2017.02.02
[DB] 클러스터  (0) 2016.11.18

+ Random Posts