2022년 5월 동안 검색하고 공부한 것들을 정리한 내용입니다.
1. DataFrame & Dictionary
dictionary 객체를 pandas의 DataFrame으로 변환할 경우, key값은 컬럼명으로 각 key에 대한 value는 컬럼값으로 들어갑니다.
1
2
3
4
5
6
import pandas as pd
dict1 = {'A':[1,2,3],'B':[4,5,6]}
df1 = pd.DataFrame(dict1)
df1
DataFrame을 dictionary로 변경하는 방법은 2가지가 있습니다.
pd.Series
: index가 key가 되고, Series의 값이 value가 됩니다.pd.DataFrame
: 2개의 컬럼만 있는 DataFrame의 value만 가져오는 경우, 앞의 컬럼이 key 그리고 뒤의 컬럼이 value가 됩니다.
1
2
3
4
5
# pd.Series with index
dict(df1['A']) # {0: 1, 1: 2, 2: 3}
# value of pd.DataFrame with 2 columns
dict(df1.values) # {1: 4, 2: 5, 3: 6}
2. 크롤링(Crawling) - 동적 웹페이지 & 마우스 오버
- 동적 웹페이지
- 동적 웹페이지란 url만으로는 들어갈 수 없는 웹페이지를 말합니다.
- 혹시 들어가지더라도 url의 변화가 없는데도 실시간으로 내용이 계속해서 추가되거나 수정된다면 동적 웹 페이지입니다.
- 여기서 무언가를 클릭해서 페이지가 변경되는 것은 다른 경우입니다.
- 사례
- 로그인을 해야만 접속 가능한 네이버 메일
- 보고 있는 위치에 출력 결과와 url이 계속 변하는 네이버 지도
- 드래그를 아래로 내리면 계속 새로운 사진과 영상이 나타나는 인스타그램과 유튜브
아래와 같이 마우스의 위치에 따라 카테고리 정보가 바뀌는 ‘네이버 쇼핑’의 카테고리 정보를 얻고자 합니다.
마우스 위치 조정 in selenium
ActionChains()
함수를 이용해 마우스의 행동을 제어할 수 있습니다. perform()
을 명시해줘야 실행됩니다.
1
2
3
4
5
# 마우스 위치 지정
move1 = driver.find_element(By.XPATH,"/html/body/div[1]/div[1]/div/div[1]/div/div/div[2]/div/div[3]/div/div/div[1]/ul/li["+str(i)+"]/a")
# 마우스 이동
ActionChains(driver).move_to_element(move1).perform()
string → list
string
타입의 데이터를 list
로 변경하는 방법은 list(a)
와 [a]
- 2가지가 있습니다. 하지만 string
타입은 iterable 하므로 2가지 방법의 결과물은 차이가 있습니다.
1
2
3
4
5
6
7
a = '가나다라'
# 1.
list(a) # ['가', '나',' 다',' 라']
# 2.
[a] # ['가나다라']
다른 길이의 list 조합 생성
for 반복문을 실행하며 지정된 ‘대분류’, ‘중분류’와 이에 대한 ‘소분류’ 간의 조합을 만들고자 합니다. cycle
함수를 통해 element를 반복 입력하여 원하는 조합을 생성할 수 있습니다.
1
2
3
4
5
from itertools import cycle
a = ['a']
b = ['b','c','d']
list(zip(cycle(a),b)) # [('a', 'b'), ('a', 'c'), ('a', 'd')]
전체코드
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
# naver_shopping_category.py
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
from itertools import cycle
import pandas as pd
# 옵션 설정
s = Service('./chromedriver')
options = webdriver.ChromeOptions()
options.add_argument('headless')
options.add_argument('window-size=1920x1080')
options.add_argument("disable-gpu")
options.add_argument("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36")
driver = webdriver.Chrome(service=s, options=options)
driver.get('https://shopping.naver.com/home/p/index.naver')
# '카테고리 더보기' 클릭
driver.find_element(By.XPATH,'/html/body/div[1]/div[1]/div/div[1]/div/div/div[2]/div/div[3]/button').click()
time.sleep(2)
# '대분류'명 수집
element1 = driver.find_element(By.CLASS_NAME,"_categoryLayer_main_category_2A7mb").text.split("\n")[1:]
cat_lst = []
for i in range(1,len(element1)):
# '대분류' 항목으로 마우스 오버
move1 = driver.find_element(By.XPATH,"/html/body/div[1]/div[1]/div/div[1]/div/div/div[2]/div/div[3]/div/div/div[1]/ul/li["+str(i)+"]/a")
ActionChains(driver).move_to_element(move1).perform()
time.sleep(1)
# '중분류'명 수집
element2 = driver.find_element(By.CLASS_NAME,"_categoryLayer_middle_category_2g2zY").text.split("\n")[1:]
for j in range(1,min(22,len(element2))):
# '중분류' 항목으로 마우스 오버
move2 = driver.find_element(By.XPATH,"/html/body/div[1]/div[1]/div/div[1]/div/div/div[2]/div/div[3]/div/div/div[2]/ul/li["+str(j)+"]/a")
ActionChains(driver).move_to_element(move2).perform()
time.sleep(1)
# '소분류'명 수집
try:
element3 = driver.find_element(By.CLASS_NAME,"_categoryLayer_subclass_1K649").text.split("\n")[1:]
except:
element3 = []
a = [element1[i-1]]
b = [element2[j-1]]
c = element3
# (대분류,중분류,소분류) 조합 생성
zip_lst = zip(cycle(a),cycle(b),c)
cat_lst.append(list(zip_lst))
# 데이터 처리
df1 = pd.DataFrame(cat_lst)
df1 = pd.melt(df1,value_vars=df1.columns).dropna()
df1 = pd.DataFrame(df1.value.to_list(),columns=['대분류','중분류','소분류'])
df1 = df1.sort_values(['대분류','중분류','소분류'])
df1.reset_index().iloc[:,1:].to_csv("naver_shopping_category.csv")
# 종료
driver.quit()