爬虫之selenium模块

一、selenium

1、介绍

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

 

2、安装

复制代码
1. 下载Chrome浏览器对应的驱动
http://chromedriver.storage.googleapis.com/index.html

2. 解压
如果是mac系统:
将解压后的chromedriver移动到/usr/local/bin目录下

如果是window系统:
把下载的chromdriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.38,并非2.9

3. 安装pip包
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium

注意:selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver
下载链接:https://github.com/mozilla/geckodriver/releases
复制代码

 

二、selenium的使用

1、简单使用

1. 示例

复制代码
from selenium import webdriver
from time import sleep

# 用webdriver生成一个驱动对象driver
driver = webdriver.Chrome()  # 刚才我们下载的是Chrome驱动,因此用他

# 用get打开百度页面
driver.get("http://www.baidu.com")

# 找到百度的输入框,并输入(send_keys) 无名
driver.find_element_by_id('kw').send_keys('甲铁城无名')  # 百度页面的输入框的id就是kw,自己去页面查看页面源代码
sleep(2)

# 点击搜索按钮
driver.find_element_by_id('su').click()  # 找到搜索按钮,调用click方法,模拟鼠标点击搜索按钮
sleep(2)

# 在打开的页面中找到 甲铁城无名_百度图片 这个文本,点击打开这个页面
driver.find_elements_by_link_text('甲铁城无名_百度图片')[0].click()
sleep(4)

# 关闭浏览器
driver.quit()
复制代码

 

2. 注意

Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。另外,也支持无界面浏览器PhantomJS。
from selenium import webdriver

driver = webdriver.Chrome()
driver = webdriver.Firefox()
driver = webdriver.Edge()
driver = webdriver.PhantomJS()
driver = webdriver.Safari()

 

2、元素定位

1. webdriver 提供了一系列的元素定位方法,常用的有以下几种

find_element_by_id()  # 根据id查找元素
find_element_by_name()  # 根据name属性查找元素
find_element_by_class_name()  # 根据class查找元素
find_element_by_tag_name()  # 根据tag(标签)查找元素
find_element_by_link_text()  # 根据链接的文本查找元素
find_element_by_partial_link_text()  # 根据链接的文本(模糊匹配)查找元素
find_element_by_xpath()  # 根据xpath的规则查找元素
find_element_by_css_selector()  # 根据CSS选择器查找元素

 

2. 注意

1,上面的查找是只找一个元素,find_element_by_xxx找的是第一个符合条件的标签,find_elements_by_xxx找的是所有符合条件的标签

2,根据ID、CSS选择器和XPath获取,它们返回的结果完全一致。

3,Selenium还提供了通用方法find_element(),它需要传入两个参数(查找方式By和值)。实际上,它就是find_element_by_xxx()这种方法的通用函数版本,
比如find_element_by_id(id)就等价于find_element(By.ID, id),二者得到的结果完全一致。
但是,这个By参数需要从selenium中导入:from selenium.webdriver.common.by import By

 

3. 示例

复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By  # 按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys  # 键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
from time import sleep

# 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
driver = webdriver.Chrome()

# 用get打开淘宝页面
driver.get("http://www.taobao.com")
input_tag = driver.find_element(By.ID, "q")  # 找到输入框

input_tag.send_keys("电脑")  # 在输入框输入 电脑
sleep(1)

input_tag.clear()  # 突然不想搜索电脑,清空输入框的内容
sleep(1)

input_tag.send_keys("美女")  # 重新输入 美女
sleep(1)

search = driver.find_element_by_class_name('btn-search')  # 找到搜索按钮
search.click()  # 点击搜索按钮
sleep(2)

# 关闭浏览器
driver.quit()
复制代码

 

3、节点交互

Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。
比较常见的用法有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击按钮时用click()方法

复制代码
from selenium import webdriver
import time

browser = webdriver.Chrome()  # 使用Chrome浏览器
browser.get('https://www.taobao.com')  # 访问淘宝页面
input_tag = browser.find_element_by_id('q')  # 找到搜索框
input_tag.send_keys('MySQL从入门到精通')  # 输入内容
time.sleep(1)
input_tag.clear()  # 清空内容
input_tag.send_keys('男装')  # 再次输入内容
button = browser.find_element_by_class_name('btn-search')  # 找到搜索按钮
button.click()  # 点击搜索按钮
复制代码

更多操作

 

4、动作链

在上面的实例中,一些交互动作都是针对某个节点执行的。比如,对于输入框,我们就调用它的输入文字和清空文字方法;对于按钮,就调用它的点击方法。其实,还有另外一些操作,它们没有特定的执行对象,比如鼠标拖曳、键盘按键等,这些动作用另一种方式来执行,那就是动作链。

比如,现在实现一个节点的拖曳操作,将某个节点从一处拖曳到另外一处,可以这样实现

 

1. 示例

复制代码
from selenium import webdriver
from selenium.webdriver import ActionChains
import time

browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)

# 找到iframe区域块,因为这个网页是嵌套了iframe标签,一个iframe标签就相当于一个新的页面
# 如果想要找到iframe区域的内容,就必须先找到iframe区域,这个iframe区域的id是iframeResult
browser.switch_to.frame('iframeResult')

source = browser.find_element_by_css_selector('#draggable')  # 被拖拽的区域
target = browser.find_element_by_css_selector('#droppable')  # 推拽到这个区域

# ActionChains类常用于模拟鼠标的行为,比如单击,双击,拖拽等行为
actions = ActionChains(browser)  # 实例化一个鼠标行为对象


actions.click_and_hold(source).perform()  # click_and_hold鼠标点击source区域且不放开,perform执行
time.sleep(1)

actions.move_to_element(target).perform()  # 鼠标移动到指定的target元素的位置
time.sleep(2)

# 上面两个动作可以用一个方法实现
# actions.drag_and_drop(source, target)

