首页 > 编程笔记

Python Selenium库详解

Python支持很多模拟浏览器的库,如 Selenium、Splash、PyV8 等,本节将重点讲解目前最常用的模拟浏览器库 Selenium。

模拟浏览器不同于 urllib 库、requests 库等网络请求库,后者通过伪装浏览器来爬取网页数据,而模拟浏览器则直接操作浏览器爬取网页数据,因此其优缺点显而易见,优点是无论网站使用了多么复杂且多么精妙的反爬虫技术,使用模拟浏览器都可以根据在 Web 浏览器中所看到的页面进行爬取,缺点是其爬取速度较网络请求库慢很多。

Selenium简介

Selenium 是一款用于 Web 应用程序测试的工具,其最大的特点是“Selenium测试直接运行在浏览器中,就像真正的用户在操作一样”。此外,Selenium 支持所有主流的浏览器,包括 IE、Firefox、Safari、Chrome、Opera、Edge 等。

Selenium 自动化测试工具集包括 Selenium 1.0、Selenium 2.0和Selenium 3.0。

Selenium 1.0 包括 Selenium RC、Selenium IDE 和 Selenium Grid:
Selenium 2.0 的主要新功能是其集成的 WebDriver,即 Selenium 2.0 可以看作 Selenium 1.0 和 WebDriver 的整合,而 WebDriver 的设计除了解决了一些 Selenium RC 的限制,还提供了一套更加简洁的编程接口,并能更好地支持动态网页。

此外,在使用 WebDriver 时需要给浏览器安装驱动,例如,Chrome 浏览器的驱动为 ChromeDriver;Firefox 浏览器的驱动为 GeckoDriver;Safari 浏览器的驱动为 SafariDriver 等。

Selenium 3.0 支持更多的新特性,例如,对 Edge 浏览器和 Safari 浏览器原生驱动的支持,以及开始支持 Firefox 浏览器的 GeckoDriver 驱动,同时废弃了一些基本不用的组件,例如 Selenium RC。

Selenium的安装

Selenium 支持所有主流的浏览器,操作浏览器前需要安装浏览器对应的驱动,具体可登录 Selenium 官网进行下载。

浏览器对应的驱动下载完成后,需要对该文件进行解压,得到对应的可执行文件,然后将可执行文件移动到 Python 安装目录中的 Scripts 目录中即可。

此外,Selenium 库属于 Python 的第三方库,所以需要进行安装,只需在命令提示符中输入命令pip install selenium

Selenium的应用

本节的示例代码均以 Chrome 浏览器为例,其他浏览器的操作参考 Chrome 浏览器即可。

1) 打开浏览器

可以通过 Selenium.webdriver 模块中浏览器所对应的相关方法(如表 1 所示)打开浏览器,并获得 WebDriver 对象。

表 1 浏览器对应的方法
浏览器 方  法
Chrome 浏览器 Chrome()
Firefox 浏览器 Firefox()
Edge 浏览器 Edge()
Opera 浏览器 Opera()
Safari 浏览器 Safari()
示例代码如下:
from selenium import webdriver
#创建浏览器WebDriver对象,并打开Chrome浏览器
Chrome_browser=webdriver.Chrome()
print(type(Chrome_browser))

2) 关闭窗口

可以通过 WebDriver 对象提供的相关方法关闭窗口,具体如下。

close() 方法用于关闭单个窗口,其语法格式如下:
close()

quit() 方法用于关闭所有窗口,其语法格式如下:
quit()
示例代码如下: 
from selenium import webdriver
import time
#创建浏览器WebDriver对象,并打开Chrome浏览器
Chrome_browser=webdriver.Chrome()
time.sleep(2)
Chrome_browser.quit()

3) 获取网页源代码

可以通过 WebDriver 对象的相关属性和方法获取网页源代码,具体如下。

page_source 属性用于获取网页的源代码。

get() 方法用于访问指定的 URL,其语法格式如下:
get(url)
其中,参数 url 表示 URL。

示例代码如下:
from selenium import webdriver
import time
Chrome_browser=webdriver.Chrome()
url='http://www.oldxia.com/'
Chrome_browser.get(url)
res=Chrome_browser.page_source
with open('oldxia.html','w',encoding='utf-8')as f:
    f.write(res)
time.sleep(2)
Chrome_browser.quit()

4) 获取网页信息

