Back-End/Python

[Python-웹 크롤링] BeautifulSoup으로 wikidocs 목차 파싱하기

uni2237 2022. 9. 8.
728x90
728x90
Why

노션에 스터디 플래너를 만들어 사용하고 있는데, 

공부하려는 위키독스 책의 목차를 예쁘게 넣고 싶었음 (링크랑 함께!)

 

파싱하려는 위키독스 도서 : 'PyTorch로 시작하는 딥러닝 입문' (https://wikidocs.net/book/2788)

 

 

How

BeautifulSoup 라이브러리를 사용했다.

 

1. 패키지 import

import requests
from bs4 import BeautifulSoup as bs

(사용 전에 pip로 requests랑 bs4 install 해야함)

 

2. url 파싱

wikidocs = requests.get("https://wikidocs.net/book/2788")
# requests.get()을 톻해 원하는 url로 GET요청을 보내고, 요청한 데이터를 변수(wikidocs)로 저장해둔다.


soup = bs(wikidocs.text, "html.parser") #html.parser: BeautifulSoup객체한테 html 파싱하라고 알려줌
'''
beautifulSoup을 통해서 웹문서 파싱 내용을 객체로 저장한다.
- wikidocs.text를 통해 UTF-8로 인코딩된 문자열을 얻는다.
- (wikidocs.content 를 사용해도 되는데, content 속성은 바이너리 원문을 가져옴)
- (wikidocs.json 도 있음, 데이터가 json 포멧이라면 json()을 을 통해 dictionary 객체 얻을 수 있음)
'''

 

 

print(soup) 결과

웹 문서를 잘 가져온 것을 확인할 수 있다.

 

 

 

3. 원하는 Tag 값 확인

크롬에서 제공하는 개발자 도구(F12) 를 통해 웹 페이지 소스를 확인

 

 

 

내가 가져오고 싶은 내용들은 "list-group list-group-toc" 클래스의 <div> 태그 하위내용들로 보인다.

 

- 하위 a 태그의 href를 통해 링크를 얻고, title을 통해 목차 제목을 얻을 수 있다. 
- 하위 span 태그의 style을 통해 큰 제목(0px)과 소제목(20px)도 구분할 수 있다.

 

4. BeautifulSoup의 Select()로 원하는 Tag 값 추출

 

BeautifulSoup에는 find()와 select()등의 함수가 있음. 

그중 select는 css의 selector를 활용해서 원하는 Tag를 찾고,  값을 추출할 수 있다.

 

- select() : 조건에 맞는 태그 여러개 가져옴
- select_one() : 조건에 맞는 태그 한개만 가져옴

 

import re 
elements = soup.select('div.list-group.list-group-toc a') 
# class명이 list-group.list-group-toc 인 div의 하위 a 태그들을 가져옴

for index, element in enumerate(elements):
	if index == 0: continue
    title= element.span.attrs['title'] # ex) 00. 파이토치 공식 문서 링크
    href = element.attrs['href'] # ex) javascript:page(53383)

    ele = soup.select('div.list-group.list-group-toc a >span>span')
    # 큰 제목, 소제목을 구별하기 위해 하위 span 태그를 가져옴
    
    padd = ele[index-1].attrs['style'] # ex) padding-left:0px
    # attrs를 통해 style 속성의 값을 받아온다.
    
    if '20' in padd:
            title='\t'+title
    # padding 값에 20이 들어있다면 소제목이므로 앞에 tap을 붙여준다.
    
    hr = re.findall("\(([^)]+)",href)[0]
    print(f"{title} https://wikidocs.net/{hr}")
    
    '''
    href 값은 javascript:page(53383)와 같은 형식이다.
    괄호안의 숫자만 얻어와 기본 링크 ( https://wikidocs.net/ ) 에 붙이면 됨
    -> 정규표현식 re.findall("\(([^)]+)",href) 을 통해 괄호 안의 값을 추출한다.
    '''

 

결과

큰제목과 소제목이 잘 나눠져있고, 링크도 잘 붙어 나옴!!

 

노션에 적용 ~~

깔꼼~~

 

 

728x90

댓글