actions.move_by_offset(xoffset=50,yoffset=0).perform()  # 再向x轴移动50px,y轴不变
time.sleep(2)

actions.release()  # 释放按下的鼠标

browser.close()
复制代码

 

2. ActionChains动作详解

复制代码
1,导入
Action Chains类常用于模拟鼠标的行为,比如单击,双击,拖拽等行为,使用下面的方法导入ActionChains类

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver import ActionChains

两种导入都可行。


2,常用的模拟鼠标的操作
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)  # 按住某个键,使用这个方法可以方便的实现某些快捷键,比如下面按下Ctrl+c键
ActionsChains(browser).key_down(Keys.CONTROL).send_keys('c').perform()

key_up(value, element=None)  # 松开某个键,可以配合上面的方法实现按下Ctrl+c并且释放
ActionsChains(browser).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

move_by_offset(xoffset, yoffset)  # 指定鼠标移动到某一个位置,需要给出两个坐标位置

move_to_element(to_element)  # 将鼠标移动到指定的某个元素的位置

move_to_element_with_offset(to_element, xoffset, yoffset)  # 移动鼠标到某个元素位置的偏移位置

perform()  # 将之前的一系列的ActionChains执行

release(on_element=None)  # 释放按下的鼠标

send_keys(*keys_to_send)  # 向某个元素位置输入值

send_keys_to_element(element, *keys_to_send)  # 向指定的元素输入数据
复制代码

 

5、执行JavaScript

对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,此时使用execute_script()方法即可实现

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('https://www.jd.com/')
time.sleep(4)
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("111")')

 

6、获取节点信息

通过page_source属性可以获取网页的源代码,接着就可以使用解析库(如正则表达式、Beautiful Soup、pyquery等)来提取信息了。
不过,既然Selenium已经提供了选择节点的方法,返回的是WebElement类型,那么它也有相关的方法和属性来直接提取节点信息,如属性、文本等。这样的话,我们就可以不用通过解析源代码来提取信息了,非常方便

复制代码
from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
# print(browser.page_source)

input_tag = browser.find_element_by_id("kw")
print(input_tag)  # WebElement

print(input_tag.get_attribute("class"))  # 获取标签属性
print(input_tag.get_attribute("name"))

print(input_tag.id)  # 获取标签ID
print(input_tag.location)  # 获取标签位置
print(input_tag.tag_name)  # 获取标签名称
print(input_tag.size)  # 获取标签大小

browser.close()
复制代码

 

7、延时等待

在Selenium中,get()方法会在网页框架加载结束后结束执行,此时如果获取page_source,可能并不是浏览器完全加载完成的页面,如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来。这里等待的方式有两种:一种是隐式等待,一种是显式等待。

 

1. 隐式等待(implicitly_wait(sec))

复制代码
当使用隐式等待执行测试的时候,如果Selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。
隐式等待是针对全局的一个变量,所有元素都等待指定的时间,超出时间则抛出异常。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys  # 键盘按键操作


browser = webdriver.Chrome()

# 隐式等待:在查找所有元素时,如果尚未被加载,则等10秒
browser.implicitly_wait(10)

browser.get('https://www.baidu.com')
input_tag = browser.find_element_by_id('kw')
input_tag.send_keys('甲铁城无名')
input_tag.send_keys(Keys.ENTER)

contents = browser.find_element_by_id('content_left')  # 没有等待环节而直接查找,找不到则会报错
print(contents)

browser.close()
复制代码

 

2. 显示等待(WebDriverWait(browser,sec))

复制代码
隐式等待的效果其实并没有那么好,因为我们只规定了一个固定时间,而页面的加载时间会受到网络条件的影响。
更合适的一种方法是显式等待方法,它指定要查找的节点,然后指定一个最长等待时间。
如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。

from selenium import webdriver
from selenium.webdriver.common.by import By  # 按照什么方式查找,By.ID,By.CSS_SELECTOR
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()
browser.get('https://www.baidu.com')

input_tag = browser.find_element_by_id('kw')
input_tag.send_keys('美女')
input_tag.send_keys(Keys.ENTER)

# 显式等待:显式地等待某个元素被加载
wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.ID, 'content_left')))

contents = browser.find_element(By.CSS_SELECTOR, '#content_left')
print(contents)

browser.close()
复制代码

 

8、前进和后退

复制代码
平常使用浏览器时都有前进和后退功能,Selenium也可以完成这个操作,它使用back()方法后退,使用forward()方法前进

# 模拟浏览器的前进后退
import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.get('https://www.taobao.com')
browser.get('http://www.sina.com.cn/')
time.sleep(2)

browser.back()
time.sleep(2)

browser.forward()
time.sleep(2)

browser.close()
复制代码

 

9、Cookies

复制代码
使用Selenium,还可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
print(browser.get_cookies())

browser.add_cookie({'name': 'ming', 'age': '38'})
print(browser.get_cookies())

browser.delete_all_cookies()
print(browser.get_cookies())

browser.close()
复制代码

 

10、异常处理

复制代码
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException, NoSuchFrameException

try:
    browser = webdriver.Chrome()
    browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
    browser.switch_to.frame('xxx')

except TimeoutException as e:
    print(e)

except NoSuchElementException as e:
    print(e)

except NoSuchFrameException as e:
    print(e)

finally:
    browser.close()
复制代码

 

三、WebDriverWait显示等待

1、WebDriverWait 方法

WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
    driver: 传入WebDriver实例,即我们上例中的driver
    timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
    poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
    ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,
                        如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。

 

2、两种等待方式

复制代码
1. until(method, message='')
method: 在等待期间,每隔一段时间(WebDriverWait中的poll_frequency)调用这个传入的方法,直到返回值不是False
message: 如果超时,抛出TimeoutException,将message传入异常


2. until_not(method, message='')
与until相反,until是当某元素出现或什么条件成立则继续执行,
until_not是当某元素消失或什么条件不成立则继续执行,参数也相同


