# 1、安装: pip install selenium
# 2、启用无界面窗口
#(1) 之前的版本都是使用webdriver.PhantomJs(),不过不建议用了,这儿也就不说了
# (2)现在使用这样的方式实现无弹窗爬虫
from selenium import webdriver #导入selenium包下的webdriver包
from time import sleep #一般使用selenium自动化测试,都会使用到sleep用于等待网页加载或者反爬虫
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=options) #给属性赋值
driver.get('http://www.baidu.com')
print(driver.page_source) #获取网页源代码
# 3、测试driver方法
driver = webdriver.Chrome()
print(dir(driver))
'''['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__',
'__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_file_detector', '_is_remote', '_mobile', '_switch_to', '_unwrap_value',
'_web_element_cls', '_wrap_value', 'add_cookie', 'application_cache', 'back',
'capabilities', 'close', 'command_executor', 'create_options', 'create_web_element',
'current_url', 'current_window_handle', 'delete_all_cookies', 'delete_cookie',
'desired_capabilities', 'error_handler', 'execute', 'execute_async_script',
'execute_cdp_cmd', 'execute_script', 'file_detector', 'file_detector_context',
'find_element', 'find_element_by_class_name', 'find_element_by_css_selector',
'find_element_by_id', 'find_element_by_link_text', 'find_element_by_name',
'find_element_by_partial_link_text', 'find_element_by_tag_name', 'find_element_by_xpath',
'find_elements', 'find_elements_by_class_name', 'find_elements_by_css_selector',
'find_elements_by_id', 'find_elements_by_link_text', 'find_elements_by_name',
'find_elements_by_partial_link_text', 'find_elements_by_tag_name',
'find_elements_by_xpath', 'forward', 'fullscreen_window', 'get', 'get_cookie',
'get_cookies', 'get_log', 'get_network_conditions', 'get_screenshot_as_base64',
'get_screenshot_as_file', 'get_screenshot_as_png', 'get_window_position',
'get_window_rect', 'get_window_size', 'implicitly_wait', 'launch_app', 'log_types',
'maximize_window', 'minimize_window', 'mobile', 'name', 'orientation', 'page_source',
'quit', 'refresh', 'save_screenshot', 'service', 'session_id', 'set_network_conditions',
'set_page_load_timeout', 'set_script_timeout', 'set_window_position', 'set_window_rect',
'set_window_size', 'start_client', 'start_session', 'stop_client', 'switch_to',
'switch_to_active_element', 'switch_to_alert', 'switch_to_default_content',
'switch_to_frame', 'switch_to_window', 'title', 'w3c', 'window_handles']'''
driver.get('http://wwww.baidu.com') #浏览器加载网址url
# (1)属性测试:
print(driver.current_url) #获取当前页面的url
# https://www.baidu.com/
print(driver.title) #获取当前页面的标题
# 百度一下,你就知道
print(driver.page_source) #获取页面的html源码
print(driver.current_window_handle) #获取当前窗口句柄
# CDwindow-BB417C5B670D0D7299EF011E62AB5147
print(driver.window_handles) #获取所有窗口的句柄,返回值为一个列表
# ['CDwindow-BB417C5B670D0D7299EF011E62AB5147']
#(2)方法测试
#00===========查找一个元素的方法=======================
btn = driver.find_element_by_id('su') #通过id属性查找
btn = driver.find_element_by_class_name('s_btn') #通过classname查找
btn = driver.find_elements_by_xpath('//*[@id="su"]') #通过xPath查找
btn = driver.find_element_by_css_selector('#su') #通过标签选择器进行查找
# 有标签选择器就可以通过属性定位元素
driver.find_element_by_css_selector('[id="su"]') #通过id属性来查找元素
newsLink = driver.find_element_by_link_text('新闻') #通过全部超链接文本查找元素
newsLink = driver.find_element_by_partial_link_text('闻') #通过部分超链接文本查找元素
input = driver.find_element_by_tag_name('input') #通过标签名查找元素
from selenium.webdriver.common.by import By
btn = driver.find_element(By.ID, 'su') #通过By模块来选择查找元素的方式
#00======查找多个元素的方法,就是上边方法中element改为elements,返回值为元素列表======
#00======其他方法
newsLink.click() #测试
sleep(5) #测试
driver.forward() #浏览器向前
sleep(2)
driver.back() #浏览器向后
driver.refresh() #刷新网页
driver.minimize_window() #最小化浏览器窗口
driver.maximize_window() #最大化浏览器窗口
driver.set_window_size(800,600) #设置窗口大小
print(driver.get_window_size()) #获取窗口的大小
print(driver.get_window_position()) #获取当前窗口坐标
driver.get_screenshot_as_file('gaofei1.png') #截图
driver.save_screenshot('gaofei2.png')
print(driver.get_screenshot_as_png()) #无参,返回png格式的二进制图片内容
driver.implicitly_wait(5) #隐式等待
#通过一定的时长等待页面上某一元素加载完成。
# 若提前定位到元素,则继续执行。若超过时间未加载出,则抛出NoSuchElementException异常
# driver.switch_to.frame(id或name属性值) #111需要测试
#切换到新表单(同一窗口)。若无id或属性值,可先通过xpath定位到iframe,再将值传给switch_to_frame()
driver.switch_to.parent_frame() #跳出当前以及表单,该方法默认对应于离它最近的switch_to.frame()方法
driver.switch_to.default_content() #跳回最外层的页面
# driver.switch_to.window(窗口句柄) #切换到新窗口
#120参数为什么?
# driver.switch_to.alert() #警告框处理。处理JavaScript所生成的alert,confirm,prompt.
# driver.execute_script(js) #调用js
print(driver.get_cookies()) #获取当前窗口的所有cookie信息
# print(driver.get_cookies(cookie_name)) #返回字典的key为“cookie_name”的cookie信息,就是从cookies中获取
# driver.add_cookie(cookie_dict) #添加cookie,字典形式必须有key,value值
# driver.delete_cookie(cookie_name) #通过cookiename删除字典中的cookie
# driver.delete_all_cookies() #删除所有的cookie信息
#4、测试元素属性方法
print(dir(btn))
'''['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_execute', '_id', '_parent', '_upload', '_w3c', 'clear', 'click', 'find_element',
'find_element_by_class_name', 'find_element_by_css_selector', 'find_element_by_id',
'find_element_by_link_text', 'find_element_by_name', 'find_element_by_partial_link_text',
'find_element_by_tag_name', 'find_element_by_xpath', 'find_elements',
'find_elements_by_class_name', 'find_elements_by_css_selector', 'find_elements_by_id',
'find_elements_by_link_text', 'find_elements_by_name',
'find_elements_by_partial_link_text', 'find_elements_by_tag_name',
'find_elements_by_xpath', 'get_attribute', 'get_property', 'id', 'is_displayed',
'is_enabled', 'is_selected', 'location', 'location_once_scrolled_into_view', 'parent',
'rect', 'screenshot', 'screenshot_as_base64', 'screenshot_as_png', 'send_keys', 'size',
'submit', 'tag_name', 'text', 'value_of_css_property']'''
#00===属性===
btn = driver.find_element(By.ID,'su')
print(btn.size) #获取标签大小
print(btn.text) #获取标签中间文本内容
print(btn.tag_name) #获取标签名
#00===方法===
input1 = driver.find_element_by_id('kw')
input1.send_keys('gaofei')
btn.click() #单击元素
sleep(2)
input1.clear() #清除文本,元素本身必须是可以编辑的文本才可以清除
input1.send_keys('gaofei') #输入文字或者键盘按键
from selenium.webdriver.common.keys import Keys #导入键盘值类
input1.send_keys('a',Keys.ENTER) #可以多次输入值
print(input1.get_attribute('id')) #获取属性值
print(div1.value_of_css_property('color')) #获取CSS样式表中的属性
print(input1.is_displayed()) #返回元素是否可见(True/False)
print(input1.is_selected()) #返回元素是否被选中
#element.find_element*() #用于二次定位元素,和driver一样
#5、补充
# (1)超时时间
driver.set_page_load_timeout(10)
# 设置页面完全加载的超时时间,完全加载即完全渲染完成,同步和异步脚本都执行完
driver.set_script_timeout(5)
#设置异步脚本的超时时间
driver.implicitly_wait(5)
#识别对象的智能等待时间,上面有具体解释
# (2)iframe/frame窗口定位
# 如果iframe/frame 有name或者id属性则:
# driver.switch_to.frame(name/id)
#如果没有name,id那么可以先用xpath定位到iframe定位到iframe/frame,然后调用元素
# iframe = driver.find_elements_by_xpath('ifrmaexpath')
# driver.switch_to.frame(iframe)
#如果要跳出iframe,用
driver.switch_to.parent_frame() #跳出当前iframe
driver.switch_to_default.content() #跳回最外层的页面
# (3)不可见元素定位 -->不可以进行操作,否则报错selenium.common.exceptions.ElementNotVisibleException
# 如下百度登录代码,通过名称为tj_login查找的登录元素,有些是不可见的,所以加一个循环判断,找到可见元素(is_displayed())点击登录即可。
#点击登录:有些name为tj_login的元素为不可见的,点击可见的那个登录按钮即可。
#否则会报:ElementNotVisibleException
element0=driver.find_elements_by_name("tj_login")
for ele0 in element0:
if ele0.is_displayed():
ele0.click()
#(4)获取标签元素内部标签文本获取
print(div1.get_attribute('innerHTML')) #获取元素的内部 HTML, 包含所有的HTML标签
print(div1.get_attribute('textContent')) #只会得到文本内容,而不会包含 HTML 标签
print(div1.get_attribute('innerText')) #只会得到文本内容,而不会包含 HTML 标签,不建议使用,很多浏览器不支持
#注意:当某个要取元素内容的标签不是可见的,那么需要用get_attribute(属性名)来获取内容。因为Selenium WebDriver
# 只会与可见元素交互,所以获取隐藏元素的文本总是会返回空字符串
#(5)有很多人在切换窗口方面有很多的疑问,那么我整理了一下窗口的切换
#A、首先要知道:定位到的元素如果不在当前定位的窗口句柄中,那么就不能对该元素进行操作
#不然会报错:selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
#B、如果你是从窗口A中新打开一个窗口B,那么此时的浏览器的窗口句柄还在窗口A,所以你要进行对窗口B的操作,必须driver.switch_to.window(driver.window_handles[-1])进行切换,当然也可以用循环的方式进行切换
# 注意:当窗口B关闭的时候,当前的浏览器窗口句柄还在窗口B,所以也要进行窗口的切换
#C、如果你是从窗口A中打开的窗口B,那么此时的浏览器句柄默认就指向B(内部A,B其实使用的是同一个句柄,所以并不需要切换)
#D 如果同时存在窗口A,B,C那么要使用其中某一个窗口,也是直接切换就行
driver.switch_to.window('要切换的窗口句柄字符串')
#--------------driver关闭的方法如下,用于测试------------------------------------------
sleep(5)
driver.close() #关闭当前窗口,或最后打开的窗口。
driver.quit() #关闭所有关联窗口,并且安全关闭session。