2์ฃผ์ ๊ฑธ์ณ beautiful soup๊ณผ selenium ์ ํตํด ํฌ๋กค๋งํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๊ณ ์๋ค. ํฌ๋กค๋งํ ์ ์๋ ์ธ์ด๊ฐ ๋ค์ํ๊ณ ๋ฐฉ๋ฒ์ด ๋ง์์์ธ์ง ๋ด ๊ฒ์ผ๋ก ์ฐฉ ๋ถ์ง๊ฐ ์๋๋ค ๐๐๐
ํ๋ ์์ํฌ๊ฐ ์ฌ๋ ์๊ฐ๋๋ก ์ฝ์ด์ฃผ์ง ์์์ ๋ต๋ตํ ๋ง์๋ ๋ง์ ๊ฒ ๊ฐ๋ค. ๊ทธ๋๋ ํ๋ค ๋ณด๋ฉด ๋ด ๊ฒ์ด ๋๋๊น ์์ฌํ์ง ๋ง๊ณ ๊ณ์ ํด๋ด์ผ๊ฒ ๋ค. *๋งํฌ๋ ์ฐธ๊ณ ํ๊ธฐ ์ข์ ์ฌ์ดํธ์ธ ๊ฒ ๊ฐ์ ์ฐ์ ๋ฃ์๋ค!
์ฐ์ ์๋์์ importํ ๋ชจ๋(bs4, requests ๋ฑ)์ ๋ชจ๋ ๊ฐ๋ฐ ํ๊ฒฝ์ ์๋ค๋ ๊ฒ์ ์ ์ ๋ก ํ๋ค. conda๋ฅผ ์ด๋ค๋ฉด crawling์ฉ ํ๊ฒฝ์ ๋ฐ๋ก ๋ง๋ค์ด ๋๋ ๊ฒ์ด ์ข๋ค. csv ํ์ผ๋ก ์ ์ฅํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ฐ์ ์ ์ฅํ ๋ฐฉ๋ฒ์ ๋ํด์ ๋จผ์ ์์๋ณด์.
csv๋ comma separted values์ ์ฝ์๋ก ๊ฐ ๋ผ์ธ์ ์ปฌ๋ผ์ด ์ฝค๋ง๋ก ๋ถ๋ฆฌ๋์ด ์๋ ํ ์คํธ ํ์ผ ํฌ๋งท์ด๋ค. ๊ฐ๋จํ ๋ฐ์ดํฐ๋ ์ฝค๋ง๋ก splitํด์ ์ฒ๋ฆฌํ์ง๋ง, ๋ฐ์ดํฐ ๋ด์ ์ฝค๋ง๊ฐ ์์ ๊ฒฝ์ฐ ํ์ด์ฌ์ ๋ด์ฅ๋ csv ๋ชจ๋์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๋ฝ์๋ธ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ๊ธฐ์ ํด์ ์ ์ฅํ๋ ์ฝ๋๋ฅผ ๋จผ์ ์์๋ณด์.
์ฐธ๊ณ : ์์ ๋ก ๋ฐฐ์ฐ๋ ํ์ด์ฌ ํ๋ก๊ทธ๋๋ฐ
import csv
# "tags.csv" ํ์ผ์ ์ฐ๊ธฐ ๋ชจ๋(w+)๋ก ๋ง๋ค๊ณ ์ด์ด์ฃผ์ธ์.
tag_open = open("tag.csv", 'w+', encoding='utf-8', newline='')
# csv.writer๋ฅผ ํตํด ํ์ผ์ ๊ฐ์ฒด๋ก ๋ง๋ค์์ด์
tag_writer = csv.writer(tag_open)
# ํ์ผ ๊ฐ์ฒด์ writerow ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ title ์ด, tags์ด์ ๋ง๋ค์ด์.
# ์ด์ ๋ค์์ ๋ฆฌ์คํธ ๋๊ฐ ์ฉ ์ถ๊ฐํ๋ฉด ์๋์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๊ฑฐ์์.
tag_writer.writerow(('title', 'tags'))
* newline ์ต์
csv ํ์ผ์ ์ฐ๊ธฐ ๋ชจ๋๋ก ๋ง๋ค ๋, ํด๋น ์ต์ ์ ๋ฃ์ง ์๊ณ ์์ ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ฒ ๋๋ฉด ๊ฐ ์ ์ ํ ๊ธ์๋ง ๋ฐ์ดํฐ๊ฐ ๋ด๊ธฐ๋ ๊ธฐ์ดํ ํ์์ ๋ณผ ์ ์๋ค. newline='' ์ฒ๋ผ newline์ ๋น์์ฃผ๋ ์ธ์๋ก ๋ฃ์ด์ผ ์์ฑ ํ ํ์ค ๋ฐ๊พธ๊ธฐ๊ฐ ์์ด์ง๋ค!
ํ๊ตญ ๋ฌธ์ ๋งํฌ ์ฐพ๊ธฐ ์ด๋ ค์์ ๋งํฌ ๋จผ์ ๋ฃ์๋ค. ์ฌ๋ด์ด์ง๋ง selenium๊ณผ ๋ค๋ฅด๊ฒ beautifulsoup์ element๋ฅผ ๋ฝ์๋ด๋ ๊ฒ์ด ์กฐ๊ธ ๋ ์ง๊ด์ ์ด๊ณ ๋น ๋ฅด๋ค๋ ํ์ด ์๋ค. ํ์ง๋ง ํ๊ธ ๋ฌธ์๊ฐ ๋๋ฌด ๊ฑฐ์ง๊ฐ๊ณ ๊ฒ์ํ๋ฉด ์ฌ๋ฌ ๊ฐ์ ์ธ์ด๊ฐ ์์ฌ ์์ด์ ์ฝ์ง์ ํ๊ธฐ ๊ต์ฅํ ์ฝ๋ค ... ๐
๋์ ๊ฒฝ์ฐ์๋ ํ์ฐธ๋์ ๊ฒ์ํ๋๋ฐ ์๊ณ ๋ณด๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฉ์๋์ธ ๊ฒฝ์ฐ๋ ์์์ด์ ์ง์ง ์ ์๊ณ ์จ์ผ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ง์ด ๋ค์๋ค.
์์งํ ์ฒ์์๋ ๋ฐฐ์ด๋๋ก ๋ค importํ๊ณ , ๋ฌด์จ ์๋ฏธ์ธ์ง๋ ๋ชฐ๋๋ค. ์์ผ๋ก ํฌ๋กค๋ง์ ๋ง์ด ํ๊ฒ๋ ์ง๋ ๋ชจ๋ฅด์ง๋ง ์๋ฏธ๋ฅผ ์๊ณ ์ฐ๊ธฐ ์ํด์ ๋ถ์ฐ ์ค๋ช ์ ๋ฌ์๋ค.
from bs4 import BeautifulSoup
from urllib.request import urlopen
import csv
import requests
import re
# ๋ด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ ํ๋ url
crawling_url = "https://www.billboard.com/charts/hot-100"
# http get request๋ฅผ ํตํด url ๋ด์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค.
req = requests.get(crawling_url)
# html ์์ค ๊ฐ์ ธ์ค๊ธฐ(request๋ฅผ ํตํด ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด ๊ฐ์ฒดstr๋ก ๋ฐํ)
# HTTP์์ฒญ ๊ฒฐ๊ณผ๋ก ๋ฐ์์จ HTML, ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ์ ํ์ด์ง ์์ค ๋ด์ฉ๊ณผ ๋์ผ
html = req.text
#bs4๋ก ๋ฐ์ดํฐ๋ฅผ python์ด ์ดํดํ ์ ์๋ ๊ตฌ์กฐ๋ก parsingํ๋ค.
bs = BeautifulSoup(html, 'html.parser')
์๋ ๋ ๋ชจ๋์ ์ฌ์ค ๋ด๊ฐ ์ด ์ฝ๋์๋ ํ์ฉ ์์๊ฐ ์๋๋ฐ, ๋ถ๋ฌ์จ ์ ํ ์ผ๋ก ๋ฐฐ์์ ์ด๋ค ๋ด์ฉ์ธ์ง ๋ฐ๋ก ์ ๋ฆฌํ๋ค.
re : ์ ๊ท ํํ์์ ์ปดํ์ผํ๊ณ , ์ปดํ์ผ๋ ํจํด ๊ฐ์ฒด๋ฅผ ์ด์ฉํด ๋ฉ์๋๋ฅผ ์ํํ ์ ์๋ค. ๋ฌธ์์ด์ ๊ฒ์ ๋ฐ ์นํํ์ฌ ๊ฐ๋จํ๊ฒ ํํํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค๊ณ ํ๋ค.
urlopen ํจ์ (์ฐธ๊ณ : ์ฝ๋ฉ ๋์ฅ): urllib.request ํจํค์ง์ urlopen ๋ชจ๋์ URL์ ์ฌ๋ ํจ์์ธ๋ฐ, URL ์ด๊ธฐ์ ์ฑ๊ณตํ๋ฉด response.status์ ๊ฐ์ด 200์ด ๋์จ๋ค.
* content ์์ฑ
๊ฐ๋ beautifulsoup ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์๋์ ๊ฐ์ด ์ฒซ ๋ฒ์งธ ์ธ์์ content๋ฅผ ๋ถ์ฌ์ฃผ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. content ์์ฑ์๋ ํ ์คํธ ํํ์ HTML์ด ๋ค์ด์๊ฒ ๋๋ค. ๊ทธ๋ฌ๋๊น ์์์ html์์ค ๊ฐ์ ธ์จ ๋ถ๋ถ(.text ๋ถ์ธ)์ ์ ๋จ๊ณ๋ก ์ถ๋ฆด ์๋ ์๋ ๊ฒ์ด๋ค.
response = requests.get("https://www.billboard.com/charts/hot->100") soup = BeautifulSoup(response.content, 'html.parser')
object๋ผ๊ณ ์ด ์ด์ ๋ ๋ด๊ฐ ๋ง๋ beautifulsoup ๊ฐ์ฒด ์ด๋ฆ์ ๋ฐ๋ผ์ ํด๋น ๋ถ๋ถ์ ์ด๋ฆ์ด ๋ฐ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์๋๋ ๋น๋ณด๋ top 100 ํ์ด์ง์ ์์, ๋ ธ๋, ๊ฐ์๋ฅผ ๋ฝ์์ csv ํ์ผ์ ๋ฃ๋ ์ฝ๋๋ค. ๊ฐ๋ฐ์ ๋๊ตฌ์์ ๋ด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฝ๊ณ ์ ํ๋ element๋ฅผ inspectํด์ ํด๋น class name ์์ ์๋ ๋ชจ๋ ํ ์คํธ๋ฅผ for loop์ผ๋ก ๋๋ ธ๋ค.
rank_list = bs.select('.chart-element__rank__number')
song_list = bs.select('.chart-element__information__song')
artist_list = bs.select('.chart-element__information__artist')
for item in zip(rank_list, song_list, artist_list):
rank = item[0].text
song = item[1].text
artist = item[2].text
csv_writer.writerow( (rank, song, artist) )
csv_open.close()
๊ฐ์ฒด์ select ๋ฉ์๋๋ฅผ ํตํด ๋์จ ๊ฒฐ๊ณผ๋ ๋ฆฌ์คํธ์ด๋ค. ๋ฐ๋ผ์
์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ํตํด์ผ๋ง ์ฌ๋์ด ๋ณผ ์ ์๋ ํํ๋ก ํ์ธ์ด ๊ฐ๋ฅํ๋ค.
์ฌ์ค ํฌ๋กค๋งํ ๋ ํ๋์ฉ ๋๋ฆฌ๋ฉด์ ๋ง๋์ง ํ๋ฆฐ์ง ํ์ธํ๊ณ ๊ฒฐ๊ณผ ์๋์ค๋ฉด ๋ต๋ตํด ํ๋ ๋ถ๋ถ์ด ์ ์ผ ์ง์ฆ๋๋ค. ๊ฐ์ด ๊ณต๋ถํ๋ ์น๊ตฌ์๊ฒ ๋ค์ ํ์ python shell๋ก ๋๋ ค๋ณด๋ ๊ฑฐ๋ค!
shell์์ ๋ชจ๋์ importํ๊ณ url get ๋ฑ ์กฐ๊ฑด์ ๋ง๋ค๊ณ ์์ํ๋ฉด, ๊ฒฐ๊ตญ interactive ํ๊ฒฝ์์ ๋ด๊ฐ ์ฐ๋ ๋ฉ์๋๊ฐ ๊ฒฐ๊ณผ๊ฐ์ returnํ๋์ง ์ ํ์ธํ ์ ์๋ค. ์ฌ๋ฌ ์ค์ ์ฐ๊ณ ๋๋ฆฌ๋ฉด ์ด๋๊ฐ ๋ฌธ์ ์ธ์ง ๋ชจ๋ฅด๊ธฐ ์ฌ์ด๋ฐ, ์ด๋ ์ค์ ๊ฒฐ๊ณผ๊ฐ ์ด๋ค์ง ์ฆ๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์์ด ์์ฃผ ์กฐ์ผ๋ค ๐
# Terminal์์ python3 ์
๋ ฅ ํ ์ํฐ ์น๋ฉด shell์ ์ ์ํ ์ ์์ด์.
Python 3.7.7 (default, Mar 26 2020, 10:32:53)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
from bs4 import BeautifulSoup
from urllib.request import urlopen
import csv
import requests
import re
crawling_url = "https://www.billboard.com/charts/hot-100"
req = requests.get(crawling_url)
html = req.text
bs = BeautifulSoup(html, 'html.parser')
rank_list = bs.select('.chart-element__rank__number')
print(rank_list[0].text) # output : 1
stackoverflow์์ ์ง๋ฌธ์ ์ฐพ๋ค๊ฐ ํฌ๋กค๋ง์์ nested tag๋ฅผ ์ฐพ์ ๋ ์ฐธ๊ณ ํ ๋งํ ๋ด์ฉ์ ์ ๋ฆฌํด๋์ ์ถ๊ฐํ๋ค. (๋งํฌ๋ ๋ง๋ถ์ด๋ ค๊ณ ํ๋๋ฐ ๊น๋จน์ด์ ๊ธธ์ ์์..)
์์ธ๋ฅผ ์ ๋๋ก ํธ๋ค๋งํ์ง ๋ชปํ ๊ฑฐ๋ผ๋ฉด, ์์์ path๋ฅผ ์ต๋ํ ๊ตฌ์ฒดํ์ํค๋๊ฒ ์ฝ๋ ์๋์ ์ฝ๊ฒ ํ ์ง๋ฆ๊ธธ!
The more detail you specify the path to find your element. The easier your code will break if you don't handle the exceptions correctly and actually, the logic you find the path might not be general at all..
์ผ๋ฐ์ ์ธ tag๋ค์ ์์๋ฅผ ์ธ๋ฉด์ ์ ๊ทผํ๊ธฐ๋ณด๋ค ๊ฐ๊ธ์ ์ด๋ฉด ์ ๋ํฌํ id๋ class๋ก ์์๋ฅผ ์ฐพ์๊ฐ๋ ๊ฒ์ด ์ข๋ค.
Try to locate elements by unique id or classes instead of counting on the order of some general tags.
๋ด๊ฐ ์ฐพ๊ณ ์ ํ๋ ํ ์คํธ๊ฐ ํน์ ํจํด์ ๋ฐ๋ฅด๋ฉด, ๋ฌธ๋ฒ์์ ํ ์คํธ ์์ฒด๋ฅผ ์ฌ์ฉํ๋ค.
If the text you are trying to collect follow a pattern. you can find it easily using text itself , which is more straightforward for programmer... texts are what people see actually.
๋์ ์ธ ํ๊ฒฝ์์ ํฌ๋กค๋ง์ ํด์ผ ํ๋ค๋ฉด ์จ์ผ ํ๋ ํ๋ ์์ํฌ. ์ฝ๋๋ฅผ ํตํด ์๋์ผ๋ก ์ปดํจํฐ๊ฐ ํด๋ฆญํ๊ฒ ๋ง๋ค๊ฑฐ๋, ํ ์คํธ ์ ๋ ฅ ์ํฐ ๋ฑ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ดํ ์ ์๋๋ก ํ๋ค. ๋๋ ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์์ ํฌ๋กค๋ง์ ํ ๊ฒ์ด๋ค.
import time
from selenium import webdriver
import requests
webdriver api๋ฅผ ํตํด ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ดํ ์ ์๋ค. ๋ด ํฌ๋กฌ ๋ฒ์ ์ ํ์ธํ ๋ค์ ํฌ๋กฌ ๋๋ผ์ด๋ฒ ๋ฒ์ ์ ๋ง์ถ์ด ๋ค์ด๋ฐ๊ณ , sciprt์ ๋ค์ด๋ฐ์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ค๋ค.
์ด ๋ Users/yeni ๊น์ง๋ง ์ฐ๋ฉด ์ ๋๊ณ , ํ์ผ ๋ช ๊น์ง ์ ์ด์ผ์ง selenium์ ์ธ์ํ๋ค...!
๋๋ ์๋์ฒ๋ผ ์ ์ฐ๊ณ ์ฒ์์ chromdriver ๋นผ๋จน๊ณ ์ผ๋ค๊ฐ ๊ณ์ ์คํ์ด ์ ๋๋ค^^driver = webdriver.Chrome('/Users/yeni/chromedriver')
์ beautifulsoup์์ bs ๊ฐ์ฒด๋ฅผ ๋ง๋ ๊ฒ์ฒ๋ผ ์๋์ driver๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์๋ค. ๊ทธ๋ฆฌ๊ณ get method๋ฅผ ํตํด url์ ์ ๊ทผํ๊ณ , time.sleep์ ํ์ด์ง์์ ๋ด์ฉ์ ๊บผ๋ด์ค๋ ์๊ฐ์ ๊ณ ๋ คํด์ ์ผ์ ์๊ฐ sleep์ ์ฃผ๋ ๊ฒ์ด๋ค.
driver = webdriver.Chrome('/Users/yeni/chromedriver')
driver.get('https://www.billboard.com/charts/hot-100')
time.sleep(1)
๊ฐ๋ฐ์ ๋๊ตฌ์์ ์ํ๋ ์ฝ๋ ์ฐํด๋ฆญํ๋ฉด ๋ด๊ฐ ๊ธ์ด์ค๊ณ ์ถ์ ๋ถ๋ถ์ ์ฝ๋๊ฐ ์๊ณ , ์ฝ๋์์ ์ฐํด๋ฆญํ์ ๋ copy์์ element, selector, xpath ์ค ๋ฌด์์ ๊ฐ์ ธ์ฌ ๊ฒ์ธ์ง ์ ํํ ์ ์๋ค. (์ฐธ๊ณ ๋งํฌ)
find_element_by_name('HTML_name')
find_element_by_id('HTML_id')
find_element_by_xpath('/html/body/some/xpath')
find_element_by_css_selector('#css > div.selector')
find_element_by_class_name('some_class_name')
find_element_by_tag_name('h1')
ํ์ด์ง์ ์ฌ๋ฌ ์์๋ค์ ์ ๊ทผํ๋ ๋ฉ์๋๋, ์์ ๋ด์ฉ์์ s๋ง ์ถ๊ฐํด์ฃผ๋ฉด(elements) ๋๋ค. ์์งํ ์ง๊ธ ๋ด ์์ค์์๋ ์ s๋ฅผ ๋ถ์ด๊ณ ๋ผ๋ ๋ฉ์๋๋ฅผ ๋ง๋ค์๋์ง ์ข ์ดํด๊ฐ ์ ๊ฐ๋ค. ์ด๋ฆ์ด ์์ ๋ค๋ฅธ ๊ฒ๋ ์๋๊ณ s๋ฅผ ๋ถ์๋์ง ์๋์ง์ ์ฐจ์ด์ธ๋ฐ ๊ธฐ๋ฅ์ ๋ค๋ฅด๊ฒ ํ๋๊น ๊ฐ๋ ์ด๊ฒ ๋๋ฌธ์ ๋ญ๊ฐ ์ ๋๋ฉด ์ข ํ๋ฑ์ง๊ฐ ๋๋ค ๐ฟ๐ฟ๐ฟ
๊ทธ๋๋ beatifulsoup์ฒ๋ผ ๋ฉ์๋ ์ด๋ฆ์ด ์ค๊ตฌ๋๋ฐฉ์ธ ๊ฒ๋ณด๋ค๋ ํต์ผ์ฑ ์์ด๋ณด์ฌ์ ์ฐจ๋ผ๋ฆฌ ์ฐ๊ธฐ ์ข๊ธด ํ๋ค... ํด ;
์ ๋ฉ์๋๋ค์ ํ์ฉ์ HTML์ ๋ธ๋ผ์ฐ์ ์์ ํ์ฑํด์ฃผ๊ธฐ ๋๋ฌธ์ ๊ตณ์ด Python, BeautifulSoup์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
๋ธ๋ผ์ฐ์ ์ ๋ณด์ด๋ ๊ทธ๋๋ก์ HTML, ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ์ Element ํญ ๋ด์ฉ๊ณผ ๋์ผํ๋ค. ํ์ด์ง์ ๋ชจ๋ elements ๊ฐ์ ธ์ค๊ธฐ ๊ธฐ๋ฅ์ผ๋ก ๋ณด๋ฉด ๋ ๋ฏ! ๋๋ ์ ์ฌ์ฉํ์ง ์์์ง๋ง ์์๋๋ฉด ์ข์ ๊ฒ ๊ฐ์์ ์ฐ์ ์ ๋ฆฌํด๋์๋ค.
html = driver.page_source
๋น๋ง์ดํซ์ ํ์ด์ง์์ ๊ฒ์๋ฌผ ํ๋ํ๋ ๋ค์ด๊ฐ์ ๋ค๋ก ๋์์ค๋ ์ฝ๋๋ฅผ ์ง๋ณด์๋ค. ์ฐ์ ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ๋ณด์ฌ์ฃผ๋ ํ์ด์ง์ ๋ค์ด์จ ๋ค, class๋ฅผ ํตํด ๊ฐ ๊ฒ์๋ฌผ์ ์ ๊ทผํ ์ ์๋ ๋ณ์ places๋ฅผ ๋ง๋ค์๋ค.
๊ทธ ๋ค์ ํด๋น ๋ณ์์ ๊ธธ์ด๋งํผ ๋ฐ๋ณต๋ฌธ์ ๋๋ฆฌ๋ฉด์,
๊น์ง ์คํํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฑฐ์ ํ๋ฃจ์ข ์ผ ๋ฌธ์ ์ ๋ด์ฐฉํ๋ ๋ ๊ฐ์ง ๋ฌธ์ ๋ ์๋์์ ์๊ฐํ๋ค^^
driver = webdriver.Chrome('/Users/yeni/chromedriver')
bemypet_url = 'https://mypetlife.co.kr/map/place-listings/'
driver.get(bemypet_url)
places = driver.find_elements_by_class_name('job_listing-clickbox')
# ํ์ด์ง ๋ด๋ถ ๋ด์ฉ์ ๊ธ์ด์ค๋ ํจ์
def save_contents_in_exel():
title = driver.find_element_by_class_name('job_listing-title').text
explanation = driver.find_element_by_css_selector('#listify_widget_panel_listing_content-1').text
tags = driver.find_elements_by_class_name('ion-pricetag')
about_writer.writerow([title, explanation])
for t in tags:
tag_writer.writerow([title, t.text])
# ํ์ด์ง๋ฅผ ์๋ค๊ฐ๋ค ํ ๋ฐ๋ณต๋ฌธ
for num in range(len(places)):
places[num].click()
save_contents_in_exel()
driver.back()
driver.get('https://mypetlife.co.kr/map/place-listings/')
time.sleep(5)
places = driver.find_elements_by_class_name('job_listing-clickbox')
์์นจ๋ถํฐ ์ ๋
๊น์ง ์ ์ผ ๋ง์ด๋ดค๋ ์๋ฌ ๋ฉ์์ง ๐คฌ๐คฌ๐คฌ๐คฌ
์์๊ฐ ํ์ด์ง์ ์์ด์ ๋ถ๋ฌ์ฌ ์ ์๋ค๋ ๋ป์ธ๋ฐ, ์ ํํ ๋ง๋ก ์ค๋ช
ํ ์๋ ์์ง๋ง! ํ ๋์ค ๋ค์ด๊ฐ๋ค๊ฐ ๋ค๋ก๊ฐ๊ธฐ๋ฅผ ํ๊ฒ ๋๋ฉด ๊ธฐ์กด์ ํ์ด์ง๊ฐ ๋ณ๊ฒฝ๋์ด์ ์์๋ค์ ๋ถ๋ฌ์ฌ ์ ์๋ค๊ณ ํ๋ค.
๊ทธ๋์ get์ ํตํด url์ ๋ค์ ์ฃผ๊ณ , ๋ณ์๋ ๋ค์ ์ ์ํด์ค์ผ๋ก์จ ๊ฐ์ ์ฌ์ดํธ์์ ๊ฐ์ ์์๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋๋ก ํฌ๋กฌ์๊ฒ ์๋ ค์ค๋ค.
๊ทธ๋์ ๋ค์ ๋์์์ ์ํ๋ ๋ด์ฉ์ ๊ธ์ด์ค๊ธฐ ์ํ ํด๋ฆญ.click()์ ํ๊ธฐ '์ '์!!!
- get url์ ๋ค์ ๊ฐ์ ธ์ค๊ธฐ
- ๋ณ์ ์ฌ์ ์ ํ๊ธฐ
๋ ๊ฐ์ ์์ ์ด ๊ผญ ํ์ํ๋ค. ๊ทธ๊ฒ๋ ์๋๋ผ๋ฉด time.sleep ์๊ฐ์ ๋๋ ค์ ์๊ฐ ์ฝ์ ์ ์๋๋ก ์๊ฐ์ ๋ ์ค์ผ ํ๋ค. ์ฝ๋๋ ์์ ์์ ์ฝ๋๋ฅผ ์ฐธ๊ณ !
๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ํฌ๋กค๋งํ๋ ํ์ด์ง๊ฐ ๊ต์ฅํ ๊ตฌ๋ฆฐ ํ์ด์ง๋ผ๋ฉด, ์ฒซ๋ฒ์งธ ํ์ด์ง์์ ๋ ๋ฒ์งธ ํ์ด์ง๋ก ๋์ด๊ฐ ๋ endpoint์ ํ์ด์ง ๊ตฌ๋ถ์ด ์์ ์๊ฐ ์๋ค. (์: map/listing/1 ์ด๋ฐ ์์ผ๋ก ์๋๊ฒ ์๋๋ผ ๊ทธ๋ฅ listing์ผ๋ก๋ง ํ์)
์ด๋ด ๋๋ ๋ ๋ฒ์งธ ํ์ด์ง๋ฅผ ๊ฐ์ ๋ด์ฉ์ ๊ธ๋๋ผ๋ get url ๋๋ฌธ์ ๋ค์ ์ฒซ ๋ฒ์งธ ํ์ด์ง๋ก ๋์๊ฐ๋ ๋ถ์์ฌ๊ฐ ์๊ธด๋ค. ๊ฒ๋ค๊ฐ ๊ธฐ์กด์ ์ฝ๋๋ก๋ ๋์ ํ ์ฒ๋ฆฌํ ์๊ฐ ์๊ฒ ๋๋ค.
๋๋ฌธ์ ๊ทธ๋ฅ ํ์ด์ง์์ ๊ฐ ๊ฒ์๋ฌผ์ url๋ง ๋ฐ๋ค๊ฐ ์ ์ฅํด์, ์๋ค๊ฐ๋ค (driver.back)ํ ํ์ ์์ด ๋ฆฌ์คํธ์ url์ ์ ์ฅํด์ ์์๋๋ก ์ ์ ํ ํฌ๋กค๋ง์ ํ๋๋ก ๋ก์ง์ ์ง๋ฉด ๋๋ค.
link = driver.get('https://mypetlife.co.kr/map/place-listings/')
time.sleep(3)
for page_idx in range(1,7):
# ํ์ด์ง์ ๋ค์ด๊ฐ ๋ค์์
page = driver.find_elements_by_xpath('//[@id="main"]/div/nav/ul/li')
time.sleep(3)
# ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๊ณ ์ถ์ ์์๋ฅผ ๋ณ์์ ์ ์ฅํด์.
places = driver.find_elements_by_class_name('job_listing')
linkx = []
# ํด๋น ๋ณ์์ url์ ์ฐจ๋ก๋๋ก ๋น ๋ฆฌ์คํธ์ ๋ฃ์ด์.
for idx in range(len(places)):
place = places[idx]
link = place.find_element_by_css_selector("a.job_listing-clickbox").get_attribute('href')
links.append(link)
# ์ ์ฅํ ๋งํฌ๋ฅผ ํ๋์ฉ ๊บผ๋ด์ ๋ด
์๋ค!
for link in liks:
page = driver.get(link)
๊ทธ๋๋ ๊ณ์ ๋ถ๋ค๊ณ ํ๋์ฉ ํด๊ฒฐํ๋๊น ๋ญ๊ฐ ์ผ์ฃผ์ผ ์ ๋ณด๋ค๋ ํ์ฐํ ๋ ๊ฒ ๊ฐ์ ๋๋์ด ๋ ๋ค. beautifulsoup find๋ ์์ง ์ข ๋ชจ๋ฅด๊ฒ ์ด์, ๋ค์์๋ ์๊ฑฐ๋ฅผ ์ ๋ฆฌํด์ผ๊ฒ ๋ค.
์ ๋ณด๊ณ ๊ฐ๋๋ค
~~~