3. WebDriverWait的使用
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)


4. 注意
需要特别注意的是until或until_not中的method要传的是可执行方法,如果你传入的是WebElement对象,是错误的。
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(driver.find_element_by_id('kw'))  # 错误
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'kw')))  # 正确
复制代码

 

四、expected_conditions

expected_conditions是Selenium的一个模块,selenium.webdriver.support.expected_conditions,可以对网页上元素是否存在,可点击等等进行判断,一般用于断言或与WebDriverWait配合使用

 

1、expected_conditions方法总览

复制代码
expected_condtions提供了16种判断页面元素的方法:

1.title_is:判断当前页面的title是否完全等于预期字符串,返回布尔值

2.title_contains:判断当前页面的title是否包含预期字符串,返回布尔值

3.presence_of_element_located:判断某个元素是否被加到dom树下,不代表该元素一定可见

4.visibility_of_element_located:判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不为0

5.visibility_of:跟上面的方法是一样的,只是上面需要传入locator,这个方法直接传定位到的element就好

6.presence_of_all_elements_located:判断是否至少一个元素存在于dom树中,举个例子,如果页面上有n个元素的class都是'coumn-md-3',name只要有一个元素存在,这个方法就返回True

7.text_to_be_present_in_element:判断某个元素中的text文本是否包含预期字符串

8.text_to_be_present_in_element_value:判断某个元素中的value属性值是否包含了预期字符串

9.frame_to_be_availabe_and_switch_to_it:判断该frame是否可以switch进去,如果可以,则返回True并且switch进去,否则返回False

10.invisibility_of_element_located:判断某个元素是否不存在于dom树或不可见

11.element_to_be_clickable:判断某个元素是见并且是enable(有效)的,这样的话才叫clickable

12.staleness_of:等某个元素从dom树下移除,返回True或False

13.element_to_be_selected:判断某个元素是否被选中,一般用于select下拉表

14.element_selection_state_to_be:判断某个元素的选中状态是否符合预期

15.element_located_selection_state_to_be:跟上面的方法一样,只是上面的方法传入定位到的element,这个方法传入locator

16.alert_is_present:判断页面上是会否存在alert
复制代码

 

2、示例1

复制代码
title_is  # 完全匹配
title_contains  # 模糊匹配

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')

title1 = EC.title_is('百度一下,你就知道')
print(title1)
print(title1(driver))  # True

title2 = EC.title_contains('你就知道')
print(title2)
print(title2(driver))  # True
复制代码

 

3、示例2

复制代码
presence_of_element_located  # 判断某个元素是否被加到了dom树里,并不代表该元素一定可见,就是元素存不存在这个页面

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.get('https://www.baidu.com')


# 结合显示等待使用
wait = WebDriverWait(driver, 10)

ele = wait.until(EC.presence_of_element_located((By.ID, 'kw')))  # 等待10秒后,判断id=kw的元素是否存在这个页面
print(ele)

# 等待直到搜索按钮(id=su)加载完,然后点击搜索按钮
wait.until(lambda x: x.find_element_by_id("su")).click()
复制代码

 

五、phantmJs

注意:phantomJS现在已经不推荐使用了,新版的selenium会提示说phantomJS已经不维护了,不知道是不是收了其他两个浏览器的钱了哈哈。

PhantomJS是一款无界面的浏览器,其自动化操作流程和上述操作谷歌浏览器是一致的。由于是无界面的,为了能够展示自动化操作流程,
PhantomJS为用户提供了一个截屏的功能,使用save_screenshot函数实现。


有些网站上的内容信息是通过动态加载js形成的,所以使用普通爬虫程序无法回去动态加载的js内容。
例如豆瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。

 

1、使用步骤

复制代码
1. 下载phantomJs驱动
http://phantomjs.org/download.html

2. 解压后,找到phantomjs.exe的路径path

3. 使用
driver = webdriver.PhantomJS(path)

4. 示例
from selenium import webdriver
import time

if __name__ == '__main__':
    url = 'https://movie.douban.com/typerank?type_name=%E5%8E%86%E5%8F%B2&type=4&interval_id=100:90&action='
    # 发起请求前,可以让url表示的页面动态加载出更多的数据
    path = r'E:\tool\phantomjs-2.1.1-windows\bin\phantomjs.exe'
    # 创建无界面的浏览器对象
    driver = webdriver.PhantomJS(path)
    # 发起url请求
    driver.get(url)
    time.sleep(3)
    # 截图
    driver.save_screenshot('1.png')

    # 执行js代码(让滚动条向下偏移n个像素(作用:动态加载了更多的电影信息))
    js = 'window.scrollTo(0,document.body.scrollHeight)'
    driver.execute_script(js)  # 该函数可以执行一组字符串形式的js代码
    time.sleep(2)

    driver.execute_script(js)  # 该函数可以执行一组字符串形式的js代码
    time.sleep(2)
    driver.save_screenshot('2.png')
    time.sleep(2)
    # 使用爬虫程序爬去当前url中的内容
    html_source = driver.page_source  # 该属性可以获取当前浏览器的当前页的源码(html)
    with open('source.html', 'w', encoding='utf-8') as fp:
        fp.write(html_source)
    driver.quit()
复制代码

 

六、Chrome驱动配置

1、无界面

我们默认直接使用webdriver.Chrome()的时候,是方便我们进行观看是否执行成功,这个时候是有界面显示的,

但是当我们这个程序需要在后台跑的时候,是不需要界面的,无界面的有两种方式:

  1. 换驱动,使用phantomJS(下面会介绍)
  2. 给Chrome驱动添加参数,让其无界面执行

这里介绍给Chrome驱动添加参数

复制代码
使用chromeOptions
chromeOptions 是一个配置 chrome 启动属性的类。通过这个类,我们可以为chrome配置如下参数:
1.设置 chrome 二进制文件位置 (binary_location)
2.添加启动参数 (add_argument)
3.添加扩展应用 (add_extension, add_encoded_extension)
4.添加实验性质的设置参数 (add_experimental_option)
5.设置调试器地址 (debugger_address)

