SK shieldus Rookies 16기 (인프라 활용을 위한 파이썬 #06)

만두다섯개·2023년 10월 30일
0

SK 루키즈 16기

목록 보기
5/52

주요 정보

  • 교육 과정명 : 클라우드기반 스마트융합보안 과정 16기
  • 교육 회차 정보 : '23. 10. 31. 인프라 활용을 위한 파이썬 과정 #6

참고 정보

  • 여러 페이지 크롤링 + 멀티스레딩 방식과 단일스레딩 방식 시간 차이 비교( 여러페이지 크롤링시 차이가 많이 나는 걸 직접 확인)
  • BeautifulSoup 사용한 크롤링 프로그램
  • 크롤링 범위 : 알라딘 베스트셀러(주간, 지금, 어제, 특가) 페이지 1, 2, 3, ...
  • 크롤링 내용 : 개별 책 URL, 제목, 순위(베스트셀러 별)
  • 굳이 멀티스레드를 사용한 이유 : 스레드별 크롤링으로 만약 일괄 실행시 소요시간 더 오래걸림.

보완할 점

피드백

  • 베스트셀러 종류 중, [지금 베스트] 페이지는 혼자 다른 URL을 사용해서 다른 베스트셀러와는 다르게 가져와야 한다.
  • 왜 자동화 크롤링이 어려운지 조금이나마 알것 같다. 반자동화 크롤링도 웹 사이트별로 다른 호출방식, URL 등을 사용할 텐데 자동화는...
  • BeautifulSouP 사용 request 크롤링(무한 스크롤 없는 페이지), Excel 문서 다루기(생성, 저장), 멀티스레딩 효율

마이크로 프로그램 : CPU 순차 동작 프로그램 기법 실행
하드 와이어드 프로그램 : 직접 전용회로를 논리 회로로 설계

알라딘 베스트셀러 종류별 책 정보 크롤링 및 Excel 저장

# 알라딘 베스트셀러 크롤링 및 Ecel 저장_ 멀티스레딩 방식 + 여러 페이지 클롤링 + 시간 차이 확인
#%%
import requests, time
from bs4 import BeautifulSoup as bs
# def get_rank_list(url):
#     req = requests.get(url)
#     html = req.text
#     soup = bs(html, 'lxml')
#     bestseller_pages = soup.find_all(class_='naviRank')

def return_soup(url):
    main_url ='https://www.aladin.co.kr'
    url = main_url+url
    return url


def crawling_bestseller(url, file_name): # 각 베스트셀러 메인 페이지가 가지고 있는 페이지들 크롤링
    start_time = time.time()
    bestseller_pages = []
    url = return_soup(url)
    req = requests.get(url) # 각 베스트셀러 종류별 페이지 2,3,4... 페이지를 얻는다
    html = req.text
    soup = bs(html, 'lxml')
    bestseller_pages.append(url) # 맨 처음에는 1위 페이지 넣는다
    for p in soup.find(class_='megaseller_rank').find_all('a')[1:-1]: # 리스트 타입이다. 1. 해당 클래스로 시작하는 원본 소스 중 'a' 기준으로 리스트를 슬라이싱 2. 맨 처음은 비어있어서 오류 발생으로 두번째 부터 자름
        bestseller_pages.append(p.get('href')) # 3 주소 리스트 추가 .

    books = []
    # base_url ='https://www.aladin.co.kr/shop/common/wbest.aspx?'  #왜 여기서 따로  base_url 추가하는지? -> crawling_bestseller메소드의 url 을 쓰면 url 의 뒤쪽 부분과 page부분이 중복된다
    for page in bestseller_pages: # 3번만 들어간다. 단, [0]은 1+2 주소
        print(page)
        if page == bestseller_pages[0]:
            req = requests.get(page) 
            html = req.text
            soup = bs(html, 'lxml')
        else:
            req = requests.get(return_soup(page))
            html = req.text
            soup = bs(html, 'lxml')

        booklist = soup.find_all(class_='ss_book_box') 
        for i in booklist:
            book = {}
            # book_rank
            book["책_URL"] = i.find(class_='bo3').get('href')
            book["책_제목"] = i.find(class_='bo3').text
            for j in i.find_all('div')[:1]:
                # book_rank = j.text
                book["책_순위"] = j.text
            # print(j.text)
            books.append(book)

    import json
    f = open('books.json','w') # 쓰기용으로 json 파일 생성
    json.dump(books,f) # 문자열 형식으로 books 가져와 json 파일 넣는다
    f.close()
    
    import openpyxl # 생성한 .json 파일로 Excel 파일 생성
    wb = openpyxl.Workbook()
    sheet = wb.active #수정 가능 시트 생성
    
    sheet.append(['책_URL', '책_제목', '책_순위']) # 시트에 값 제목 지정

    for book_to_excel in books: # 생성한 json 파일을 Excel 파일에 추가
        sheet.append([book_to_excel['책_URL'], book_to_excel['책_제목'], book_to_excel['책_순위']])
        print(book_to_excel)
    wb.save(f"{file_name}.xlsx")
    print(f'{file_name}.xlsx 파일이 생성 되었습니다. 소요 시간은' + str(int(time.time()-start_time)) + ' 초 소요됨.')

def main():
    import threading #함수내 import 가능
    mid_url = '/shop/common/wbest.aspx?BranchType=1'

    bestseller_type_url = [
        '&BestType=Bestseller', # 주간 베스트셀러
        '&BestType=NowBest', # 지금 베스트셀러
        '&BestType=DailyBest', # 어제 베스트셀러
        '&BestType=HotSale' # 특가 베스베스트셀러트
    ]

    file_name = [
        '주간 베스트셀러',
        '지금 베스트셀러',
        '어제 베스트셀러',
        '특가 베스트셀러'
    ]

    print("멀티스레드 사용한 알라딘 베스트셀러 항목별 크롤링 프로그램 입니다")
    thread_1 = threading.Thread(target=crawling_bestseller, args=(f"{mid_url}{bestseller_type_url[0]}", file_name[0]))
    # thread_2 = threading.Thread(target=crawling_bestseller, args=(f"{mid_url}{bestseller_type_url[1]}", file_name[1]))
    thread_3 = threading.Thread(target=crawling_bestseller, args=(f"{mid_url}{bestseller_type_url[2]}", file_name[2]))
    thread_4 = threading.Thread(target=crawling_bestseller, args=(f"{mid_url}{bestseller_type_url[3]}", file_name[3]))
    
    print("스레드 1,2,3,4 실행합니다.")
    thread_1.start()
    # thread_2.start()
    thread_3.start()
    thread_4.start()

if __name__ == "__main__":
    main()


# %%

결과

profile
磨斧爲針

0개의 댓글