[ํ”„๋กœ์ ํŠธ] (2) ๐Ÿ‘พ ๋„ค์ด๋ฒ„ ์ง€๋„ ํฌ๋กค๋งํ•˜๊ธฐ

jeeenyยท2025๋…„ 6์›” 25์ผ

๐Ÿงจย ๋ฌธ์ œ ์ƒํ™ฉ

์ฒ˜์Œ์—๋Š” 1ํŽ˜์ด์ง€์˜ ์Œ์‹์  ์ •๋ณด๋งŒ ํฌ๋กค๋งํ•ด์˜ค๋‹ค ์ˆ˜๋ฅผ ๋Š˜๋ ค ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€์˜ ์ถฉ๋ฌด๋กœ ์Œ์‹์ ๊นŒ์ง€ ๋ชจ๋‘ ํฌ๋กค๋งํ•ด์˜ค๊ธฐ๋กœ ํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ฝ”๋“œ๋ฅผ ๋Œ๋ฆฌ๋Š”๋ฐ 2ํŽ˜์ด์ง€๋ถ€ํ„ฐ ์ ์  ๋А๋ ค์ง€๋”๋‹ˆ ๊ธ‰๊ธฐ์•ผ ๊ฑฐ์˜ ๋ฉˆ์ถ˜๋“ฏํ•œ ์ž‘์—… ์†๋„๋ฅผ ๋ณด์˜€๋‹ค.

ํ•œ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋” ์žˆ์—ˆ๋‹ค. ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ™•์ธํ•˜๋˜ ์ค‘ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ™•์ธํ•ด๋ดค๋Š”๋ฐ 3ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด์˜ค๋Š”๋ฐ 3G๊ฐ€ ๋„˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŽ˜์ด์ง€๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก ์ ์  ๋Š˜์—ˆ๋‹ค. Selenium์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•Œ๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์ด์ •๋„๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด๋ณด์ธ๋‹ค. ๋˜ํ•œ ํ˜„์žฌ ์„œ๋ฒ„ ์ŠคํŽ™์œผ๋กœ 3G๊ฐ€ ๋„˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋‹ค.

๐Ÿงชย ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์‹œ๋„๋“ค

1. ๋ธŒ๋ผ์šฐ์ € ๋กœ๊ทธ ํ™•์ธํ•˜๊ธฐ

๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ‚ค๊ณ  ํ™•์ธํ•˜๋‹ค๋ณด๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์คฌ๋‹ค. ๋‹ต์˜ ์‹ค๋งˆ๋ฆฌ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„๊นŒ ์‹ถ์–ด heap snapshot์„ ํ™•์ธํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ,

์ž˜๋ชป๋ณธ ์ค„ ์•Œ์•˜๋‹ค. heap snapshot์„ ์ฐ์œผ๋ ค๊ณ ๋ณด๋‹ˆ 16G๊นŒ์ง€ ๊ฐ‘์ž๊ธฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์น˜์†Ÿ์•„์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ˜๋ณต์ ์œผ๋กœ DOM์ด๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , DOM ์š”์†Œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ๋ˆ„์ ๋˜์–ด ๋А๋ ค์ง„๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

2. ํฌ๋กฌ ๋“œ๋ผ์ด๋ฒ„ ์ข…๋ฃŒํ–ˆ๋‹ค๊ฐ€ ์žฌ์‹คํ–‰

๊ฐ€์žฅ ๊ฐ„๋‹จํ•ด๋ณด์ด๋Š” ํ•ด๊ฒฐ์ฑ…์€ ํฌ๋กฌ ๋“œ๋ผ์ด๋ฒ„ ์ž์ฒด๋ฅผ ์ข…๋ฃŒํ–ˆ๋‹ค๊ฐ€ ์žฌ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

# ์ž‘์—… ํ›„ ๋“œ๋ผ์ด๋ฒ„ ์ข…๋ฃŒ
driver.quit()