# 例子
from selenium import webdriver


# 实例化option
options = webdriver.ChromeOptions()
# 添加headless参数使浏览器不提供可视化页面
options.add_argument('headless') 
# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)
复制代码

 

2、其他配置参数

原文:https://blog.csdn.net/weixin_42020284/article/details/84853103

chromeOptions相关配置

chromeOptions 是一个配置 chrome 启动是属性的类。通过这个类,我们可以为chrome配置如下参数(这个部分可以通过selenium源码看到):

1.设置 chrome 二进制文件位置 (binary_location)
2.添加启动参数 (add_argument)
3.添加扩展应用 (add_extension, add_encoded_extension)
4.添加实验性质的设置参数 (add_experimental_option)
5.设置调试器地址 (debugger_address)

源码剖析:

# .\Lib\site-packages\selenium\webdriver\chrome\options.py
class Options(object):
    def __init__(self):
        self._binary_location = ''           # 设置 chrome 二进制文件位置
        self._arguments = []                 # 添加启动参数
        self._extension_files = []           # 添加扩展应用
        self._extensions = []
        self._experimental_options = {}      # 添加实验性质的设置参数
        self._debugger_address = None        # 设置调试器地址

 

1.模拟移动设备

# 通过设置user-agent,用来模拟移动设备
user_ag='MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; '+
'CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
options.add_argument('user-agent=%s'%user_ag)
#option.add_argument('--user-agent=iphone')

 

2.禁止图片加载

from selenium import webdriver
options = webdriver.ChromeOptions()
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
#或者  使用下面的设置, 提升速度
options.add_argument('blink-settings=imagesEnabled=false')

 

3.添加代理

from selenium import webdriver
# 静态IP:102.23.1.105:2005
PROXY = "proxy_host:proxy:port"
options = webdriver.ChromeOptions()
desired_capabilities = options.to_capabilities()
desired_capabilities['proxy'] = {
    "httpProxy": PROXY,
    "ftpProxy": PROXY,
    "sslProxy": PROXY,
    "noProxy": None,
    "proxyType": "MANUAL",
    "class": "org.openqa.selenium.Proxy",
    "autodetect": False
}
driver = webdriver.Chrome(desired_capabilities = desired_capabilities)

 

4.浏览器启动时安装crx扩展

# -*- coding=utf-8 -*-
from selenium import webdriver
option = webdriver.ChromeOptions()
option.add_extension('d:\crx\AdBlock_v2.17.crx')  # 自己下载的crx路径
driver = webdriver.Chrome(chrome_options=option)
driver.get('http://www.taobao.com/')

 

5.加载所有Chrome配置

用Chrome地址栏输入chrome://version/,查看自己的“个人资料路径”,然后在浏览器启动时,调用这个配置文件,代码如下:

#-*- coding=utf-8 -*-
from selenium import webdriver
option = webdriver.ChromeOptions()
p=r'C:\Users\Administrator\AppData\Local\Google\Chrome\User Data'
option.add_argument('--user-data-dir='+p)  # 设置成用户自己的数据目录
driver = webdriver.Chrome(chrome_options=option)

 

6.携带Cookie

chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("http://www.baidu.com")

通过使用Chrome选项保持所有登录在会话之间持久user-data-dir

 

7.其他

# -*- coding: utf-8 -*-
from selenium import webdriver
options = webdriver.ChromeOptions()

#谷歌无头模式
options.add_argument('--headless')
options.add_argument('--disable-gpu')#谷歌文档提到需要加上这个属性来规避bug

options.add_argument('disable-infobars')#隐藏"Chrome正在受到自动软件的控制"
options.add_argument('lang=zh_CN.UTF-8')      # 设置中文
options.add_argument('window-size=1920x3000') # 指定浏览器分辨率
options.add_argument('--hide-scrollbars')     # 隐藏滚动条, 应对一些特殊页面
options.add_argument('--remote-debugging-port=9222')
options.binary_location = r'/Applications/Chrome' #手动指定使用的浏览器位置

# 更换头部
user_agent = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) " +
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
    )
options.add_argument('user-agent=%s'%user_agent)

#设置图片不加载
prefs = {
    'profile.default_content_setting_values': {
        'images': 2
    }
}
options.add_experimental_option('prefs', prefs)
#或者  使用下面的设置, 提升速度
options.add_argument('blink-settings=imagesEnabled=false')


#设置代理
options.add_argument('proxy-server=' +'192.168.0.28:808')

driver = webdriver.Chrome(chrome_options=options)

#设置cookie
driver.delete_all_cookies()# 删除所有的cookie
driver.add_cookie({'name':'ABC','value':'DEF'})# 携带cookie打开
driver.get_cookies()

# 通过js新打开一个窗口
driver.execute_script('window.open("https://www.baidu.com");')

 

chrome地址栏命令

  about:version - 显示当前版本
  about:memory - 显示本机浏览器内存使用状况
  about:plugins - 显示已安装插件
  about:histograms - 显示历史记录
  about:dns - 显示DNS状态
  about:cache - 显示缓存页面
  about:gpu -是否有硬件加速
  about:flags -开启一些插件 //使用后弹出这么些东西:“请小心,这些实验可能有风险”,不知会不会搞乱俺的配置啊!
  chrome://extensions/ - 查看已经安装的扩展

 

