python/자동화

[Python] 웹크롤링 - 태그를 이용해서 크롤링하기 - (최종) 한국민족문화대백과사전 크롤링하기

sillon 2023. 3. 8. 12:53
728x90
반응형
from bs4 import BeautifulSoup
import urllib.request as req 
import argparse # 특정 웹사이트로 접속하기 위해
import re
from urllib.parse import quote
import json
from tqdm import tqdm


def crawling_list(url):
    res = req.urlopen(url).read()
    soup = BeautifulSoup(res, 'html.parser') #분석 용이하게 파싱
    find_tag = soup.findAll("a",{"class":"depth1-title"}) # "div",{"class":"section_body"}
    korean_hist = dict()
    for i in range(len(find_tag)):
        txt = re.sub(r"[^가-힣a-zA-Z0-9]","",str(find_tag[i].get_text())) # 특수문자 제거
        korean_hist[txt] = {"words":[],"word_size":0,"error_page":[]}
    return korean_hist

def search_size(visit_url,word):
    url = visit_url + word + "/" + "전체" + "?p=" + str(1) + "&"
    encoded_url = quote(url, safe=':/?&=') # 한글 주소 인코딩
    res = req.urlopen(encoded_url).read()
    soup = BeautifulSoup(res, 'html.parser')#분석 용이하게 파싱
    find_tag = soup.findAll("div",{"class":"count-text"})
    cnt = 0
    for i in range(len(find_tag)):
        cnt =  re.sub(r"[^0-9]","",str(find_tag[i].get_text()))
    return int(cnt) // 20 + 1

def visit_site(visit_url,word):
    word_list = []
    error_page = []
    target_cnt = search_size(visit_url,word)
    idx = 1
    print(word,"사전",target_cnt,"페이지 탐색")
    for idx in tqdm(range(1,target_cnt+1)):
        url = visit_url + word + "/" + "전체" + "?p=" + str(idx) + "&"
        encoded_url = quote(url, safe=':/?&=') # 한글 주소 인코딩
        try:
            res = req.urlopen(encoded_url).read()
            soup = BeautifulSoup(res, 'html.parser')#분석 용이하게 파싱
            find_tag = soup.findAll("div",{"class":"title"}) # "div",{"class":"section_body"}
            tmp = []
            for i in range(len(find_tag)):
                txt = re.sub(r"[^가-힣a-zA-Z0-9]","",str(find_tag[i].get_text()))
                if txt != "의견주제": # 특정 태그가 파싱된경우
                    tmp.append(txt)
            if tmp:
                word_list.extend(tmp)
            else:
                break
        except:
            error_page.append(idx)
    return word_list,error_page

def dict2json(hist_dict,savepath):
    # json 파일로 저장
    with open(savepath + 'korean_hist.json', 'w',encoding="UTF-8") as f : 
        json.dump(hist_dict, f, indent=4)

def readjson(savepath):
    with open(savepath, 'r') as f:
        data = json.load(f)
    print(data)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--url", type=str, default='https://encykorea.aks.ac.kr/')
    parser.add_argument("--visit_url", type=str, default='https://encykorea.aks.ac.kr/Article/List/Type/')
    parser.add_argument("--savepath", type=str, default='./data_crawl/')
    args = parser.parse_args()

    korean_hist = crawling_list(args.url)
    for hist in tqdm(korean_hist):
        word_list,error_page = visit_site(args.visit_url,hist)
        korean_hist[hist]["words"].extend(word_list)
        korean_hist[hist]["word_size"] = len(word_list)
        korean_hist[hist]["error_page"].extend(error_page)

    dict2json(korean_hist,args.savepath)

    print("done")

    # readjson(args.savepath)

 

  0%|                                                                                                                                                  | 0/14 [00:00<?, ?it/s]인물 사전 941 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 941/941 [10:11<00:00,  1.54it/s]
  7%|█████████▋                                                                                                                             | 1/14 [10:11<2:12:29, 611.47s/it]지명 사전 186 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 186/186 [01:48<00:00,  1.71it/s]
 14%|███████████████████▎                                                                                                                   | 2/14 [12:00<1:03:14, 316.19s/it]개념 사전 324 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 324/324 [03:14<00:00,  1.67it/s]
 21%|█████████████████████████████▎                                                                                                           | 3/14 [15:15<47:48, 260.79s/it]유물 사전 121 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 121/121 [01:19<00:00,  1.53it/s]
 29%|███████████████████████████████████████▏                                                                                                 | 4/14 [16:35<31:32, 189.27s/it]단체 사전 290 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 290/290 [03:06<00:00,  1.55it/s]
 36%|████████████████████████████████████████████████▉                                                                                        | 5/14 [19:42<28:15, 188.40s/it]작품 사전 236 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 236/236 [02:20<00:00,  1.68it/s]
 43%|██████████████████████████████████████████████████████████▋                                                                              | 6/14 [22:03<22:57, 172.22s/it]문헌 사전 605 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 605/605 [06:24<00:00,  1.57it/s]
 50%|████████████████████████████████████████████████████████████████████▌                                                                    | 7/14 [28:27<28:11, 241.63s/it]사건 사전 58 페이지 탐색
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 58/58 [00:34<00:00,  1.67it/s]
 57%|██████████████████████████████████████████████████████████████████████████████▎                                                          | 8/14 [29:02<17:35, 175.91s/it]물품 사전 79 페이지 탐색
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 79/79 [00:47<00:00,  1.67it/s]
 64%|████████████████████████████████████████████████████████████████████████████████████████                                                 | 9/14 [29:50<11:18, 135.78s/it]제도 사전 333 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 333/333 [03:14<00:00,  1.71it/s]
 71%|█████████████████████████████████████████████████████████████████████████████████████████████████▏                                      | 10/14 [33:05<10:16, 154.11s/it]놀이 사전 12 페이지 탐색
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12/12 [00:09<00:00,  1.22it/s]
 79%|██████████████████████████████████████████████████████████████████████████████████████████████████████████▊                             | 11/14 [33:15<05:30, 110.05s/it]유적 사전 407 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 407/407 [04:49<00:00,  1.41it/s]
 86%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▌                   | 12/14 [38:05<05:29, 164.64s/it]의식행사 사전 2 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.32it/s]
 93%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▎         | 13/14 [38:07<01:55, 115.48s/it]동식물 사전 3 페이지 탐색
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:02<00:00,  1.28it/s]
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 14/14 [38:10<00:00, 163.61s/it]
done

이렇게 잘 파싱되어 있는 모습을 볼 수 있습니다.

 

다음 포스팅은 해당 사전의 데이터를 살펴보도록 하겠습니다.

728x90
반응형