python/python_selenium
Selenium 활용2
몽자비루
2023. 4. 29. 01:45
import requests
from bs4 import BeautifulSoup
header = {'User-Agent':("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36")
,"Accept-Language":"ko-KR,ko"} # 한글 언어 웹페이지를 불러옴
url = "<https://play.google.com/store/games>"
res = requests.get(url, headers=header)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml")
# with open("movie.html", "w", encoding="utf8") as f:
# f.write(soup.prettify()) # html 문서를 보기좋게 출력
# 처음 보이는 5개의 헤더만 가져옴
games_title = soup.find_all("header", attrs = {"class":"oVnAB"})
print(len(games_title))
for game in games_title:
title = game.find("div", attrs = {"class":"kcen6d"}).get_text()
print(title)
- user-agent 없이 https://play.google.com/store/games 접근 시 미국버전으로 나옴
ㄴ 헤더가 다르거나 언어가 다르면 다른 방식으로 뿌려좀 - 한국 버전으로 받기 위해 user-agent 입력 + 언어를 한국어로 설정함.
- f.write(soup.prettify()) : 가져온 소스를 보기좋게 정렬함.
from bs4 import BeautifulSoup
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.maximize_window()
url = "<https://play.google.com/store/games>"
browser.get(url)
# 브라우저 로딩이 끝날때까지 기다림
time.sleep(1)
# 스크롤 내리기
# 윈도우에서 1080 위치로 스크롤을 내린다(모니터 해상도)
browser.execute_script("window.scrollTo(0,1080)")
# 화면 가장 아래로 스크롤 내리기
# document.body.scrollHeight = 스크롤하지 않았을 때 전체 높이를 구함.
# 아래 작업을 반복하여 화면높이 변화가 없을 때까지 스크롤 내림.
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
interval = 2
pre_height = browser.execute_script("return document.body.scrollHeight")
# 현재와 이전 높이가 같아질때까지 스크롤을 최하단으로 내림
while True:
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
# 페이지 로딩 대기
time.sleep(interval)
curr_height = browser.execute_script("return document.body.scrollHeight")
if pre_height == curr_height:
break
pre_height = curr_height
print("스크롤 완료")
- execute_script(동적 이벤트) : execute_script : js 코드를 인자로 넣어 동적 이벤트 작성 가능.
ㄴ "window.scrollTo(x,y))" : x, y위치로 스크롤을 내림
ㄴ "window.scrollTo(x,document.body.scrollHeight): 화면 최하단으로 이동함.
ㄴ return document.body.scrollHeight : 스크롤바에 감춰진 영역을 포함한 높이 return
ㄴ document.body.scrollwidth : 스크롤바에 감춰진 영역을 포함한 너비를 의미함. - while + 현재 페이지와 이전 페이지 높이를 비교하여 끝까지 스크롤함.
# header = {'User-Agent':("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
# "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36")
# ,"Accept-Language":"ko-KR,ko"} # 한글 언어 웹페이지를 불러옴
# url = "<https://play.google.com/store/games>"
# res = requests.get(url, headers=header)
# res.raise_for_status()
# soup = BeautifulSoup(res.text, "lxml")
soup = BeautifulSoup(browser.page_source, "lxml")
# 각 게임 범위 가져옴 (제목, 가격정보, 할인여부, 링크)
# div의 class 가 "kcen6d" 혹은 "kMqehf" 혹은 "kW9Bj" 인것 모두 가져오는 방법
# games = soup.find_all("div", attrs={"class":["kcen6d","kMqehf", "kW9Bj"]})
# 타이틀 정보
games_title = soup.find_all("header", attrs = {"class":"oVnAB"})
print(len(games_title))
for game in games_title:
# 타이틀정보 출력
print(game.div.span.get_text())
# 제목, 가격정보, 할인여부, 링크가 포함된 div로 이동
games_list = game.find_next_sibling("div")
games_list = games_list.find_all("div", attrs = {"class":"VfPpkd-aGsRMb"})
# 하위 제목 정보 출력
for n, game_list in enumerate(games_list,1):
# 제목 정보 가져오기
# span element 중에서 sT93pb,DdYX5,OnEJge 세가지 클래스를 가지고 있는 모든 element를 찾음
title = game_list.select_one("span.sT93pb.DdYX5.OnEJge").get_text()
price = ""
# 가격 정보 가져오기 (할인중이지 않은 class와 할인중 class가 다르다.)
origin_price = game_list.select_one("span.sT93pb.w2kbF.ePXqnb")
prior_price = game_list.select_one("span.sT93pb.JUF8md.ePXqnb")
# 원래 가격이 존재한다면
if origin_price:
price = origin_price.get_text()
if price == "" :
price="무료"
else :
price = "가격정보 없음"
# 할인 시, 할인 가격 + 안내 가져오기
if prior_price:
# 할인 전 가격
price = game_list.select_one("span.sT93pb.w2kbF.Q64Ric").get_text()
price = prior_price.get_text() +"->"+ price+"(할인중)"
# 링크
link = game_list.select_one("a.Si6A0c.Gy4nib")["href"]
print (str(n)+"번째 게임 : ",title ," ", price," ", "<https://play.google.com>"+link)
print("-"*100)
input("종료하려면 enter을 입력하세요")
- selenium과 bs4를 동시에 사용 : res.text 대신 browser.page_source 를 사용.
- class 가 “A" or "B" or "C" 인 div 모두 가져오기 : soup.find_all(”div”,”attrs={”class”:[”A”,”B”,”C”]}
- select / select_one : find_all/find 와 비슷한 역할.
ㄴ tag : 태그 이름으로 찾음
ㄴ .class : 클래스 이름으로 찾음.
ㄴ tag.class.class… : 여러 클래스인 element를 가져올 수 있다.
ㄴ element#id : id 이름으로 찾음 (연속X)
ㄴ tag > child_tag > child_tag : 부모자식 경로로 이동가능
ㄴ [attribute] : 태그 안의 속성을 찾음
ㄴ #id>tag.class : 아이디 이름으로 찾은 뒤 자식태그 중 클래스이름으로 찾음