용어 사전
파싱Parsing
문자열로 된 HTML을 읽어 태그 구조를 가진 트리로 바꾸는 일
크롤러가 받은 HTML은 태그가 줄바꿈도 없이 이어진 긴 문자열입니다. 사람 눈에는 구조가 보여도, 프로그램에게는 글자를 늘어놓은 것일 뿐입니다. 이 상태로는 "두 번째 책의 가격"이 어디 있는지 물을 수 없습니다.
그래서 문자열을 처음부터 읽으며 여는 태그와 닫는 태그를 짝지어 트리로 만듭니다. 이 일이 파싱이고, 파싱을 맡는 프로그램을 파서(Parser)라고 합니다. 트리가 되면 "article 안의 h3"처럼 위치로 물을 수 있습니다. HTML을 파싱해 만든 트리가 DOM입니다.
아래에서 [다음]을 누르면 HTML을 한 줄씩 읽으며 트리가 만들어집니다. 여는 태그를 만나면 지금 부모 아래에 자식이 붙고, 닫는 태그를 만나면 부모가 한 단계 위로 돌아갑니다.
- 1<body>
- 2 <article class="book">
- 3 <h3>책 제목 1</h3>
- 4 <p class="price">12,000원</p>
- 5 </article>
- 6 <article class="book">
- 7 <h3>책 제목 2</h3>
- 8 <p class="price">15,000원</p>
- 9 </article>
- 10</body>
누가 파싱하나요
브라우저는 HTML을 받자마자 직접 파싱합니다. Python 크롤러에서는 보통 BeautifulSoup이 이 일을 맡습니다.
soup = BeautifulSoup(html, "html.parser") # 문자열을 트리로
soup.select("article h3") # 트리에서 위치로 찾기HTML 파서는 너그러워서, 닫는 태그가 빠진 HTML도 짐작해서 트리를 만듭니다. 그래서 파서마다 결과가 조금씩 다를 수 있습니다. BeautifulSoup에서 html.parser와 lxml을 바꿔 썼을 때 결과가 달라지는 것도 이 때문입니다.
HTML만 파싱하는 것은 아닙니다
JSON, CSV처럼 글자로 된 데이터를 프로그램이 다룰 수 있는 구조로 바꾸는 일도 모두 파싱입니다. AI의 답을 JSON으로 받아 쓰다가 아래 같은 오류를 본 적이 있다면, 파싱에 실패한 것입니다.
SyntaxError: Unexpected token '요', "요약은 다음과 같습니다..." is not valid JSON받은 문자열이 JSON 형식이 아니라는 뜻입니다. AI가 JSON 앞에 "요약은 다음과 같습니다" 같은 문장을 붙였을 때 자주 생깁니다. 받은 문자열을 그대로 출력해 보면 원인이 보입니다.
파싱과 렌더링
렌더링은 DOM을 보고 화면에 그리는 일입니다. 브라우저는 파싱한 다음 렌더링까지 하고, 크롤러는 화면을 그릴 필요가 없어서 파싱까지만 합니다.