selenium

本文详细介绍了Selenium的安装、浏览器驱动下载,以及如何使用Selenium进行浏览器自动化,包括启动浏览器、元素定位、等待策略和实战练习。重点讲解了显示等待WebDriverWait()的用法,并列举了多种元素定位方法,如id、name、link text等。

selenium

  • 基于浏览器自动化的一个模块;
  • 便捷的获取网站中动态加载的数据;
  • 便捷实现模拟登录;

 

一、selenium安装

  • 安装:pip install --user selenium

 

二、selenium各浏览器驱动下载

  • 使用:把驱动文件存放在python根目录下,例如:C:\Python38\下

 

1、Chrome浏览器驱动Driver下载:http://npm.taobao.org/mirrors/chromedriver/

from selenium import webdriver
#启动浏览器
driver = webdriver.Chrome()

 

2、Firefox浏览器驱动Driver下载:https://github.com/mozilla/geckodriver/releases/

from selenium import webdriver
#启动浏览器
driver = webdriver.Firefox()

 

3、IE浏览器驱动Driver下载http://selenium-release.storage.googleapis.com/index.html

注意:IE浏览器的Internet选项中,安全页的4个安全选项,Internet、本地Internet、受信任的站点、受限制的站点,启用保护模式,都需要勾选上;

from selenium import webdriver
# 启动浏览器
driver = webdriver.Ie()

 

4、Microsoft Edge (EdgeHTML)浏览器驱动Driver下载:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

from selenium import webdriver
# 启动浏览器
driver = webdriver.Edge()

 

5、Opera浏览器驱动Driver下载:https://github.com/operasoftware/operachromiumdriver/releases

from selenium import webdriver
# 启动浏览器
driver = webdriver.Opera()

 

6、Safari浏览器驱动Driver下载:该浏览器不用下载驱动,可以直接执行代码

from selenium import webdriver
# 启动浏览器
driver = webdriver.Safari()

 

三、selenium使用

1、浏览器常用操作

  • 启动chrome浏览器,bro = webdriver.Chrome()
  • 打开网页,bro.get(url)
  • 最大化浏览器,bro.maximize_window()
  • 等待定位的元素出现:
    • 1)隐式等待2秒,bro.implicitly_wait(2)webdriver 提供的一个超时等待,等待一个元素被发现,或一个命令完成,如果超出了设置的时间,则抛出异常;
    • 2)显示等待10秒,WebDriverWait(),在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到,则抛出异常。
      • 2.1> 等待元素出现:element = WebDriverWait(bro, 10).until(lambda x: x.find_element_by_id("kw"))
      • 2.2> 等待元素消失:is_disappeared = WebDriverWait(bro, 10, 1, ).until_not(lambda x: x.find_element_by_id("denglu").is_displayed())
      • 默认检测频率为0.5s,默认抛出异常为:NoSuchElementException
    • 3)强制等待2秒,sleep(2)  python的time包中的sleep()方法
  • 获取当前页面的源码,page_text = bro.page_source
    • 使用字符串查找关键字;
    • 使用etree的xpath解析;
  • 获取当前页面的url,bro.current_url
  • 退出浏览器,bro.quit()
  • 关闭当前标签页,bro.close()

 

显示等待WebDriverWait()

  • 一旦页面上某些js无法加载出来(其实界面元素已经出来了),左上角那个图标一直转圈,这时候会一直等待的,所以可以使用显示等待来解决等待时间过长的问题。
  • WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None)
    • 入参driver,浏览器的一个实例,如传入bro,bro = webdriver.Chrome()
    • 入参timeout,超时的总时长;
    • 入参poll_frequency,循环去查询的间隙时间,默认0.5秒;
    • 入参ignored_exceptions,默认的忽略报错异常NoSuchElementException
    • 经常使用场景:
      • 直到元素出现,结束等待;
      • 直到元素消失,结束等待;


1)设置显示等待总时长,直到元素出现后自动结束等待时间 element = WebDriverWait(bro, 10).until(lambda x: x.find_element_by_id("kw"))

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time

bro = webdriver.Chrome()
bro.get('http://www.baidu.com')
start = time.time()
# 显示等待时长10秒,默认0.5秒询问一次
element = WebDriverWait(bro, 10).until(lambda x: x.find_element_by_id("kw"))
end = time.time()
element.send_keys("python")
print("显示等待的实际时间为:", end - start)

