import matplotlib.pyplot as plt
import pandas as pd
from selenium import webdriver
import urllib.request
from PIL import Image
import sqlite3
import time
import glob
import os
import math
%matplotlib inline
여행 정보를 담을 DB Table 만들기
def tour_crawl(place='보라카이'):
dbpath = "tour_info.db"
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
script = """
DROP TABLE IF EXISTS tour_crawl;
CREATE TABLE tour_crawl(
id INTEGER PRIMARY KEY AUTOINCREMENT, -- 여행 상품의 ID 값
title TEXT, -- 여행 상품의 제목
price INTEGER, -- 여행 상품의 가격
image TEXT -- 여행 상품의 썸네일 이미지 링크
);
"""
cur.executescript(script)
Selenium으로 스크래핑
def tour_crawl(place='보라카이'):
# 코드 이어서
service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
driver.get('http://tour.interpark.com')
print('\nCurrent URL :', driver.current_url)
time.sleep(5)
driver.find_element_by_id('SearchGNBText').send_keys(place)
driver.find_element_by_class_name('search-btn').click()
print('\n(2 of 3) {} 여행 상품에 대한 크롤링을 곧 시작합니다.'.format(place))
time.sleep(3)
driver.find_element_by_class_name('moreBtn').click()
print('\n여행 상품 리스트에 도착했습니다.')
time.sleep(3)
maxpage = math.ceil(int(driver.find_element_by_class_name('mainTxt').find_element_by_tag_name('span').text)/10)
# maxpage = 3 # 여행 상품의 페이지 수가 3 미만일 경우 에러가 발생합니다.
for page in range(1, maxpage + 1):
driver.find_element_by_xpath('/html/body/div[3]/div/div[1]/div[2]/div[4]/div[3]/ul/li[{}]'.format(page)).click()
time.sleep(3)
print("\n{}번째 페이지의 크롤링을 시작합니다.\n".format(page))
box_list = driver.find_element_by_id('boxList')
box_items = box_list.find_elements_by_class_name('boxItem')
for li in box_items:
title = li.find_element_by_class_name('infoTitle').text
price = li.find_element_by_class_name('infoPrice').find_element_by_tag_name('strong').text.replace(',','')
image = li.find_element_by_tag_name('img').get_attribute('src')
# DB에 한 행씩 추가
base_sql = "INSERT INTO tour_crawl(title, price, image) values('{}',{},'{}')" # TEXT인 제목은 ''로 감싸주는 것에 유의
sql_query = base_sql.format(title, price, image)
print('SQL Query :', sql_query[:90], "...")
cur.execute(sql_query)
conn.commit()
driver.close()
driver.quit()
print('\n총 {}페이지의 크롤링이 정상적으로 종료되었습니다.'.format(maxpage))
# DB를 확인하기 위해 추가해준 line
df = pd.read_sql_query("SELECT image FROM tour_crawl;", conn)
conn.close()
URL을 통한 이미지 일괄 다운로드
def tour_crawl(place):
# 코드 이어서
# 패턴을 따르는 파일들의 (경로를 포함한) 파일명을 리스트로 리턴
previous_images = glob.glob('images/*.jpg')
# 이전 크롤링의 결과 images 폴더 안에 남아있는 이미지 파일들이 있다면 모두 삭제
for image in previous_images:
os.remove(image)
img_urls = list(df['image'])
print('\n(3 of 3) 총 {}장의 여행지 이미지에 대한 다운로드를 시작합니다.\n'.format(len(img_urls)))
for index, url in enumerate(img_urls):
urllib.request.urlretrieve(url, "images/{}.jpg".format(index)) # 실제 이미지를 다운로드하는 코드
time.sleep(0.3)
if index % 10 == 0:
print('총 {}장까지 이미지 다운로드가 성공했습니다.'.format(index))
print('\n모든 이미지의 다운로드가 종료되었습니다! (총 이미지 수 : {})'.format(len(img_urls)))
fig = plt.figure(figsize=(15, 30))
rows = len(df['image']) // 5 + 1 # 전체 이미지를 5개씩 하나의 행에 보여줄 때 필요한 행의 수
cols = 5
i = 1
for filename in glob.glob("images/*.jpg"):
ax = fig.add_subplot(rows, cols, i)
ax.axis('off')
ax.imshow(Image.open(filename))
i += 1
plt.tight_layout(pad=0)
plt.show()
'멋쟁이 사자처럼 AI SCHOOL 5기 > Today I Learned' 카테고리의 다른 글
[5주차 총정리] Ensemble 기법 종류 (Boosting 알고리즘 중심으로) (0) | 2022.04.12 |
---|---|
[5주차 총정리] scikit-learn 머신러닝 모델 학습 단계 Framework (0) | 2022.04.12 |
[4주차 총정리] Python 기반 SQL 프로그래밍(5) _ORDER BY, WHERE, JOIN, GROUP BY, SubQuery 총정리 (0) | 2022.04.11 |
[4주차 총정리] Python 기반 SQL 프로그래밍(4) _DML 실습 (0) | 2022.04.08 |
[4주차 총정리] Python 기반 SQL 프로그래밍(3) _DDL 실습 (0) | 2022.04.08 |