网络上有着很多这种类型的使用说明以及教程,但终归不是自己的。
遇到不会的时候还得不断的重复去百度,这样导致效率低下。
最终还是想着结合网上的教程,给自己归纳总结一部分库的使用,方便自己回顾。
安装步骤2:安装与计算机使用浏览器版本相对应的WebDriver
安装步骤3:下载完成解压后,将文件移动到一个配置了环境变量的文件夹中,例如Python环境的文件夹下。
可见即可爬
'''
功能如下:
自动弹出一个Chrome浏览器,浏览器首先会跳转至百度,然后输入Python,回车,等待3秒,自动关闭浏览器。
'''
import time
from selenium import webdriver
from selenium.webdriver.common.by import By # 显示等待中使用By进行定位元素
from selenium.webdriver.common.keys import Keys # 可以实现键盘回车的功能
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome() # 声明Chrome浏览器对象
try:
browser.get('https://www.baidu.com') # get()方法请求网页
input_item = browser.find_element(By.ID, 'kw') # 定位到百度输入框,find_element()方法获取单个元素节点
input_item.send_keys('Python') # send_keys()方法向input框中填入字符串
input_item.send_keys(Keys.ENTER) # 模拟键盘回车
wait = WebDriverWait(browser, 10) # 显示等待,指定加载的最长时间
wait.until(EC.presence_of_element_located((By.ID, "content_left"))) # 等待内容节点,直到出现进行下一步
print(browser.current_url) # 获取当前浏览器中url
print(browser.page_source) # 获取当前url的网页源代码
finally:
time.sleep(3) # 等待3s
browser.quit() # 退出浏览器
'''
功能如下:
声明浏览器对象
'''
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.Safari()
'''
功能如下:
输入一个网址,通过selenium进行访问页面
'''
from selenium import webdriver
browser = webdriver.Chrome() # 创建浏览器对象
browser.get("https://www.baidu.com") # get() 方法访问页面
print(browser.page_source) # 获取网页源代码
browser.quit() # 退出浏览器
更多请查看:英文文档、中文文档
from selenium.webdriver.common.by import By
方法1 | 方法2 |
---|---|
find_element_by_id | find_element(By.ID, “”) |
find_element_by_name | find_element(By.NAME, “”) |
find_element_by_xpath | find_element(By.XPATH, “”) |
find_element_by_link_text | find_element(By.LINK_TEXT, “”) |
find_element_by_partial_link_text | find_element(By.PARTIAL_LINK_TEXT, “”) |
find_element_by_tag_name | find_element(By.TAG_NAME, “”) |
find_element_by_class_name | find_element(By.CLASS_NAME, “”) |
find_element_by_css_selector | find_element(By.CSS_SELECTOR, “”) |
单独拿一个id做案例,代码使用参考如下:
'''
功能如下:
实现查找节点中id方法的案例
案例网站:【豆瓣电影排行榜】https://movie.douban.com/chart
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def fun_one():
'''
使用 find_element_by_xxx类型
:return:
'''
icp1 = browser.find_element_by_id('icp')
icp2 = browser.find_element_by_xpath('//span[@id="icp"]')
icp3 = browser.find_element_by_css_selector('#icp')
print("方法一:")
print(icp1)
print(icp2)
print(icp3)
def fun_two():
'''
使用 find_element()类型
:return:
'''
icp1 = browser.find_element(By.ID, 'icp')
icp2 = browser.find_element(By.XPATH, '//span[@id="icp"]')
icp3 = browser.find_element(By.CSS_SELECTOR, '#icp')
print("方法二:")
print(icp1)
print(icp2)
print(icp3)
if __name__ == '__main__':
browser = webdriver.Chrome()
browser.get('https://movie.douban.com/chart')
wait = WebDriverWait(browser, 15)
wait.until(EC.presence_of_element_located((By.ID, "content")))
fun_one() # 方法一:find_element_by_xxx类型
fun_two() # 方法二:find_element()类型
browser.quit()
# 最后运行的结果如下
#方法一:
#
#
#
#方法二:
#
#
#
方法1 | 方法2 |
---|---|
find_elements_by_id | find_elements(By.ID, “”) |
find_elements_by_name | find_elements(By.NAME, “”) |
find_elements_by_xpath | find_elements(By.XPATH, “”) |
find_elements_by_link_text | find_elements(By.LINK_TEXT, “”) |
find_elements_by_partial_link_text | find_elements(By.PARTIAL_LINK_TEXT, “”) |
find_elements_by_tag_name | find_elements(By.TAG_NAME, “”) |
find_elements_by_class_name | find_elements(By.CLASS_NAME, “”) |
find_elements_by_css_selector | find_elements(By.CSS_SELECTOR, “”) |
'''
功能如下:
实现查找节点中id方法的案例
案例网站:【豆瓣电影排行榜】https://movie.douban.com/chart
'''
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def fun_one():
'''
使用 find_elements_by_xxx类型
:return:
'''
items1 = browser.find_elements_by_css_selector('div.indent .item')
items2 = browser.find_elements_by_xpath('//div[@class="indent"]//tr[@class="item"]')
print("方法一:")
print(items1)
print(items2)
def fun_two():
'''
使用 find_elements()类型
:return:
'''
items1 = browser.find_elements(By.CSS_SELECTOR, 'div.indent .item')
items2 = browser.find_elements(By.XPATH, '//div[@class="indent"]//tr[@class="item"]')
print("方法二:")
print(items1)
print(items2)
if __name__ == '__main__':
browser = webdriver.Chrome()
browser.get('https://movie.douban.com/chart')
wait = WebDriverWait(browser, 15)
wait.until(EC.presence_of_element_located((By.ID, "content")))
fun_one() # 方法一:find_elements_by_xxx类型
fun_two() # 方法二:find_elements()类型
browser.quit()
'''
功能如下:
实现input框的输入
实现input框的清空
实现元素的点击操作
'''
import time
from selenium import webdriver
from selenium.webdriver.common.by import By # 显示等待中使用By进行定位元素
from selenium.webdriver.common.keys import Keys # 可以实现键盘回车的功能
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome() # 声明Chrome浏览器对象
try:
browser.get('https://cn.bing.com/') # get()方法请求网页
input_item = browser.find_element(By.ID, 'sb_form_q') # 定位到百度输入框,find_element()方法获取单个元素节点
input_item.send_keys('Python') # send_keys()方法:向input框中填入字符串
input_item.submit() # 模拟键盘回车
# input_item.send_keys(Keys.ENTER) # 模拟键盘回车
wait = WebDriverWait(browser, 10) # 显示等待,指定加载的最长时间
wait.until(EC.presence_of_element_located((By.ID, "b_results"))) # 等待内容节点,直到出现进行下一步
time.sleep(1)
input_item2 = browser.find_element(By.ID, 'sb_form_q')
input_item2.clear() # clear()方法:清空input框内容
time.sleep(0.2)
input_item2.send_keys("阿尔法") # send_keys()方法:输入字符串
browser.find_element(By.ID, "sb_form_go").click() # click()方法:进行点击操作
finally:
time.sleep(3) # 等待3s
browser.quit() # 退出浏览器
使用动作链常用的几个场景,如下:
ActionChains方法列表
click(on_element=None) # 单击鼠标左键
click_and_hold(on_element=None) # 点击鼠标左键,不松开
context_click(on_element=None) # 单击鼠标右键
double_click(on_element=None) # 双击鼠标左键
drag_and_drop(source, target) # 按住鼠标左键拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) # 拖拽到某个坐标(偏移量)然后松开
key_down(value, element=None) # 按下某个键盘上的键,不释放
key_up(value, element=None) # 松开某个键
move_by_offset(xoffset, yoffset) # 鼠标从当前位置移动到某个坐标
move_to_element(to_element) # 鼠标移动到某个元素的中间
move_to_element_with_offset(to_element, xoffset, yoffset) # 移动到距某个元素(左上角坐标)多少距离的位置
perform() # 执行链中的所有动作
release(on_element=None) # 在某个元素位置松开鼠标左键
reset_actions() # 清除链中的所有操作
send_keys(*keys_to_send) # 发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) # 发送某个键到指定元素
示例网址:https://sahitest.com/demo/clicks.htm
'''
功能如下:
1. 实现左键单击操作
2. 实现左键双击操作
3. 实现右键单击操作
'''
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome() # 初始化浏览器对象
try:
browser.maximize_window() # 窗口最大化
browser.get('http://sahitest.com/demo/clicks.htm')
time.sleep(0.5)
click_btn = browser.find_element(By.XPATH, '//input[@value="click me"]') # 单击按钮
doubleclick_btn = browser.find_element(By.XPATH, '//input[@value="dbl click me"]') # 双击按钮
rightclick_btn = browser.find_element(By.XPATH, '//input[@value="right click me"]') # 右键单击按钮
ActionChains(browser).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform() # 链式用法,执行动作链
time.sleep(0.5)
textarea = browser.find_element(By.XPATH, '//textarea[@name="t2"]').get_attribute('value') # 获取textarea文本域中的值
print(textarea)
finally:
time.sleep(3)
browser.quit()
示例网址:https://sahitest.com/demo/mouseover.htm
'''
功能如下:
解决某些hover的问题
'''
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome() # 初始化浏览器对象
try:
browser.maximize_window() # 窗口最大化
browser.get('https://sahitest.com/demo/mouseover.htm')
time.sleep(0.5)
write = browser.find_element(By.XPATH, '//input[@value="Write on hover"]') # Writer on hover
black = browser.find_element(By.XPATH, '//input[@value="Blank on hover"]') # Blank on hover
action = ActionChains(browser)
action.move_to_element(write).perform() # 将鼠标移动到Writer on hover
time.sleep(2)
action.move_to_element(black).perform() # 将鼠标移动到Blank on hover
finally:
time.sleep(3)
browser.quit()
示例网址:https://sahitest.com/demo/dragDropMooTools.htm
'''
功能如下:
实现鼠标将某一个元素拖拽到另一个元素中
'''
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome() # 初始化浏览器对象
try:
browser.maximize_window() # 窗口最大化
browser.get('https://sahitest.com/demo/dragDropMooTools.htm')
time.sleep(0.5)
dragger = browser.find_element(By.ID, 'dragger') # dragger
items = browser.find_elements(By.XPATH, '//div[@class="item"]') # items
action = ActionChains(browser)
action.drag_and_drop(dragger, items[0]).perform() # 将drop拖拽到第一个item中
time.sleep(2)
action.drag_and_drop(dragger, items[2]).perform() # 将drop拖拽到第三个item中
time.sleep(2)
action.drag_and_drop(dragger, items[-1]).perform() # 将drop拖拽到第四个item中
finally:
time.sleep(3)
browser.quit()
示例网址:http://sahitest.com/demo/keypress.htm
'''
功能如下:
在selenium中实现键盘的简易操作
'''
import time
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('http://sahitest.com/demo/keypress.htm')
key_up_radio = browser.find_element(By.ID, 'r1') # 监测按键升起
key_down_radio = browser.find_element(By.ID, 'r2') # 监测按键按下
key_press_radio = browser.find_element(By.ID, 'r3') # 监测按键按下升起
enter = browser.find_elements(By.XPATH, '//form[@name="f1"]/input')[1] # 输入框
result = browser.find_elements(By.XPATH, '//form[@name="f1"]/input')[0] # 监测结果
# 监测key_down
key_down_radio.click()
ActionChains(browser).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform() # 在输入框中按下ctrl建
print(result.get_attribute('value'))
time.sleep(5)
# 监测key_up
key_up_radio.click()
enter.click()
ActionChains(browser).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform() # 在输入框中按下shift建,松开
print(result.get_attribute('value'))
time.sleep(5)
# 监测key_press
key_press_radio.click()
enter.click()
ActionChains(browser).send_keys('a').perform()
print(result.get_attribute('value'))
time.sleep(5)
browser.quit()
代码如下:
'''
功能如下:
- 将滚动条拉至顶部
- 将滚动条拉至底部
- JS执行元素操作(点击、输入文本、等)
'''
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
time.sleep(2)
# driver.execute_script("arguments[0].click();", element),点击操作
# driver.execute_script("arguments[0].scrollIntoView();", element),移动到目标元素,类似于滑动查找
# 滚动条拉到底部
js = 'window.scrollTo(0, document.body.scrollHeight)'
browser.execute_script(js)
print(f'''滚动条滑动到底部''')
time.sleep(2)
# 滚动条拉到顶部
js = 'window.scrollTo(0, 0)'
browser.execute_script(js)
print(f'''滚动条滑动到顶部''')
time.sleep(2)
# 输入文本操作
msg = '悬疑'
send_js = f"text_input = document.getElementById('inp-query'); " \
f"text_input.value = '{msg}'"
browser.execute_script(send_js)
print(f'''{msg}文本输入成功。。。''')
time.sleep(2)
# 点击操作
input_btn = browser.find_element(By.CSS_SELECTOR, ".inp-btn input")
click_js = 'arguments[0].click();'
browser.execute_script(click_js, input_btn)
print(f'''搜索按钮点击成功''')
# 创建一个新的选项卡
browser.execute_script('window.open()')
handles = browser.window_handles # 获取当前浏览器对象中有多少选项卡
print(handles)
browser.switch_to.window(handles[-1]) # 跳转到最后一个选项卡中
browser.get('https://www.taobao.com') # 跳转至淘宝中
time.sleep(3)
browser.quit()
page_source属性可以获取网页的源代码,也可以使用解析库(如正则表达式、BeautifulSoup、pyquery、parsel等)来提取信息
Selenium已经提供了选择节点的方法,返回的是WebElement类型,那么它也有相关的方法和属性来直接提取节点信息,如属性、文本等。这样的话,我们就可以不用通过解析源代码来提取信息了,非常方便。
get_attribute():获取节点的属性,但是其前提是先选中这个节点,示例如下:
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
time.sleep(2)
items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
for item in items:
print(item.get_attribute('href')) # 获取节点属性href
time.sleep(2)
browser.quit()
# 运行效果
# https://movie.douban.com/subject/30314848/
# https://movie.douban.com/subject/27199850/
# https://movie.douban.com/subject/35874097/
# https://movie.douban.com/subject/35008440/
# https://movie.douban.com/subject/34861178/
# https://movie.douban.com/subject/30165311/
# https://movie.douban.com/subject/35769174/
# https://movie.douban.com/subject/35307624/
# https://movie.douban.com/subject/35303842/
# https://movie.douban.com/subject/35441573/
text:获取文本值,每个WebElement节点都有text属性,直接调用这个属性就可以得到节点内部的信息,示例如下:
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
time.sleep(2)
items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
for item in items:
print(item.text) # 获取文本数据
time.sleep(2)
browser.quit()
# 运行结果
# 瞬息全宇宙 / 妈的多重宇宙(台) / 奇异女侠玩救宇宙(港)
# 暗夜博士:莫比亚斯 / 莫比亚斯 / 魔比煞(港)
# 网络炼狱:揭发N号房 / 网路炼狱:揭发N号房(台) / 网络地狱:N号房现形记
# 唐顿庄园2 / 唐顿庄园电影版2 / 唐顿庄园:全新世代(港/台)
# 北欧人 / 北方人(台)
# 坏蛋联盟 / 大坏蛋 / 坏家伙
# 万湖会议 / The Conference
# 渔港的肉子酱 / 渔港的肉子 / Fortune Favors Lady Nikuko
# 迷失之城 / 迷失D城 / Lost City of D
# 首尔怪谈 / Urban Myths / Urban Myths: Tooth Worms
id属性:selenium 使用的内部 ID。
location属性:获取节点在页面中的相对位置
tag_name属性:可以获取标签名称
size属性:可以获取节点元素大小
'''
功能如下:
id属性:selenium 使用的内部 ID。
location属性:获取节点在页面中的相对位置
tag_name属性:可以获取标签名称
size属性:可以获取节点元素大小
'''
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
time.sleep(2)
item = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')[0]
print(item.id) # 获取节点在selenium中的id
print(item.location) # 获取节点在页面中的位置
print(item.size) # 获取节点的大小
print(item.tag_name) # 获取节点的标签名称
time.sleep(2)
browser.quit()
# 执行效果
# 8c32db1c-1321-4674-9aee-92abad562603
# {'x': 534, 'y': 281}
# {'height': 16, 'width': 318}
# a
示例网址:https://sahitest.com/demo/iframesTest.htm
selenium中处理iFrame有三种方式
1、如果iframe有id或name,则可根据iframe的id或name切换。
<iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
browser.switch_to.frame('x-URS-iframe1610006384373.8518') # id定位
browser.switch_to.frame('aa') # name定位
2、把iframe当作页面元素,通过元素定位表达式进行切换。
<iframe name="aa"id="x-URS-iframe1610006384373.8518"></iframe>
frame = browser.find_element_by_xpath('//iframe[@id="x-URS-iframe"]') # 先定位元素
browser.switch_to.frame(frame) # 在切换iframe
3、将iframe存储到list中,然后根据ifrane的索引定位 (适合页面有多个iframe,且前两种方法无法使用)。
browser.switch_to.frame(0)
返回上一级
browser.switch_to.parent_frame() # 返回上一级
跳出iframe窗口并返回到Top Window 上
browser.switch_to_default_conten() # 跳出iframe窗口并返回Window主窗体
这里案例只用将元素作为参数传递,进入iframe中。
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('https://sahitest.com/demo/iframesTest.htm')
time.sleep(2)
item = browser.find_element(By.ID, 'checkRecord').get_attribute('value')
h2_out = browser.find_element(By.TAG_NAME, 'h2').text
print(f'''外层的主体输出:{item}, {h2_out}''')
time.sleep(2)
# 第一层iframe
iframe = browser.find_element(By.TAG_NAME, 'iframe')
browser.switch_to.frame(iframe)
h2_in = browser.find_element(By.TAG_NAME, 'h2').text
print(f'''内层iframe的输出:{h2_in}''')
time.sleep(2)
browser.quit()
在selenium中,get()方法会在网页框架加载完之后结束,但是在这时候获取网页源代码page_source,可能并不是浏览器加载完之后的数据,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来。
等待的方式有两种:一种是显示等待,一种是隐式等待
隐式等待implicily_wait()
:当使用隐式执行测试时,如果selenium没有在DOM中找到节点,将继续等待,超出设定时间后则抛出找不到节点的异常。【换句话说,当前查找节点的节点没有立即出现,则进行等待隐式等待设定的时候,再查找DOM节点,默认的隐式等待时间为0】
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.implicitly_wait(10) # 隐式等待10s
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
items = browser.find_elements(By.XPATH, '//div[@class="pl2"]/a[1]')
for item in items:
print(item.get_attribute('href')) # 获取节点属性href
browser.quit()
显式等待wait = WebDriverWait(browser,10)
:隐式等待的效果其实没有这么好,隐式等待只是设置固定等待一段时间,而页面会收到网络的影响。有一中更适合的显示等待方法,去处理上述问题,【简单的说,显示等待就是在查找节点时,设置一个最长等待时间,在这个规定的时间内,不断的间隔查找节点是否加载出来,如果加载出来,则返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出找不到节点的异常】
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.implicitly_wait(10) # 隐式等待10s
browser.maximize_window()
browser.get('https://movie.douban.com/chart')
item = WebDriverWait(browser, 10).\
until(EC.presence_of_element_located((By.XPATH, '//div[@class="pl2"]')))
print(item)
time.sleep(2)
browser.quit()
# 运行结果
<selenium.webdriver.remote.webelement.\
WebElement (session="21cb0b79ea3b60b9711ae9bb7aab33a5", element="0d6c5acb-9eba-40eb-8075-3655d02b336a")>
详细操作:文档
等待条件 | 含义 |
---|---|
title_is | 标题是某内容 |
title_contains | 标题包含某内容 |
presence_of_element_located | 节点加载出来,传入定位元组,如(By.ID,‘p’) |
visibility_of_element_located | 节点可见,传入定位元组 |
visibility_of | 可见,传入节点对象 |
presence_of_all_elements_located | 所有节点加载出来 |
text_to_be_present_in_element | 某个节点文本包含某文字 |
text_to_be_present_in_element_value | 某个节点值包含某文字 |
frame_to_be_available_and_switch_to_it | 加载并切换 |
invisibility_of_element_located | 节点不可见 |
element_to_be_clickable | 节点可点击 |
staleness_of | 判断一个节点是否仍在DOM,可判断页面是否已经刷新 |
element_to_be_selected | 节点可选择,传节点对象 |
element_located_to_be_selected | 节点可选择,传入定位元组 |
element_selection_state_to_be | 传入节点对象以及状态,相等返回true,否则返回False |
element_located_selection_state_to_be | 传入定位元组以及状态,相等返回True,否则返回False |
alert_is_present | 是否出现警告 |
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.zhihu.com/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
cookies = browser.get_cookies() # 获取页面的cookie【列表格式】
print(cookies)
time.sleep(1)
browser.add_cookie({'name': 'name', 'domain': '.baidu.com', 'value': 'xuan'}) # 添加cookie
time.sleep(0.5)
print(browser.get_cookies())
time.sleep(0.5)
browser.delete_all_cookies() # 删除所有的cookies
time.sleep(0.5)
print(browser.get_cookies())
browser.close()
# 运行结果
# [{'domain': '.baidu.com', 'expiry': 1685068239, 'httpOnly': False, 'name': 'ZFY', 'path': '/', 'sameSite': 'None', 'secure': True, 'value': '6L4XyME:AUQ:AgwiMtufstx4tSWgLYItHOAIkkYt6HSMo:C'}, {'domain': '.baidu.com', 'expiry': 1653618639, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8cak8121ah252lela01h8tpif15'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '36454_31253_36452_36421_36165_36488_36055_26350_36301_36469_36311_36447'}, {'domain': '.baidu.com', 'expiry': 1685068238, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE343265E238C99CE101CAC:FG=1'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE3432620590E72CBC92B05'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1653532239'}, {'domain': 'www.baidu.com', 'expiry': 1654396239, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]
# [{'domain': '.baidu.com', 'expiry': 1685068239, 'httpOnly': False, 'name': 'ZFY', 'path': '/', 'sameSite': 'None', 'secure': True, 'value': '6L4XyME:AUQ:AgwiMtufstx4tSWgLYItHOAIkkYt6HSMo:C'}, {'domain': '.baidu.com', 'expiry': 1653618639, 'httpOnly': False, 'name': 'BA_HECTOR', 'path': '/', 'secure': False, 'value': '8cak8121ah252lela01h8tpif15'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'H_PS_PSSID', 'path': '/', 'secure': False, 'value': '36454_31253_36452_36421_36165_36488_36055_26350_36301_36469_36311_36447'}, {'domain': '.baidu.com', 'expiry': 1685068238, 'httpOnly': False, 'name': 'BAIDUID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE343265E238C99CE101CAC:FG=1'}, {'domain': '.baidu.com', 'httpOnly': False, 'name': 'name', 'path': '/', 'secure': True, 'value': 'xuan'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'BIDUPSID', 'path': '/', 'secure': False, 'value': 'C0B5A9B5DBE3432620590E72CBC92B05'}, {'domain': '.baidu.com', 'expiry': 3801015885, 'httpOnly': False, 'name': 'PSTM', 'path': '/', 'secure': False, 'value': '1653532239'}, {'domain': 'www.baidu.com', 'expiry': 1654396239, 'httpOnly': False, 'name': 'BD_UPN', 'path': '/', 'secure': False, 'value': '12314753'}, {'domain': 'www.baidu.com', 'httpOnly': False, 'name': 'BD_HOME', 'path': '/', 'secure': False, 'value': '1'}]
# []
# 网页中的cookie转换成selenium使用的cookie
def cookie_seleinium(cookieStr, domain):
'''
将requests拿到的cookie转换成selenium使用的cookie
:param cookieStr: cookie
:param domain: 填入统一的domin域名
:return:
'''
cookie_list = cookieStr.split(';')
selenium_cookie_list = []
for cookie in cookie_list:
# print(cookie)
# print(cookie.split('=', 1))
cookie = cookie.strip()
name = cookie.split('=', 1)[0]
value = cookie.split('=', 1)[-1]
cookie_dict = {
"domain": domain,
"name": name,
"value": value,
"path": "/"
}
selenium_cookie_list.append(cookie_dict)
return selenium_cookie_list
# selenium获取cookie可转成requests使用的cookie
def selenium_requests_cookie(selenium_list):
#获取cookies
cookie_list = [item["name"] + "=" + item["value"] for item in selenium_list]
cookieStr = ';'.join(item for item in cookie_list)
return cookieStr
browser.current_window_handle
hanles = browser.window_handles
handle = handles[-1] # 取最新窗口的id
browser.switch_to.window(handle) # 切换窗口
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
# 调用execute_script()方法,传入window.open()这个javascript语句新开启一个选项卡
browser.execute_script('window.open()')
# 获取当前开启的所有选项卡,返回的是选项卡的代号列表
print(browser.window_handles)
# 调用switch_to.window()方法切换选项卡,参数是选项卡代号,跳转到最后一个,选项卡中序号默认从0开始
browser.switch_to.window(browser.window_handles[-1])
browser.get('https://www.taobao.com')#打开淘宝页面
time.sleep(1)
browser.switch_to.window(browser.window_handles[0])#跳转到第一个选项卡
browser.get('https://douban.com')
time.sleep(1)
browser.quit()
# 运行结果:
# ['CDwindow-AD42B99E578AAAFBD39CE0B27261CEFB', 'CDwindow-A06ACF8B3CABE2F92782552A95C36071']
from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
# 运行结果
# No Element
在linux中,使用selenium进行截图,需要安装中文库,否则中文会变成方框。
Selenium截图有大的两个方式,一个是针对于浏览器而言,另一种是针对与元素而言
针对于浏览器对象browser而言,有四种截图方式
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
def save_screenshot_demo():
'''
获取截屏png图片,参数是文件名称,截屏必须是.png图片, 如果只给文件名,截图会保存在项目的根目录下面。
:return:
'''
try:
browser.get('https://www.baidu.com')
browser.find_element(By.LINK_TEXT, '新闻').click()
time.sleep(3)
browser.switch_to.window(browser.window_handles[-1])
browser.save_screenshot('save_screenshot_demo.png') # save_screenshot的图片数据必须以png结尾
finally:
time.sleep(3)
browser.quit()
def get_screenshot_as_file_demo():
'''
获取截屏png图片,参数是文件的绝对路径,截屏必须是.png图片。如果只给文件名,截屏会存在项目的根目录下。
:return:
'''
try:
browser.get('https://www.baidu.com')
browser.find_element(By.LINK_TEXT, '新闻').click()
time.sleep(3)
browser.switch_to.window(browser.window_handles[-1])
browser.get_screenshot_as_file('get_screenshot_as_file_demo.png') # get_screenshot_as_file的图片数据必须以png结尾
finally:
time.sleep(3)
browser.quit()
def get_screenshot_as_base64_demo():
'''
以 base64 编码字符串形式获取当前窗口的屏幕截图,在HTML界面输出截图时使用。
:return:
'''
try:
browser.get('https://www.baidu.com')
browser.find_element(By.LINK_TEXT, '新闻').click()
time.sleep(3)
browser.switch_to.window(browser.window_handles[-1])
b64 = browser.get_screenshot_as_base64()
print(b64)
finally:
time.sleep(3)
browser.quit()
def get_screenshot_as_png_demo():
'''
以二进制数据形式获取当前窗口的屏幕截图。
:return:
'''
try:
browser.get('https://www.baidu.com')
browser.find_element(By.LINK_TEXT, '新闻').click()
time.sleep(3)
browser.switch_to.window(browser.window_handles[-1])
b_data = browser.get_screenshot_as_png()
print(b_data)
finally:
time.sleep(3)
browser.quit()
针对于元素而言
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
import random
def selenium_screenshot(url, css_element: str, width=None, height=None, file_name=None):
"""
快照截图(截图某个元素)
:param url: url
:param width: 窗口宽度
:param height:
:param css_element: css定位
:return:
"""
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
driver = ""
ip = ''
# ip = "xxx.xxx.xxx.xxx"
try:
chrome_options = Options()
chrome_options.add_argument('--headless') # 无头模式
chrome_options.add_argument('--disable-gpu') # 禁用gpu
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument(f'user-agent={ua}') # 添加UA
if ip:
chrome_options.add_argument(f'--proxy-server=http://{ip}:port"')
driver = webdriver.Chrome(options=chrome_options)
driver.maximize_window()
if width:
driver.set_window_size(width, height)
driver.get(url)
wait = WebDriverWait(driver, 10)
wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, css_element)))
ele = driver.find_element(By.CSS_SELECTOR, css_element)
except Exception as err:
print(f"{url} selenium_screenshot false: {err} ")
return
else:
if not file_name:
file_name = random.random()
save_file_path = f"{file_name}.png"
ele.screenshot(save_file_path)
print(f"selenium_screenshot success {url}")
return save_file_path
finally:
if driver:
driver.quit()
这里给大家分享一个我自己常用的Selenium脚本执行的模板。
import time
from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.support.wait import WebDriverWait
from tenacity import retry, stop_after_attempt
TIME_OUT = 15 # wait最长等待时间
class Selenium_Chrome(object):
def __init__(self):
# 参数初始化
self.chrome_path = r'' # 指定chrome版本浏览器存放的路径
self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36'
@retry(
stop=stop_after_attempt(3) # 重启三次
)
def start_chrome(self):
'''
Chrome初始化配置对象
:return:
'''
chrome_options = ChromeOptions()
if self.chrome_path: # 如果指定Chrome的版本,就设置这个
chrome_options.binary_location = self.chrome_path
# chrome_options.add_argument("--headless") # 无界面运行
chrome_options.add_argument('accept-language="zh-CN,en-US;q=0.8"')
chrome_options.add_argument(f'''user-agent={self.user_agent}''')
chrome_options.add_experimental_option('useAutomationExtension', False)
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
chrome_options.add_argument("--disable-blink-features=AutomationControlled")
chrome_options.add_argument('--disable-gpu') # 爬虫的时候,我们一般会选择禁用GPU,如果不禁用,访客GPU都相同,太容易判断了
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument("-incognito") # 设置无痕模式
# 创建Chrome对象
self.browser = Chrome(options=chrome_options)
# 进行简单的规避操作
self.browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
self.browser.maximize_window() # 将窗口最大化
self.wait = WebDriverWait(self.browser, TIME_OUT)
def end_chrome(self):
"""
清除缓存并关闭chrome
"""
time.sleep(3)
self.browser.delete_all_cookies()
self.browser.quit()
def start(self):
try:
self.start_chrome()
'''
这里存放主程序的各种执行函数
'''
self.browser.get('https://www.baidu.com')
finally:
self.end_chrome()
if __name__ == '__main__':
test = Selenium_Chrome()
test.start()
以上便是目前我在selenium中常用的方法以及知识汇总,其中可能还会有欠缺,如果实际操作中,有用到其他的案例,也会继续在这里进行添加。当然如果文章中有不对的地方,欢迎评论区留言进行指导,我会及时更改。在这里非常感谢开头的几篇优质文章作为参考。