# ์žฌ์‹คํ–‰
driver = get_driver();

ํ•˜์ง€๋งŒ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋ฉด ๋„ค์ด๋ฒ„์—์„œ 429์—๋Ÿฌ, ToomanyRequest๋ฅผ ๋ณด๋‚ธ๋‹ค. ํ™•์ธํ•ด๋ณด๋‹ˆ 3๋ถ„์ •๋„ ์ง€๋‚˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ์ •์ƒ ๋™์ž‘ํ–ˆ๋‹ค. 3๋ถ„๋งˆ๋‹ค ํฌ๋กค๋งํ• ๊นŒ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ํ•œ ๋ฒˆ์— ํฌ๋กค๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์‹ถ์—ˆ๋‹ค.

3. proxy ์‚ฌ์šฉ

๋‹ค์‹œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•„๋ณด๋‹ค proxy๋ฅผ ์‚ฌ์šฉํ•ด 429 ์—๋Ÿฌ๋ฅผ ์šฐํšŒํ•˜๋Š” ๊ธ€์„ ๋ณด์•˜๋‹ค. 429 ํŒ๋‹จ ๊ธฐ์ค€์ด ํŠน์ • IP์—์„œ ์ง€์†๋œ ์š”์ฒญ์„ ๋ณด๋ƒˆ์„ ๋•Œ๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  proxy๋ฅผ ํ†ตํ•ด IP๋ฅผ ์†์ด๋Š” ๊ฒƒ์ด๋‹ค.

ํ”„๋ก์‹œ๋ฅผ ๋ฌด๋ฃŒ๋กœ ์ œ๊ณตํ•ด์ฃผ๋Š” ์‚ฌ์ดํŠธ์—์„œ ํ”„๋ก์‹œ๋ฅผ ๊ฐ€์ ธ์™€ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์†๋„๊ฐ€ ๋„ˆ๋ฌด ๋А๋ ธ๊ณ  ์–ธ์ œ๋“  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ถˆ์•ˆ์ •ํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ Tor ๋ธŒ๋ผ์šฐ์ €์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. Tor ๋ธŒ๋ผ์šฐ์ €๋Š” ๋„คํŠธ์›Œํฌ ์šฐํšŒ๋ฅผ ํ†ตํ•ด ์ต๋ช…์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๋„คํŠธ์›Œํฌ์ด๊ณ  proxy์™€ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

Tor ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๊น”๊ณ  ์‹œ๋„ํ•ด๋ณด์•˜์œผ๋‚˜ ์ด๋˜ํ•œ ์†๋„๊ฐ€ ๋„ˆ๋ฌด ๋А๋ฆฌ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. 1ํŽ˜์ด์ง€์˜ ์‹๋‹น ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ๊ธฐ์กด์˜ chrome ๋ธŒ๋ผ์šฐ์ €๋Š” 2๋ถ„, Tor๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด 11๋ถ„์ด ๊ฑธ๋ ธ๋‹ค. ์—ฌ๋Ÿฌ ๊ตญ๊ฐ€์˜ ๋„คํŠธ์›Œํฌ๋ฅผ ๊ฒฝ์œ ํ•˜์—ฌ ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค๊ณ  ํ•œ๋‹ค.

๐Ÿ”—ย ์ฐธ๊ณ 
https://jakpentest.tistory.com/entry/Seleinum-Proxy%EC%99%80-OSX%EC%97%90%EC%84%9C-Selenium%EC%9C%BC%EB%A1%9C-Tor-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
https://dundung.tistory.com/248
https://real1004zz.tistory.com/224
https://peanut159357.tistory.com/2

4. ํฌ๋กฌ ์ฐฝ ๊ป๋‹ค ํ‚ค๊ธฐ

