๐ ํฌ๋กค๋ง ๋ถ์ ํ๋ก์ ํธ (2) - Selenium ํ์ฉ ๋ด์ค ํฌ๋กค๋ง
์ฌ๋ฌ ํ์ด์ง ํฌ๋กค๋ง ํ๊ธฐ
์ผ์ชฝ ๋ด์คํ์ด์ง ๋ฐ์ค ๋ถ๋ถ์ ์ค๋ฅธ์ชฝ ์ฌ์ง๊ณผ ๊ฐ์ด ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
์ ๋ ์ฌ๊ธฐ์ a ํ๊ทธ๋ฅผ ๊ฐ์ง, ๊ฐ ๋ฐ์ค์ ํด๋น ๋๋ ๋ด์ฉ๋ค์ ๊ฐ์ ธ์ค๋ ค ํฉ๋๋ค.
url='https://news.kbs.co.kr/news/pc/category/category.do?ref=pSiteMap#20241017&1'
html_doc=requests.get(url).text
html_doc
soup=BeautifulSoup(html_doc,'html.parser')
soup
# ๋ฐ์ค์์ ํ๊ทธ์ด๋ฆ์ด a์ธ๊ฑธ ๋ชจ๋ ์ฐพ์์ ๋ฐ์ค ์ปจํ
์ธ ๋ผ๋ ๋ณ์์ ๋ด์
box_contents=soup.find_all('a',class_='box-content flex-style')
box_contents
์ด์ ๊ฒ์๊ธ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋๋ก BeautifulSoup ๊ธฐ๋ฅ์ ํ์ฉํด ์ฝ๋๋ฅผ ์์ฑํ์ต๋๋ค.
ํ์ง๋ง ํ์ด์ง๊ฐ ๋ด๊ฒจ์์ง ์์ต๋๋ค.
ํด๋น ๋ด์ฉ์ BeautifulSoup ๊ธฐ๋ฅ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
์ด ๊ฒฝ์ฐ Selenium์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Selenium์ด๋?
๋ฐ์ดํฐ๊ฐ ๋ด๊ฒจ์ ธ ์์ง ์์ ์์ธ
1. ํฌ๋กค๋ง ํ๋ ค๋ ํ๊ทธ๋ค์ด ์ ์ฑ์ ๋์ด ์๋์ง ํ์ธํ๋ค
2. ํ์ด์ง ์์ค์ javascript๊ฐ ์ฌ์ฉ ๋์๋์ง ํ์ธ - ๋ง์ ์นํ์ด์ง๋ค์ด javascript ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋
ํ์ด์ง์ ๋จผ์ ์ ๊ทผ ํ ์ดํ์ ๋์ ์ผ๋ก javascript๋ฅผ ํ์ฉํด ์ปจํ ์ธ ๋ค์ด ์์ฑ๋๋ค๋ฉด ๊ฐ์ ธ์ฌ ์๊ฐ์๋ค
์ด ๊ฒฝ์ฐ, ํด๊ฒฐ์ฑ = Selenium
Selenium ์น ํ์ด์ง๋ฅผ ์๋์ผ๋ก ์ ์ด, ํ ์คํธ ํ ์ ์๋ ๋๊ตฌ
์ง์ ์ ์ผ๋ก ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์ ์ดํ๋ค
Request, BeautifulSoup์ผ๋ก ํฌ๋กค๋ง์ด ๋ถ๊ฐ๋ฅ ํ ๋, ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ค์ง ๋ชปํ ๊ฒฝ์ฐ Selenium ์ฌ์ฉ
์ ์ ํ์ด์ง = Requests + Beautiful Soup
- ์๋ฒ๋ก๋ถํฐ ํ ๋ฒ ์์ฒญํ๋ฉด ๋ณํ์ง ์๋ ํํ์ html๋ก ์์ฑ๋ ํ์ด์ง
- ์น ์๋ฒ๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ด ๋ค์ด์ฌ๋ ๋ง๋ค ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋์ html ํ์ผ์ ๊ทธ๋๋ก ๋ฐํํ๋ค
- ์๋ฒ ์ธก์์ ๋ฏธ๋ฆฌ ์ค๋น๊ฐ ๋์ด ์๊ธฐ ๋๋ฌธ์, ํด๋ผ์ด์ธํธ ์ธก์์ ๋ณ๋ค๋ฅธ ์ฒ๋ฆฌ ์์ด ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ์ ํ์
๋์ ํ์ด์ง = Selenium
- ์น ์๋ฒ๋ก๋ถํฐ html์ ๋ฐ์์จ ๋ค์, ๋ธ๋ผ์ฐ์ ๊ฐ ํด์ํ๊ณ ์คํํ๋ฉด์ javascript ๊ฐ์ ์คํฌ๋ฆฝํธ ์ธ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์ผ๋ก ์นํ์ด์ง๋ฅผ ๋ง๋ ๋ค
- ์ด๋ ๊ฒ ํ์ฑ๋ html ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ณ , ์ ๋ ฅ, ํด๋ฆญ,์คํฌ๋กค ํ ๋ ํ๋ฉด์ด ๋ณ๊ฒฝ๋๋ ๋ฑ์ ์ํธ ์์ฉ์ด ํ์ํ ์นํ์ด์ง์์ ์ฌ์ฉ
Selenium์ ํ์ฉํ์ฌ ๋ด์ค ํฌ๋กค๋ง
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
# selenium์ผ๋ก ์น๋๋ผ์ด๋ฒ ์คํ
service=Service(executable_path=ChromeDriverManager().install())
# ํฌ๋กฌ ์น ๋๋ผ์ด๋ฒ๊ฐ ์ด๋์ ์์นํด ์๋ค๋ ์๋ ค์ฃผ๋ ๊ฒฝ๋ก ์๋ฆฌ์ ํฌ๋กฌ๋๋ผ์ด๋ฒ ๋งค๋์ ์ค์นํ ๊ฐ์ ๋ฃ๊ธฐ
driver = webdriver.Chrome(service=service)
#url ์ ๋ฌ
url='https://news.kbs.co.kr/news/pc/category/category.do?ref=pSiteMap#20241017&1'
driver.get(url)
# ๊ธฐ๋ค๋ ค๋ฌ๋ผ๋ ๊ฐ์ ์ ๋ฌ : ์ต๋ 10์ด ๊ธฐ๋ค๋ฆฌ๊ธฐ
wait=WebDriverWait(driver,10)
# ๋๋ผ์ด๋ฒ ์ ๊ทผ > ํ์ด์ง ์์ค ๊ฐ์ ธ์ค๊ธฐ
html=driver.page_source
#๋๋ผ์ด๋ฒ ์ข
๋ฃ
driver.quit()
๋๋ผ์ด๋ฒ๋ฅผ ์ข ๋ฃํ์ง ์์ผ๋ฉด ๊ณ์ ์คํ๋๋ ๊ผญ ์ข ๋ฃ ์ฝ๋๋ฅผ ์จ์ผ ํฉ๋๋ค.
soup=BeautifulSoup(html,'html.parser')
box_contents=soup.find_all('a',class_='box-content flex-style')
box_contents
์ด๋ฒ์๋ ์ํ๋ ๋ด์ฉ์ด ์ ๋๋ก ๋ด๊ฒผ์ต๋๋ค.
์ํ๋ ์ ๋ณด๋ง ๊ฐ์ ธ์ค๊ธฐ
https://news.kbs.co.kr/news/pc/view/view.do?ncd=8083891
BBC “๋ฌ ๊ทน๋ ๊ตฐ์ฌ๊ธฐ์ง์ ๋ถํ์ธ ๋์ฐฉ…์ธ์์ ํ์ธ ๋ชปํด”
์ ค๋ ์คํค ์ฐํฌ๋ผ์ด๋ ๋ํต๋ น์ด ๋ถํ์ ๋ฌ์์ ํ๋ณ์ ํ์ธํ๋ค๊ณ ์ฃผ์ฅํ๋ ๊ฐ์ด๋ฐ ์๊ตญ BBC ๋ฐฉ์ก์ด ํ์ง ์ทจ...
news.kbs.co.kr
ํด๋น ๊ธฐ์ฌ๋https://news.kbs.co.kr + /news/pc/view/view.do?ncd=808391๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
url="http://news.kbs.co.kr" + box_contents[0]['href']
url
๋ฐ์ค ์ปจํ ์ธ ์์ ๊ฐ์ฅ ์ฒซ๋ฒ์งธ ๊ธฐ์ฌ๋ฅผ ๊ฐ์ ธ์จ ๋ค์ href์ ํํ๋ฉด url์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
# ํ์ดํ ์ถ๋ ฅ
title=box_contents[0].find('p',class_='title').text
title
# ๋ณธ๋ฌธ ์ถ๋ ฅ
body=box_contents[0].find('p',class_='news-text').text
body
# ๋ ์ง ์ถ๋ ฅ
date=box_contents[0].find('span',class_='date').text
date
์ด๋ฐ์์ผ๋ก ์ํ๋ ๊ธฐ์ฌ๋ง ์ ํํด์ ์ ๋ชฉ,๋ณธ๋ฌธ,๋ ์ง๋ฅผ ์ถ๋ ฅํ ์ ์์ต๋๋ค.
for๋ฌธ์ ์ฌ์ฉํด ๋ฐ์ดํฐ ์ถ์ถ
# ์ํ๋ ๋ถ๋ถ๋ค๋ง ์ฐพ์์, ๋ฆฌ์คํธ์ ๋ด๊ณ , ๋ฐ์ดํฐ ํ๋ ์์ผ๋ก ๋ง๋ค๊ธฐ
# ๋น ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ
url_list=[]
title_list=[]
body_list=[]
date_list=[]
for box_content in box_contents:
url = "http://news.kbs.co.kr" + box_content['href']
title = box_content.find('p',class_='title').text
body = box_content.find('p',class_='news-text').text
date = box_content.find('span',class_='date').text
url_list.append(url)
title_list.append(title)
body_list.append(body)
date_list.append(date)
box_contents์๋ 12๊ฐ์ ๋ด์ฉ์ด ๋ด๊ธด ๋ฆฌ์คํธ์ ๋๋ค.
๊ทธ ๋ฆฌ์คํธ๋ฅผ ๋๋ฉด์ ๋ด์ฉ๋ค์ ๊ฐ์ ธ์ต๋๋ค.
# ๋ฐ์ดํฐ ์ ์ฅ
data={'๋ด์คurl':url_list,'์ ๋ชฉ':title_list,'๋ด์ฉ':body_list,'๋ ์ง':date_list}
df=pd.DataFrame(data)
df
์ ๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ต๋๋ค.
ํ์ด์ง๋ค์ด์ ์ ํ์ฉํด ์ฌ๋ฌ ํ์ด์ง ํฌ๋กค๋ง
1ํ์ด์ง๋ง์ด ์๋๋ผ 1~13ํ์ด์ง๋ฅผ ๋๋ฉด์ ํฌ๋กค๋ง์ ํด๋ณด๊ฒ ์ต๋๋ค.
# ๋น ๋ฆฌ์คํธ ๋ง๋ค๊ธฐ
url_list=[]
title_list=[]
body_list=[]
date_list=[]
#์๋น์ค ๋ณ์ ์ค์
service=Service(executable_path=ChromeDriverManager().install())
#1. ํ์ด์ง๋ฅผ ๋๋ฉด์ ์์
์ ์ํ
for page_num in range(1,14):
#Selenium์ผ๋ก ์น ๋๋ผ์ด๋ฒ๋ฅผ ์คํ
driver = webdriver.Chrome(service=service)
#url ์ ๋ฌ
url=f'https://news.kbs.co.kr/news/pc/category/category.do?ref=pSiteMap#20241017&{page_num}'
driver.get(url)
# ๊ธฐ๋ค๋ ค๋ฌ๋ผ๋ ๊ฐ์ ์ ๋ฌ : ์ต๋ 10์ด ๊ธฐ๋ค๋ฆฌ๊ธฐ
wait=WebDriverWait(driver,10)
# ๋๋ผ์ด๋ฒ ์ ๊ทผ > ํ์ด์ง ์์ค ๊ฐ์ ธ์ค๊ธฐ
html=driver.page_source
#๋๋ผ์ด๋ฒ ์ข
๋ฃ
driver.quit()
#2. BeautifulSoup ์ฌ์ฉํด์ ํ์ฑํ๊ณ , ํ๊ทธ๋ฅผ ์ฐพ์์ ๋ด์์ค
soup=BeautifulSoup(html,'html.parser')
box_contents=soup.find_all('a',class_='box-content flex-style')
#3. ๋ฐ์ค ๋ฐ์ดํฐ๋ค์ ํ๋์ฉ ๋๋ฉด์ ๋ฆฌ์คํธ์ ๋ฐ์ดํฐ๋ฅผ ๋ด์
for box_content in box_contents:
url = "http://news.kbs.co.kr" + box_content['href']
title = box_content.find('p',class_='title').text
body = box_content.find('p',class_='news-text').text
date = box_content.find('span',class_='date').text
url_list.append(url)
title_list.append(title)
body_list.append(body)
date_list.append(date)
#4. ๋ฐ์ดํฐ ํ๋ ์์ผ๋ก ๋ฐ์ดํฐ ์ ์ฅ
data={'๋ด์คurl':url_list,'์ ๋ชฉ':title_list,'๋ด์ฉ':body_list,'๋ ์ง':date_list}
df=pd.DataFrame(data)
df
1~13 ํ์ด์ง์ ๋ด์ค๋ค์ด ๋ชจ๋ ํฌ๋กค๋ง ๋์์ต๋๋ค.