chromedriver下载地址:npmmirror 中国镜像站
selenium直接pip,默认最新版本
如果指定版本:
pip install selenium==3.141.0
1.导包
from selenium import webdriver
from selenium.webdriver.common.by import By
(高版本的selenium需要导入这个By,否则find_element(By.XPATH, ...)无法使用
低版本可以直接用 find_element_by_xpath
如果需要显式等待,也需要另外导包
2.创建一个浏览器对象
两种方式:
1.将chromedriver放在python目录内,直接调用
chrome_obj = webdriver.Chrome()
2.如果不在python目录内,则可以在括号内指定绝对路径
chrome_obj = webdriver.Chrome(executable_path='D:/chromedriver.exe')
注意:
这里的Chrome() 首字母是大写 且必须要带括号
3.无头浏览器(正常运行,但是看不到)
from selenium.webdriver.chrome.options import Options
注意:后面的Options 首字母是大写
opt = Options() opt.add_argument('--headless') # 设置参数 改成无界面模式 chrome_obj = webdriver.Chrome(options=opt)
或者使用
selenium+phantomJS
4.三种等待方式
1.显式等待
需要导包,思想就是如果等待超时,会报错
from selenium.common.exceptions import TimeoutException
try: chrome_obj.get('url') except TimeoutException: print('超时了....')
2.隐式等待
在创建浏览器对象chrome_obj = webdriver.Chrome()后,下一行就写上下面代码
整个周期内都有效,直到 浏览器对象quit()
chrome_obj.implicitly_wait(20)
最好用的,括号内的时间写长一点
在规定的时间内,如果执行完当前行代码,立即自动执行下一行代码
如果规定时间内,没有执行完当前行代码,到了设置的时间,也会执行下一行代码
唯一的缺点:不报错
3.固定等待
time.sleep()
5.窗口最大化
有些情况下,如果窗口不在最大化的情况下,可能会找不到某些元素
chrome_obj.maximize_window()
6.selenium的定位操作
chrome_obj.find_element_by_id('login_username').send_keys('111111') chrome_obj.find_element_by_id('login_password').send_keys('123456') chrome_obj.find_element_by_xpath('//*[@id="login-form"]/div[4]/button').click()
send_keys() -----填入内容
click()-----鼠标点击
新版本写作find_element(By.ID,...)
find_element ------返回一个元素
find_elements -------返回一个由元素组成的列表 (这种情况一般用xpath解析)
一般情况,前三种就完全够用了
find_element_by_id (返回一个元素)
find_elements_by_xpath (返回一个包含元素的列表)
find_elements_by_class_name (根据类名获取元素列表)
find_elements_by_link_text (根据连接文本获取元素列表) 精准匹配
find_elements_by_partial_link_text (根据链接包含的文本获取元素列表) 只要包含有该文本都匹配
find_elements_by_tag_name (根据标签名获取元素列表)
获取数据语法
find_element仅仅能够获取元素,不能够直接获取其中的数据,如果需要获取数据需要使用以下方法:
- 获取文本:
element.text
- 获取属性值:
element.get_attribute("href")
先用finde_elements 得到一个由元素组成的列表
然后for循环遍历这个列表,列表每个元素调用上面的方法
list_att,list_text=[],[]
for i in list_elements: list_att.append(i.get_attribute('href')) list_text.append(i.text)
7.有iframe嵌套的情况
如果有iframe块,需要先切换到该frame,然后再去找下面相应的元素,否则找不到
chrome_obj.switch_to.frame(chrome_obj.find_element_by_...('frame对象')
然后再去定位元素
8.selenium执行滚动条
滚动到指定位置
chrome_obj.execute_script('window.scrollTo(0,2000)')
拖动滚动条到底部
chrome_obj.execute_script('window.scrollTo(0,document.body.scrollHeight)')
如果是滚动后页面出现再加载的情况 可以多次执行代码 确保所有数据加载完全
或者用循环 判断条件两次得到的页面高度相等 表示拖动到最下面 所有数据已加载
auto_test.execute_script('return document.body.scrollHeight')得到页面高度
拖动滚动条到指定位置
chrome_obj.execute_script('document.documentElement.scrollTop=6000')
不建议滚动条一次直接滚动到底,不符合人的操作习惯,数值写大一点,大于页面底部
可以用for循环分段多次滚动
for i in range(8): time.sleep(0.5) chrome_obj.execute_script(f'document.documentElement.scrollTop={(i+1)*1000}')
9.其他
截屏
chrome_obj.save_screenshot('baidu02.png')
获取当前时刻的cookie cookie_ = chrome_obj.get_cookies()
获取当前页面内容 str_data = chrome_obj.page_source
如果获取的页面内容可以解析得到想要的数据,那就直接解析就可以了
有些js渲染的数据在获取的页面内容里找不到,则需要通过find_elements或者元素,然后再解析这些元素的文本或者属性
得到的是html
经测试,要保存页面内容,用with open时,必须要指明encoding=
python默认UTF-8可以不写,但是我在测试一些网页时,发现缺省时中文会乱码,加上encoding=‘UTF-8’后中文就能正常显示了
加载超时
chrome_obj.set_page_load_timeout(5)
设置页面加载时间超时,超时则自动执行下面的代码
没有设置超时时间而且get方法默认是等待页面全部加载完成才会执行下一步
有时候页面想要的元素早就加载完成了,不用因为个别js之类的东西特别慢,只能干等着
driver.set_page_load_timeout(time) # 设置页面加载超时
driver.set_script_timeout(time) # 设置页面异步js执行超时
关闭浏览器 chrome_obj.quit()
传入键盘按键
from selenium.webdriver.common.keys import Keys
chrome_obj.find_element......send_keys('.....' , Keys.ENTER)
切换窗口
当在当前页面 点击链接 打开新的窗口时
虽然页面已经切换到新窗口,但是selenium默认还是在之前的窗口,而不会自动切换到新窗口
如果需要得到新窗口的数据,需要手动切换
chrom_obj.switch_to_window(chrome_obj.window_handles[-1])
# window_handles即代表浏览器的标签页, -1代表最后一个 跟python索引的方式 一样
# 关闭当前窗口
chrome_obj.close()
# 同样的,关闭当前窗口后,selenium也不会切换到原来的窗口 ,需要再次手动切换
chrom_obj.switch_to_window(chrome_obj.window_handles[0])
通过这种方式,可以打开一个源头网页,然后for循环 模拟点击进入不同的目标网页获得数据,得到数据后关闭目标网页,返回源头网页,再打开另一个新的目标网页 。。。
下拉列表
from selenium.webdriver.support.select import Select
# 定位到下拉列表
select_element = chrome_obj.find_element.........
# 对元素进行包装,包装成下拉菜单
select_menu = Select(select_element)
# 模拟切换选项
for i in range(len(select_menu.options)):
select_menu.select_by_index(i)
# 切换到指定选项 可以获得指定选项下的数据,然后可以再切换到其他选项获得数据
# 提供三种方式
# select_by_index 根据索引
# select_by_value 根据值
# select_by_visible_text 根据显示的内容(选项内容)