forked from soyoonJ/jejucafe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrawlingtest.py
125 lines (109 loc) · 7.18 KB
/
crawlingtest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import time
import random
from pymongo import MongoClient
from bs4 import BeautifulSoup
from selenium import webdriver
# 윈도우의 경우
# client = MongoClient('localhost', 27017)
#client = MongoClient('13.209.87.246', 27017, username="test", password="test")
# Ubuntu의 경우
client = MongoClient('mongodb://test:test@localhost', 27017)
db = client.dbsparta
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
# EC2 내 Ubuntu 에서 수행 시 Display가 없는 형태로 실행하되, 일반 Chrome 브라우저 인 것처럼 접근하도록 위장.
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument("--single-process")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument(
"User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36")
# Ubuntu 의 경우
path = '/home/ubuntu/jejucafe/driver/chromedriver'
# path = './driver/chromedriver.exe'
driver = webdriver.Chrome(path, chrome_options=chrome_options)
# 제주 구역 중 제주시, 서귀포시, 성산읍, 애월읍의 카페를 조회할 수 있는 URL을 문자열 list 형태로 저장.
# 한 페이지에 최대 15개의 카페 조회 가능.
jeju_cafe_lists = list()
jeju_cafe_lists = ['https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region1%3E11&pageSize=15&sortListType=reviewcnt&viewType=thumb','https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region2%3E21&pageSize=15&sortListType=reviewcnt&viewType=thumb','https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region2%3E17&pageSize=15&sortListType=reviewcnt&viewType=thumb','https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region1%3E12&pageSize=15&sortListType=reviewcnt&viewType=thumb']
for jeju_cafe_list in jeju_cafe_lists:
if jeju_cafe_list == 'https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region1%3E11&pageSize=15&sortListType=reviewcnt&viewType=thumb':
cafe_area = '제주시'
cafe_id_area = 100000
elif jeju_cafe_list == 'https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region2%3E21&pageSize=15&sortListType=reviewcnt&viewType=thumb':
cafe_area = '서귀포시'
cafe_id_area = 200000
elif jeju_cafe_list == 'https://www.visitjeju.net/kr/detail/list?menuId=DOM_000001719008000000&cate1cd=cate0000000005&cate2cd=cate0000001272#p1®ion2cd=region2%3E17&pageSize=15&sortListType=reviewcnt&viewType=thumb':
cafe_area = '성산읍'
cafe_id_area = 300000
else:
cafe_area = '애월읍'
cafe_id_area = 400000
driver.get(jeju_cafe_list)
# 사이트 내용을 불러오는데 로딩되는 시간이 다소 걸려 15~20초 사이를 랜덤하게 대기.
time.sleep(random.uniform(15, 20))
cafe_list_html = driver.page_source
cafe_list_soup = BeautifulSoup(cafe_list_html, 'html.parser')
cafe_list = list()
cafe_common_url = 'https://www.visitjeju.net'
# for 문을 돌며 해당 지역의 카페 개별 항목의 URL을 리스트로 변환.
for i in range(1, 16, 1):
cafe_url = cafe_list_soup.select_one('#content > div > div.cont_wrap > div.recommend_area > ul > li:nth-child(' + str(i) + ') > dl > dt > a')['href']
cafe_list.append(cafe_common_url + cafe_url)
# 지역별 카페들의 정보를 조회하고 가공하여 데이터베이스에 저장.
for link in cafe_list:
cafe_id_num = random.randint(1, 99999)
driver.get(link)
time.sleep(random.uniform(15, 20))
cafe_html = driver.page_source
cafe_soup = BeautifulSoup(cafe_html, 'html.parser')
cafe_raw_url = cafe_soup.select_one('#content > div > div.sub_visual_wrap')
if cafe_raw_url is not None:
# 15 ~ 20초를 대기하였으나 썸네일을 불러오지 못했을 경우 오류 발생 가능.
# 또는 실제 스크래핑 해오는 사이트 내 카페 페이지에 데이터 값이 안들어있는 경우도 있었음.
try:
cafe_modified_url = cafe_raw_url['style']
# style 태그 내 background: url 내용 중 주소만 스크래핑
cafe_thumbnail_url = cafe_modified_url.split('background: url("')[1].split('")')[0]
except KeyError:
# KeyError 가 발생하는 경우는 실제로 지역의 카페 항목 내에 썸네일 URL 또는 제목이 없는 경우.
cafe_thumbnail_url = "NoThumbnailUrl"
cafe_raw_name = cafe_soup.select_one(
'#content > div > div.sub_visual_wrap > div.inner_wrap > div.sub_info_area > div.sub_info_title > h3')
if cafe_raw_name is not None:
# \n (개행) 값이 들어있는 경우가 있어 제거 작업 진행
cafe_name = cafe_raw_name.string.splitlines()[0]
cafe_raw_address = cafe_soup.select_one('#content > div > div.sub_visual_wrap > div.inner_wrap > div.sub_info_area > div.basic_information > div:nth-child(2) > p.info_sub_cont')
if cafe_raw_address is not None:
cafe_address = cafe_raw_address.string
cafe_id = cafe_id_area + cafe_id_num
# 지역 내 카페 정보가 잘 들어있는 경우, 데이터베이스에 이름이 같은 경우 Update, 또는 Create.
if cafe_thumbnail_url != "NoThumbnailUrl":
print('카페 ID: ', cafe_id)
print('카페 이름: ', cafe_name)
print('카페 주소: ', cafe_address)
print('카페 지역: ', cafe_area)
print('카페 썸네일 주소: ', cafe_thumbnail_url)
# 이미 카페 이름이 등록된 경우, Update 진행
if db.jejucafedb.find_one({'cafe_name': cafe_name}) is not None:
time.sleep(5)
db.jejucafedb.update_many({'cafe_name': cafe_name},
{'$set': {'cafe_address': cafe_address,
'cafe_thumbnail_url': cafe_thumbnail_url
}})
# 카페 이름이 Database 내에 없고, 최초 등록 시 Create 진행
else:
cafe_info = {
'cafe_id': cafe_id,
'cafe_name': cafe_name,
'cafe_address': cafe_address,
'cafe_area': cafe_area,
'cafe_thumbnail_url': cafe_thumbnail_url,
'star_rate': 0,
'favorite_count': 0
}
db.jejucafedb.insert_one(cafe_info)
print("모든 URL 내용 확인 완료")
# 스크래핑에 사용하였던 Chromedriver를 사용 종료
driver.close()
driver.quit()