레이블이 selenium인 게시물을 표시합니다. 모든 게시물 표시
레이블이 selenium인 게시물을 표시합니다. 모든 게시물 표시

2023년 1월 29일 일요일

python selenium 으로 post 사용하기

selenium post 

 selenium 에서 post 를 사용하기 위해서는 selenium-requests 라는 패키지를 설치해서 사용하는 방식이 있습니다. selenium-requests 를 사용하게 되면 selenium 으로 주로 사용했던 키동작이라던가 그런 부분을 사용을 할 수 없습니다.

그리고 selenium 과  selenium-requests 는 각각의 브라우저로 동작하기 때문에 필요한 부분에서만 처리를 하고자 하는 경우 web session 유지가 되지 않습니다. 예를 들어 selenium 를 이용하여 로그인 처리를 한 후 selenium-requests 를 이용하고자 한다면 로그인이 유지가 안된다는 뜻입니다.

그래서 selenium 으로만 post 할 수 있는 방법에 대해 알아 보았습니다.

아무곳이나 테스트할 수 없기 때문에 예전에 사용하던 flask 를 이용해서 간단하게 post 테스트 할 수 있는 환경을 만들었습니다.

from flask import Flask, make_response, jsonify, request

stock = {
	"fruit": {
		"apple": 10,
		"banana": 20
	}
}

app = Flask(__name__)

@app.route("/stock")
def get_stock():
	res = make_response(jsonify(stock), 200)
	return res
 
@app.route("/stock/<goods>")
def get_goods(goods):
	""" Returns a goods from stock """
	if goods in stock:
		res = make_response(jsonify(stock[goods]), 200)
		return res
	res = res = make_response(jsonify({"error": "Not found"}), 404)
	return res

@app.route("/stock/<goods>", methods=["POST"])
def create_goods(goods):
	""" Creates a new goods if it doesn't exist """
	req = request.get_data()
	print("create_goods")
	print(req)
	res = make_response(jsonify({"message": "goods created"}), 201)
	return res

if __name__ == '__main__':
	app.run(debug=True)

크게 내용은 없고 post가 들어오면 어떤 식으로 들어온 것인지 그대로 출력만 해줍니다.

그리고 다음으로는 selenium 을 래핑한 함수입니다. 이전 예제에서도 주로 사용했어서 

이름은 selenium_v1.py 로 지었습니다.

import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import os

class selenium_v:
	def __init__(self):
		self.driver = None
		self.download_path = None
		return
		
	def create_web_driver_chrome(self, headless=True, download_path=None):
		options = webdriver.ChromeOptions()
		options.add_argument('disable-gpu')
		options.add_experimental_option('excludeSwitches',['enable-logging'])
		
		if headless:
			options.add_argument('headless')
		
		if download_path!=None:
			self.download_path = os.path.abspath(download_path)
			prefs = {"download.default_directory":self.download_path}
			options.add_experimental_option("prefs",prefs)
		
		if self.driver!=None:
			self.driver.close()
		self.driver = None
		
		chromedriver_autoinstaller.install()
		
		try:
			self.driver = webdriver.Chrome(options=options)
			self.driver.implicitly_wait(10)
		except Exception as e:
			print("exception",e)
		
		return self.driver
		
	def download_wait(self, timeout_min=1):
		if self.download_path==None:
			print("error can not find download path")
			return -2
		path_to_downloads = self.download_path
		seconds = 0
		dl_wait = True
		sum_after = 0
		while dl_wait and seconds < timeout_min*60:
			time.sleep(5)
			dl_wait = False
			sum_before = sum_after
			sum_after = 0
			for fname in os.listdir(path_to_downloads):
				if fname.endswith('.crdownload'):
					sum_after += os.stat(path_to_downloads+'/'+fname).st_size
					dl_wait = True
			if dl_wait and seconds > 10 and sum_before == sum_after:
				print("download timeout")
				dl_wait = False
				return -1
			seconds += 5
		return seconds
	
	def get(self,url):
		if self.driver == None:
			return -1
		return self.driver.get(url)
		
	def close(self):
		if self.driver == None:
			return -1
		return self.driver.close()
		
	def save_page_source(self, filename):
		if self.driver == None:
			return -1
		html = self.driver.page_source
		try:
			f = open(filename, 'w', encoding = 'utf-8')
			f.write(html)
			f.close()
		except:
			print("exception",e)
		return 0
		