chrome实用参数 

  –user-data-dir=”[PATH]” 指定用户文件夹User Data路径,可以把书签这样的用户数据保存在系统分区以外的分区。
  –disk-cache-dir=”[PATH]“ 指定缓存Cache路径
  –disk-cache-size= 指定Cache大小,单位Byte
  –first run 重置到初始状态,第一次运行
  –incognito 隐身模式启动
  –disable-javascript 禁用Javascript
  –omnibox-popup-count=”num” 将地址栏弹出的提示菜单数量改为num个。我都改为15个了。
  –user-agent=”xxxxxxxx” 修改HTTP请求头部的Agent字符串,可以通过about:version页面查看修改效果
  –disable-plugins 禁止加载所有插件,可以增加速度。可以通过about:plugins页面查看效果
  –disable-javascript 禁用JavaScript,如果觉得速度慢在加上这个
  –disable-java 禁用java
  –start-maximized 启动就最大化
  –no-sandbox 取消沙盒模式
  –single-process 单进程运行
  –process-per-tab 每个标签使用单独进程
  –process-per-site 每个站点使用单独进程
  –in-process-plugins 插件不启用单独进程
  –disable-popup-blocking 禁用弹出拦截
  –disable-plugins 禁用插件
  –disable-images 禁用图像
  –incognito 启动进入隐身模式
  –enable-udd-profiles 启用账户切换菜单
  –proxy-pac-url 使用pac代理 [via 1/2]
  –lang=zh-CN 设置语言为简体中文
  –disk-cache-dir 自定义缓存目录
  –disk-cache-size 自定义缓存最大值(单位byte)
  –media-cache-size 自定义多媒体缓存最大值(单位byte)
  –bookmark-menu 在工具 栏增加一个书签按钮
  –enable-sync 启用书签同步
  –single-process 单进程运行Google Chrome
  –start-maximized 启动Google Chrome就最大化
  –disable-java 禁止Java
  –no-sandbox 非沙盒模式运行

 

selenium抓取chromedriver的network

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
d = DesiredCapabilities.CHROME
d['loggingPrefs'] = {'performance': 'ALL'}
driver = webdriver.Chrome( desired_capabilities=d)
driver.get("https://www.baidu.com")
register = driver.find_element_by_partial_link_text("登录")
register.click()
for entry in driver.get_log('performance'):
    print(entry)

参考:https://blog.csdn.net/Ambulong/article/details/52672384


参考博文:https://blog.csdn.net/zwq912318834/article/details/78933910
Selenium启动Chrome时配置选项 https://blog.csdn.net/liaojianqiu0115/article/details/78353267
Chrome命令行设置 https://peter.sh/experiments/chromium-command-line-switches/
selenium操作chrome时的一些配置 https://blog.csdn.net/hellozhxy/article/details/80245296

 

selenium设置phantomjs请求头

#-------------------------------------------------------------------------------------
#设置phantomjs请求头和代理方法一:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# 设置代理
service_args = [
    '--proxy=%s' % ip_html,       # 代理 IP:prot(eg:192.168.0.28:808)
    '--proxy-type=http',          # 代理类型:http/https
    '--load-images=true',         # 关闭图片加载(可选)在linux下有bug,这样设置的话会导致内存不断增加,最后挂掉
    '--disk-cache=true',          # 开启缓存(可选)
    '--ignore-ssl-errors=true'    # 忽略https错误(可选)
]

#设置请求头
user_agent = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) " +
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
    )
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(executable_path="phantomjs.exe",
                             desired_capabilities=dcap,
                             service_args=service_args)

driver.get(url='http://www.baidu.com')




#-------------------------------------------------------------------------------------
#设置phantomjs请求头和代理方法二:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.proxy import ProxyType
desired_capabilities = DesiredCapabilities.PHANTOMJS.copy()
# 从USER_AGENTS列表中随机选一个浏览器头,伪装浏览器
user_agent = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) " +
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
    )
desired_capabilities["phantomjs.page.settings.userAgent"] = user_agent
# 不载入图片,爬页面速度会快很多
desired_capabilities["phantomjs.page.settings.loadImages"] = False

# 利用DesiredCapabilities(代理设置)参数值,重新打开一个sessionId,
# 相当于浏览器清空缓存后,加上代理重新访问一次url
proxy = webdriver.Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy ='192.168.0.28:808'
# 将代理设置添加到webdriver.DesiredCapabilities.PHANTOMJS中
proxy.add_to_capabilities(desired_capabilities)
# 打开带配置信息的phantomJS浏览器
driver = webdriver.PhantomJS(executable_path='phantomjs.exe',
                             desired_capabilities=desired_capabilities)
driver.start_session(desired_capabilities)

driver.get(url='http://www.baidu.com')

# ==========================或者==========================
from    selenium import  webdriver
proxy=webdriver.Proxy()
proxy.proxy_type=ProxyType.MANUAL
proxy.http_proxy='192.168.0.28:808'
# 将代理设置添加到webdriver.DesiredCapabilities.PHANTOMJS中
proxy.add_to_capabilities(webdriver.DesiredCapabilities.PHANTOMJS)
browser.start_session(webdriver.DesiredCapabilities.PHANTOMJS)
browser.get('http://www.baidu.com')

#-------------------------------------------------------------------------------------
# 还原为系统代理
proxy=webdriver.Proxy()
proxy.proxy_type=ProxyType.DIRECT
proxy.add_to_capabilities(webdriver.DesiredCapabilities.PHANTOMJS)
browser.start_session(webdriver.DesiredCapabilities.PHANTOMJS)
browser.get('http://1212.ip138.com/ic.asp')

 

火狐相关设置

# -*- coding: utf-8 -*-
from selenium import webdriver
options = webdriver.FirefoxOptions()
#火狐无头模式
options.add_argument('--headless')
options.add_argument('--disable-gpu')
# options.add_argument('window-size=1200x600')

driver_path = webdriver.Firefox(executable_path='geckodriver.exe',
                                firefox_options=options)

 

常用的浏览器请求头User-Agent

https://blog.csdn.net/mouday/article/details/80182397

 

博文参考:
https://blog.csdn.net/xc_zhou/article/details/80823855
https://www.zhihu.com/question/35547395
https://segmentfault.com/a/1190000013067705
https://www.cnblogs.com/lgh344902118/p/6339378.html

 

3、跳过https验证

