Python 4Day

채상혁·2022년 2월 25일
0

python

목록 보기
5/5

파이썬 4일차 :

크롤링 유의해야함:
웹사이트 뒤 robots.txt 를 작성하면 파일을 다운받거나 화면이 옮겨지는데
naver 같은 경우

허용하지 않는다고 나와있다.

  • selenium
  • aladin
  • crawler

selenium :

웹 자동화 및 웹의 소스코드를 수집하는 모듈
cmd -> pip install selenium (셀레늄 라이브러리 다운로드)

import time
from selenium import webdriver
# 다운로드 받은 크롬 물리 드라이버 가동 명령

driver = webdriver.Chrome('C:/Users/shcha/Desktop/python/chromedriver.exe')

# 물리 드라이버로 사이트 이동 명령
driver.get('https://www.naver.com')

time.sleep(1)

자동으로 버튼 클릭 제어, 텍스트 입력할 수 있다.

crawler :

from selenium import webdriver
import time
# 뷰티풀수프 임포트
from bs4 import BeautifulSoup

# 웹 드라이버 활성화 및 알라딘 홈페이지 이동.
# 다운로드 받은 크롬 물리 드라이버 가동 명령

driver = webdriver.Chrome('C:/Users/shcha/Desktop/python/chromedriver.exe')

# 물리 드라이버로 사이트 이동 명령
driver.get('https://www.aladin.co.kr')

time.sleep(1)

#베스트셀러 탭 클릭
driver.find_element_by_xpath('//*[@id="re_mallmenu"]/ul/li[3]/div/a/img').click()

time.sleep(1)

# selenium으로 현재 페이지의 html 소스코드를 전부 불러와라
src = driver.page_source
# print(src)

# 뷰티풀수프 객체 생성
# 뷰티풀수프 객체를 생성하면서, 셀레늄이 가지고 온 html 소스코드를 제공
# 하고, 해당 소스코드를 html 문법으로 변환하라는 주문.
soup = BeautifulSoup(src,'html.parser')


'''
- 뷰티풀수프를 사용하여 수집하고 싶은 데이터가 들어있는
 태그를 부분 추출할 수 있습니다.

- find_all() 메서드는 인수값으로 추출하고자 하는 태그의 
 이름을 적으면 해당 태그만 전부 추출하야 리스트에 담아 대입합니다.
'''
div_list = soup.findAll('div',class_='ss_book_box')
# print('div_list에 들어있는 데이터 수', len(div_list))
# print(div_list[0]) #1위 책만 가져와 보자

first_book = div_list[0].find_all('li')
print(first_book)

# print(first_book) li안에 필요한 텍스트가 다 있더라 2,3,4 번째 li의 텍스트를 가져와야 겠더라
# 텍스트만을 추출하여 문자열 형태로 반환합니다.

book_title = first_book[1].text
book_author = first_book[2].text
book_price = first_book[3].text

auth_info = book_author.split('|')

print('# 제목:',book_title)
print('# 저자:',auth_info[0])
print('# 출판사:',auth_info[1])
print('# 출판일:',auth_info[2])
print('# 가격:',book_price.split(', ')[0])

'''
# with문을 사용하면 with 블록을 벗어나는 순간
 객체가 자동으로 해제됩니다. (자바의 try with resources과 비슷) 
# with 작성 시 사용할 객체의 이름을 as 뒤에 작성해 줍니다.
'''

'''
*  표준 모듈 codecs
- 웹이나 다른 프로그램의 텍스트 데이터와 파이썬 내부의 텍스트 데이터의
    인코딩 방식이 서로 다를 경우에 내장함수 open()이 제대로 인코딩을
    적용할 수 없어서 에러가 발생합니다. (UnicodeEncodeError)

- 파일 입출력시 인코딩 코덱을 변경하고 싶다면
codecs 모듈을 사용합니다.
'''