if __name__ == "__main__":
	sel = selenium_v()
	sel.create_web_driver_chrome(headless=True,download_path=".")
	print(sel.get("https://www.daum.net"))
	print(sel.driver.page_source)
	print(sel.get("https://www.python.org/ftp/python/3.9.11/python-3.9.11-embed-amd64.zip"))
	sel.download_wait()
	print(sel.driver.page_source)
	sel.save_page_source("test.html")

다음의 코드가 핵심 코드입니다.

import requests
import selenium_v1 as selenium_v
from bs4 import BeautifulSoup

def print_roundtrip(response, *args, **kwargs):
	format_headers = lambda d: '\n'.join(f'{k}: {v}' for k, v in d.items())
	print((""
		"---------------- request ----------------\n"
		"{req.method} {req.url}\n"
		"{reqhdrs}\n"
		"\n"
		"{req.body}\n"
		"---------------- response ----------------\n"
		"{res.status_code} {res.reason} {res.url}\n"
		"{reshdrs}\n"
		"\n"
		"{res.text}\n"
		"").format(
		req=response.request, 
		res=response, 
		reqhdrs=format_headers(response.request.headers), 
		reshdrs=format_headers(response.headers), 
	))
data1={"cat":1,"dog":2}
data2={"cat":3,"lion":4,"bird":2}
data3={"cat":3,"dog":4}

resp = requests.post('http://127.0.0.1:5000/stock/animal', data=data2, hooks={'response': print_roundtrip})


def get_script(url, params):
	post_script = '''
	function post_to_url(path, params, method) {
		method = method || "post";
		var form = document.createElement("form");
		form._submit_function_ = form.submit;
		form.setAttribute("method", method);
		form.setAttribute("action", path);
		for(var key in params) {
			var hiddenField = document.createElement("input");
			hiddenField.setAttribute("type", "hidden");
			hiddenField.setAttribute("name", key);
			hiddenField.setAttribute("value", params[key]);
			form.appendChild(hiddenField);
		}
		document.body.appendChild(form);
		form._submit_function_();
	}

	'''
	run_script = f'post_to_url("{url}",'
	run_script = run_script + "{"
	first = True
	for odata in params:
		if first == False:
			run_script = run_script + ","
		else:
			first = False
		run_script = run_script + odata + ':' + str(params[odata])
	run_script = run_script + "} )"
	#print(post_script + run_script)
	return post_script + run_script

sel = selenium_v.selenium_v()
sel.create_web_driver_chrome(headless=True, download_path=".")
sel.driver.execute_script(get_script("http://127.0.0.1:5000/stock/animal", data1))
print(sel.driver.page_source)

# get page
#sel.get('http://127.0.0.1:5000/stock/animal')
#sel.driver.implicitly_wait(3)

requests 와 selenium 을 비교하기 위해서 requests 예제가 위쪽에 있습니다.

핵심은 selenium 의 execute_script 를 이용하게 됩니다.

스크립트를 실행시키기 위해서 스크립트를 구성하는 함수가 get_script 함수입니다.

get_script( 접속하고자 하는url 정보, 전달하고자 하는 data의 dict 타입 필요합니다. )

script의 내용은 javascript 형태로 form을 만들고 post를 하게 되는 내용입니다. default가 post가되고 get으로 구현할 수 도 있습니다.


실행 결과

서버쪽 실행 켤과를 살펴보면 아래와 같이 나오게 되는데 

앞쪽 결과가 requests로 넘긴 결과 입니다.

create_goods
b'cat=3&lion=4&bird=2'
127.0.0.1 - - [29/Jan/2023 20:31:41] "POST /stock/animal HTTP/1.1" 201 -
create_goods
b'cat=1&dog=2'
127.0.0.1 - - [29/Jan/2023 20:31:43] "POST /stock/animal HTTP/1.1" 201 -

차이가 없으며 출력 값이 다른 것은 보낼때 data1,data2 각각 다른 값을 보냈기에 다른것입니다.


보내는쪽 결과

아래는 requests 로 보낸 결과 입니다.

---------------- request ----------------
POST http://127.0.0.1:5000/stock/animal
User-Agent: python-requests/2.28.1
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Length: 19
Content-Type: application/x-www-form-urlencoded

cat=3&lion=4&bird=2
---------------- response ----------------
201 CREATED http://127.0.0.1:5000/stock/animal
Server: Werkzeug/2.2.2 Python/3.8.8rc1
Date: Sun, 29 Jan 2023 11:31:41 GMT
Content-Type: application/json
Content-Length: 33
Connection: close

{
  "message": "goods created"
}