有没有遇到过这样的情况,selenium请求一个url的时候,出现大大的几个字----------您的连接不是私密连接

如何解决呢,请往下看。

 

1、chrone

Chrome浏览器:需要添加ChromeOptions()参数

复制代码
from selenium import webdriver


# 实例化ChromeOptions
options = webdriver.ChromeOptions()

# 增加参数跳过验证
options.add_argument('--ignore-certificate-errors')

# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)

# 后面一样使用即可
driver.get('http://www.baidu.com')

driver.quit()
复制代码

 

2、Firefox

firefox浏览器:需要添加FirefoxProfile()的accept_untrusted_certs的选项为True

from selenium import webdriver

profile = webdriver.FirefoxProfile()

profile.accept_untrusted_certs = True
driver = webdriver.Firefox(firefox_profile=profile)
driver.get('http://www.baidu.com')
driver.quit()

 

3、PhantomJS
from selenium import webdriver

driver = webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])

driver.quit()

 

4、无痕模式

当启用浏览器打开网页的时候,可以直接启用无痕模式,省去清理缓存这一步骤。
初始化ChromeOptions 并设置"–incognito"

复制代码
from selenium import webdriver


# 实例化ChromeOptions
options = webdriver.ChromeOptions()

# 启动无痕模式
options.add_argument('–incognito')

# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)

# 后面一样使用即可
driver.get('http://www.baidu.com')

driver.quit()
复制代码

 

常用的启动项参数如下所示
启动参数 作用
–user-agent="" 设置请求头的User-Agent
–window-size=1366,768 设置浏览器分辨率(窗口大小)
–headless 无界面运行(无窗口)
–start-maximized 最大化运行(全屏窗口)
–incognito 隐身模式(无痕模式)
–disable-javascript 禁用javascript
–disable-infobars 禁用浏览器正在被自动化程序控制的提示

最后一个’–disable-infobars’,意思是这样的
如果不设置这个参数,浏览器打开会有这样的提示框
设置这个参数可以取消这个提示

 

5、Linux启动Chrome

在Linux上安装Chrome和使用selenium,我真是踩了好多坑,现在这里记录一下。

1.下载Chrome的Linux版本

直接找到GoogleChrome的官网:https://www.google.cn/chrome

后面加一些参数:standalone=1代表离线下载,platform=linux代表下载的是Linux平台的

所以最终下载地址是:https://www.google.cn/chrome/?standalone=1&platform=linux

对了,可能会需要下载一些对应的依赖,自行下载吧,因为每个人的机器配置可能不一致,就不写出来了,

验证Chrome是否安装成功并查看版本:google-chrome --version

注意了,Chrome是有多个发行版本的,我这里下载的是稳定常用的版本,如果是其他版本,

比如Ubuntu,一般下载chromium-browser会比较简单,那么就使用:chromium-browser --version 检查是否安装成功

 

2.下载对应Chrome的Chromedrive

无论是Chrome版本或者chromium-browser版本,下载的Chromedriver都是一样的。

国内可以在淘宝镜像下载(注意,需下载跟Chrome对应的版本):http://npm.taobao.org/mirrors/chromedriver/

 

3.下载Python的selenium模块

pip install selenium

 

4.推荐下载虚拟桌面配置

我尝试过了,有些机器不需要虚拟桌面也可以,但是有些是需要的,

推荐下载吧,因为无论需不需要,下载了都能用。

Centos下载:yum install Xvfb -y

Ubuntu下载:apt-get install Xvfb

下载好之后,需要下载Python对应的虚拟桌面模块:pip install PyVirtualDisplay

 

5.示例

复制代码
from selenium import webdriver
from pyvirtualdisplay import Display


# 启动虚拟桌面
display = Display(visible=0, size=(800, 600))
display.start()

# 实例化ChromeOptions
options = webdriver.ChromeOptions()
# Linux机器需要添加这些参数
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--headless')  # 无头模式
options.add_argument('--ignore-certificate-errors')  # 跳过https验证
# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)

# 你的操作...
driver.get('http://www.baidu.com')

# 清理
driver.quit()  # 退出浏览器
display.stop()  # 关闭虚拟桌面
复制代码

 

6、Linux下完全退出chrome进程

我们可能会遇到这样的情况,就是如果我们只开启一个Chromedriver进程,那么只要使用了driver.quit()是能够正常关闭并退出这个进程,

但是ChromeDriver是轻量级的服务,在单任务或不需要频繁启动浏览器的情况下,使用driver.quit()关闭浏览器,可以正常结束ChromeDriver进程。

若在一个比较大的测试套件中频繁的启动关闭,会增加一个比较明显的延时导致浏览器进程不被关闭的情况发生,

为了避免这一状况我们可以通过ChromeDriverService来控制ChromeDriver进程的生死,达到用完就关闭的效果避免进程占用情况出现。

复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

chrome_service = Service('/bin/usr/chromedriver')  # 括号内填写Chromedriver驱动路径
chrome_service.command_line_args()
chrome_service.start()

# 实例化ChromeOptions
options = webdriver.ChromeOptions()
# Linux机器需要添加这些参数
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--headless')  # 无头模式
options.add_argument('--ignore-certificate-errors')  # 跳过https验证
# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)

# 你的操作...
driver.get('http://www.baidu.com')

# 清理
driver.quit()  # 退出浏览器

chrome_service.stop()
复制代码

 

7、清理cookie缓存

如果你在服务器上跑selenium和webdriver,你可以 ls -la /tmp 查看 ,你会发现有很多 .org.chromium.xxx的隐藏文件。这就是访问网页的时候留下的缓存。

其实也很简单,直接 delete_all_cookies 即可

复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

chrome_service = Service('/bin/usr/chromedriver')  # 括号内填写Chromedriver驱动路径
chrome_service.command_line_args()
chrome_service.start()