输出结果:

显示等待的实际时间为: 0.028921842575073242

 

2)设置显示等待总时长,直到元素消失后自动结束等待时间 is_disappeared = WebDriverWait(bro, 10, 1, ).until_not(lambda x: x.find_element_by_id("denglu").is_displayed())

  • 判断元素是否消失,是,返回Ture;否,返回False;
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time

bro = webdriver.Chrome()
# 古诗文网-我的页面(包含登录按钮)
bro.get('https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx')
# 古诗文网首页(不包含登录按钮)
bro.get('https://www.gushiwen.cn/')
start = time.time()
# 显示等待时长10秒,默认1秒询问一次, 判断登录按钮是否消失
is_disappeared = WebDriverWait(bro, 10, 1).until_not(lambda x: x.find_element_by_id("denglu").is_displayed())
end = time.time()
print("显示等待的实际时间为:", end - start)
print(is_disappeared)  # True,登录按钮已消失,即在页面中不显示
 

输出结果:

显示等待的实际时间为: 3.6595070362091064
True

 

2、元素定位常用操作

  • 通过【属性中id的值】定位元素(一般唯一),search = bro.find_element_by_id('s')
  • 通过【属性中name的值】定位元素(可能有多个),search = bro.find_element_by_name('s')
  • 通过【超链接的文本】定位元素,element = bro.find_element_by_link_text('地图') 
  • 通过【超链接的文本】模糊匹配定位元素(可能有多个),element = bro.find_element_by_partial_link_text('学') 
  • 通过【属性中class的值】定位元素(可能有多个),element = bro.find_element_by_class_name('s_ipt')
  • 通过【标签名tagname】定位元素(可能有多个),element_list = bro.find_element_by_tag_name('input')
  • 通过【css的selector】定位元素,element = bro.find_element_by_css_selector('#kw')
  • 通过【xpath相对位置】定位元素,element = bro.find_element_by_xpath('//*[@id="kw"]')
  • 通过【xpath绝对位置】定位元素,element = bro.find_element_by_xpath('/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input')

 

四、八大元素定位

元素定位常见报错:element not interactable

原因:

1)定位的元素无法进行交互;如:div标签执行click是不行的;对button标签执行send_keys也是不行的;

2)可能是浏览器驱动driver的某个小版本,对元素操作的支持有问题,可以升级浏览器驱动试试看;

 

元素定位

  • 所有的UI层的自动化,都是基于元素定位来实现的;
  • 所有的被操作的元素,都是WebElement对象;
  • 元素=HTML标签
  • 基本格式:<tagName attribute1="" attribute2>text</tagName>
  • 常见标签:
    • a:超链接
    • img:图片
    • input:输入框,文件上传
    • button:按钮
    • 通用:div,li,span等
  • 实际系统中,元素的标签类型,不是由表象来决定的(如看到的是图片,但不是在img标签,而是在div标签中),是通过CSS样式表来决定的;
  • 自动化时,是基于标签的属性定位标签的;
  •  

 

1、基于属性中的id的值进行定位

  • 菜鸟教程的搜索输入框标签:<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
  • 基于属性中的id的值进行定位,search = bro.find_element_by_id('s')
  • 在搜索输入框中,输入“html”,search.send_keys('html')
  • 浏览器窗口最大化,bro.maximize_window()
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.runoob.com/python/python-tutorial.html'
bro.get(url)

# 基于属性中的id的值进行定位
search = bro.find_element_by_id('s')
# 在搜索输入框中,输入“html”
search.send_keys('html')

代码效果:打开菜鸟教程,在搜索框输入html

 

2、基于属性中的name的值进行定位

  • 菜鸟教程的搜索输入框标签:<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
  • 基于属性中的name的值进行定位,search = bro.find_element_by_name('s')
  • name的取值为s的元素可能有多个,可以使用search_list = bro.find_elements_by_name('s'),再遍历search_list对元素进行处理;
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.runoob.com/python/python-tutorial.html'
bro.get(url)

# 基于属性中的name的值进行定位
search_list = bro.find_elements_by_name('s')
for search in search_list:
    search_id = search.get_attribute('id')
    print(f"name属性值为s的元素的id为:{search_id}")
bro.quit()

输出结果:

name属性值为s的元素的id为:
name属性值为s的元素的id为:s

 

