Python๋ก ํฌ๋กค๋งํด์ ์๋์ผ๋ก ๊ธ ์ ๋ ฅํ๊ธฐ
์ต๊ทผ ํ์ฌ์์ ์ผํ๋ ์ค, HTML ๋ด์ฉ์ ํฌ๋กค๋งํด ํ์ฌ ๋ด ์์คํ ๋ด์ ๋ฒ์ ๋ณ๋ก ๋ฑ๋กํด์ผ ํ๋ ์ ๋ฌด๋ฅผ ์ํํด์ผ ํ๋ ์ผ์ด ์๊ฒผ๋ค. ์ฌ์ค ๋ณต๋ถํด๋ ๋๋ ์ผ์ด๊ธด ํ์ง๋ง, ์๊ทผ ๋ณต๋ถํด์ผ ํ๋ ์์ด ๋ง์๊ธฐ ๋๋ฌธ์ "๋ด๊ฐ ๊ฐ๋ฐ์์ธ๋ฐ..! ๋จ์๋ฐ๋ณต์ ํ ์ ์์ง!" ์๋ก ๋ง์์ด ๋ค์ด (ใ ใ ใ ์์์๋ ๋ง์) ๊ทธ๋ฅ ๋๋ฑ ๋ง๋ค์๋ค. ๋ถ๋ช ํ์ด์ฌ์ผ๋ก ์๊ณ ๋ฆฌ์ฆ๋ ํ์๋๋ฐ 2๋ ์ ์ด๋ผ ๊ธฐ์ต์ด ํ๋๋ ๋์ง ์๋๋ผ ๐ง ๋ถ๋ช ํ์ด์ฌ ์ ๋ฆฌ๋ ํ๋ ๊ฑฐ ๊ฐ์๋ฐ.. ๋ค ์ด๋๊ฐ์ง.. ใ ใ
์๋ฌดํผ, ๊ทธ๋์ ์ด๋ฒ์ ๋ค์์ ๊ณ ์ํ ๋๋ฅผ ์ํด ๊ธ์ ๋จ๊ฒจ๋๊ธฐ๋ก ํ๋ค.
๊ธ์ ์์ํ๊ธฐ์ ์, ์ฐธ๊ณ ๋ก ์ ๋ Python ๊ฐ๋ฐ์๋ ์๋๊ณ 2๋ ์ ์ ๋ฐฐ์ ๋ ๊ธฐ์ต + 2์๊ฐ๋ง์ ๊ฐ๋ฐํ ๋ด์ฉ์ด์ฌ์.. ๊ฐ์ฅ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋๊ณ ํ๋ ธ๋๋ผ๋ ์ฐธ๊ณ ๋ถํ ๋๋ฆฝ๋๋ค. ๐จ (๊ธฐ์ต์ฐฝ๊ณ ๊ธ์ด๋ผ๊ณ ์๊ฐํด์ฃผ์ธ์)
๊ฐ๋ฐ ์๊ฑด
- HTML ๋ด์ฉ์ ํฌ๋กค๋งํ๋ค.
- ํฌ๋กค๋ง ํ ๋ฐ์ดํฐ๋ฅผ ํ ์คํธ ํ์ผ๋ก ์ ์ฅํ๋ค. (์คํตํด๋ ๋จ)
- ํฌ๋กค๋ง ํ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ๊ธ์ ๋ฑ๋กํ๋ค.
1๏ธโฃ pycharm ๋ค์ด๋ก๋
https://www.jetbrains.com/ko-kr/pycharm/download/#section=mac
๋ญ ๋ค์ด๋ฐ์๋ ์๊ด์ ์์ผ๋, ๋ณดํต ์ปค๋ฎค๋ํฐ ๋ฒ์ ์ผ๋ก ๋ค์ด ๋ฐ์ผ๋ฉด ๋๋ค. ์ค์น ์ ๋ณ๋ค๋ฅธ ํน์ด์ฌํญ์ ์๋ค.
2๏ธโฃ python3 ๋ค์ด๋ก๋
3.x ๋ฒ์ ์ค ํ๋๋ฅผ ๋ค์ด ๋ฐ๋๋ค. ์ด๊ฒ๋ ์ฌ์ค 3.x๋ฉด ์๋ฌด ๋ฒ์ ์ด๋ ์๊ด์์ ๋ฏ ํ๋ค.
3๏ธโฃ ๋ฐ์ดํฐ ํฌ๋กค๋ง
๊ฐ๋ฐ์๊ฑด ์ค, ์ฒซ๋ฒ์งธ๋ ํ์ด์ง์์ ๋ฐ์ดํฐ๋ฅผ ํฌ๋กค๋ง ํด์ผ ํ๋ ์๊ฑด์ด๋ค.
ํฌ๋กค๋ง์๋ BeautifulSoup์ ์ฌ์ฉํ๋ค. ๋ฐ๋ก ํฐ๋ฏธ๋์์ ์ค์นํ ํ์๋ ์๊ณ , ๋ฏธ์ค์น์ํ๋ผ๋ฉด pycharm์์ import์ ์ค๋ฅ๊ฐ ๋ ํ ๋ฐ ๊ทธ๋ ๊ฑฐ๊ธฐ์ ์ค์นํ๋ฉด ๋๋ค.
๐ ํฌ๋กค๋ง ํ ํ์ด์ง์ HTML๋ด์ฉ์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ
url = 'www.naver.com' # <- ์์
html = request.get(url) # ํฌ๋กค๋งํ url์ ๋ฃ์ด์ค๋ค
soup = BeautifulSoup(html.text, 'html.parser') # url html ๋ด์ฉ์ ์ด์ฉํด BeautifulSoup ๊ฐ์ฒด๋ฅผ ๋ง๋๋๋ฏ (?)
class_name_tag = soup.find('div', {'class' : 'class_name'}) # class๊ฐ์ด class_name์ธ ํ๊ทธ ํ์ ๋ด์ฉ์ ๊ฐ์ ธ์จ๋ค.
- ์ด๋ find๋ง๊ณ select๋ ์๋๋ฐ, ์ฌ์ค ๋ญ ์ฌ์ฉํด๋ ์๊ด์ ์๋ค. ๋ ํจ์์ ์ฐจ์ด์ ์ ์๊ฐ์ด ๋๋ฉด ์ถ๊ฐํด ๋๊ฒ ๋ค(๐ต)
๐ ๊ฐ์ ธ์จ HTML๋ด์ฉ์์ ํน์ ํ๊ทธ ๋ด์ฉ์ ์ญ์ ํ๋ ๋ฐฉ๋ฒ
# ๋ฐฉ๋ฒ1
class_name_tag = class_name_tag.find('div', {'id' :'remove_tag_id'}).decompose()
# ๋ฐฉ๋ฒ2
for s in class_name_tag.select('script'): # script ํ๊ทธ ์ ๊ฑฐ
s.extract()
๐ ์ ์ฅํ๊ณ ์ถ์ ๋ด์ฉ์ ํ ์คํธ ํ์ผ๋ก ์ ์ฅํ๋ ๋ฐฉ๋ฒ
file = open(file_path_and_name,'w') # ์ฐ๊ธฐ ๋ชจ๋๋ก ์ด๊ธฐ
file.write(str(class_name_tag)) # str์ผ๋ก ํ๋ณํ ํ ์ ์ฅํด์ผ ์ค๋ฅ๊ฐ ์๋๋ค
file.close()
- beautifulSoup ๊ฐ์ฒด๋ฅผ str์ผ๋ก ํ๋ณํ ํ ์ ์ฅํด์ผ ํ๋ค.
4๏ธโฃ ํ์ด์ง ๋์ ์ผ๋ก ํธ๋ค๋งํ๊ธฐ
๊ฐ๋ฐ์๊ฑด ์ค, ๋๋ฒ์งธ๋ ์๊น ์ ์ฅํ ํ ์คํธ ํ์ผ์ ์ฝ์ด์ ํ์ฌ ๋ด๋ถ ์์คํ ์ ๋์ ์ผ๋ก ์ ์ฅํด์ผ ํ๋ค.
์ด๋๋ selenium์ ์ฌ์ฉํ๋ค. ์ด๊ฒ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐ๋ก ํฐ๋ฏธ๋์์ ์ค์นํ ํ์๋ ์๊ณ , ๋ฏธ์ค์น์ํ๋ผ๋ฉด pycharm์์ import์ ์ค๋ฅ๊ฐ ๋ ํ ๋ฐ ๊ทธ๋ ๊ฑฐ๊ธฐ์ ์ค์นํ๋ฉด ๋๋ค.
selenium ์ฌ์ฉ์์๋ ๋งค๋ฒ ์๋ก์ด ๋ธ๋ผ์ฐ์ ๋ฅผ ๋์ฐ๊ธฐ ๋๋ฌธ์, ๋ก๊ทธ์ธ ํ ์ ๊ทผ์ด ๊ฐ๋ฅํ ํ์ด์ง๋ฅผ ํธ๋ค๋งํ ๋์๋ ใ ใ ๋งค ์์ฒญ๋ง๋ค ๊ณ์ ๋ก๊ทธ์ธํด์ผ ํ๋ ์ด๋ ค์์ด ์๋ค.
์ด๋ด๋ ๋๋ฒ๊น ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ํ๋จ์ ๊ธ์ ํฐ๋ฏธ๋์ ๋ถ์ฌ๋ฃ์ผ๋ฉด ๋๋ฒ๊น ๋ชจ๋๋ก ์ค์ ๋ ํฌ๋กฌ์ด ์คํ๋๋ค.
$ /Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=9222 --user-data-dir="~/ChromeProfile"
๋๋ฒ๊น ๋ชจ๋๋ก ์ด๋ฆฐ ํ์ด์ง์์ ํธ๋ค๋ง ํ๊ณ ์ํ๋ ํ์ด์ง ์ง์ ํ ๋ก๊ทธ์ธ์ ํด๋์ผ๋ฉด, ์ด๋ฐ selenium์ด ๋์ํ ๋ ์ ์ฐฝ์ด ์๋ ํ์ฌ์ฐฝ์์ ์๋ํ๊ธฐ ๋๋ฌธ์ ๋ค์ ๋ก๊ทธ์ธํ์ง ์์๋ ๋๋ค.
๋ํ ๋ค์๊ณผ ๊ฐ์ด selenium ์ค์ ์ ํด์ค์ผ ํ๋ค.
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
webdriver.Chrome(options=chrome_options)
์ด์ฒ๋ผ driver ๊ฐ์ฒด๋ฅผ ์ป์๋ค๋ฉด, ์ด์ ์ํ๋ ๋ด์ฉ์ด ์๋์ผ๋ก ์ ๋ ฅ๋๊ณ ์ ์ฅ ๋ฒํผ๊น์ง ํด๋ฆญํ๊ฒ ํด๋ณด์.
๐ 1. ํ ์คํธ ํ์ผ์ ์ด๋ฆ์ผ๋ก ๋ ์ง ํ๋๋ฅผ ์ ๋ ฅ
for filename in os.listdir(path_dir):
with open(os.path.join(path_dir, filename), 'r') as f:
f.read()
์๊น ์ ์ฅํ ํ ์คํธํ์ผ๋ค์ด ์๋ path_dir๋ฅผ ์ ๋ ฅํ๊ณ , ํด๋น path์ ์๋ ๋ชจ๋ ํ์ผ์ ์ฝ๋ ๊ณผ์ ์ด๋ค. ๋๋ ์๊น ํ ์คํธ ํ์ผ์ ์ด๋ฆ์ผ๋ก ๋ ์ง ํ๋์ ๊ฐ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ๋ค์๊ณผ ๊ฐ์ ํํ๋ก ๊ฐ๋ค์ด ์ ์ฅ๋์ด ์๋ค.
# ํ์ผ๋ช
: 20230614.txt
# ๋ด์ฉ : <html><body>hello</body></html>
date_str = '20211212'
datetime.strptime(date_str, '%Y%m%d').strftime('%Y-%m-%dT00:00')
๋ด๊ฐ ํ์ด์ง์ ๋ฑ๋กํ ๋ ์งํ๋๋ %Y-%m-%dT00:00 ํํ๋ก ์ ๋ ฅํด์ผ ํ๊ธฐ ๋๋ฌธ์, ๋ฌธ์์ด์ datetime๊ฐ์ฒด๋ก ๋ณํํ๊ณ ๋ค์ ์ํ๋ ๋ ์งํ์์ ๋ฌธ์์ด๋ก ๋ณํํด์ผ ํ๋ค.
๐ 2. ํ ์คํธ ํ์ผ๋ด์ ๋ด์ฉ์ผ๋ก ๋ด์ฉ ํ๋๋ฅผ ์ ๋ ฅ
driver.find_element(By.XPATH, XPATH๊ฐ).send_keys('text')
๊ทธ๋ฆฌ๊ณ ํ ์คํธ ํ์ผ์ ๋ด์ฉ์ผ๋ก ๋ด์ฉํ๋์ ๊ฐ์ ์ ๋ ฅํ์ด์ผ ํ๋๋ฐ, ๋ณดํต ๋ค์๊ณผ ๊ฐ์ด send_keys ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
XPATH๋? ๊ฐ๋ฐ์ ๋๊ตฌ๋ก ๋ค์ด๊ฐ์, send_keys ํจ์๋ฅผ ์คํ์ํฌ ํ๊ทธ ๊ฐ์ ํด๋ฆญํ๊ณ ์ค๋ฅธ์ชฝ ๋ง์ฐ์ค๋ฅผ ๋๋ฅด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ด๊ฒ ๋๋ค. ์ด๋ ๋ณต์ฌ -> XPath ๋ณต์ฌ๋ฅผ ํด๋ฆญํ๋ฉด ์ด ํ๊ทธ์ ์ ์ผํ ์ผ์ข ์ ID(?)๊ฐ์ ์ป์ ์ ์๋ค.
์๋ฌดํผ, ๋ณดํต send_keys์ ์ด์ฉํด ํด๋น ํ๊ทธ์ ๊ฐ์ ์ ๋ ฅํ ์ ์๋๋ฐ.. ์ ๋ ฅํ ๋ด์ฉ์ด ๊ธธ ๊ฒฝ์ฐ ์ ๋ ฅํ๋ค๋ง๊ณ ๋ฉ์ถ๋ ์ค๋ฅ๋ฅผ ํ์ธํ ์ ์๋ค. ์ด๋๋ ๋๋ฆ์ ๊ผผ์๋ก ๋ด์ฉ์ ๋ณต์ฌํ๊ณ .. ๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ํํ๊ฒ ํ๋ฉด ๋๋ค!
text = '๊ฐ๋๋ค๋ผ๋ง๋ฐ์ฌ'
pyperclip.copy(text) # ์ค์ ๋ก ctrl + c๋ ๊ฐ๋ค
driver.find_element(By.XPATH, XPATH๊ฐ).send_keys(Keys.COMMAND, 'v') # mac์ผ๊ฒฝ์ฐ COMMAND/ ์ค์ ๋ก ๋ถ์ฌ๋ฃ๊ธฐํ๋๊ฒ๊ณผ ๊ฐ๋ค
pyperclip์ copy๋ฅผ ์ด์ฉํ๋ฉด ๋ด์ฉ์ด ๋ณต์ฌ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์๊น์ฒ๋ผ send_keys์ ๋ด์ฉ์ ๋ณด๋ผ์๋ ์์ง๋ง, ๋ช ๋ น์ด๋ฅผ ๋ณด๋ผ ์๋ ์๋๋ฐ ์์ ๊ฐ์ด Keys.COMMAND, 'v'๋ฅผ ์ ๋ ฅํ๋ฉด COMMAND + V๋ฅผ ํ ํจ๊ณผ์ ๋์ผํ๊ฒ ์ํ๋๋ค. (์ฆ, mac์ ๊ฒฝ์ฐ ๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ํํ ๊ฒ๊ณผ ๋์ผ)
๐ 3. ์ ์ฅ ๋ฒํผ ํด๋ฆญ
๐ 4. ์ ์ฅํ์๊ฒ ์ต๋๊น? confirm ํด๋ฆญ
confirm = driver.switch_to.alert
confirm.accept()