
ํ๋ผ๋ชจ์์์๋ ์๋น ์ถ์ฒ ๊ธฐ๋ฅ์ ์ํด ์๋์ ๊ฐ์ ์๋น ์ ๋ณด๊ฐ ํ์ํ๋ค.
์ฃผ์, ์์
์๊ฐ, ๋ฉ๋ด์ ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ํ์ํ๋ค.ํ๊ท ์์ ๊ฐ๊ฒฉ์ด๋ผ๋ ์ค์ํ ์ ๋ณด๋ ์ ๊ณตํด์ฃผ์ด์ผ ํ๋ค.๊ฐ์ฅ ๋จผ์ ๊ณต๊ณต๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ณด์์ผ๋ ์ถฉ๋ถํ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ฃผ์ง ์์๋ค. ๋ฐ๋ผ์ ๋ค์ด๋ฒ ์ง๋์์ ํฌ๋กค๋ง์ ํตํด ์๋น ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ ํ์ฉํ๊ธฐ๋ก ํ๋ค.
ํฌ๋กค๋ง์๋ ์ ์ ํฌ๋กค๋ง๊ณผ ๋์ ํฌ๋กค๋ง์ด ์๋ค. ๋ค์ด๋ฒ ์ง๋์์ ์๋น ์ ๋ณด๋ฅผ ์์ธํ ๋ณด๊ธฐ ์ํด์๋ ๊ฒ์ํ ์๋น์ โํด๋ฆญโํ๊ณ , ๋ฉ๋ด๋ฅผ ๋ณด๋ ค๋ฉด ๋ฉ๋ด ๋ฒํผ์ โํด๋ฆญโํด์ผ ํ๋ค. ์ด๋ ๋ฏ ๋ค์ด๋ฒ ์ง๋๋ ํ๋์ ํ์ด์ง์ ๋ชจ๋ ์ ๋ณด๊ฐ ๋์์๋ ๊ฒ์ด ์๋๋ผ ๋์ ์ผ๋ก ํ์ด์ง๋ฅผ ๋ ๋๋งํ๊ธฐ ๋๋ฌธ์ ๋์ ํฌ๋กค๋ง์ด ํ์ํ๋ค. ์ด๋ Selenium์ ์ด์ฉํ๋ฉด ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋์ผ๋ก ์ ์ดํ์ฌ ๋์ ์ผ๋ก ์คํ๋๋ ํ์ด์ง ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
Iframe : ์น ํ์ด์ง ์์ ๋ ๋ค๋ฅธ ์น ํ์ด์ง๋ฅผ ์ฝ์ ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ HTML ์์
โ์ถฉ๋ฌด๋ก ์์์ โ์ ๊ฒ์ํ๋ฉด ์๋น ์ ๋ณด๋ค์ด ์ฃผ๋ฅด๋ฅต ๋์ด๋๊ณ , ๊ฐ๊ฐ์ ์๋น์ ๋๋ฌ ์๋น์ ๋ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ค. ์ด๋ค์ ๊ฐ๊ฐ searchIframe, entryIframe์ด๋ผ๋ ์๋ก ๋ค๋ฅธ Iframe ๋ด์ ์์นํ๋ค.
์ํ๋ ์ ๋ณด๋ฅผ ์ถ์ถํ๊ธฐ ์ํด ์ด๋ค ํ๊ทธ์ ์ด๋ค HTML ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์ด ์๋์ง ํ์ ํด๋ณด์.
searchIframe : ๊ฐ๊ฒ ๋ฆฌ์คํธ ๋ฐ์ดํฐ ๊ตฌ์กฐ ํ์

| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| ๊ฐ๊ฒ ๋ฆฌ์คํธ | <div class = โRyr1Fโ> |
| ๊ฐ๊ฒ ๋ฆฌ์คํธ ์์ธ ์ ๋ณด | <div class = โplace_bluelink.N_KDL> |
| ๊ฐ๊ฒ ์ด๋ฆ | <div class="TYaxT"> |
| ์นดํ ๊ณ ๋ฆฌ | <div class=โKCMntโ> |
entryIframe : ๊ฐ๊ฐ์ ๊ฐ๊ฒ ์์ธ ์ ๋ณด ๊ตฌ์กฐ ํ์

| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| ์ฃผ์ | <span class = โLDgIHโ> |
| ์์ ์๊ฐ | <div class = โgKP9i RMgN0"> |
| ์์ ์๊ฐ ์์ธ ์ ๋ณด | <span class="i8cJw"> , <div class=โH3ua4โ> |
| ๊ฐ๊ฒ ์ด๋ฏธ์ง | <div class = โCB8aPโ> |
| ๊ฐ๊ฒ ์ด๋ฏธ์ง ์์ธ ์ ๋ณด | <div class = โuDR4i> |
| ๋ฉ๋ด ์์ธ ์ ๋ณด | <span class = โlPzHiโ>, <span class = โkPogFโ>, <em>, <img src = โhttps://โ> |
ํฌ๋กค๋ง์ ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ์งํ๋๋ค.
- ์น ๋ธ๋ผ์ฐ์ ๋์ฐ๊ธฐ
- ์ถฉ๋ฌด๋ก ์์์ ๊ฒ์
- searchIframe ์ง์ ๋ฐ ์คํฌ๋กค ์กฐ์
- ๊ฐ๊ฒ ๋ฆฌ์คํธ ์์ง
- ์๋น ํด๋ฆญ ๋ฐ entryIframe ์ ํ
- ๊ฐ๊ฒ ์์ธ ์ ๋ณด ์์ง
์๋๋ ํฌ๋กค๋ง์ ํ๋ฉด์ ์ด๋ ค์ ๋ ๋ถ๋ถ๋ค์ ์ ๋ฆฌํด๋ณธ๋ค.

๋ค์ด๋ฒ ์ง๋๋ ์คํฌ๋กค์ ๋ด๋ฆด ๋๋ง๋ค ๋์ ์ผ๋ก ์ง์ฐ ๋ก๋ฉ๋๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ๋์ด ์๋ค. lazyload-wrapper ์์ ์๋น ์ ๋ณด๊ฐ ์จ๊ฒจ์ ธ ์๋ค. ํฌ๋กค๋ง์ ํ๋ฉด์ ๋ง๋ ์ฒซ ๋๊ด์ด์๋ค ๐ซ
Selenium์ driver.execute_script() ํจ์๋ฅผ ์ฌ์ฉํด ๋์ด๋ฅผ ์กฐ์ ํด์ค์ผ๋ก์จ ์ง์ ์คํฌ๋กคํ๋ ๊ฒ๊ณผ ๋์ผํ ํจ๊ณผ๋ฅผ ๋ผ ์ ์๋ค. ํ์ด์ง์ ๋งจ ์๋๊น์ง ์คํฌ๋กคํ์ฌ ์๋น ์ ๋ณด๊ฐ HTML์ ์ฑ์์ง๊ฒ ํ๋ค.
def scroll(driver, scroll_container, px):
last_height = driver.execute_script("return arguments[0].scrollHeight", scroll_container)
while True:
driver.execute_script("arguments[0].scrollTop += arguments[1]", scroll_container, px)
time.sleep(0.5)
current_height = driver.execute_script("return arguments[0].scrollTop", scroll_container)
if current_height == last_height:
break
last_height = current_height
driver.find_element(By.ID, "searchIframe") // ๐งจ
WebDriverWait(driver, 60).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "searchIframe"))) // ๐
์๊ฐํ๋ ๊ฒ๋ณด๋ค ๋ก๋ฉ ์๋๊ฐ ๊ต์ฅํ ๋๋ ธ๋ค. ํ์ด์ง์ ์์๋ฅผ ์ฐพ๊ธฐ๋ ์ ์ find_element ํจ์๋ฅผ ํธ์ถํ๋ฉด ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก WebDriverWait์ ์ฌ์ฉํ์. WebDriverWait์ ํน์ ์๊ฐ๊น์ง ๋ธ๋ผ์ฐ์ ์ ์์๋ฅผ ์ฐพ์ ์ ์๋๋ก ๊ธฐ๋ค๋ฆฐ๋ค.