可以通过 WebDriver 对象的相关属性获取网页信息,具体如下。

title 属性用于获取当前页面的标题;current_url 用于获取当前页面的 URL。

示例代码如下:
from selenium import webdriver
import time
Chrome_browser=webdriver.Chrome()
url='http://www.oldxia.com/'
Chrome_browser.get(url)
Chrome_title=Chrome_browser.title
Chrome_current_url=Chrome_browser.current_url
print(Chrome_title)
print(Chrome_current_url)
time.sleep(2)
Chrome_browser.quit()

5) 操作网页

可以通过 WebDriver 对象的相关方法操作网页,具体如下。

set_window_size() 方法用于设置浏览器的尺寸,其语法格式如下:
set_window_size(width,height)
其中,参数 width 表示浏览器的宽度;参数 height 表示浏览器的高度。

back() 方法用于控制浏览器后退,其语法格式如下:
back()

forward() 方法用于控制浏览器前进,其语法格式如下:
forward()

refresh() 方法用于刷新当前页面,其语法格式如下:
refresh()

示例代码如下:
from selenium import webdriver
import time
Chrome_browser=webdriver.Chrome()
url='http://www.oldxia.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1000,600)
Chrome_browser.refresh()
Chrome_browser.back()
Chrome_browser.forward()
time.sleep(2)
Chrome_browser.quit()

6)元素定位

可以通过 WebDriver 对象的相关方法对网页中的元素进行定位。

find_element() 方法用于获取符合条件的第 1 个元素,并返回一个 WebElement 对象,其语法格式如下:
find_element(by,value)
其中,参数 by 表示 selenium.webdriver.common.by 模块中的 By 类,其包括多种元素定位的方式,即 By.ID(id属性)、By.CLASS_NAME(class属性)、By.NAME(name属性)、By.TAG_NAME(标签名)、By.XPATH(XPath)、By.CSS_SELECTOR(CSS选择器)、By.LINK_TEXT(超链接文本内容)、By.CSS_SELECTOR(CSS选择器)、By.LINK_TEXT(超链接文本内容)和By.PARTIAL_LINK_TEXT(部分超链接文本内容);参数 value 表示元素定位方式所对应的值。

find_elements() 方法用于获取符合条件的所有元素,并返回一个由 WebElement 对象所组成的列表,其语法格式如下:
find_elements(by,value)
其中,参数 by 表示 selenium.webdriver.common.by 模块中的 By 类,其包括多种元素定位的方式,即 By.ID(id属性)、By.CLASS_NAME(class属性)、By.NAME(name属性)、By.TAG_NAME(标签名)、By.XPATH(XPath)、By.CSS_SELECTOR(CSS选择器)、By.LINK_TEXT(超链接文本内容)和 By.PARTIAL_LINK_TEXT(部分超链接文本内容);参数 value 表示元素定位方式所对应的值。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='http://www.sina.com.cn/'
Chrome_browser.get(url)
res1=Chrome_browser.find_element(by=By.ID,value='xy-impcon')
print(res1)
print(type(res1))
print('================================')
res2=Chrome_browser.find_elements(by=By.CLASS_NAME,value='linkNewsTopBold')
print(res2)
print(type(res2))
print('================================')
res3=Chrome_browser.find_element(by=By.NAME,value='loginname')
print(res3)
print(type(res3))
print('================================')
res4=Chrome_browser.find_element(by=By.TAG_NAME,value='input')
print(res4)
print(type(res4))
print('================================')
res5=Chrome_browser.find_element(by=By.XPATH,value="//div[@id='SI_Order_B']")
print(res5)
print(type(res5))
print('================================')
res6=Chrome_browser.find_element(by=By.CSS_SELECTOR,value='#SI_Order_B')
print(res6)
print(type(res6))
print('================================')
res7=Chrome_browser.find_element(by=By.LINK_TEXT,value='做大做强数字经济构筑国家竞争
新优势')
print(res7)
print(type(res7))
print('================================')
res8=Chrome_browser.find_element(by=By.PARTIAL_LINK_TEXT,value='文明之美看东方')
print(res8)
print(type(res8))
time.sleep(2)
Chrome_browser.quit()

7) 获取元素信息

可以通过 WebElement 对象的相关属性和方法获取元素信息,具体如下:

text 属性用于获取元素的文本内容;size 属性用于获取元素的尺寸。