๋‹ค์‹œ ์ฒ˜์Œ์œผ๋กœ ๋Œ์•„๊ฐ€ ๊ณ ๋ฏผ์„ ํ•ด๋ณด์•˜๋‹ค.

ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €์— ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋งŽ์ด ์Œ“์ธ๋‹ค โ†’ ๋“œ๋ผ์ด๋ฒ„ ์ข…๋ฃŒ๋กœ๋Š” ํ•ด๊ฒฐ์ด ์•ˆ ๋œ๋‹ค โ†’ ์ฐฝ ๊ป๋‹ค ํ‚ค๋Š” ๊ฒƒ์€?

์ด๋Ÿฐ ์‚ฌ๊ณ ์˜ ํ๋ฆ„์œผ๋กœ ์ƒˆ๋กœ์šด ์ฐฝ์„ ๋„์› ๋‹ค ๋„๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

def crawling_restaurants(url):
    driver = get_driver()

	driver.get(url)
    WebDriverWait(driver, 60).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "searchIframe")))
    WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".place_on_pcmap #app-root .zRM9F")))
    main_tab = driver.current_window_handle
    
    for page in range(5):
		driver.execute_script("window.open('');") // ๐Ÿ“Œ ์ƒˆ๋กœ์šด ์ฐฝ ๊ป๋‹ค ํ‚ค๊ธฐ
        driver.switch_to.window(driver.window_handles[-1])
        driver.get(url)
        WebDriverWait(driver, 60).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "searchIframe")))
        WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".place_on_pcmap #app-root .zRM9F")))
		    ...
		driver.close()
        driver.switch_to.window(main_tab)
    driver.quit
    return restaurants_info

๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜์ง€ ์•Š๋‹ค.

์ด์ „์—๋Š” 3ํŽ˜์ด์ง€๋งŒ ๋„˜์–ด๊ฐ€๋„ ๊ธ‰๊ฒฉํžˆ ๋А๋ ค์ง€๋˜ ์†๋„๊ฐ€ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋˜์—ˆ๊ณ , 3G๋ฅผ ํฌ๊ฒŒ ๋„˜์ง€ ์•Š๋Š” ์„ ์—์„œ ํฌ๋กค๋ง์„ ๋งˆ๋ฌด๋ฆฌํ•˜์˜€๋‹ค.

์ด์ „ ๋ฐฉ์‹ ์ƒˆ๋กœ์šด ๋ฐฉ์‹(ํŽ˜์ด์ง€๋งˆ๋‹ค ์ฐฝ ๊ป๋‹ค ํ‚ค๊ธฐ)
์ด๋ฏธ์ง€ 1 ์ด๋ฏธ์ง€ 2

์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ณด๊ณ  ์‹ถ์–ด ๊ทธ๋ž˜ํ”„๋ฅผ ๊ทธ๋ ค๋ณด๋‹ˆ ํ™•์‹คํžˆ ๋งˆ์ง€๋ง‰ ๋ฐฉ์‹์ด ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ฒซ๋ฒˆ์งธ ๋ฐฉ์‹์€ 600์ดˆ๊ฐ€ ๋„˜๋„๋ก 3ํŽ˜์ด์ง€์— ๋จธ๋ฌผ๋Ÿฌ ์žˆ์–ด์„œ ์ค‘๊ฐ„์— ๋Š์—ˆ๋‹ค.

์ง€๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๋Œ์•„์˜ค๋Š” ๊ธธ์€ ๊ธธ์—ˆ์ง€๋งŒ ์ƒ๊ฐ๋ณด๋‹ค ๋‹จ์ˆœํ•œ ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐ๋œ ๋“ฏ ์‹ถ๋‹ค.

์ด๋กœ์จ ๋ฉฐ์น ๊ฐ„์˜ ์‚ฝ์งˆ ๋ ~

profile
๋‚˜์˜ ์„ฑ์žฅ ๊ธฐ๋ก

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 11์›” 15์ผ

ํ˜„์žฌ 429์• ๋Ÿฌ ์•ˆ๋œจ๊ณ  ์ž˜ ๋˜์‹œ๋‚˜์š”?

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