์๋น ๋ณ๋ก ์ธ๋ถ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด์๋ click()์ ๋ฐ์์์ผ ์๋ก์ด ํ์ด์ง๋ฅผ ์ด์ด์ผ ํ๋ค. ๋ํ ์๋น ์ธ๋ถ ์ ๋ณด๋ entryIframe์ ์๊ธฐ ๋๋ฌธ์ searchIframe์์ ๋์์ ์๋ก์ด entryIframe์ผ๋ก ์ง์ ํด์ผ ํ๋ค. Selenium์ ํ ๋ฒ์ ํ๋์ ๋ฌธ์๋ง ์กฐ์ํ ์ ์๋ค๊ณ ํ๋ค.
driver.execute_script("arguments[0].click();", restaurant)
driver.switch_to.default_content()
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '//*[@id="entryIframe"]')))
iframe = driver.find_element(By.XPATH, '//*[@id="entryIframe"]')
driver.switch_to.frame(iframe)
Iframe ์ ํํ ๋ WebDriverWait ๊ฑธ์ด์ฃผ๋ ๊ฒ ์์ง ๋ง์
| ํฌ์ฅ ๊ฐ๋ฅํ ์๋น | ์ผ๋ฐ ์๋น |
|---|---|
![]() |
![]() |
๊ณ์ํด์ 82์ฌ๋ฆฌ์ธ์ฆ์์ ์๋ฌ๊ฐ ๋ฐ์ํด์ ์ ๊ทธ๋ฐ์ง ๋ดค๋๋ ๋ฉ๋ด๊ฐ ๋ค๋ฅธ ์๋น๋ค๊ณผ ์ข ๋ค๋ฅด๊ฒ ๊ตฌ์ฑ๋์ด ์๋ค. ํฌ์ฅ ์ฃผ๋ฌธ์ด ๊ฐ๋ฅํ ๋งค์ฅ์ผ๋ก, ๋ค๋ฅธ ์๋น๋ค๊ณผ ๋ฉ๋ด์ ๊ตฌ์กฐ์ ํ๊ทธ ์ด๋ฆ์ด ๋ค๋ฅด๋ค. ๋ํ lazy ๋ก๋ฉ์ด ๊ฑธ๋ ค์์ด ์คํฌ๋กค ์์ ์ด ํ์ํ๋ค. ์๋น๋ง๋ค ๋ค๋ฅธ ๋ถ๋ถ์ ๋ฐ๋ก ๋ถ๊ธฐ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํ๋ค.
Traceback (most recent call last):
File "/app/crawling_restaurnats_detail.py", line 28, in crawling_restaurant_info
iframe_src = iframe.get_attribute("src")
File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webelement.py", line 231, in get_attribute
attribute_value = self.parent.execute_script(
File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 528, in execute_script
return self.execute(command, {"script": script, "args": converted_args})["value"]
File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 429, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 232, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: script timeout
(Session info: chrome=136.0.7103.59)
์์ธ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ง ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด WebDriverWait์ด ํด๋น ํ๊ทธ๋ค์ ์ฐพ์ ์ ์์ด TimeoutException์ด ๋ฐ์ํ๋ค.
์๋น ์ ๋ณด๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ํฌ๋กค๋งํ์ฌ ์ต์ ์ ๋ณด๋ฅผ ์ ์งํ๊ธฐ ์ํด ํฌ๋กค๋ง ์๋ฒ๋ฅผ ๊ตฌ์ถํ๋ค. ํ๋ฆฌํฐ์ด๋ก ์ฌ์ฉํ ์ ์๋ ์คํ์ด micro์๋๋ฐ ์ค๋ง ๊ณ ์ 70๊ฐ ๊ฐ์ ธ์ค๋๋ฐ ์ฃฝ๊ฒ ์ด? ํ๋ ์๊ฐ์ผ๋ก ๋๋ ธ๋๋ฐ, ๋ฐ๋ก ์ฃฝ์ด๋ฒ๋ ธ๋ค.

์ฝ๋๋ ๊ณ ์ณ๋ณด๊ณ ์๋ฒ๋ฅผ ์ฌ๋ฌ ๋ฒ ๊ป๋ค ์ผ๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง ์์ ๊ฒฐ๊ตญ small๋ก ์ฌ๋ ธ๋ค. ๋น์ฉ์ด ๋ฌธ์ ์ด๊ธดํ๋ ์ด์ ์ต์ข ๋ฐํ๊น์ง 1๋ฌ ์กฐ๊ธ ๋๊ฒ๋ฐ์ ์ ๋จ์์ผ๋ ๊ทธ ์ ๋๋ ๊ฐ์ํ๊ธฐ๋ก ํ๋ค. (์ด ๋ฌธ์ ๋ ๋ค์ ๊ธ์์ ํด๊ฒฐํ๋ค.)
์ ๋ฒ ํ๋ก์ ํธ๋ ๋์ปค๋ฅผ ์ฌ์ฉํ ํ์ด๋ฐ์ ๋์ณ ์ฌ์ฉํ์ง ๋ชปํ๋ค. ๋ชจ๋ํฐ๋ง ์๋ฒ ๊ตฌ์ถํ ๋๋ ์๋ฒ ๋ค์ ์์ฑํ ๋๋ ๊ต์ฅํ ํ๋ค์๊ธฐ ๋๋ฌธ์ ์ด๋ฒ์๋ ๋์ปค๋ฅผ ์ ๊ทน ํ์ฉํด๋ณด๊ธฐ๋ก ํ๋ค.
์๋ฒ์ ํฌ๋กค๋ง ์ฝ๋๋ฅผ ๋ฐฐํฌํ๋ ค๊ณ ๋ณด๋ python, selenium, webdriver ๋ฑ๋ฑ .. ์ค์นํ ๊ฒ ํ๊ฐ๋์ด๋ค. ๋์ปค ์ด๋ฏธ์ง๋ก ๋น๋ํด์ ํ์ํ ํ๊ฒฝ์ ํ ๋ฒ์ ๊ตฌ์ฑํ๊ณ , ์์ฝ๊ฒ ์คํ/๋ฐฐํฌํ ์ ์๋๋ก ๊ด๋ฆฌํ๋ค.
// Python 3.10์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๋ฆฌ๋
์ค ์ด๋ฏธ์ง ์ฌ์ฉ
FROM python:3.10-slim
// ํฌ๋กฌ ์ค์น ๋ฐ ์ธ์ฆ์ ๊ฒ์ฆ์ ์ํด ํ์์ ์ธ ๋ฆฌ๋
์ค ํจํค์ง ์ค์น
RUN apt-get update && apt-get install -y \
wget curl unzip gnupg ca-certificates fonts-nanum apt-transport-https \
&& rm -rf /var/lib/apt/lists/*
// Google Chrome์ ๊ณต์ ๋ฆฌํฌ์งํ ๋ฆฌ ํค๋ฅผ ์ถ๊ฐํ๊ณ , ์ต์ ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ค์น
RUN mkdir -p /usr/share/keyrings && \
curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg && \
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" \
> /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && apt-get install -y google-chrome-stable && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
// pip ์ต์ ํ ๋ฐ ํ๋ก์ ํธ ์์กด์ฑ ์ค์น
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
| ๊ฒ์ ํค์๋ | ์ถฉ๋ฌด๋ก ์์์ |
|---|---|
| ์ต์ข ์์ง ์๋น ์ | 65๊ฐ |
| ์์ ์๊ฐ | 278์ด |
| ๋ฐํ ๋ฐ์ดํฐ | ์๋น ์ด๋ฆ, ์ฃผ์, ์๋น์ด๋ฏธ์ง, ์์ ์๊ฐ, ๋ฉ๋ด ์ ๋ณด |