get_attribute() 方法用于获取元素中指定属性的属性值,其语法格式如下:
get_attribute(name)
其中,参数 name 表示元素的属性。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='https://www.baidu.com/'
Chrome_browser.get(url)
time.sleep(3)
element=Chrome_browser.find_element(by=By.LINK_TEXT,value="新闻")
ele_text=element.text
ele_attribute=element.get_attribute('class')
ele_size=element.size
print(ele_text)
print(ele_attribute)
print(ele_size)
time.sleep(2)
Chrome_browser.quit()

8) 操作元素

可以通过 WebElement 对象的 click() 方法单击指定的元素,其语法格式如下:
click()
示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='https://www.baidu.com/'
Chrome_browser.get(url)
time.sleep(3)
element=Chrome_browser.find_element(by=By.LINK_TEXT,value="新闻")
element.click()
time.sleep(2)
Chrome_browser.quit()

9) 鼠标事件

鼠标事件主要用于在网页中模拟鼠标操作。

在 Selenium 中,关于鼠标事件的相关方法均封装在 selenium.webdriver.common.action_chains 模块中的 ActionChains 类,具体如下。

ActionChains() 方法主要用于创建 ActionChains 对象,其语法格式如下:
ActionChains(driver)
其中,参数 driver 表示 WebDriver 对象。

move_to_element() 方法主要用于执行鼠标的悬停操作,其语法格式如下:
move_to_element(to_element)
其中,参数 to_element 表示 WebElement 对象。

context_click() 方法主要用于执行鼠标的右击操作,其语法格式如下:
context_click(on_element)
其中,参数on_element表示WebElement对象。

double_click() 方法主要用于执行双击鼠标的左键操作,其语法格式如下:
double_click(on_element)
其中,参数 on_element 表示 WebElement 对象。

perform() 方法用于提交鼠标事件,其语法格式如下:
perform()
示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
Chrome_browser=webdriver.Chrome()
url='http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600,800)
element1=Chrome_browser.find_element(by=By.ID,value='s-usersetting-top')
ActionChains(Chrome_browser).move_to_element(element1).perform()
time.sleep(3)
Chrome_browser.refresh()
element2=Chrome_browser.find_element(by=By.LINK_TEXT,value="图片")
ActionChains(Chrome_browser).context_click(element2).perform()
time.sleep(3)
Chrome_browser.refresh()
element3=Chrome_browser.find_element(by=By.LINK_TEXT,value="新闻")
ActionChains(Chrome_browser).double_click(element3).perform()
time.sleep(2)
Chrome_browser.quit()

10) 键盘事件

键盘事件主要用于在网页中模拟键盘操作。

可以通过 WebElement 对象的 send_keys() 方法模拟键盘操作,其语法格式如下:
send_keys(*value)
其中,参数 value 既可以表示用户自定义的输入信息,又可以模拟键盘中的按键,而键盘中的按键则需要通过 selenium.webdriver.common.keys 模块中 Keys 类的常量进行表示,其常用的按键如下表所示。

表 2 键盘中常用的按键
按  键 描  述
Keys.BACK_SPACE Backspace 键
Keys.SPACE 空格键
Keys.TAB Tab 键
Keys.ESCAPE Esc 键
Keys.ENTER Enter 键
Keys.DELETE Delete 键
Keys.CONTROL Ctrl 键,可用于组合键
Keys. ALT Alt 键,可用于组合键
Keys.SHIFT Shift 键,可用于组合键
示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600,800)
Chrome_browser.find_element(by=By.ID,value='kw').send_keys('老夏学院')
Chrome_browser.find_element(by=By.ID,value='su').click()
time.sleep(2)
Chrome_browser.quit()

11) 切换窗口

在操作网页的过程中,经常涉及窗口的切换,即当单击网页中的某个链接时,如果新打开了一个窗口,并且需要在该窗口进行相关操作,则此时必须进行窗口切换,因为当前的窗口句柄仍然是链接所在页面的窗口,如果不切换窗口,就无法在新打开的窗口中进行相关操作。

可以通过 WebDriver 对象中的相关属性切换窗口,具体如下。

current_window_handle 属性用于获得当前窗口句柄。

window_handles 属性用于获得当前所有打开的窗口句柄。