아래는 다음 코드에 의해서 나오는 값입니다.

print(sel.driver.page_source)


<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">{
  "message": "goods created"
}
</pre></body></html>


2022년 10월 23일 일요일

python selenium 실전 사용과 BeautifulSoup로 정보 읽기

selenium 과 BeautifulSoup 그리고 크롬을 이용한 예제


web page의 원하는 부분을 읽어낼때는 크롬의 F12를 눌러 DevTools 를 이용합니다.

여기에서는 daum page의 "로또당첨번호" 라는 텍스트 위치를 읽어 내보도록 하겠습니다.


DevTools에서 마우스를 클릭해가면서 원하는 부분을 찾습니다.
그리고 마우스 우측 버튼을 눌러 Copy > Copy selector를 합니다.
여기에서는 아래와 같은 값이 되며 해당값은 CSS selector로 BeautifulSoup 에서 원하는 위치를 읽어낼때 사용하게 될것입니다.

#wrapSearch > div.slide_favorsch > ul:nth-child(2) > li:nth-child(1) > a

해당 부분이 왜 저렇게 되는지는 css selector 를 검색 해보시기 바랍니다.


selenium을 이용해 html 읽기

selenium 을 통해서 html을 읽는 예제는 아래와 같이 작업하였습니다.
아래 파일은 selenium_v1.py 로 저장하겠습니다.

import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import os

class selenium_v1:
	def __init__(self):
		self.driver = None
		self.download_path = None
		return
		
	def create_web_driver_chrome(self, headless=True, download_path=None):
		options = webdriver.ChromeOptions()
		options.add_argument('disable-gpu')
		options.add_experimental_option('excludeSwitches',['enable-logging'])
		
		if headless:
			options.add_argument('headless')
		
		if download_path!=None:
			self.download_path = os.path.abspath(download_path)
			prefs = {"download.default_directory":self.download_path}
			options.add_experimental_option("prefs",prefs)
		
		if self.driver!=None:
			self.driver.close()
		self.driver = None
		
		chromedriver_autoinstaller.install()
		
		try:
			self.driver = webdriver.Chrome(options=options)
			self.driver.implicitly_wait(10)
		except Exception as e:
			print("exception",e)
		
		return self.driver
		
	def download_wait(self, timeout_min=1):
		if self.download_path==None:
			print("error can not find download path")
			return -2
		path_to_downloads = self.download_path
		seconds = 0
		dl_wait = True
		sum_after = 0
		while dl_wait and seconds < timeout_min*60:
			time.sleep(5)
			dl_wait = False
			sum_before = sum_after
			sum_after = 0
			for fname in os.listdir(path_to_downloads):
				if fname.endswith('.crdownload'):
					sum_after += os.stat(path_to_downloads+'/'+fname).st_size
					dl_wait = True
			if dl_wait and seconds > 10 and sum_before == sum_after:
				print("download timeout")
				dl_wait = False
				return -1
			seconds += 5
		return seconds
	
	def get(self,url):
		if self.driver == None:
			return -1
		return self.driver.get(url)
		
	def close(self):
		if self.driver == None:
			return -1
		return self.driver.close()
		
	def save_page_source(self, filename):
		if self.driver == None:
			return -1
		html = self.driver.page_source
		try:
			f = open(filename, 'w', encoding = 'utf-8')
			f.write(html)
			f.close()
		except:
			print("exception",e)
		return 0
		
if __name__ == "__main__":
	sel = selenium_v1()
	sel.create_web_driver_chrome(headless=True,download_path=".")
	print(sel.get("https://www.daum.net"))
	print(sel.driver.page_source)
	print(sel.get("https://www.python.org/ftp/python/3.9.11/python-3.9.11-embed-amd64.zip"))
	sel.download_wait()
	print(sel.driver.page_source)
	sel.save_page_source("test.html")

여기 예제는 chrome 드라이버를 이용한 파일을 다운로드 하는 코드를 샘플로 작성하였고 실제 page는 sel.driver.page_source 가 됩니다.


import 에러 발생시

ModuleNotFoundError: No module named 'chromedriver_autoinstaller'

pip install chromedriver-autoinstaller


ModuleNotFoundError: No module named 'selenium'

pip install -U selenium


sel.driver.page_source 여기에 html 코드가 들어가는데는 시간이 좀 필요합니다. 그래서 조금 시간이 필요한데 driver.implicitly_wait(3) 함수를 이용해서 html 페이지가 로딩되도록 하겠습니다.


daum 페이지를 읽어 화면에 출력하는 코드