3、基于link text的值进行定位

  • 百度首页的地图标签:<a href="http://map.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">地图</a>
  • 基于link text的值进行定位,element = bro.find_element_by_link_text('地图') 
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于link text的值进行定位
element = bro.find_element_by_link_text('地图')  # 基于超链接的文本内容【地图】进行定位
element.click()  # 点击地图超链接,进入百度地图页面

输出结果:点击地图超链接后,打开了百度地图页面

 

4、基于partial link text的值进行定位

  • 百度首页的学术标签:<a href="http://xueshu.baidu.com" target="_blank" class="mnav c-font-normal c-color-t">学术</a>
  • 基于partial link text的值进行定位(模糊查找匹配),element = bro.find_element_by_partial_link_text('学') 
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于partial link text的值进行定位
element = bro.find_element_by_partial_link_text('学')  # 基于超链接的文本内容模糊匹配定位,查找包含【学】的超链接
element.click()  # 点击学术超链接,进入学术页面

输出结果:百度首页找到学术超链接,进行点击,跳转到学术页面

 

5、基于属性中的classname的值进行定位

  • 百度搜索的输入框标签:<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
  • 基于属性中的classname的值进行定位,element = bro.find_element_by_class_name('s_ipt')
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于属性中的classname的值进行定位
element = bro.find_element_by_class_name('s_ipt')  # 定位到搜索输入框
element.send_keys('python')

 

6、基于tagname标签名的值进行定位

  • 百度搜索的输入框标签:<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
  • 基于tagname标签名的值进行定位,element_list = bro.find_element_by_tag_name('input')
  • 页面中input标签有多个时,可以使用element_list = bro.find_elements_by_tag_name('input'),再遍历处理判断
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于tagname的值进行定位,定位input标签
element_list = bro.find_elements_by_tag_name('input')

for element in element_list:
    if element.get_attribute('id') == 'kw':
        # 定位到搜索输入框
        element.send_keys('python')
        break

 

7、基于cssselector的值进行定位

  • 百度搜索的输入框标签:<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
  • 基于cssselector的值进行定位,element = bro.find_element_by_css_selector('#kw')
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于cssselector的值进行定位
element = bro.find_element_by_css_selector('#kw')
element.send_keys('python')

 

8、基于xpath的值进行定位

  • 百度搜索的输入框标签:<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">
  • 基于xpath的相对位置值进行定位,element = bro.find_element_by_xpath('//*[@id="kw"]')
  • 基于xpath的绝对位置值进行定位,element = bro.find_element_by_xpath('/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input')
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于xpath的值进行定位,相对位置
element = bro.find_element_by_xpath('//*[@id="kw"]')
element.send_keys('python')
from selenium import webdriver

# 创建chrome浏览器对象
bro = webdriver.Chrome()

# 访问页面
url = 'https://www.baidu.com/'
bro.get(url)

# 基于xpath的值进行定位,绝对位置
element = bro.find_element_by_xpath('/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input')
element.send_keys('python')

 

9、元素定位后的操作、可获取的信息

菜鸟教程首页的搜索框的HTML标签:<input class="placeholder" id="s" name="s" placeholder="搜索……" autocomplete="off">

定位到搜索框:search = bro.find_element_by_id('s')

  • search.text,获取定位标签的文本内容
  • search.tag_name,获取定位的标签名称
  • search.get_attribute("placeholder"),获取属性placeholder的值
  • search.get_property("autocomplete"),获取autocomplete属性的值
  • search.location,获取基于浏览器的页面位置坐标,{'x': 831, 'y': 27}
  • search.rect,获取搜索框的高度和宽度,基于浏览器的页面坐标x,y
  • search.size,获取搜索框的高度和宽度,{'height': 37, 'width': 446}
  • search.is_enabled(),是否可修改
  • search.is_displayed(),是否在页面中显示
  • search.is_selected(),是否被选中
  • search.send_keys('html'),搜索框中,输入html
  • search.clear(),清空搜索框中的输入内容(html被清除)
  • search.screenshot('img.png'),仅定位的元素进行截图,对搜索框进行截图
from selenium import webdriver
from time import sleep

# 创建chrome浏览器对象
bro = webdriver.Chrome()
# 访问页面-菜鸟教程首页
url = 'https://www.runoob.com/python/python-tutorial.html'
bro.get(url)
# 浏览器窗口最大化
bro.maximize_window()
bro.implicitly_wait(2)  # 隐式等待2秒