# 实例化ChromeOptions
options = webdriver.ChromeOptions()
# Linux机器需要添加这些参数
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--headless')  # 无头模式
options.add_argument('--ignore-certificate-errors')  # 跳过https验证
options.add_argument('--disable-gpu')
options.add_argument('--disable-infobars')  # 禁用浏览器正在被自动化程序控制的提示
# 清理缓存的参数
options.add_argument('disable-cache')  # 禁用缓存
options.add_argument('--incognito')  # 无痕模式
# 实例化Chrome驱动
driver = webdriver.Chrome(chrome_options=options)

# 你的操作...
driver.get('http://www.baidu.com')

# 清理
driver.delete_all_cookies()  # 退出前清理cookie
driver.quit()  # 退出浏览器

chrome_service.stop()
复制代码

 

七、破解滑动验证码

复制代码
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait  # 等待元素加载的
from selenium.webdriver.common.action_chains import ActionChains  # 拖拽
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.by import By
from PIL import Image
import requests
import re
import random
from io import BytesIO
import time


def merge_image(image_file, location_list):
    """
     拼接图片
    """
    im = Image.open(image_file)
    im.save('code.jpg')
    new_im = Image.new('RGB', (260, 116))
    # 把无序的图片 切成52张小图片
    im_list_upper = []
    im_list_down = []
    # print(location_list)
    for location in location_list:
        # print(location['y'])
        if location['y'] == -58:  # 上半边
            im_list_upper.append(im.crop((abs(location['x']), 58, abs(location['x']) + 10, 116)))
        if location['y'] == 0:  # 下半边
            im_list_down.append(im.crop((abs(location['x']), 0, abs(location['x']) + 10, 58)))

    x_offset = 0
    for im in im_list_upper:
        new_im.paste(im, (x_offset, 0))  # 把小图片放到 新的空白图片上
        x_offset += im.size[0]

    x_offset = 0
    for im in im_list_down:
        new_im.paste(im, (x_offset, 58))
        x_offset += im.size[0]
    # new_im.show()
    return new_im


def get_image(driver, div_path):
    '''
    下载无序的图片  然后进行拼接 获得完整的图片
    :param driver:
    :param div_path:
    :return:
    '''
    background_images = driver.find_elements_by_xpath(div_path)
    location_list = []
    for background_image in background_images:
        location = {}
        result = re.findall('background-image: url\("(.*?)"\); background-position: (.*?)px (.*?)px;',
                            background_image.get_attribute('style'))
        # print(result)
        location['x'] = int(result[0][1])
        location['y'] = int(result[0][2])

        image_url = result[0][0]
        location_list.append(location)
    image_url = image_url.replace('webp', 'jpg')
    # '替换url http://static.geetest.com/pictures/gt/579066de6/579066de6.webp'
    image_result = requests.get(image_url).content
    image_file = BytesIO(image_result)  # 是一张无序的图片
    image = merge_image(image_file, location_list)

    return image


def get_track(distance):
    # 初速度
    v = 0
    # 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
    t = 0.2
    # 位移/轨迹列表,列表内的一个元素代表0.2s的位移
    tracks = []
    tracks_back = []
    # 当前的位移
    current = 0
    # 到达mid值开始减速
    mid = distance * 7 / 8
    print("distance", distance)
    global random_int
    random_int = 8
    distance += random_int  # 先滑过一点,最后再反着滑动回来

    while current < distance:
        if current < mid:
            # 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细
            a = random.randint(2, 5)  # 加速运动
        else:
            a = -random.randint(2, 5)  # 减速运动
        # 初速度
        v0 = v
        # 0.2秒时间内的位移
        s = v0 * t + 0.5 * a * (t ** 2)
        # 当前的位置
        current += s
        # 添加到轨迹列表
        if round(s) > 0:
            tracks.append(round(s))
        else:
            tracks_back.append(round(s))

        # 速度已经达到v,该速度作为下次的初速度
        v = v0 + a * t

        print("tracks:", tracks)
        print("tracks_back:", tracks_back)
        print("current:", current)

    # 反着滑动到大概准确位置

    tracks_back.append(distance - current)
    tracks_back.extend([-2, -5, -8, ])

    return tracks, tracks_back


def get_distance(image1, image2):
    '''
       拿到滑动验证码需要移动的距离
      :param image1:没有缺口的图片对象
      :param image2:带缺口的图片对象
      :return:需要移动的距离
      '''
    # print('size', image1.size)

    threshold = 50
    for i in range(0, image1.size[0]):  # 260
        for j in range(0, image1.size[1]):  # 160
            pixel1 = image1.getpixel((i, j))
            pixel2 = image2.getpixel((i, j))
            res_R = abs(pixel1[0] - pixel2[0])  # 计算RGB差
            res_G = abs(pixel1[1] - pixel2[1])  # 计算RGB差
            res_B = abs(pixel1[2] - pixel2[2])  # 计算RGB差
            if res_R > threshold and res_G > threshold and res_B > threshold:
                return i  # 需要移动的距离


def main_check_code(driver, element):
    """
    拖动识别验证码
    :param driver:
    :param element:
    :return:
    """

    login_btn = driver.find_element_by_class_name('js-login')
    login_btn.click()

    element = WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, 'gt_guide_tip')))
    slide_btn = driver.find_element_by_class_name('gt_guide_tip')
    slide_btn.click()

    image1 = get_image(driver, '//div[@class="gt_cut_bg gt_show"]/div')
    image2 = get_image(driver, '//div[@class="gt_cut_fullbg gt_show"]/div')
    # 图片上 缺口的位置的x坐标

    # 2 对比两张图片的所有RBG像素点,得到不一样像素点的x值,即要移动的距离
    l = get_distance(image1, image2)
    print('l=', l)

    # 3 获得移动轨迹
    track_list = get_track(l)
    print('第一步,点击滑动按钮')
    element = WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, 'gt_slider_knob')))
    ActionChains(driver).click_and_hold(on_element=element).perform()  # 点击鼠标左键,按住不放
    import time
    time.sleep(0.4)
    print('第二步,拖动元素')
    for track in track_list[0]:
        ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
    # time.sleep(0.4)
    for track in track_list[1]:
        ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
        time.sleep(0.1)
    import time
    time.sleep(0.6)
    # ActionChains(driver).move_by_offset(xoffset=2, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
    # ActionChains(driver).move_by_offset(xoffset=8, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
    # ActionChains(driver).move_by_offset(xoffset=2, yoffset=0).perform()  # 鼠标移动到距离当前位置(x,y)
    print('第三步,释放鼠标')
    ActionChains(driver).release(on_element=element).perform()
    time.sleep(1)