import selenium_v1


if __name__ == "__main__":
	sel = selenium_v1.selenium_v1()
	sel.create_web_driver_chrome(headless=True, download_path=".")
	print(sel.get("https://www.daum.net"))
	sel.driver.implicitly_wait(3)
	print(sel.driver.page_source)


BeautifulSoup 로 정보 읽기

import selenium_v1
from bs4 import BeautifulSoup


if __name__ == "__main__":
	sel = selenium_v1.selenium_v1()
	sel.create_web_driver_chrome(headless=True, download_path=".")
	# get page
	sel.get("https://www.daum.net")
	sel.driver.implicitly_wait(3)
	#print(sel.driver.page_source)

	soup = BeautifulSoup(sel.driver.page_source, "html.parser")
	result = soup.select('#wrapSearch > div.slide_favorsch > ul:nth-child(2) > li:nth-child(1) > a')
	print(f'type:{type(result)},result:{result}')
	for one in result:
		print(f'type:{type(one)},result:{one},href:{one.href},text:{one.text},get:{one.get("data-tiara-layer")}')

	result = soup.select_one('#wrapSearch > div.slide_favorsch > ul:nth-child(2) > li:nth-child(1) > a')
	print(f'type:{type(result)},result:{result}')

실행 결과

type:<class 'bs4.element.ResultSet'>,result:[<a class="link_favorsch" data-tiara-action-name="header-search-txt" data-tiara-layer="header search txt" href="https://search.daum.net/search?w=tot&amp;q=%EB%A1%9C%EB%98%90%EB%8B%B9%EC%B2%A8%EB%B2%88%ED%98%B8&amp;DA=NPI&amp;rtmaxcoll=LOT">로또당첨번호</a>]
type:<class 'bs4.element.Tag'>,result:<a class="link_favorsch" data-tiara-action-name="header-search-txt" data-tiara-layer="header search txt" href="https://search.daum.net/search?w=tot&amp;q=%EB%A1%9C%EB%98%90%EB%8B%B9%EC%B2%A8%EB%B2%88%ED%98%B8&amp;DA=NPI&amp;rtmaxcoll=LOT">로또당첨번호</a>,href:None,text:로또당첨번호,get:header search txt
type:<class 'bs4.element.Tag'>,result:<a class="link_favorsch" data-tiara-action-name="header-search-txt" data-tiara-layer="header search txt" href="https://search.daum.net/search?w=tot&amp;q=%EB%A1%9C%EB%98%90%EB%8B%B9%EC%B2%A8%EB%B2%88%ED%98%B8&amp;DA=NPI&amp;rtmaxcoll=LOT">로또당첨번호</a>


import 에러시

ModuleNotFoundError: No module named 'bs4'

pip install beautifulsoup4


BS4로 CSS select 하기

예제에 있듯이 select, select_one 두개의 메소드를 이용가능 합니다. select 메소드를 사용하게 되면 선택한 tag가 여러개라는 가정하에 list 형태로 묶이게 됩니다.

select_one 메소드는 첫번째 결과만 tag에 저장하게 됩니다.

결과로 돌아오는 tag는 기본적으로 text, href 를 이용하여 직접 읽을 수도 있지만 get 을 이용하여 읽을 수도 있습니다. 

아래 부분 참고

print(f'type:{type(one)},result:{one},href:{one.href},text:{one.text},get:{one.get("data-tiara-layer")}')

결론적으로 우리가 원하는 텍스트는 one.text에 저장되게 됩니다.


2022년 5월 9일 월요일

python selenium, chrome driver 파일 저장시 저장 위치 설정 다운로드 완료시 까지 대기

 selenium을 사용하다보면 가끔 저장받는 파일 위치를 설정할 필요가 있는 경우가 있습니다. 기본적으로 브라우저를 사용하기 때문에 브라우저 저장 위치로 설정이 됩니다. 그리고 파일이 완벽하게 다운로드 될때까지 기다려야 할 필요도 있기 때문에 이 부분에 대해 정리해서 함수로 만들어 봤습니다.

기본 구성은 selenium을 래핑해서 간단하게 만들어 봤습니다. 다운로드 받는 위치는 기본적으로 브라우저가 생성될때 설정이 됩니다. 그래서 create_web_driver_chrome 함수를 통해서 경로를 설정해야하며 내부적으로는 절대 경로로 변경하는 self.download_path = os.path.abspath(download_path) 함수를 사용하였습니다.