switch_to 属性用于创建 SwitchTo 对象,并通过该对象的 window() 方法切换到指定的窗口,其语法格式如下:
switch_to.window(window_name)
其中,参数 window_name 表示窗口句柄。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600,800)
#获得当前的窗口句柄,即"百度首页"
sreach_Windows=Chrome_browser.current_window_handle
Chrome_browser.find_element(by=By.LINK_TEXT,value='登录').click()
time.sleep(2)
Chrome_browser.find_element(by=By.LINK_TEXT,value="立即注册").click()
time.sleep(2)
#获得当前所有打开的窗口句柄,包括"百度首页",以及新弹出的窗口"立即注册"
all_handles=Chrome_browser.window_handles
for handle in all_handles:
#如果当前窗口句柄不是"百度首页",则将窗口切换为"立即注册"
if handle!=sreach_Windows:
Chrome_browser.switch_to.window(handle)
print('这里是"立即注册"')
Chrome_browser.find_element(by=By.NAME,value="userName").send_keys('123456789')
time.sleep(2)
time.sleep(2)
Chrome_browser.quit()

12) 操作警告框、确认框和提示框

首先,通过 SwitchTo 对象的属性 alert 定位到 JavaScript 所生成的警告框、确认框和提示框,并返回一个 Alert 对象,其语法格式如下:
alert
然后,通过 Alert 对象的相关属性和方法即可操作警告框、确认框和提示框。

text 属性用于获取警告框、确认框或提示框中的文本内容,其语法格式如下:
text

accept() 方法用于接受警告框、确认框和提示框,其语法格式如下:
accept()

dismiss() 方法用于解散警告框、确认框和提示框,其语法格式如下:
dismiss()

send_keys() 方法用于将文本内容发送至提示框,其语法格式如下:
send_keys(keysToSend)
其中,参数keysToSend表示待发送的文本内容。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
Chrome_browser=webdriver.Chrome()
url='http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600,800)
link=Chrome_browser.find_element(by=By.ID,value='s-usersetting-top')
ActionChains(Chrome_browser).move_to_element(link).perform()
Chrome_browser.find_element(by=By.LINK_TEXT,value="搜索设置").click()
time.sleep(2)
#保存设置
Chrome_browser.find_element(by=By.CLASS_NAME,value="prefpanelgo").click()
time.sleep(2)
print(Chrome_browser.switch_to.alert.text)
Chrome_browser.switch_to.alert.accept()
time.sleep(2)
Chrome_browser.quit()

13) 操作下拉菜单

可以通过 selenium.webdriver.support.select 模块中 Select 类的相关方法操作下拉菜单,具体如下。

select_by_value() 方法通过 select 标签中 value 属性的属性值操作下拉菜单,其语法格式如下:
select_by_value(value)
其中,参数 value 表示 select 标签中 value 属性的属性值。

select_by_index() 方法通过下拉菜单中的选项索引值操作下拉菜单,其语法格式如下:
select_by_index(index)
其中,参数 index 表示下拉菜单中的选项索引值。

select_by_visible_text() 方法通过 select 标签中 option 标签的文本内容操作下拉菜单,其语法格式如下:
select_by_visible_text(text)
其中,参数 text 表示 select 标签中 option 标签的文本内容。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import time
Chrome_browser=webdriver.Chrome()
url='http://www.oldxia.com/selenium.html'
Chrome_browser.get(url)
time.sleep(3)
sel=Chrome_browser.find_element(by=By.NAME,value="city")
Select(sel).select_by_visible_text('大连')
time.sleep(2)
Chrome_browser.quit()

14) 上传文件

可以通过 WebElement 对象的 send_keys() 方法操作 input 标签上传文件,其语法格式如下:
send_keys(*value)
其中,参数value表示待上传文件的路径。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='http://www.oldxia.com/selenium.html'
Chrome_browser.get(url)
time.sleep(3)
Chrome_browser.find_element(by=By.NAME,value="file").send_keys('E:\Python全栈开发\
selenium.txt')
time.sleep(2)
Chrome_browser.quit()

15) 管理Cookie

可以通过 WebDriver 对象的相关方法管理 Cookie,具体如下。

get_Cookies() 方法用于获取所有 Cookie 信息,其语法格式如下:
get_Cookies()

get_Cookie() 方法用于获取指定名称的 Cookie 信息,其语法格式如下:
get_Cookie(name)
其中,参数 name 表示 Cookie 的名称。