# 基于属性中的id的值进行定位,搜索框
search = bro.find_element_by_id('s')
print(f'search.text为:{search.text}')  # 获取定位标签的文本内容
print(f'search.tag_name为:{search.tag_name}')  # input, 获取定位的标签名称
print(f'search.id为:{search.id}')  # fd2b61f4-91d8-42d5-9d70-ed0176f935cd,selenium内置id
print(f'search.get_attribute("placeholder")为:{search.get_attribute("placeholder")}')  # 搜索……,获取属性placeholder的值
print(f'search.get_property("autocomplete")为:{search.get_property("autocomplete")}')  # off,获取autocomplete属性的值
print(f'search.location为:{search.location}')  # {'x': 831, 'y': 27},获取基于浏览器的页面位置坐标
print(f'search.rect为:{search.rect}')  # 获取搜索框的高度和宽度,基于浏览器的页面坐标x,y
print(f'search.size为:{search.size}')  # {'height': 37, 'width': 446},获取搜索框的高度和宽度

print(type(search))  # search对象的类型
print(f'search.parent为:{search.parent}')  # search对象的父节点
print(f'search.is_enabled()为:{search.is_enabled()}')  # True,是否可修改
print(f'search.is_displayed()为:{search.is_displayed()}')  # True,是否在页面中显示
print(f'search.is_selected()为:{search.is_selected()}')  # False,是否被选中
search.send_keys('html')  # 搜索框中,输入html
sleep(2)
search.clear()  # 清空搜索框中的输入内容(html被清除)
search.screenshot('img.png')  # 仅定位的元素进行截图,对搜索框进行截图

输出结果:

search.text为:
search.tag_name为:input
search.id为:5395f69e-74cb-49b6-b402-22b5e202bd3e
search.get_attribute("placeholder")为:搜索……
search.get_property("autocomplete")为:off
search.location为:{'x': 831, 'y': 27}
search.rect为:{'height': 37, 'width': 446, 'x': 830.953857421875, 'y': 26.988462448120117}
search.size为:{'height': 37, 'width': 446}
<class 'selenium.webdriver.remote.webelement.WebElement'>
search.parent为:<selenium.webdriver.chrome.webdriver.WebDriver (session="9606371fc6279acd5110543d4127ca10")>
search.is_enabled()为:True
search.is_displayed()为:True
search.is_selected()为:False

截图:img.png

 

 

3、实践练习

1、爬取页面动态加载的数据(国家药品--生产许可证

需求:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据

化妆品许可证网址:http://scxk.nmpa.gov.cn:81/xk/

爬取企业名称:

  • 浏览器驱动放入python默认安装目录C:\Python38,就不用显示指定驱动,不用传入参数;bro = webdriver.Chrome()
  • 浏览器发起指定url请求;bro.get(url)
  • 获取浏览器当前页面的页面源码数据;page_text = bro.page_source
  • 使用etree的xpath方式解析页面;
  • 浏览器退出关闭;bro.quit()
    • bro.close() 与bro.quit() 的区别:
      • bro.close(),关闭当前标签页
      • bro.quit(),关闭浏览器,释放进程
  • 注意:要多给代码添加注释,否则后期自己都看不明白在做什么;
from selenium import webdriver
from lxml import etree
from time import sleep

# 实例化一个浏览器对象(传入对应浏览器驱动)
# bro = webdriver.Chrome(executable_path='C:\Python38\chromedriver')

# 浏览器驱动放入python默认安装目录C:\Python38,就不用显示指定驱动,不用传入参数
bro = webdriver.Chrome()

# 化妆品许可证网址
url = 'http://scxk.nmpa.gov.cn:81/xk'
# 浏览器发起指定url请求
bro.get(url)

# 获取浏览器当前页面的页面源码数据
page_text = bro.page_source

# 解析企业名称
tree = etree.HTML(page_text)
li_list = tree.xpath('//*[@id="gzlist"]/li')
for li in li_list:
    name = li.xpath('./dl/@title')[0]
    print(name)

sleep(3)
bro.quit()

输出结果:

广东天姿化妆品科技有限公司
广州玖泰生物科技有限公司
广州雅奕生物科技有限公司

 

2、selenium自动化操作

1> 文本输入框,输入文字

2> 点击按钮

3> 在页面中向下滑动滚轮

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值