또한 이전에 사용하였던 chromedriver_autoinstaller 를 이용해서 크롬 버전이 맞지 않더라도 자동으로 다운로드 하도록 구현하였습니다.

http url중 자동으로 다운로드가 걸리게 되는 링크들이 있는데 크롬은 다운로드가 시작되면 crdownload라는 확장자 파일이 생깁니다. (여기에서는 python 예전 버전 다운로드 링크를 예제로 담아봤습니다.) download_wait()에서 해당 파일의 크기를 주기적으로 확인해서 크기 증가가 발생하지 않으면 오류로 판단해서 리턴하게 됩니다.


import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import os

class selenium_v1:
	def __init__(self):
		self.driver = None
		self.download_path = None
		return
		
	def create_web_driver_chrome(self, headless=True, download_path=None):
		options = webdriver.ChromeOptions()
		options.add_argument('disable-gpu')
		options.add_experimental_option('excludeSwitches',['enable-logging'])
		
		if headless:
			options.add_argument('headless')
		
		if download_path!=None:
			self.download_path = os.path.abspath(download_path)
			prefs = {"download.default_directory":self.download_path}
			options.add_experimental_option("prefs",prefs)
		
		if self.driver!=None:
			self.driver.close()
		self.driver = None
		
		chromedriver_autoinstaller.install()
		
		try:
			self.driver = webdriver.Chrome(options=options)
			self.driver.implicitly_wait(10)
		except Exception as e:
			print("exception",e)
		
		return self.driver
		
	def download_wait(self, timeout_min=1):
		if self.download_path==None:
			print("error can not find download path")
			return -2
		path_to_downloads = self.download_path
		seconds = 0
		dl_wait = True
		sum_after = 0
		while dl_wait and seconds < timeout_min*60:
			time.sleep(5)
			dl_wait = False
			sum_before = sum_after
			sum_after = 0
			for fname in os.listdir(path_to_downloads):
				if fname.endswith('.crdownload'):
					sum_after += os.stat(path_to_downloads+'/'+fname).st_size
					dl_wait = True
			if dl_wait and seconds > 10 and sum_before == sum_after:
				print("download timeout")
				dl_wait = False
				return -1
			seconds += 5
		return seconds
	
	def get(self,url):
		if self.driver == None:
			return -1
		return self.driver.get(url)
		
	def close(self):
		if self.driver == None:
			return -1
		return self.driver.close()
		
	def save_page_source(self, filename):
		if self.driver == None:
			return -1
		html = self.driver.page_source
		try:
			f = open(filename, 'w', encoding = 'utf-8')
			f.write(html)
			f.close()
		except:
			print("exception",e)
		return 0
		
if __name__ == "__main__":
	sel = selenium_v1()
	sel.create_web_driver_chrome(headless=True,download_path=".")
	print(sel.get("https://www.daum.net"))
	print(sel.driver.page_source)
	print(sel.get("https://www.python.org/ftp/python/3.9.11/python-3.9.11-embed-amd64.zip"))
	sel.download_wait()
	print(sel.driver.page_source)
	sel.save_page_source("test.html")


2023-03-28 업데이트

크롬드라이버가 버전업이 되면서 폴더 설정하는 부분이 동작 하지 않아서 소스 코드를 변경했습니다.

if headless:
# options.add_argument('headless')
# for chrome driver version up
options.add_argument('headless=new')

위와 같이 "headless=new" 로 변경해줘야하고

if sys.platform.startswith('win'):
self.download_path = self.download_path.replace("/", "\\")

path를 '/' 대신 "\" 를 사용해줘야 합니다. \\ 두개를 사용하는 이유는 \ 하나는 특수 문자라서 그렇습니다.

아래 변경한 전체 소스를 공유합니다.

Preview:

import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import os
import sys