def main_check_slider(driver):
    """
    检查滑动按钮是否加载
    :param driver:
    :return:
    """
    while True:
        try:
            driver.get('https://www.huxiu.com/')
            element = WebDriverWait(driver, 30, 0.5).until(EC.element_to_be_clickable((By.CLASS_NAME, 'js-login')))
            if element:
                return element
        except TimeoutException as e:
            print('超时错误,继续')
            time.sleep(5)


if __name__ == '__main__':

    try:
        count = 3  # 最多识别3次
        driver = webdriver.Chrome()
        while count > 0:
            # 等待滑动按钮加载完成
            element = main_check_slider(driver)
            main_check_code(driver, element)
            try:
                success_element = (By.CSS_SELECTOR, '.gt_success')
                # 得到成功标志
                success_images = WebDriverWait(driver, 3).until(EC.presence_of_element_located(success_element))
                if success_images:
                    print('成功识别!!!!!!')
                    count = 0
                    import sys

                    sys.exit()
            except Exception as e:
                print('识别错误,继续')
                count -= 1
                time.sleep(1)
        else:
            print('too many attempt check code ')
            exit('退出程序')
    finally:
        driver.close()
View Code
复制代码

 

八、使用desired_capabilities获取浏览器日志

复制代码
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

# 定义日志参数
caps = DesiredCapabilities.CHROME
caps['loggingPrefs'] = {'performance': 'ALL'}

# 实例化驱动的时候把参数写进去
driver = webdriver.Chrome(desired_capabilities=caps)

driver.get("http://www.baidu.com")
# 获取全部日志
driver.get_log('performance')
复制代码

 

九、获取网页加载的各种时间

1、介绍

这里简单介绍下用法吧,如果需要深入研究,可参考这篇文章:https://blog.51cto.com/shuizhongyue/1718327

这里主要是使用window.performance去分析web前端性能,主要是通过window.performance.timing这个对象去进行分析,

window.performance.timing对象主要的页面属性如下:

复制代码
navigationStart               准备加载页面的起始时间
unloadEventStart              如果前一个文档和当前文档同源,返回前一个文档开始unload的时间
unloadEventEnd                如果前一个文档和当前文档同源,返回前一个文档开始unload结束的时间
redirectStart                 如果有重定向,这里是重定向开始的时间.
redirectEnd                   如果有重定向,这里是重定向结束的时间.
fetchStart                    开始检查缓存或开始获取资源的时间
domainLookupStart             开始进行dns查询的时间
domainLookupEnd               dns查询结束的时间
connectStart                  开始建立连接请求资源的时间
connectEnd                    建立连接成功的时间.
secureConnectionStart         如果是https请求.返回ssl握手的时间
requestStart                  开始请求文档时间(包括从服务器,本地缓存请求)
responseStart                 接收到第一个字节的时间
responseEnd                   接收到最后一个字节的时间.
domLoading                    current document readiness’ 设置为 loading的时间 (这个时候还木有开始解析文档)
domInteractive                文档解析结束的时间
domContentLoadedEventStart    DOMContentLoaded事件开始的时间
domContentLoadedEventEnd      DOMContentLoaded事件结束的时间
domComplete                   current document readiness被设置 complete的时间
loadEventStart                触发onload事件的时间
loadEventEnd                  onload事件结束的时间
复制代码

 

主要分析性能:

复制代码
对我们比较有用的页面性能数据大概包括如下几个:
DNS查询耗时、TCP链接耗时、request请求耗时、解析dom树耗时、白屏时间、domready时间、onload时间等,而这些参数是通过上面的performance.timing各个属性的差值组成的,计算方法如下:

DNS查询耗时 :domainLookupEnd - domainLookupStart

TCP链接耗时 :connectEnd - connectStart

request请求耗时 :responseEnd - responseStart

解析dom树耗时 : domComplete- domInteractive

白屏时间 :responseStart - navigationStart

domready时间 :domContentLoadedEventEnd - navigationStart

事件onload时间 :loadEventEnd - navigationStart

页面加载完成时间:performance.now()

NavigationTiming的目的是用于分析页面整体性能指标。如果要获取个别资源(例如JS、图片)的性能指标,就需要使用Resource Timing API。
复制代码

 

2、例子

思路其实很加单,就是上面介绍方法,用js去获取页面的加载时间,然后selenium使用execute_script方法执行js脚本

说明:js直接return的结果就是 execute_script 的返回值。不过,js是类型的,python也是弱类型的拿到返回值后腰给他一个数据类型,不然后期都没法处理。

页面加载一次后会有缓存存在,但是selenium打开浏览器打开新的页面的时候回自动清理缓存。

复制代码
from selenium import webdriver


driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

domready = """ 
// domready时间 
let mytiming = window.performance.timing;
return mytiming.domContentLoadedEventEnd - mytiming.fetchStart;
"""

loadEventTime = """
// 事件onload时间
let mytiming = window.performance.timing;
return mytiming.loadEventEnd - mytiming.navigationStart;
"""

domready_time = driver.execute_script(domready)
onload_time = driver.execute_script(loadEventTime)
print("dom加载完成时间:%s" % domready_time)
print("事件加载完成时间:%s" % onload_time)
driver.quit()
复制代码

 

posted @   我用python写Bug  阅读(1544)  评论(3编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示