add_Cookie() 方法用于添加 Cookie 信息,其语法格式如下:
add_Cookie(Cookie_dict)
其中,参数 Cookie_dict 表示字典,并且必须具有 name 键和 value 键。

delete_Cookie() 方法用于删除指定的 Cookie 信息,其语法格式如下:
delete_Cookie(name)
其中,参数 name 表示待删除的 Cookie 名称。

delete_all_Cookies() 方法用于删除所有 Cookie 信息,其语法格式如下:
delete_all_Cookies()

示例代码如下:
from selenium import webdriver
import time
Chrome_browser=webdriver.Chrome()
url='https://www.baidu.com'
Chrome_browser.get(url)
print('=====================================')
print("所有的Cookie信息:")
print(Chrome_browser.get_Cookies())
print('=====================================')
dict={'name':"name",'value':'夏正东'}
Chrome_browser.add_Cookie(dict)
print('添加的Cookie信息:')
print(Chrome_browser.get_Cookie('name'))
print('=====================================')
Chrome_browser.delete_Cookie('name')
print('删除名称为name的Cookie后,所有的Cookie信息:')
num=0
forCookie in Chrome_browser.get_Cookies():
    print(f"{Cookie['name']}——{Cookie['value']}")
    num+=1
print(f'共有{num}条Cookie信息')
print('=====================================')
print('删除所有Cookie信息:')
Chrome_browser.delete_all_Cookies()
num=0
forCookie in Chrome_browser.get_Cookies():
    print(f"{Cookie['name']}——{Cookie['value']}")
    num+=1
print(f'共有{num}条Cookie信息')
print('=====================================')
time.sleep(2)
Chrome_browser.quit()

16) 控制滚动条

在 Selenium 中,没有提供相关的属性或方法用于控制滚动条。在这种情况下,可以首先使用 JavaScript 控制滚动条,然后使用 WebDriver 对象提供的 execute_script() 方法来执行 JavaScript 代码即可,其语法格式如下:
execute_script(script)
其中,参数 script 表示 JavaScript 代码,示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser = webdriver.Chrome()
url= 'http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600, 800)
Chrome_browser.find_element(by = By.ID, value = "kw").send_keys("老夏学院")\
Chrome_browser.find_e1ement(by = By.ID, value = "su").click()
time.sleep(2)
i= 0
while i < 300 :
time.sleep(2)
js = f"window.scrollTo({i},{i} + 100);"
Chrome_browser.execute_script(js)
i += 100
time.sleep(2)
Chrome_browser.quit()

17) 窗口截图

可以通过 WebDriver 对象提供的 get_screenshot_as_file()方法进行窗口截图,其语法格式如下:
get_screenshot_as_file(filename)
其中,参数 filename 表示图片存储的路径,示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
Chrome_browser=webdriver.Chrome()
url='http://www.baidu.com/'
Chrome_browser.get(url)
Chrome_browser.set_window_size(1600,800)
Chrome_browser.find_element(by=By.ID,value="kw").send_keys("老夏学院")
Chrome_browser.find_element(by=By.ID,value="su").click()
time.sleep(2)
Chrome_browser.get_screenshot_as_file("E:\Python全栈开发\selenium.png")
time.sleep(2)
Chrome_browser.quit()

18) Chrome无界面浏览器

之前所应用的 Selenium,都是直接操作有界面的浏览器,这就势必会影响爬取数据的速度,而为了尽可能地提高爬取数据的速度,则可以使用 Chrome 无界面浏览器进行数据的爬取,其步骤如下:

首先,通过 selenium.webdriver.chrome.options 中的 Options 类创建 Options 对象,用于操作 Chrome 无界面浏览器。

其次,使用 Options 对象的 add_argument() 方法启动参数配置,并将该方法中的参数 argument 的值设置为“—headless”,表示使用无界面浏览器。

最后,在使用 Chrome 类创建 WebDriver 对象时设置参数 options,并且该参数对应的值需为之前所创建的 Options 对象。

示例代码如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
Chrome_options=Options()
Chrome_options.add_argument(argument='--headless')
Chrome_browser=webdriver.Chrome(options=Chrome_options)
url='http://www.oldxia.com/'
Chrome_browser.get(url)
Chrome_browser.get_screenshot_as_file('oldxia.png')
Chrome_browser.quit()

推荐阅读