class selenium_v1:
	def __init__(self):
		self.driver = None
		self.download_path = None
		return
		
	def create_web_driver_chrome(self, headless=True, download_path=None):
		options = webdriver.ChromeOptions()
		options.add_argument('disable-gpu')
		options.add_experimental_option('excludeSwitches',['enable-logging'])
		
		if headless:
			# options.add_argument('headless')
			# for chrome driver version up
			options.add_argument('headless=new')
		
		if download_path!=None:
			self.download_path = os.path.abspath(download_path)
			if sys.platform.startswith('win'):
				self.download_path = self.download_path.replace("/", "\\")
			prefs = {"download.default_directory":self.download_path}
			options.add_experimental_option("prefs",prefs)
		
		if self.driver!=None:
			self.driver.close()
		self.driver = None
		
		chromedriver_autoinstaller.install()
		
		try:
			self.driver = webdriver.Chrome(options=options)
			self.driver.implicitly_wait(10)
		except Exception as e:
			print("exception",e)
		
		return self.driver
		
	def download_wait(self, timeout_min=1):
		if self.download_path==None:
			print("error can not find download path")
			return -2
		path_to_downloads = self.download_path
		seconds = 0
		dl_wait = True
		sum_after = 0
		while dl_wait and seconds < timeout_min*60:
			time.sleep(5)
			dl_wait = False
			sum_before = sum_after
			sum_after = 0
			for fname in os.listdir(path_to_downloads):
				if fname.endswith('.crdownload'):
					sum_after += os.stat(path_to_downloads+'/'+fname).st_size
					dl_wait = True
			if dl_wait and seconds > 10 and sum_before == sum_after:
				print("download timeout")
				dl_wait = False
				return -1
			seconds += 5
		return seconds
	
	def get(self,url):
		if self.driver == None:
			return -1
		return self.driver.get(url)
		
	def close(self):
		if self.driver == None:
			return -1
		return self.driver.close()
		
	def save_page_source(self, filename):
		if self.driver == None:
			return -1
		html = self.driver.page_source
		try:
			f = open(filename, 'w', encoding = 'utf-8')
			f.write(html)
			f.close()
		except Exception as e:
			print("exception", e)
		return 0
		
if __name__ == "__main__":
	sel = selenium_v1()
	sel.create_web_driver_chrome(headless=True, download_path=".")
	print(sel.get("https://www.daum.net"))
	print(sel.driver.page_source)
	print(sel.get("https://www.python.org/ftp/python/3.9.11/python-3.9.11-embed-amd64.zip"))
	sel.download_wait()
	print(sel.driver.page_source)
	sel.save_page_source("test.html")





2022년 2월 6일 일요일

auto download chrome driver file(크롬 드라이버 파일 자동 설치 하기)

기본 지식

selenium에서 브라우저로서 크롬을 사용하기 위해서는 설치된 크롬 브라우저와 동일한 버전의 크롬 드라이버라는 것을 설치해야 합니다.

여기에서는 selenium 설치부터, 크롬 드라이버를 자동으로 설치하는 부분까지 다룹니다.


python에서 selenium 설치법

pip install selenium


크롬 드라이버 설치

selenium에서는 여러 종류의 브라우저를 실행시킬 수 있는데 그중 크롬이 대중적이고 사용하기 편해서 사용하다보면, 크롬 버전과 동일한 chrome driver를 다운로드 받아야합니다. 

해당 하는 버전은 크롬 브라우저창에서 아래 주소를 입력합니다.

chrome://version/

크롬 드라이버는 아래에서 입력합니다.

chromedriver.chromium.org/downloads


기본 예제

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time


driver = webdriver.Chrome()

driver.get("https://www.naver.com")

driver.implicitly_wait(3)


적절한 버전의 크롬 드라이버를 설치하지 않았을때 오류 문구

DevTools listening on ws://127.0.0.1:50815/devtools/browser/18099847-b9a2-4edc-a02e-7aa5b142da4c
Traceback (most recent call last):
  File "selenium_auto_chromedriver.py", line 8, in <module>
    driver = webdriver.Chrome()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 76, in __init__
    RemoteWebDriver.__init__(
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 83


크롬브라우저는 자체적으로 업데이트가 되어서 가끔 크롬 드라어버의 버전과 맞지 않는 경우가 있습니다.


크롬 드라이버를 자동으로 업데이트 하는 방법

설치

pip install chromedriver-autoinstaller


사용법

chromedriver_autoinstaller.install() 


예제

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

chromedriver_autoinstaller.install()

driver = webdriver.Chrome()

driver.get("https://www.naver.com")

driver.implicitly_wait(3)


막상 해보면 아래와 같은 오류가 나옵니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Traceback (most recent call last):
  File "selenium_auto_chromedriver.py", line 9, in <module>
    driver = webdriver.Chrome()
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 76, in __init__
    RemoteWebDriver.__init__(
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Failed to create Chrome process.


이게 발생하는 사유는 chromedriver를 다운로드하는데 시간이 걸려서 그런것 같습니다. 

몇차례 하다보면 정상 작동합니다.

이 부분은 고치려면 처음본 exception일때 

Message: session not created: This version of ChromeDriver only supports Chrome version 위 exception 일때만 크롬드라이버 install을 명령하도록 수정하면 될것입니다.