selenium介绍
selenium是一个用于web应用测试的工具,selenium所做的测试会直接运行在浏览器中,就像真人进行操作一样,像是打开浏览器,输入账号密码登录等等。目前selenium支持大部分的浏览器,例如:IE,Mozilla Firefox,Safari,Google Chrome,Opera,Edge等等浏览器,selenium是一个相当成功的开源工具,支持众多的语言包括C#,Java,php,python等等,在爬虫领域也有他的一席之地
安装selenium
win+r输入cmd,输入以下代码即可完成python selenium库的安装
pip install selenium
安装完毕后可以使用pip show selenium来检验是否安装成功
安装浏览器驱动
不同的浏览器需要不同的驱动去支持,但目前浏览器版本的更新速度很快,有时候驱动的版本赶不上浏览器的版本,这时候可以根据需求选择降低浏览器版本或者在selenium的高版本中有些功能不需要webdriver也能实现(个人经历,有误还请指出)
-
Firefox webdriver:Firefox
阿里镜像:https://npm.taobao.org/mirrors/geckodriver/
-
Google Chrome:Chrome
阿里镜像:https://npm.taobao.org/mirrors/chromedriver/
-
Opera:Opera
阿里镜像:https://npm.taobao.org/mirrors/operadriver/
-
PhantomJS:PhantomJS
-
Edge:Edge
-
IE:IE
确认版本号并下载
本人常用浏览器为edge,且谷歌的webdriver更新速度较慢,所以这里就用edge来展示操作内容,但是最好推荐使用firefox进行测试,官方推荐的报错的概率小一些
上图中的"版本 117.0.2045.60 (正式版本) (64 位)"中的117.0.2045.60就是浏览器的版本号,然后去edge的webdriver网站上查找相关的webdiver驱动即可
选择自己的版本进行下载即可,我的是x64版本的,点击开始下载,下载完毕后将文件进行解压,获得一个名为msedgedriver.exe的运行文件,将该文件保存到你想放的位置
配置环境变量
搜索查看高级系统设置,或者找到【我的电脑】——【右键打开属性】——【高级系统设置】——【环境变量】
检验环境变量
运行以下代码,检测是否可以成功运行,其他浏览器指令类似
from selenium import webdriver
#edge
driver=webdriver.Edge()
#chrome
driver=webdriver.Chrome()
#firefox
driver=webdriver.Firefox()
定位元素
注意:在说定位前,需要注意的是selenium的新旧版本是有差别的,本文章将对两种都分别给出代码
随便打开一个网页点击F12打开开发者工具,可以看到下面的就是网页的代码,我们要做的就是定位我们需要的元素,比如说登录框这个a标签,但是我们首先要学会打开这个页面
打开指定网页
from selenium import webdriver
#edge
driver=webdriver.Edge()
driver.get('https://www.pixiv.net/')
运行上述代码后会发现浏览器在出现一瞬间后就会马上消失,为了方便我们看,可以添加语句防止selenium自动关闭浏览器
from selenium import webdriver
from selenium.webdriver.edge.options import Options
#设置options
options=Options()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
另外一种写法,两种写法效果一致,下面一种代码较为简洁
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
输出网页代码
定位的标准就是在这个driver获取的网页源码中找的,否则会报错
#在driver.get('https://www.pixiv.net/')后加下面一句话
print(driver.page_source)
运行代码
<html lang="zh" class=" page-cool-index" xmlns:wb="http://open.weibo.com/wb" data-theme="default"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=1160">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="pixiv">
<meta property="fb:app_id" content="140810032656374">
<meta property="wb:webmaster" content="4fd391fccdb49500">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:site" content="@pixiv">
<meta property="twitter:title" content="插画交流网站 [pixiv]">
<meta property="twitter:description" content="pixiv是提供插画等作品的投稿、阅览服务的「插画交流网站」。这里有各种各样不同风格的投稿作品,我们还会举办官方、用户企画的各种比赛。">
<meta property="twitter:image"
......展示一部分
ID定位
我们知道html中的id标签具有唯一性,就像是车牌号或是身份证之类的,比如有如下的标签,可以知道这个form标签的id为nav-searchform
<form id="nav-searchform" class="" style="border-radius:8px 8px 8px 8px;"></form>
现在我们通过id定位到这个form,如果定位到就输出,下面是演示代码
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element_by_id('nav-searchform')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element(By.ID,'nav-searchform')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="b141db7f98f14935fcf0b02a16ec9697", element="73445B08D791A4DDB8C1767A1DBFBF95_element_38")>
NAME定位
标签中的name参数可以不是唯一的,所以这了就有两个函数等下分别介绍,有如下html代码片段
<meta name="viewport" content="width=1160">
现在我们通过name对这个标签进行定位,找到了就输出,下面是演示代码
获取单一标签
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element_by_name('viewport')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element(By.NAME,'viewport')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="25b0d0b64d3509caceeeb4d230439803", element="4788C4EB780A9EB1FC46683E4EE01C58_element_19")>
在上文中我们提到,name不是唯一的,所以说selenium提供了多个定位的函数,将element改成elements即可,演示代码将打印获取到的数据是什么样的
获取多个标签
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
print(driver.find_elements(By.NAME,'viewport'))
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
print(driver.find_elements(By.NAME,'viewport'))
运行结果
[<selenium.webdriver.remote.webelement.WebElement (session="261f740729f8b59c23a38ed2f5f4641d", element="E79CC23F1DED57B9C919314A269D19B4_element_19")>]
返回的是一个列表,如果我们要对每一个都进行操作,只要遍历即可
CLASS定位
在html中,class参数也不是唯一的,所以和NAME定位一样也有获取多个标签的方法,这里不再举例,只展示单个标签获取的代码,例如有如下html片段
<a href="/login.php?ref=wwwtop_accounts_index" class="signup-form__submit--login">登录</a>
现在我们通过class对这个标签进行定位,找到了就输出内容,下面是演示代码
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element_by_class_name('signup-form__submit--login')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element(By.CLASS_NAME,'signup-form__submit--login')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="d082718db12b989c1ddb140d2c6a3993", element="D076E06740ACFCF12941AB330A3E4FCB_element_16")>
TAG定位
在html中,tag就是标签例如input标签,div标签等等,我们也可以通过tag来定位,显然tag不止有一个,同样和name和class一样可以找多个,由于原理相同,这里只展示获取一个,有如下代码
<meta charset="utf-8">
<meta name="viewport" content="width=1160">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="pixiv">
现在我们通过class对这个标签进行定位,找到了就输出内容,下面是演示代码
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element_by_tag_name('meta')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element(By.TAG_NAME,'meta')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="98f22eab1bc456c95a8caafea956d8c6", element="A08DF5AC2486B8A4A58AF09E9A149177_element_19")>
XPATH定位
xpath是一种常见的对html和xml文本进行定位的一种手段,下面先简单介绍一下xpath中常见的语法,由于部分xpath的表述同样有多个标签符合要求,所以同样拥有查找多个的方法,这里不再做过多展示
#使用绝对路径(层级关系)进行定位
xpath="/html/body/div[2]/div[2]/div[1]/div[1]/div/div/form"
#使用元素属性进行定位
xpath="//*[@class='username']" #注意此处单引号和双引号的使用
#使用层级+元素属性进行定位
xpath="//div[@class='center-search__bar']/form/div/input"
#在xpath中使用逻辑表达进行定位
xpath="//*[@name='viewport' and @content='width=1160']"
有如下html片段,接下来将使用xpath对其进行定位,找到了就输出
<input class="nav-search-input" type="text" autocomplete="off" accesskey="s" maxlength="100" x-webkit-speech="" x-webkit-grammar="builtin:translate" value="" placeholder="李佳琦offer3" title="李佳琦offer3">
下面是演示代码
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element_by_xpath('//*[@id="nav-searchform"]/div[1]/input')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element(By.XPATH,'//*[@id="nav-searchform"]/div[1]/input')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="02861773f803549fb01e7c8e57b904e2", element="DB7C3EEAA07DFC4162BAA688C9963C04_element_2")>
CSS定位
css定位十分灵活,一般速度较快,但是需要对css语法有一定的掌握才能更好的使用,以下介绍一些常见的语法,同时和name一样也有其不唯一性,这里不在赘述
方法 | 举例 | 概述 |
---|---|---|
* | * | 选择所有 |
#id | #i_cecream | 选择id="i_cecream"的标签 |
.class | .bili-feed4 | 选择class="bili-feed4"的标签 |
element | form | 选择所有<form>标签 |
element1>element2 | form>input | 选择父标签为<form>之下的所有<input>标签 |
element1+element2 | form+input | 选择在同一级在<form>之后的所有<input>标签 |
[attribute=value] | type=“text/javascript” | 找到所有type="text/javascript"的标签 |
比如有如下html片段,接下来将使用css对其进行定位,找到了就输出
<a href="//cm.bilibili.com" data-target-url="**" data-v-7f4a51a0=""></a>
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element_by_css_selector('[href="//cm.bilibili.com"]')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.bilibili.com/')
#定位元素
element=driver.find_element(By.CSS_SELECTOR,'[href="//cm.bilibili.com"]')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="1a8502b5fd94e89fb3672d5fb2ed0a0b", element="E808FDEC6AEA4FA3127234D28D4406C2_element_179")>
LINK定位
link定位是通过定位文本内容来定位标签,对于动态的标签并不是十分的好用,link定位也和name定位类似有不唯一性,例如有如下html片段
<a href="/login.php?ref=wwwtop_accounts_index" class="signup-form__submit--login">登录</a>
下面将通过"登录"来进行对标签的定位,演示代码如下
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element_by_link_text('登录')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element(By.LINK_TEXT,'登录')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="8c18f357881cc23da103887ff7edb56a", element="E6F3BF9A611DD85EB20D78401F4609A4_element_19")>
PARTIAL_LINK 定位
对于较长的文本内容,如果全部复制到代码中会影响到代码的简洁性的观赏性,所以partial_link就是通过部分内容来进行定位,同样的name等定位方法一样具有不唯一性,例如有如下html片段
<a href="https://policies.google.com/terms"> Terms of Service</a>
下面将通过"登录"来进行对标签的定位,演示代码如下
较老版本
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element_by_partial_link_text('Terms')
print(element)
较新版本
from selenium import webdriver
from selenium.webdriver.common.by import By
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
#定位元素
element=driver.find_element(By.PARTIAL_LINK_TEXT,'Terms')
print(element)
运行结果
<selenium.webdriver.remote.webelement.WebElement (session="21869cd58281999dc690c87f145183a9", element="63373D4A1F4660B9672E1B408575CA74_element_19")>
页面控制
在实际操作中根据需要我们要对浏览器的页面进行操作,比如刷新网页,切换标签页等等,就像我们手动控制一样,selenium也能实现这些功能
修改浏览器窗口
selenium中常见的三种方式调整浏览器窗口,自定义,最大窗口,最小化窗口
自定义大小
通过使用set_window_size(宽,高)来调整窗口大小,代码实现如下
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
driver.set_window_size(1000,1000) #写在driver.get()的上面也行
最小化窗口
通过使用minimize_window()方法实现浏览器最小化
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
driver.minimize_window() #写在driver.get()的上面也行
全屏窗口
通过使用maximize_window()方法实现浏览器最小化
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
driver.get('https://www.pixiv.net/')
driver.maximize_window() #写在driver.get()的上面也行
页面的前进与后退
selenium提供了back()和forward()两个方法实现页面的前进与后退
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开pixiv网页
driver.get('https://www.pixiv.net/')
time.sleep(2.5)
#打开bilibili网页
driver.get('https://www.bilibili.com/')
time.sleep(2.5)
#后退至pixiv网页
driver.back()
time.sleep(1.5)
#前进到bilibili网页
driver.forward()
time.sleep(1.5)
上述方法中使用了两次,如果想要在新标签页打开,可以使用js的方法进行操作
#打开pixiv网页
driver.get('https://www.pixiv.net/')
time.sleep(2.5)
#打开bilibili网页
driver.get('https://www.bilibili.com/')
time.sleep(2.5)
#替换为如下内容
#打开pixiv网页
driver.get('https://www.pixiv.net/')
time.sleep(2.5)
#在新建标签页打开bilibili网页
js="window.open('https://www.bilibili.com/')"
driver.execute_script(js)
time.sleep(2.5)
页面刷新
有一些特殊情况下我们可能需要刷新页面才能加载出来,要通过刷新来获取最新数据,这就要用到refresh()方法了
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开pixiv网页
driver.get('https://www.pixiv.net/')
driver.refresh()
切换窗口
在我们访问网站的时候,比如某站就会弹出一个登录窗口让我们登录,但是我们直接定位这些窗口的元素是无法直接定位到的,所以要先切换到窗口上,一般我们把这些窗口称为句柄,当我们点击登录按钮后就会弹出新的句柄,我们通过driver.window_handles来获取句柄,由于句柄是按时间顺序获得的,取得的数据类似于数据和列表,可以通过索引来进行切换,由于我们一般会获取最新的句柄,所以一般会取最新的也就是-1所对应的句柄,下面是某站的代码演示
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b站
driver.get('https://www.bilibili.com/')
time.sleep(1.5)
#点击登录按钮
login_element=driver.find_element(By.CSS_SELECTOR,'#i_cecream > div.bili-feed4 > div.bili-header.large-header > div.bili-header__bar > ul.right-entry > li:nth-child(1) > li > div.right-entry__outside.go-login-btn > div > span')
login_element.click()
#获取句柄并切换至最新句柄
windows=driver.window_handles
driver.switch_to.window(windows[-1])
#点击注册按钮
register_element=driver.find_element(By.CLASS_NAME,'btn_other')
register_element.click()
鼠标控制
selenium的鼠标控制可以模拟人一样的操作对元素、标签进行点击来达到我们想要的效果或者数据,通常我们正常的操作有:单击左键、单击右键、双击、拖拽、悬停等
鼠标单击左键
我们一般使用单机左键来实现一些普通的点击功能,如点击登录等,在selenium中也是一样,对标签使用click()的方法即可完成简单的单击左键,下面以点击某网站的登录键为例
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开p站
driver.get('https://www.pixiv.net/')
#点击登录按钮
login_element=driver.find_element(By.CLASS_NAME,'signup-form__submit--login')
login_element.click()
鼠标单击右键
由于单击左键和单击右键差别较大,所以selenium提供了不同的方法需要用到名为ActionChains的类来实现,下面以单击右键某网站的登录键为例
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开p站
driver.get('https://www.pixiv.net/')
#右键点击登录按钮
login_element=driver.find_element(By.CLASS_NAME,'signup-form__submit--login')
ActionChains(driver).context_click(login_element).perform()
鼠标左键双击
双击与单机同样有所差异,所以我们依旧要使用ActionChains的类来实现,下面我们将双击某网站输入密码的小眼睛来观察
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b站登录界面
driver.get('https://passport.bilibili.com/login')
#左键双击小眼睛按钮
eye_element=driver.find_element(By.CLASS_NAME,'eye-btn')
ActionChains(driver).double_click(eye_element).perform()
鼠标拖拽
将一个元素拖拽到另一个要释放的元素上,比如滑动登录和设计拖拽等就用到这种方法,以下是某网站的实例,我们将标题拖到一个画布上
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开某网站的设计界面并点击文字选项
driver.get('https://www.canva.cn/design/play?locale=zh-CN')
time.sleep(2)
text_element=driver.find_element(By.CLASS_NAME,'sW2TIg')
text_element.click()
driver.implicitly_wait(20)
#定位标题元素位置
title_element=driver.find_element(By.CLASS_NAME,'mqHySA')
#定位画布元素位置
draw_element=driver.find_element(By.CLASS_NAME,'xvJQZA')
#推拽图片至画布位置
ActionChains(driver).drag_and_drop(title_element, draw_element).perform()
鼠标悬停
有时候当我们鼠标悬停在某个元素上的时候才会出现内容,所以selenium也十分贴心的准备了这个功能,同样是在ActionChains的类中实现,下面以某科技网站为例
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开apple网站
driver.get('https://www.apple.com')
#定位Store标签位置
store_element=driver.find_element(By.XPATH,'//*[@id="globalnav-list"]/li[2]/div/div/div[1]')
time.sleep(1)
#移动鼠标至Store并悬浮,因为edge有外部弹窗,所以我们写一个死循环,让鼠标一直悬浮在Store上
while True:
ActionChains(driver).move_to_element(store_element).perform()
键盘控制
我们使用键盘常用的就是输入作用,selenium也实现了这些功能,同时还实现了快捷键的使用,比如复制粘贴的键盘快捷键,但要实现快捷键的使用则需要使用Keys来实现
输入内容
输入内容通过定位标签并输入数据来实现,使用了send_keys()的方法函数,下面是输入登录框的代码实现
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b网的登录页
driver.get('https://passport.bilibili.com/login')
#定位账号标签
username_element=driver.find_element(By.XPATH,'//[@id="app"]/div[2]/div[2]/div[3]/div[2]/div[1]/div[1]/input')
#输入内容
username_element.send_keys('123456789')
其他操作
使用其他操作就要用到Keys来实现,下面是Keys中的常见用法
代码 | 等效操作 |
---|---|
Keys.ENTER | 回车键 |
Keys.BACK_SPACE | 按一次删除键 |
Keys.CONTROL | 按住Ctrl键 |
Keys.F1 | 按F1键【F2等同理】 |
Keys.SPACE | 按空格键 |
Keys.TAB | 按Tab键 |
Keys.ESCAPE | 按ESC键 |
Keys.ALT | 按Alt键 |
Keys.SHIFT | 按Shift键 |
Keys.ARROW_DOWN | 按向下箭头 |
Keys.ARROW_LEFT | 按向左箭头 |
Keys.ARROW_RIGHT | 按向右箭头 |
Keys.ARROW_UP | 按向上箭头 |
下面演示其中的几种来感受以下效果
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b网的登录页
driver.get('https://passport.bilibili.com/login')
#定位账号标签
username_element=driver.find_element(By.CSS_SELECTOR,'#app > div.login_wp > div.login__main > div.main__right > div.login-pwd > div.tab__form > div:nth-child(1) > input[type=text]')
#输入内容
username_element.send_keys('123456789')
time.sleep(1.5)
#删除一个符号
username_element.send_keys(Keys.BACKSPACE)
time.sleep(1.5)
#全选内容
username_element.send_keys(Keys.CONTROL,'a')
time.sleep(1.5)
#按Tab键
username_element.send_keys(Keys.TAB)
time.sleep(1.5)
等待操作
由于许多页面采用异步实现不可能一次性全部加载完毕,所以我们需要进行等待,而等待操作分为显式等待、隐式等待两种,这两者都是selenium自己提供的,还有一种是外界的强制等待,也就是使用time.sleep()来实现进程的休息
显式等待
我们设定一个超时的时限,每过一段实现就去检验一次某元素是否出现,如果出现了,就执行下一句代码,如果超出了时间限制还没有出现,则报错,我们需要用到一个叫WebDriverWait的类,代码基本格式如下
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None).until(expected_conditions.title_is(data),message='')
#dirver就是驱动,你写的driver.get()的driver
#timeout就是超时时间,单位是秒
#poll_frequency就是每次检测的时间间隔,默认是0.5秒检测一次
#ignored_exceptions就是指定忽略的异常,如果在调用until或until_not的过程中抛出指定忽略的异常,则不中断代码,默认忽略的只有NoSuchElementException
#until()也可改为until_not(),until()用于指定预期条件的判断方法,在等待期间,每隔一段时间调用该方法,判断元素是否存在,直到元素出现,until_not()则正好相反,当元素消失或指定条件不成立,则继续执行后续代码
WebDriverWait方法函数判断由expected_conditions提供,可以在设置message来返回自定义报错信息,以下是常见的几种方法判断函数,先来定义一下方法判断中要出现的参数
locator=(By.ID,"1")
element = driver.find_element_by_id('1')
content='1'
方法 | 概述 |
---|---|
title_is(content) | 判断当前页面的title是否等于content |
title_contains(content) | 判断当前页面的title是否包含content |
presence_of_element_located(locator) | 判断元素是否被加到了dom树里,但并不代表该元素一定可见 |
visibility_of_element_located(locator) | 判断元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不等于0 |
visibility_of(element) | 同上,但传入的是element |
text_to_be_present_in_element(locator ,content) | 判断元素中的text是否包含了content |
text_to_be_present_in_element_value(locator ,content) | 判断元素中的value属性是否包含了content |
frame_to_be_available_and_switch_to_it(locator) | 判断该frame是否可以switch进去,True则switch进去,反之False |
invisibility_of_element_located(locator) | 判断元素中是否不存在于dom树或不可见 |
element_to_be_clickable(locator) | 判断元素中是否可见并且是可点击的 |
element_to_be_clickable(locator) | 等待元素从dom树中移除 |
element_to_be_selected(element) | 等待元素从dom树中移除 |
element_selection_state_to_be(element, True) | 判断元素的选中状态是否符合预期,参数 element,第二个参数为True/False |
element_located_selection_state_to_be(locator, True) | 跟上一个方法作用相同,但传入参数为locator |
alert_is_present() | 判断页面上是否存在alert |
下面是例子,我们定义一个不存在的元素,然后让代码抛出异常
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b网的登录页
driver.get('https://passport.bilibili.com/login')
#定位标签
element = WebDriverWait(driver, 8, 0.5).until(
EC.presence_of_element_located((By.ID, '1')),
message='访问超时')
运行结果
selenium.common.exceptions.TimeoutException: Message: 访问超时
隐式等待
隐式等待同样是设置时间,如果没有被加载出来就抛出NoSuchElementException异常,在隐式等待的情况下你是可以在下面写driver.find_element()的语段的,如果没有找到,隐式就会不断的查找元素,知道被找到或者超出时间限制抛出异常,隐式等待语法为driver.implicitly_wait(“时间【单位秒】”),下面是示例
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开b网的登录页
driver.get('https://passport.bilibili.com/login')
#设置隐式等待时间
driver.implicitly_wait(5)
#设置初始时间用于计时
start=time.time()
#查找元素
try:
element=driver.find_element(By.ID,'1')
except Exception as E:
print('error')
finally:
#输出耗时
print(time.time()-start)
运行结果
error
5.047070503234863
强制等待
强制等待需要使用time.sleep()来实现,单位为秒,这里不再过多赘述,需要注意的是,time.sleep()是一种进程挂起,相比隐式等待,如果设定等待时间均为5秒,而元素在2秒内被加载出来,此时隐式等待将直接运行下一段代码,而强制等待则需要等待5秒结束
表单切换
由于网页会使用嵌套来写也就是iframe和frame,使用嵌套的表单selenium是无法直接获取的,所以就有了表单切换这个需求,下面是代码演示
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开某视频网站
driver.get('http://yhdm72.com/acg/68717/1.html')
driver.implicitly_wait(10)
#查找iframe标签
driver.switch_to.frame('playiframe') #默认使用id和name进行定位
#因为该网站有两个嵌套且id相同,所以切换两次
driver.switch_to.frame('playiframe')
#使用xpath定位方法
#iframe_element=driver.find_element(By.XPATH,'/html/body/div[3]/div[2]/iframe')
#driver.switch_to.frame(iframe_element)
#查找video标签
video_element=driver.find_element(By.TAG_NAME,'video')
print(video_element.get_attribute('src'))
运行结果,可知这个src是加密
blob:http://ss2.quelingfei.com:9900/8322436d-6f35-4f90-905f-531cde8352e5
JS弹窗处理
弹出js弹窗时,我们先定位switch_to.alert来获取弹窗,然后在使用方法进行操作
方法 | 概述 |
---|---|
text | 获取弹窗中的文字 |
accept | 确认弹窗内容 |
dismiss | 取消弹窗 |
send_keys | 发送内容至警告框 |
下面是对某网站的实际操作
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://incsky16.github.io/2022/06/18/142test/')
#切换至弹窗
alert=driver.switch_to.alert
time.sleep(2)
#点击取消
alert.dismiss()
time.sleep(2)
#切换至下一个弹窗
new_alert=driver.switch_to.alert
#获取内容并点击确认
print(new_alert.text)
time.sleep(2)
new_alert.accept()
运行结果
密码错误,将返回主页!
文件处理
常见的有文件上传处理,以及文件下载处理,selenium也同样可以实现
上传文件
一般上传文件是使用input标签写的,所以说可以直接写入文件路径就行,下面是示例
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://deershare.com/send')
#查找input标签
video_element=driver.find_element(By.XPATH,'/html/body/div[1]/div[1]/div[2]/div[1]/div[3]/input')
#输入内容
video_element.send_keys(r'C:\Users\14040\Desktop\新建文本文档.txt')
下载文件
下载文件也十分简单,找到标签点击下载即可,下面是示例代码
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.lifeofpix.com/')
driver.implicitly_wait(5)
#查找下载标签
download_element=driver.find_element(By.CLASS_NAME,'download')
download_element.click()
Cookie的操作
cookie是浏览器与服务器会话的十分重要的东西,webdriver对cookie有增删查的操作,下面是具体用法和说明
方法 | 概述 |
---|---|
get_cookies() | 以字典形式返回会话中的cookie全部信息 |
get_cookie(name) | 返回字典中key=name的cookie信息 |
add_cookie(cookie_dict) | 添加自定义cookie到会话中 |
delete_cookie(name) | 删除key=name的cookie信息 |
delete_all_cookies() | 删除会话范围内的所有cookie |
一下是演示代码,只展示一部分的方法
from selenium.webdriver.common.by import By
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.apple.com/')
#打印当前所有cookie
print(driver.get_cookies())
运行结果如下
[{'domain': '.apple.com',
'expiry': 1697020222,
'httpOnly': False,
'name': 's_vi',
'path': '/',
'sameSite': 'None',
'secure': True,
'value': '[CS]v1|3293391B4A21700D-4000122643359156[CE]'},
{'domain': '.apple.com',
'httpOnly': False,
'name': 'mk_epub',
'path': '/',
'sameSite': 'Lax',
'secure': True,
'value': '%7B%22btuid%22%3A%221q1ybut%22%2C%22prop57%22%3A%22www.us.homepage%22%7D'},
{'domain': '.apple.com',
'httpOnly': False,
'name': 's_cc',
'path': '/',
'sameSite': 'Lax',
'secure': True,
'value': 'true'},
{'domain': '.apple.com',
'expiry': 1697020221,
'httpOnly': False,
'name': 's_fid',
'path': '/',
'sameSite': 'Lax',
'secure': True,
'value': '63B91D4F3A5FB748-21AF8E60CCC2B67D'},
{'domain': '.apple.com',
'httpOnly': False,
'name': 'geo',
'path': '/',
'sameSite': 'Lax',
'secure': False,
'value': 'HK'}]
JavaScript应用
有时候我们需要JavaScript才能实现某些功能,比如说懒加载的显示就需要我们滑到最下面才能继续加载,selenium提供了execute_script()的方法来实现对JavaScript的操控,下面介绍两种常见思想
通过页面坐标来滑动
我们来尝试一下使用页面坐标滑动来访问bilibili的首页,下面是代码示例
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.bilibili.com/')
#滑动页面
js='window.scrollTo(0,1000)'
driver.execute_script(js)
滑动标签来实现懒加载运行
还是以b站首页为例,来演示一下一直执行懒加载,下面是代码示例
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.bilibili.com/')
driver.implicitly_wait(2)
#由于bilibili网页特殊性,先下滑
js = "window.scrollTo(0,1000);"
driver.execute_script(js)
time.sleep(2)
#写一个死循环,找到card就往下滑
while True:
time.sleep(1)
target=driver.find_elements(By.CLASS_NAME,'bili-video-card')[-1]
driver.execute_script("arguments[0].scrollIntoView();", target)
其他常用操作
东西太多不好逐个去讲解,这里的常见操作相对简单,所以就不逐一展示,我把怕们放在一个长代码中来展示并讲解,下面是代码内容及解释
from selenium.webdriver.common.by import By
from selenium import webdriver
import time
#设置options
options=webdriver.EdgeOptions()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.bilibili.com/')
#关闭全部窗口并退出驱动
driver.quit()
#关闭当前页面
driver.close()
#对当前页面进行截图保存
driver.get_screenshot_as_file('你的路径')
# 获取当前页面url
driver.current_url
# 获取当前html源码
driver.page_source
# 获取当前页面标题
driver.title
# 获取浏览器名称(chrome)
driver.name
# 对页面进行截图,返回二进制数据
driver.get_screenshot_as_png()
# 设置浏览器尺寸
driver.get_window_size()
# 获取浏览器尺寸,位置
driver.get_window_rect()
# 获取浏览器位置(左上角)
driver.get_window_position()
# 设置浏览器尺寸
driver.set_window_size(width=100, height=100)
# 设置浏览器位置(左上角)
driver.set_window_position(x=100, y=100)
# 设置浏览器的尺寸,位置
driver.set_window_rect(x=100, y=100, width=100, height=100)
关于反爬的一些配置
selenium虽然看上去十分强大,但是依然会被某些网站轻松检测出来,所以说我们就要对options进行一些设置来反反爬
header的设置
有时候我们会觉得selenium突然将页面弹出十分的麻烦,会导致电脑看上去十分混乱,selenium就提供了headless的方式来隐藏显示,但是headless有一个很大的缺陷,就是十分容易被网站检测到是爬虫,但是这里还是讲一下
headless
以下是不显示的无头浏览器headless的代码演示
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
options.add_argument('--headless')
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://bot.sannysoft.com/')
#截图网页
driver.save_screenshot('page.png')
我们会发现这是一片红,虽然说正常网站是不会太在意反爬这件事情的,但是但凡别人想反爬,我们这种方法肯定不行,所以我们尽量不使用headless来请求,那与之相对的,我们可以设置随机头来帮助我们这时就要用到一个fake-useragent的库
fake-useragent+selenium
首先我们先下载fake-useragent库,win+r并输入cmd回车进入命令提示符,输入以下代码完成下载
pip install fake-useragent
由于fake-useragent远程访问获取的地址需要等待时间很久,所以我们使用本地加载的文件来进行获取
下载地址
下载完成后放在与你python文件运行的同级目录下,或者其他目录但要自己输入绝对路径来使用,下面来演示一下fake-useragent与selenium的结合
from fake_useragent import UserAgent
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
ua=UserAgent(cache_path='fake_useragent.json') #注意版本不同cache_path可能为path或者不用填写
user_agent=ua.random
options.add_experimental_option('detach', True)
#也可以在这里使用option.add_argument("--headless"),然后和下面的代码结合
options.add_argument(f'user-agent={user_agent}')
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://bot.sannysoft.com/')
#截图网页
driver.save_screenshot('page.png')
由上图我们可以知道,现在只有一个参数可以知道我们是爬虫了
隐藏指纹
在上面我们看到了我们还差一条就差不多躲过了大部分的网站了,我们现在将在这里实现,让上面的表格全部伪造成绿色。隐藏指纹这个事情已经有前人为我们开好了路,需要用到一个名为stealth.min.js的文件,我在这里提供下载资源和源码地址,将下好的文件放在与你python文件运行的同级目录下,或者其他目录但要自己输入绝对路径来使用
CSDN站内下载资源
源码地址
下面来演示一下使用,代码如下
from fake_useragent import UserAgent
from selenium import webdriver
#设置options
options=webdriver.EdgeOptions()
ua=UserAgent(cache_path='fake_useragent.json') #注意版本不同cache_path可能为path或者不用填写
user_agent=ua.random
options.add_experimental_option('detach', True)
#也可以在这里使用option.add_argument("--headless"),然后和下面的代码结合
options.add_argument(f'user-agent={user_agent}')
#edge,将option传入edge中,并隐藏指纹
driver=webdriver.Edge(options=options)
with open('stealth.min.js') as f:
js = f.read()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": js
})
#打开网站
driver.get('https://bot.sannysoft.com/')
#截图网页
driver.save_screenshot('page.png')
对网页Networks的记录
由于selenium的更新,新旧版本的获取networks的方法可能会有所不同,这里会进行区分,大家可以通过尝试来看是否可行,此外除了selenium自带的方法外,github上还有人提供了使用java的方法来实现记录,在下文中我也会进行呈现
selenium自带
这里将给大家讲解selenium自带的记录networks的方法,会分新旧两个版本进行讲解
较老版本
有多种方法进行实现,首先先将selenium中的方法,driver.get_log()的方法
from selenium import webdriver
import json
#设置caps
caps = {
'browserName': 'edge',
'loggingPrefs': {
'browser': 'ALL',
'driver': 'ALL',
'performance': 'ALL',
},
'goog:edgeOptions': {
'perfLoggingPrefs': {
'enableNetwork': True,
},
'w3c': False,
},
}
driver = webdriver.Edge(desired_capabilities=caps)
driver.get('https://www.bilibili.com/')
#获取日志信息
networks = driver.get_log('performance')
for network in networks:
#将json格式信息转化为字典
dic_info = json.loads(network["message"])
#request信息,在字典的键["message"]["params"]中
info = dic_info["message"]["params"]
#打印一下request
print(info)
由于并没有亲自尝试老版本的代码,可能出现纰漏,大家可以自己试试看
较新版本
在较新的版本中,selenium不在提供上面所用的方法,而是改用了selenium-wire的外部库来实现,首先下载selenium-wire库,win+r输入cmd打开命令提示符输入以下代码
pip install selenium-wire
下面进行代码演示,并展示结果
from selenium.webdriver.edge.options import Options
from seleniumwire import webdriver
#设置options
options=Options()
options.add_experimental_option('detach', True)
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#打开网站
driver.get('https://www.bilibili.com/')
#输出network内容
for request in driver.requests:
print(request.url)
print(request.headers)
print(request.method)
print(request.response)
print(request.date)
break
输出结果
#request.url
https://edge.microsoft.com/serviceexperimentation/v3/?osname=win&channel=stable&scpfull=0&scpguard=0&scpver=0&osver=10.0.19045&devicefamily=desktop&installdate=1674739257&clientversion=117.0.2045.60&experimentationmode=2
#request.headers
pragma: no-cache
cache-control: no-cache
sec-mesh-client-edge-version: 117.0.2045.60
sec-mesh-client-edge-channel: stable
sec-mesh-client-os: Windows
sec-mesh-client-os-version: 10.0.19045
sec-mesh-client-arch: x86_64
sec-mesh-client-webview: 0
x-client-data: eyIxIjoiMCIsIjEwIjoiIiwiMiI6IjAiLCIzIjoiMCIsIjQiOiI1NDUwNTU1ODEyNjE5MzA2NzIyIiwiNSI6IiIsIjYiOiJzdGFibGUiLCI3IjoiMSIsIjkiOiJkZXNrdG9wIn0=
sec-fetch-site: none
sec-fetch-mode: no-cors
sec-fetch-dest: empty
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
#request.method
GET
#request.response
200
#request.date
2023-10-11 20:39:49.448413
通过js控制来获取
通过js语法对networks进行获取,以下是代码示例
from selenium import webdriver
# 打开浏览器并访问目标网页
driver = webdriver.Edge()
driver.get('https://www.bilibili.com/')
# 执行js代码,获取网页的network信息
networks = driver.execute_script('return window.performance.getEntries();')
# 输出获取到的信息
for network in networks:
print(network)
结果类似如下,可根据需要自行提取数据
{'activationStart': 0, 'connectEnd': 23.80000001192093, 'connectStart': 3, 'criticalCHRestart': 0, 'decodedBodySize': 106758, 'deliveryType': '', 'domComplete': 2404.5999999940395, 'domContentLoadedEventEnd': 1988.300000011921, 'domContentLoadedEventStart': 1986.7000000178814, 'domInteractive': 1301, 'domainLookupEnd': 1.9000000059604645, 'domainLookupStart': 1.9000000059604645, 'duration': 2418.5999999940395, 'encodedBodySize': 26255, 'entryType': 'navigation', 'fetchStart': 1.9000000059604645, 'firstInterimResponseStart': 0, 'initiatorType': 'navigation', 'loadEventEnd': 2418.5999999940395, 'loadEventStart': 2404.800000011921, 'name': 'https://www.bilibili.com/', 'nextHopProtocol': 'h2', 'redirectCount': 0, 'redirectEnd': 0, 'redirectStart': 0, 'renderBlockingStatus': 'non-blocking', 'requestStart': 23.900000005960464, 'responseEnd': 1086.9000000059605, 'responseStart': 1077.7000000178814, 'responseStatus': 200, 'secureConnectionStart': 3.5999999940395355, 'serverTiming': [], 'startTime': 0, 'toJSON': {}, 'transferSize': 26555, 'type': 'navigate', 'unloadEventEnd': 0, 'unloadEventStart': 0, 'workerStart': 0}
{'duration': 0, 'entryType': 'visibility-state', 'name': 'visible', 'startTime': 0, 'toJSON': {}}
{'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'deliveryType': '', 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 97.40000000596046, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 1081.300000011921, 'firstInterimResponseStart': 0, 'initiatorType': 'script', 'name': 'https://s1.hdslb.com/bfs/static/laputa-home/client/assets/svgfont.af80f0d3.js', 'nextHopProtocol': '', 'redirectEnd': 0, 'redirectStart': 0, 'renderBlockingStatus': 'non-blocking', 'requestStart': 0, 'responseEnd': 1178.7000000178814, 'responseStart': 0, 'responseStatus': 0, 'secureConnectionStart': 0, 'serverTiming': [], 'startTime': 1081.300000011921, 'toJSON': {}, 'transferSize': 0, 'workerStart': 0}
外部实现
外部实现需要用到browsermob-proxy和库,以及java环境才能使用,相对较为麻烦,首先我们先下载相应的库win+r输入cmd并输入以下代码回车下载
pip install browsermob-proxy
然后我们下载browsermob-proxy的官方文件,以下是我上传的地址和官方地址
CSDN站内地址
官网地址
现在我们来配置java环境,要想使用browsermob-proxy我们必须需要1.8以上的jdk环境才行,大家可以上网查一下jdk的配置,这里不在过多赘述,下面来展示通过browsermob-proxy实现的获取networks的代码
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
from browsermobproxy import Server
from selenium import webdriver
import time
#开启服务
server = Server(r'.\browsermob-proxy\bin\browsermob-proxy.bat')
server.start()
proxy = server.create_proxy()
#设置options
options=Options()
options.add_experimental_option('detach', True)
options.add_argument('--proxy-server={0}'.format(proxy.proxy))
#edge,将option传入edge中
driver=webdriver.Edge(options=options)
#开始捕获网络流量
proxy.new_har("example")
#打开网站
driver.get('https://www.bilibili.com/')
#由于我在打开中出现了连接不安全,所以这种方式来解决
driver.switch_to.window(driver.window_handles[-1])
driver.find_element(By.XPATH,'./html').send_keys('thisisunsafe')
time.sleep(2)
#停止捕获网络流量
result = proxy.har
for entry in result['log']['entries']:
print(entry)
#关闭浏览器和代理服务器
driver.quit()
server.stop()
输出结果
{'pageref': 'example', 'startedDateTime': '2023-10-11T21:19:40.492+08:00', 'request': {'method': 'CONNECT', 'url': 'https://www.bilibili.com', 'httpVersion': 'HTTP/1.1', 'cookies': [], 'headers': [], 'queryString': [], 'headersSize': 0, 'bodySize': 0, 'comment': ''}, 'response': {'status': 0, 'statusText': '', 'httpVersion': 'unknown', 'cookies': [], 'headers': [], 'content': {'size': 0, 'mimeType': '', 'comment': ''}, 'redirectURL': '', 'headersSize': -1, 'bodySize': -1, 'comment': '', '_error': 'Unable to connect to host'}, 'cache': {}, 'timings': {'comment': '', 'ssl': -1, 'receive': 0, 'blocked': 0, 'connect': 161, 'send': 0, 'dns': 0, 'wait': 0}, 'serverIPAddress': '183.131.147.27', 'comment': '', 'time': 161}
......
参考文献以及温馨提示
selenium用法详解【从入门到实战】【Python爬虫】【4万字】_selenium学习-CSDN博客
【selenium自动化过程中的api抓包】browsermobproxy的安装和配置_browsermob-proxy-CSDN博客
Python+Selenium+Browsermob-Proxy 爬虫-获取浏览器Network请求和响应_selenium获取network-CSDN博客文章来源:https://www.toymoban.com/news/detail-725569.html
Selenium获取浏览器Network数据包_selenium获取network_0xActive的博客-CSDN博客
温馨提示:文章来源地址https://www.toymoban.com/news/detail-725569.html
- 有的代码可能由于网站问题定位会发生变化,可能需要大家自行调节
- 本文章最后更新于2023年10月14日
到了这里,关于【Python爬虫】selenium的详细使用方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!