爬虫 安装 selenium = 3.141.0,chromedriver=84.0.4147.30

一、安装配置环境 

1、安装环境需要注意的点:
    chromedriver的版本需要与chrome的版本一一对应

   

1、安装  selenium = 3.141.0

pip install -i https://mirrors.aliyun.com/pypi/simple/ --upgrade selenium=3.141.0

2、安装 chromedriver selenium在ananconda环境下的安装与浏览器配置

浏览器驱动下载地址
Chromehttps://sites.google.com/a/chromium.org/chromedriver/downloads
Edgehttps://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefoxhttps://github.com/mozilla/geckodriver/releases
Safarihttps://webkit.org/blog/6900/webdriver-support-in-safari-10/

       验证

from selenium import webdriver
options = webdriver.ChromeOptions()
# 增加无头
options.add_argument('--headless')
options.add_argument('--disable-gpu')
# 防止被网站识别,开发者模式
options.add_experimental_option('excludeSwitches',['enable-automation'])

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

3、可能遇到的问题

      1.安装完selenium后,matplotlib无法使用,使用pip/conda uninstall matplotlib卸载后在重新安装matplotlib

      2.chromedriver.exe的版本应该与Chrome浏览器的版本相一致。在浏览器中输入chrome://version/可以查看浏览

        器版本,以下是版本对应关系

4、selenium 的简单用法 Python Selenium库的使用

       (1)不弹出浏览器设置

from selenium import webdriver
options = webdriver.ChromeOptions()
# 增加无头
options.add_argument('--headless')
options.add_argument('--disable-gpu')
# 防止被网站识别,开发者模式
options.add_experimental_option('excludeSwitches',['enable-automation'])

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

二、selenium启动Chrome配置参数问题

每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件、没有收藏、没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器,这就是为什么需要配置参数的原因,但是有些时候我们需要的不仅是一个裸浏览器。
selenium启动配置参数接收是ChromeOptions类,创建方式如下:

from selenium import webdriver
option = webdriver.ChromeOptions()

创建了ChromeOptions类之后就是添加参数,添加参数有几个特定的方法,分别对应添加不同类型的配置项目。

设置 chrome 二进制文件位置 (binary_location)

from selenium import webdriver
option = webdriver.ChromeOptions()
# 添加启动参数
option.add_argument()
# 添加扩展应用 
option.add_extension()
option.add_encoded_extension()
# 添加实验性质的设置参数 
option.add_experimental_option()
# 设置调试器地址
option.debugger_address()
from selenium import webdriver
options = webdriver.ChromeOptions()
# 增加无头
options.add_argument('--headless')
options.add_argument('--disable-gpu')
# 防止被网站识别,开发者模式
options.add_experimental_option('excludeSwitches',['enable-automation'])

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

常用配置参数:

