▶ select 태그 선택 테스트
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import Select
url = 'https://www.selenium.dev/selenium/web/formPage.html'
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=webdriver.ChromeOptions())
driver.get(url)
select = Select(driver.find_element(By.NAME, 'selectomatic'))
# 인덱스를 기준으로 선택하기
# select.select_by_index(1)
# 보여지는 선택값 텍스트로 선택하기
# select.select_by_visible_text('Four')
# option 요소의 값으로 선택하기
# select.select_by_value('four')
# select 태그에 onchange 옵션이 있어서 Select 클래스를 사용할 수 없는 경우
driver.find_element(By.CSS_SELECTOR, 'option[value="four"]').click() # 직접 click 함수를 호출해야만 작동함
[실습] yes24에서 파이썬 도서 검색하기
- yes24 사이트에서 파이썬 도서 검색 후 평점 9.6 이상인 도서 제목과 가격, 평점 가져오기
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=webdriver.ChromeOptions())
driver.get('https://www.yes24.com')
# 검색어 입력
ele = driver.find_element(By.CSS_SELECTOR, '#query')
ele.send_keys('파이썬')
ele.send_keys(Keys.ENTER)
# 검색어 화면 노출설정 변경
select = Select(driver.find_element(By.ID, 'stat_gb'))
driver.find_element(By.CSS_SELECTOR, 'option[value="120"]').click()
page = 1
while True:
time.sleep(5)
# 도서 별 info 영역 불러오기
bs = BeautifulSoup(driver.page_source, 'lxml')
books = bs.find('ul', attrs={'id':'yesSchList'})
books = books.find_all('div', attrs={'class':'itemUnit'})
# 별점 필터 걸기 (9.6이상)
filtered_book = {}
for book in books:
book_name = book.find('a', attrs={'class':'gd_name'})
rating = book.find('span', attrs={'class':'rating_grade'})
try:
rating = rating.find('em', attrs={'class':'yes_b'})
except:
continue
if float(rating.text) >= 9.6:
filtered_book[book_name.text] = rating.text
print(book_name.text, rating.text)
print(len(books), len(filtered_book))
print(f'페이지 번호: {page}')
print('END')
page += 1
try:
time.sleep(5)
driver.find_element(By.CSS_SELECTOR, f'#goodsListWrap > div.sGoodsPagen > div > a:nth-child({page})').click()
except: break
driver.find_element(By.CSS_SELECTOR, '#goodsListWrap > div.sGoodsSecArea > div > span.baseFilter > a:nth-child(6)').click()
soup = BeautifulSoup(driver.page_source, 'lxml')
book_list = soup.find('ul', attrs={'id':'yesSchList'})
books = book_list.find_all('li')
# print(len(books)) # 130개
page = 1
while True:
for book in books:
title = book.find('a', attrs={'class':'gd_name'})
# <em class='yes_b'> 태그가 가격과 평점에서 동일하기 때문에 상위 태그를 이용
price = book.find('strong', attrs={'class':'txt_num'})
rating = book.find('span', attrs={'class':'rating_grade'})
if not rating: continue # 평점이 없는 도서는 pass
rating = rating.find('em', attrs={'class':'yes_b'}).text # 범위를 좁혀서 평점 값만 가져옴
if float(rating) < 9.6: continue
print(f'{title.text} | {price.text} | {rating}')
page += 1
# 다음 페이지 클릭
time.sleep(3)
driver.find_element(By.CSS_SELECTOR, f'#goodsListWrap > div.sGoodsPagen > div > a:nth-child({page})').click() # 페이지 번호의 CSS 값
[실습] 다음 영화 사이트에서 박스오피스 1위 영화의 감상평 및 평점 수집
- 감상평을 수집하여 텍스트 파일로 저장하기
- 평점을 수집하여 csv 파일로 저장하기
import csv
with open('rating.csv', 'w') as f:
writer = csv.writer(f):
writer.writerow(ratings) # ratings : 평점을 모아놓은 리스트 객체
* 스크래핑 순서
Selenium : 다음 영화 접속 (movie.daum.net) -> '랭킹' 링크 클릭 -> '박스오피스' 링크 클릭 -> 1위 영화를 클릭 -> '평점' 클릭 -> 마지막 평점까지 스크롤
BeautifulSoup : 사용자별 감상평 및 평점 수집 -> 수집된 정보들은 리스트에 저장 -> 파일 저장!
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup
# 페이지가 로드될 때까지 기다리는 시간
SCROLL_PAUSE_TIME = 1
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=webdriver.ChromeOptions())
driver.get('https://movie.daum.net')
driver.find_element(by=By.LINK_TEXT, value='랭킹').click()
driver.find_element(by=By.LINK_TEXT, value='박스오피스').click()
# 박스오피스 1위 영화 클릭
driver.find_element(By.CSS_SELECTOR, '#mainContent > div > div.box_boxoffice > ol > li:nth-child(1) > div > div.thumb_cont > strong > a').click()
# 평점 탭 클릭
time.sleep(SCROLL_PAUSE_TIME)
driver.find_element(by=By.LINK_TEXT, value='평점').click()
last_height = driver.execute_script('return document.body.scrollHeight')
# 스크롤 횟수
scroll_cnt = 0
while True:
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
scroll_cnt += 1
time.sleep(SCROLL_PAUSE_TIME)
new_height = driver.execute_script('return document.body.scrollHeight')
print(f'last height:{last_height}, new height:{new_height}, scroll count:{scroll_cnt}')
if last_height != new_height:
last_height = new_height
else:
try:
ele = driver.find_element(By.CSS_SELECTOR, '#alex-area > div > div > div > div.cmt_box > div.alex_more > button')
ele.click()
print('평점 더보기 클릭')
except:
break
soup = BeautifulSoup(driver.page_source, 'lxml')
ratings = []
comments =[]
ele = soup.find('ul', attrs={'class':'list_comment'}) # 전체 영역 선택
ele = ele.find_all('li') # 모든 유저에 대한 감상평 가져오기
for e in ele:
rating = e.select_one('div > div').text # li 밑에 div 밑에 div에 있는 평점 가져오기
ratings.append(int(rating)) # 정수로 바꿔줌
# 감상평이 이모티콘으로 되어 있는(텍스트가 없는) 경우에 예외 발생
try:
comment = e.select_one('div > p').text # li 밑에 div 밑에 p에 있는 감상평 가져오기
except:
continue
comment = comment.replace('\n', ' ') # 한줄의 형태로 변환해줌
comments.append(comment)
print(f'네티즌 평점: {sum(ratings) / len(ratings):.1f}점')
import csv
import os
with open('ratings.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(ratings)
print('평점 저장 완료')
with open('comments.txt', 'a', encoding='utf-8') as f:
for comment in comments:
f.write(comment+'/n')
print('감상평 저장 완료')
▶ iframe을 사용한 웹 페이지 스크래핑 하기
- iframe의 id 값을 찾는다
- frame = driver.find_element(By.ID, 'entryIFrame')
- 해당 iframe으로 switch
- driver.switch_to.frame(frame)
- 이 후 iframe내의 element를 검색하여 데이터를 스크래핑 한다
- iframe내의 스크래핑 작업이 끝난 루 기본 frame의 내용을 스크래핑 하기 위해 기본 frame으로 전환한다
- driver.switch_to.default_content()
'데이터 분석 > 웹 스크래핑' 카테고리의 다른 글
[Web Scrapping 과목평가] (0) | 2023.11.07 |
---|---|
[Web Scrapping 실습] Auto Crawler (0) | 2023.11.06 |
[Web Scrapping] XPath (XML Path Language) (0) | 2023.11.01 |
[Web Scrapping 실습] Selenium (0) | 2023.11.01 |
[Web Scrapping 실습] BeautifulSoup (0) | 2023.11.01 |