with codecs.open(file_path, mode='w', encoding='utf-8') as f:
    driver = webdriver.Chrome('C:/Users/shcha/Desktop/python/chromedriver.exe')
    driver.get('https://www.aladin.co.kr')
    time.sleep(1)

    driver.find_element_by_xpath('//*[@id="re_mallmenu"]/ul/li[3]/div/a/img').click()
    time.sleep(1)

    src = driver.page_source

    soup = BeautifulSoup(src,'html.parser')

    div_list = soup.findAll('div',class_='ss_book_box')

    rank = 1

    for div in div_list:
        book_info = div.findAll('li')

        if book_info[0].text[0] != '[':
            book_title = book_info[0].text
            book_author = book_info[1].text
            book_price = book_info[2].text

        else:
            book_title = book_info[1].text
            book_author = book_info[2].text
            book_price = book_info[3].text

        

        auth_info = book_author.split('|')

        f.write(f'# 순위 : {rank}위 \n')
        f.write(f'# 제목: {book_title} \n')
        f.write(f'# 저자: {auth_info[0]} \n')
        f.write(f'# 출판사: {auth_info[1]} \n')
        f.write(f'# 출판일: {auth_info[2]} \n')
        f.write('# 가격: ' + book_price.split(', ')[0] + '\n')
        f.write('-' * 40 + '\n')

        rank += 1
        best_tab = f'//'
        driver.find_element_by_xpath(best_tab).click()

selenium으로 xlsx 파일 처리 :

import imp
from selenium import webdriver
import time
from bs4 import BeautifulSoup
from datetime import datetime
from selenium.webdriver.chrome.options import Options

# 엑셀처리 모듈 임포트
import xlsxwriter

# user-agent 정보를 변환해 주는 모듈 임포트
# 특정 브라우저로 크롤링을 진행할 때 차단되는 것을 방지.
from fake_useragent import UserAgent

#이미지를 바이트 변환 처리 모듈
from io import BytesIO

# 요청 헤더 정보를 꺼내올 수 있는 모듈
import urllib.request as req

d = datetime.today()

file_path = f'C:/Users/shcha/Desktop/python/crawling/알라딘 베스트셀러 1~400위_{d.year}_{d.month}_{d.day}.xlsx'

# UserAgent 정보 변환 (필수는 아니다.)
opener = req.build_opener() # 헤더 정보를 초기화
opener.addheaders = [('User-agent', UserAgent().ie)]
req.install_opener(opener) # 새로운 헤더 정보를 삽입.

# 엑셀 처리 선언
# Workbook 객체를 생성하여 엑셀 파일을 하나 생성 (매개값으로 저장될 경로를 지정)
workbook = xlsxwriter.Workbook(file_path)

# 워크 시트 생성
worksheet = workbook.add_worksheet()

# 브라우저 안뜨게 하기
chrome_option = Options()
chrome_option.add_argument('--headless')

# 브라우저 설정 - 일반 모드
browser = webdriver.Chrome('C:/Users/shcha/Desktop/python/chromedriver.exe')

# 브라우저 설정 - headless 모드 
# browser = webdriver.Chrome('C:/Users/shcha/Desktop/python/chromedriver.exe',options=chrome_option)

# 브라우저 사이즈 조정
browser.set_window_size(800,600)

#브라우저 내부 대기
#time.sleep(10) -> 브라우저 로딩에 상관없이 무조건 10초 대기

#웹 페이지 전체가 로딩될 떄 까지 대기 후 남은 시간 무시.
browser.implicitly_wait(10)

# 페이지 이동
browser.get('https://www.aladin.co.kr/shop/common/wbest.aspx?BranchType=1&start=we')

# 엑셀에 텍스트 저장
cell_format = workbook.add_format({'bold':True,'font_color':'red','bg_color':'yellow'})
worksheet.write('A1','썸네일',cell_format)
worksheet.write('B1','제목',cell_format)
worksheet.write('C1','작가',cell_format)
worksheet.write('D1','출판사',cell_format)
worksheet.write('E1','출판일',cell_format)
worksheet.write('F1','가격',cell_format)
worksheet.write('G1','링크',cell_format)

while True:
    #bs4 초기화
    soup = BeautifulSoup(browser.page_source, 'html.parser')

    div_ss_book_box_list = soup.find_all('div',class_='ss_book_box')

    for div_ss_book_box in div_ss_book_box_list:

        #이미지 
        img_url = div_ss_book_box.select_one('table div > a > img.i_cover')
        print(img_url)

0개의 댓글