from selenium import webdriver
option = webdriver.ChromeOptions()
# 添加UA
options.add_argument('user-agent="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('window-size=1920x3000') 
# 谷歌文档提到需要加上这个属性来规避bug
options.add_argument('--disable-gpu') 
# 隐藏滚动条, 应对一些特殊页面
options.add_argument('--hide-scrollbars')
# 不加载图片, 提升速度
options.add_argument('blink-settings=imagesEnabled=false') 
# 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
options.add_argument('--headless') 
# 以最高权限运行
options.add_argument('--no-sandbox')
# 手动指定使用的浏览器位置
options.binary_location = r"C:\Google\Chrome\Application\chrome.exe" 
#添加crx插件
option.add_extension('d:\crx\AdBlock_v2.17.crx') 
# 禁用JavaScript
option.add_argument("--disable-javascript") 
# 设置开发者模式启动,该模式下webdriver属性为正常值
options.add_experimental_option('excludeSwitches', ['enable-automation']) 
# 禁用浏览器弹窗
prefs = {  
    'profile.default_content_setting_values' :  {  
        'notifications' : 2  
     }  
}  
options.add_experimental_option('prefs',prefs)

driver = webdriver.Chrome(chrome_options=options)

浏览器地址栏参数:

在浏览器地址栏输入下列命令得到相应的信息

about:version - 显示当前版本
about:memory - 显示本机浏览器内存使用状况
about:plugins - 显示已安装插件
about:histograms - 显示历史记录
about:dns - 显示DNS状态
about:cache - 显示缓存页面
about:gpu -是否有硬件加速
chrome://extensions/ - 查看已经安装的扩展

其他配置项目参数

options.add_argument('--headless') #设置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个
  --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 

三、selenium 三种等待方式 点击

遇到的问题描述

我们经常会碰到用selenium操作页面上某个元素的时候, 需要等待页面加载完成后, 才能操作。  否则页面上的元素不存在,会抛出异常。  

比如:

一个动态网页使用了ajax的异步加载,我们需要等待元素加载完成后, 才能操作这个元素

(事实上,现在我们遇到的所有想要爬取的网站都或多或少的使用了各种各样的动态技术加载局部元素来提升访问效率)

selenium 中提供了非常简单,智能的方法,来判断元素是否存在.

最直接的方法就是

强制等待:sleep():

import time
sleep(5) #等待5秒

缺点不言而喻,对程序不友好,影响脚本运行效率,占用服务器资源


隐式等待:implicitly_wait() 这种方法具有全局性

driver.implicitly_wait(10) #隐式等待10秒 

由webdriver提供的方法,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用,它不针对某一个元素,是全局元素等待,即在定位元素时,需要等待页面全部元素加载完成,才会执行下一个语句。如果超出了设置时间的则抛出异常。

缺点:当页面某些js无法加载,但是想找的元素已经出来了,它还是会继续等待,直到页面加载完成(浏览器标签左上角圈圈不再转),才会执行下一句。某些情况下会影响脚本执行速度。

测试代码

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import os
url = "file:///E:/code/py_project/untitled/testHtml.html"
def fun_1(URL):
    browner = webdriver.Chrome()
    browner.get(URL)
    browner.find_element_by_id("testBtn").click()
    browner.implicitly_wait(10) # 隐式等待10秒
    WebElement = browner.find_element_by_class_name("red_box")
    my_js = 'arguments[0].style.width = "200px";arguments[0].style.height = "200px"'
    browner.execute_script(my_js, WebElement)
    os.system("pause")

fun_1(url)

显式等待:WebDriverWait(driver, timeout, poll_frequency, ignored_exceptions)

  • driver:浏览器驱动
  • timeout:最长超时时间,默认以秒为单位
  • poll_frequency:检测的间隔步长,默认为0.5s
  • ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。

   与until()或者until_not()方法结合使用

WebDriverWait(driver,10).until(method,message="")
调用该方法提供的驱动程序作为参数,直到返回值为True
WebDriverWait(driver,10).until_not(method,message="")
调用该方法提供的驱动程序作为参数,直到返回值为False

在设置时间(10s)内,等待后面的条件发生。如果超过设置时间未发生,则抛出异常。在等待期间,每隔一定时间(默认0.5秒),调用until或until_not里的方法,直到它返回True或False. 

测试代码:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import os
 
url = "file:///E:/code/py_project/untitled/testHtml.html"
 
def fun_1(URL):
    browner = webdriver.Chrome()
    browner.get(URL)
    browner.find_element_by_id("testBtn").click()
    # 设置隐式等待
    # browner.implicitly_wait(10)  # 隐式等待10秒
 
    # 设置显示等待 - 1
    wait = WebDriverWait(browner, 10, 0.5)
    # 使用匿名函数
    wait.until(lambda diver: browner.find_element_by_class_name('red_box'))
 
    # 等到这个元素加载完毕再操作就不会报错
    WebElement = browner.find_element_by_class_name("red_box")
    my_js = 'arguments[0].style.width = "200px";arguments[0].style.height = "200px"'
    browner.execute_script(my_js, WebElement)
 
    os.system("pause")
 
fun_1(url)

WebDriverWait与expected_conditions结合使用

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
 
wait = WebDriverWait(driver,10,0.5)
element =waite.until(EC.presence_of_element_located((By.ID,"kw"),message="")

测试代码:

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os
 
url = "file:///E:/code/py_project/untitled/testHtml.html"
 
 
def fun_1(URL):
    browner = webdriver.Chrome()
    browner.get(URL)
    browner.find_element_by_id("testBtn").click()
 
    wait = WebDriverWait(browner, 10, 0.5)
    wait.until(EC.presence_of_element_located((By.CLASS_NAME, "red_box")))
 
    # 等到这个元素加载完毕再操作就不会报错
    WebElement = browner.find_element_by_class_name("red_box")
    my_js = 'arguments[0].style.width = "200px";arguments[0].style.height = "200px"'
    browner.execute_script(my_js, WebElement)
 
    os.system("pause")
 
fun_1(url)

expected_conditions类提供的预期条件判断的方法 

方法说明
title_is判断当前页面的 title 是否完全等于(==)预期字符串,返回布尔值
title_contains判断当前页面的 title 是否包含预期字符串,返回布尔值
presence_of_element_located判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见
visibility_of_element_located判断元素是否可见(可见代表元素非隐藏,并且元素宽和高都不等于 0)
visibility_of同上一方法,只是上一方法参数为locator,这个方法参数是 定位后的元素
presence_of_all_elements_located判断是否至少有 1 个元素存在于 dom 树中。举例:如果页面上有 n 个元素的 class 都是’wp’,那么只要有 1 个元素存在,这个方法就返回 True
text_to_be_present_in_element判断某个元素中的 text 是否 包含 了预期的字符串
text_to_be_present_in_element_value判断某个元素中的 value 属性是否包含 了预期的字符串
frame_to_be_available_and_switch_to_it判断该 frame 是否可以 switch进去,如果可以的话,返回 True 并且 switch 进去,否则返回 False
invisibility_of_element_located判断某个元素中是否不存在于dom树或不可见
element_to_be_clickable判断某个元素中是否可见并且可点击
staleness_of等某个元素从 dom 树中移除,注意,这个方法也是返回 True或 False
element_to_be_selected判断某个元素是否被选中了,一般用在下拉列表
element_selection_state_to_be判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locator
alert_is_present判断页面上是否存在 alert

显示等待,自定义等待条件

#设置等待
wait = WebDriverWait(driver,10,0.5)
#使用匿名函数
wait.until(lambda diver:driver.find_element_by_id('kw'))

四、常见的操作

     1、多个窗口进行切换

# 关闭源网站的窗口
main_handle = browser.current_window_handle  # 输出当前窗口句柄(百度)
handles = browser.window_handles  # 获取当前窗口句柄集合(列表类型)
for handle in handles:  # 切换窗口(切换到搜狗)
    if handle != main_handle:
        browser.switch_to.window(handle) # 切换窗口
        browser.close()
        break
browser.switch_to.window(main_handle) # 切换为主窗口

     2、自动滚动条,滚动到页面最下方(缺点:无法点击 ‘ 加载更多 ’)

# TODO 滑动到底的js代码
js = """ 
       (function () { 
           var y = document.documentElement.scrollTop; 
           var step = 100; 
           window.scroll(0, y); 
           function f() { 
               if (y < document.body.scrollHeight) { 
                   y += step; 
                   window.scroll(0, y); 
                   setTimeout(f, 70); //每两次间隔滑动的时间

               }
               else { 
                   window.scroll(0, y); 
                   document.title += "scroll-done"; 
               } 
           } 
           setTimeout(f, 1500); //滑动过程中极限停止滑动时间
       })(); 
"""

# TODO 执行滑动到底的操作
browser.execute_script(js)

3、 document.documentElement.scrollTop 各个浏览器滚动条 

          参考:JavaScript学习笔记之 document.body.scrollTop用法

谷歌浏览器
网页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度:window.screen.availWidth;

scrollHeight 获取对象的滚动高度。
scrollLeft 设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
scrollWidth 获取对象的滚动宽度
offsetHeight 获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度
offsetLeft 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
offsetTop 获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置
event.clientX 相对文档的水平座标
event.clientY 相对文档的垂直座标

event.offsetX 相对容器的水平坐标
event.offsetY 相对容器的垂直坐标
document.documentElement.scrollTop 垂直方向滚动的值
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量

     需要注意的是: 

要获取当前页面的滚动条纵坐标位置,用:
document.documentElement.scrollTop;
而不是:
document.body.scrollTop;

documentElement 对应的是 html 标签,而 body 对应的是 body 标签

五、利用selenium爬取 Google 引擎高清图片

                自写利用 selenium 下载Google高清图片

六、selenium 使用过程中常遇到得问题

      1、Selenium 元素定位正确,但始终报找不到元素错误?

               Selenium 元素定位正确,但始终报找不到元素错误几种情况

      2、

 

Reference

       selenium启动Chrome配置参数问题

 

 

 

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值