引言

本文为某课程笔记,用于记录学习

1.selenium课程概要

本阶段课程主要学习selenium自动化测试框架在爬虫中的应用,selenium能够大幅度降低爬虫的编写难度,但是也同样会大幅降低爬虫的爬取速度。在逼不得已的情况下我们可以使用selenium进行爬虫的编写。
通常是前面requests和数据提取模块的配合进行数据抓取。

2.selenium的介绍

知识点:
了解 selenium的工作原理
了解 selenium以及chromedriver的安装
掌握 标签对象click点击以及send_keys输入

2.1selenium工作原理

利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)
在这里插入图片描述
浏览器厂商遵循了selenium规则
webdirver本质是一个web-server,对外提供webapi,其中封装了浏览器的各种功能
不同的浏览器使用各自不同的webdriver
原理:
代码 --> 调用webdriver --> 操作浏览器
不同的浏览器使用各自不同的driver

2.2selenium模块与driver的安装

2.2.1 在python虚拟机环境中安装selenium模块

pip/pip3 install selenium==版本号(不加版本号,默认为最新版的)

2.2.2 下载版本符合的webdriver,并配置

(1)查看浏览器的版本
在这里插入图片描述
(2)下载对应的版本
http://npm.taobao.org/mirrors/chromedriver/
在这里插入图片描述
(3)解压压缩包后获取python代码可以调用的谷歌浏览器的webdriver的可执行文件
windows为 chromedriver.exe
linux和macos为 chromedriver
(4)chromedriver环境的配置
windows环境下需要将chromedriver.exe所在的目录设置为path环境变量中的路径
linux/mac环境下,将chromedriver所在的目录设置到系统的PATH环境值中

注意:此处的本人的webdriver驱动直接放在pycharm虚拟环境的script目录下,调用时路径直接就可以,本人没有配置环境变量,直接使用驱动(driver.Chrome()),在开发时就不用写路径了。当然可以使用绝对路径的方式调用Chromedriver驱动,在后续打包exe时可以用到。

2.3selenium的简单使用

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 13:47
#@Author : 招财进宝
#@File : 2.selenium_baidu.py
#@Software: PyCharm


import time
from selenium import webdriver

# 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录
driver = webdriver.Chrome(executable_path='chromedriver.exe')
# chromedriver已经添加环境变量
#driver = webdriver.Chrome()

# 控制浏览器访问url地址
driver.get('https://www.baidu.com')
time.sleep(3)

# 在百度搜索框中搜索'python'(先定位,后输入)
driver.find_element_by_id('kw').send_keys('python')
time.sleep(3)

# 点击百度搜索(先定位,后点击)
driver.find_element_by_id('su').click()
time.sleep(6)

# 退出浏览器
driver.quit()

webdriver.Chrome(executable_path=‘chromedriver.exe’)中executable_path参数指定的是下载好的chromedriver文件的路径
driver.find_element_by_id(‘kw’).send_keys(‘python’)定位id属性值是’kw’的标签,并向其中输入字符串’python’
diver.find_element_by_id(‘su’).click()定位id属性值是su的标签,并点击
click函数作用是:触发标签的js的click事件

2.4selenium运行效果展示

selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,selenium可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等。我们可以使用selenium很容易完成之前编写的爬虫,但性能更慢一些,接下来我们就来看一下selenium的运行效果。

像360,搜狗,UC都不支持;支持Chrome,Firefox,等世界常用的
chrome浏览器的运行效果

2.4.1 chrome浏览器的运行效果

在下载好chromedriver以及安装好selenium模块后,执行下列代码并观察运行的过程。(也是有隐藏Chrome这个功能的)
下载地址:
http://npm.taobao.org/mirrors/chromedriver/
http://chromedriver.storage.googleapis.com/index.html
查看自己谷歌浏览器的版本:
chrome://version/
在这里插入图片描述
Google Chrome 86.0.4240.198 (正式版本) (64 位)

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 12:42
#@Author : 招财进宝
#@File : 1.selenium_test.py
#@Software: PyCharm


from selenium import webdriver

# 如果driver没有添加到了环境变量,则需要将driver的绝对路径赋值给executable_path参数
driver = webdriver.Chrome(executable_path='chromedriver.exe')

# 如果driver添加了环境变量则不需要设置executable_path
# driver = webdriver.Chrome()

# 向一个url发起请求
driver.get("http://www.baidu.com")

# 把网页保存为图片,69版本以上的谷歌浏览器将无法使用截图功能
#driver.save_screenshot('baidu.png')
try:
    picture_url=driver.save_screenshot('baidu.png')
    print("%s:截图成功!!!" % picture_url)
except BaseException as msg:
    print(msg)


# 打印页面的标题
print(driver.title)

# 退出模拟浏览器
driver.quit()  # 一定要退出,不退出会残留进程!

本地环境初次运行时截图失败错误
分析错误应该是chromedriver与chrome版本不匹配导致的
重新下载与chrome版本对应的chromedriver,下载链接
http://chromedriver.storage.googleapis.com/index.html
http://npm.taobao.org/mirrors/chromedriver/
以上两个链接都可以使用
本人的是86版本的,故下载了86版本的驱动,所以能进行截屏了
在这里插入图片描述
在这里插入图片描述

2.4.2Python selenium操作浏览器全屏截图

全屏截图时必须使用无界面模式
参考链接:https://www.cnblogs.com/hanfe1/p/13131583.html

# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
import time

def get_image(url, pic_name):
#chromedriver的路径
    chromedriver = r"C:\Users\name\AppData\Local\Google\Chrome\Application\chromedriver.exe"
    os.environ["webdriver.chrome.driver"] = chromedriver
#设置chrome开启的模式,headless就是无界面模式
#一定要使用这个模式,不然截不了全页面,只能截到你电脑的高度
    chrome_options = Options()
    chrome_options.add_argument('headless')
    driver = webdriver.Chrome(chromedriver,chrome_options=chrome_options)
#控制浏览器写入并转到链接
    driver.get(url)
    time.sleep(1)
#接下来是全屏的关键,用js获取页面的宽高,如果有其他需要用js的部分也可以用这个方法
    width = driver.execute_script("return document.documentElement.scrollWidth")
    height = driver.execute_script("return document.documentElement.scrollHeight")
    print(width,height)
#将浏览器的宽高设置成刚刚获取的宽高
    driver.set_window_size(width, height)
    time.sleep(1)
#截图并关掉浏览器
    driver.save_screenshot(pic_name)
    driver.close()

#你输入的参数
url = 'https://movie.douban.com/top250'
pic_name = r'D:\image.png'
get_image(url, pic_name)

2.4.3 phantomjs无界面浏览器的运行效果

不会产生界面,只是用来加载渲染的,需要用到浏览器引擎,webkit也是一个浏览器引擎,只是运行时不给界面,在内存中运行,依然按照有界面的内容进行运行。

PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript。下载地址:https://phantomjs.org/download.html
本地环境会有警告:
UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless ’
翻译过来就是:selenium已经放弃PhantomJS了,建议使用火狐或者谷歌无界面浏览器。

无头浏览器与有头浏览器的使用场景:
通常在开发过程中使用有头在部署时,部署到Linux服务器要使用无头浏览器(可以直接让Chrome隐藏界面,在后续会有讲解)

from selenium import webdriver

# 指定driver的绝对路径
driver = webdriver.PhantomJS(executable_path='phantomjs')

# 向一个url发起请求
driver.get("http://www.baidu.com")

# 把网页保存为图片,69版本以上的谷歌浏览器将无法使用截图功能
driver.save_screenshot('baidu.png')

# 打印页面的标题
print(driver.title)

# 退出模拟浏览器
driver.quit()  # 一定要退出,不退出会残留进程!

3.元素定位

元素定位非常重要,所有操作都必须先定位,找到数据在哪个标签上,再操作
知识点:
了解 driver对象的常用属性和方法
掌握 driver对象定位标签元素获取标签对象的方法
掌握 标签对象提取文本和属性值的方法

3.1driver属性和方法

在使用selenium过程中,实例化driver对象后,driver对象有一些常用的属性和方法
(1)driver.page_source 当前标签页浏览器渲染之后的网页源代码
(2)driver.current_url 当前标签页的url(可能被重定向后的url)
(3)driver.close() 关闭当前标签页,如果只有一个标签页则关闭整个浏览器
(4)driver.quit() 关闭浏览器
(5)driver.forward() 页面前进(很少用,直接get即可)
(6)driver.back() 页面后退(很少用,直接get即可)
(7)driver. save_screenshot() 页面截图

在有些时候要识别验证码,获取验证码图片,但验证码是一直变化的,无法准确的下载下来,可以对整个屏幕截图,然后抠图保存文件,调用相关方法对验证码进行解析。

3.2selenium中元素的定位

定位最重要
在selenium中可以通过多种方式来定位标签,返回标签元素对象
一共8种,只推荐6种
find_element_by_id(返回一个元素)
find_element(s)_by_class_name (根据类名获取元素列表)
find_element(s)_by_name(根据标签的name属性值返回包含标签对象元素的标签)
find_element(s)_by_xpath(返回一个包含元素的列表)
find_element(s)_by_link_text(根据连接文本获取元素列表)
find_element(s)_by_partial_link_text(根据链接包含的文本获取元素列表)
find_element(s)_by_tag_name(根据标签名获取元素列表)
find_element(s)_by_css_selector(根据css选择器来获取元素列表)
注意:
find_element和find_elements的区别:多了个s就返回列表,没有s就返回匹配到的第一个标签对象
find_element匹配不到就抛出异常,find_elements匹配不到就返回空列表
by_link_text和by_partial_link_text的区别:全部文本和包含某个文本
以上函数的使用方法
driver.find_element_by_id(‘id_str’)

在selenium中使用xpath只需要定位到节点就行,不用text()或者@属性等了。

Css选择器会被翻译成xpath,可以用xpath定位就行,或者id等,name等定位

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 15:34
#@Author : 招财进宝
#@File : 4.selenium_locate.py
#@Software: PyCharm

from selenium import webdriver

url='http://ww.baidu.com'

# 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录
driver = webdriver.Chrome(executable_path='chromedriver.exe')

driver.get(url)

# 通过xpath进行元素定位
# driver.find_element_by_xpath('//*[@id="kw"]').send_keys('python')
# 通过css选择器进行元素定位
# driver.find_element_by_css_selector('#kw').send_keys('java')
# 通过name属性值进行元素定位
# driver.find_element_by_name('wd').send_keys('html')
# 通过class属性值进行元素定位
# driver.find_element_by_class_name('s_ipt').send_keys('ruby')

# 通过链接文本进行元素定位(链接是鼠标移动到上面会变成小手的文本)
# driver.find_element_by_link_text('hao123').click()
# driver.find_element_by_partial_link_text('hao').click()       #此处的连接文本不用完全,包含一部分就能定位了

# 目标元素在当前html中是唯一标签的时候或者是众多定位出来的标签中的第一个的时候才能使用(定位到是对象,定位不到报错)
print(driver.find_element_by_tag_name('title'))

driver.find_element_by_id('su').click()

driver.quit()

在这里插入图片描述
下方为elements元素列表(不是上方只定位一个元素的element)

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 15:58
#@Author : 招财进宝
#@File : 5.selenium_locate_multi.py
#@Software: PyCharm


from selenium import webdriver
url='https://yt.58.com/chuzu/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.BDPCPZ_BT&PGTID=0d100000-000e-4493-e05f-7a52e80afcee&ClickID=2'
# 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录
driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get(url)
el_list = driver.find_elements_by_xpath('//li[@class="house-cell"]/div[2]/h2/a')
for el in el_list:
    print(el)

driver.quit()

当name和id和class没有的时候,使用xpath就万金油都能定位

3.3selenium中的元素操作

以前在xpath中使用text(等取数据,但在此处就不同了)
find_element仅仅能够获取元素,不能够直接获取其中的数据,如果需要获取数据需要使用以下方法:
获取文本 element.text
通过定位获取的标签对象的 text 属性,获取文本内容
获取属性值 element.get_attribute(“属性名”)
通过定位获取的标签对象的 get_attribute 函数,传入属性名,来获取属性的值

代码实现,如下:

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 15:58
#@Author : 招财进宝
#@File : 5.selenium_locate_multi.py
#@Software: PyCharm

from selenium import webdriver

url='https://yt.58.com/chuzu/?utm_source=market&spm=u-2d2yxv86y3v43nkddh1.BDPCPZ_BT&PGTID=0d100000-000e-4493-e05f-7a52e80afcee&ClickID=2'
# 通过指定chromedriver的路径来实例化driver对象,chromedriver放在当前目录
driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get(url)
el_list = driver.find_elements_by_xpath('//li[@class="house-cell"]/div[2]/h2/a')
print(len(el_list))
for el in el_list:
    print(el.text,el.get_attribute('href'))

driver.quit()

在这里插入图片描述
El.Click()
若定位的元素支持点击(如按钮,或者超链接等),可以调用click()函数,若无法点击的元素是会报错的
El.Send_keys()
必须是input标签能输入的标签,才能send_keys
El.clear()
可以对输入框进行清空操作,在登录时可能默认文字,可以先清空再send_keys

4.selenium的其他使用方法

知识点:
掌握 selenium控制标签页的切换
掌握 selenium控制iframe的切换
掌握 利用selenium获取cookie的方法
掌握 手动实现页面等待
掌握 selenium控制浏览器执行js代码的方法
掌握 selenium开启无界面模式
了解 selenium使用代理ip
了解 selenium替换user-agent

4.1selenium中的标签切换

selenium标签页的切换
当我们使用click时会新建一个标签页面,但我们还停留在原来的标签页上,并没有在新的标签页,所以

当selenium控制浏览器打开多个标签页时,如何控制浏览器在不同的标签页中进行切换呢?需要我们做以下两步:

  • 获取所有标签页的窗口句柄
  • 利用窗口句柄切换到句柄指向的标签页
    这里的窗口句柄是指:指向标签页对象的标识

具体的方法
1.获取当前所有的标签页的句柄构成的列表
Current_windows = driver.window_handles
我们每新开一个标签,在列表会加入新开的标签的句柄,通过此可以切换过去

2.根据标签页句柄列表索引下标进行切换
Switch_to.window(current_windows[0])
参考代码示例:

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 16:36
#@Author : 招财进宝
#@File : 3.window_handles.py
#@Software: PyCharm

from selenium import webdriver

url='https://jn.58.com/'

driver = webdriver.Chrome()
driver.get(url)

#打印当前标签页的url地址,打印窗口句柄
print(driver.current_url)
print(driver.window_handles)

#定位并点击租房按钮
el = driver.find_element_by_xpath('//*[@id="fcNav"]/em/a[1]')
el.click()

print(driver.current_url)
print(driver.window_handles)

driver.quit()

在这里插入图片描述
我们需要使用driver.switch_to.window(driver.window_handles[-1])跳转到最新标签页

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 16:36
#@Author : 招财进宝
#@File : 3.window_handles.py
#@Software: PyCharm

from selenium import webdriver

url='https://jn.58.com/'
driver = webdriver.Chrome()
driver.get(url)

#打印当前标签页的url地址,打印窗口句柄
print(driver.current_url)
print(driver.window_handles)

#定位并点击租房按钮
el = driver.find_element_by_xpath('//*[@id="fcNav"]/em/a[1]')
el.click()

print(driver.current_url)
print(driver.window_handles)

driver.switch_to.window(driver.window_handles[-1])
print(driver.current_url)
print(driver.window_handles)

el_list = driver.find_elements_by_xpath('//li[@class="house-cell"]/div[2]/h2/a')
print(len(el_list))

driver.quit()

在这里插入图片描述

4.2switch_to切换frame标签

Iframe是HTML中常用的一种技术,即一个页面中嵌套了另一个页面,selenium默认是访问不了frame中的内容的,对应的解决思路是driver.switch_to.frame(frame_element)。接下来我们通过qq邮箱模拟登陆来学习这个知识点
#跳转的方法一、
#driver.switch_to.frame(‘login_frame’) #里面可以放置iframe的id值

#跳转的方法二(先定位元素,再将元素放入)
el_frame = driver.find_element_by_xpath(’//*[@id=“login_frame”]’)
driver.switch_to.frame(el_frame)

只能操作外部大范围的内容,而frame中的内容不能直接操作
在这里插入图片描述
在这里插入图片描述

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 17:05
#@Author : 招财进宝
#@File : 7.qzone.py
#@Software: PyCharm


from selenium import webdriver
import time

url='https://i.qq.com/'

driver = webdriver.Chrome()
driver.get(url)

#跳转的方法一、
#driver.switch_to.frame('login_frame')       #里面可以放置iframe的id值

#跳转的方法二(先定位元素,再将元素放入)
el_frame = driver.find_element_by_xpath('//*[@id="login_frame"]')
driver.switch_to.frame(el_frame)

driver.find_element_by_id('switcher_plogin').click()
time.sleep(3)
driver.quit()

在这里插入图片描述

5.cookies操作

Selenium能够帮助我们处理页面中的cookie,比如获取、删除

(1)获取cookie
Driver.get_cookies() 返回列表,其中包含的是完整的cookies信息!不光有name、value,还有domain等cookie其他维度的信息,所以如果想要把获取的cookies信息和requests模块配合使用的话,需要转换成name、value作为键值对的cookie字典。

#把cookie转化成为字典
#方法一(for 循环获取字典)、
cookies = {}
for data in driver.get_cookies():
    cookies[data['name']] = data['value']

#方法二(字典推导式获取字典)、
cookies = {cookie['name']:cookie['value'] for cookie in driver.get_cookies()}

from selenium import webdriver
import time

url='https://www.baidu.com/'

driver = webdriver.Chrome()
driver.get(url)
print(driver.get_cookies())

driver.quit()

可以拿到cookie
拿到cookie字典,进行requests应用
有的网站登录非常麻烦,可以先用selenium登录,登录后记住cookie,使用cookie字典,剩下的后面的操作可以使用requests模块,那个模块就比较快了

from selenium import webdriver
import time

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

#print(driver.get_cookies())
cookies = {}
for data in driver.get_cookies():
    cookies[data['name']] = data['value']

print(cookies)
driver.quit()

在这里插入图片描述
字典推导式,列表推导式,经常在面试一行九九乘法表,一行什么东西

(2)删除cookie(一般是用不到的)
#删除一条cookie
driver.delete_cookie(‘CookieName’)

(3)删除所有的cookie
driver.delete_all_cookies()

6.selenium控制浏览器执行js代码

在使用selenium过程中绝大多数操作,都可以通过selenium这个模块相关方法实现相应功能,但也存在一些无法操作的功能,可以执行js代码来实现。
Selenium是没有下拉的功能的,可以使用js实现,用于触发式的请求中
有时再去进行元素定位时,如果想要定位的元素没有出现在视野中(浏览器的左上角到浏览器的左下角),这个元素就可能点击不成功,此时会报一种unknown err的错误

#滚动条的拖动
js = 'scrollTo(0,500)'			#x水平移动,y垂直移动

#执行js
driver.execute_script(js)

如链家,通常下拉点击租房()
在这里插入图片描述

from selenium import webdriver
import time

url='http://jn.lianjia.com/'

driver = webdriver.Chrome()
driver.get(url)

el_button = driver.find_element_by_xpath('/html/body/div[2]/ul/li/a')
el_button.click()

要点击的图片未在视野中,会报错
在这里插入图片描述

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/2 20:25
#@Author : 招财进宝
#@File : 5.script_excute.py
#@Software: PyCharm

from selenium import webdriver
import time

url='http://jn.lianjia.com/'

driver = webdriver.Chrome()
driver.get(url)

#滚动条的拖动
js = 'scrollTo(0,500)'
#执行js
driver.execute_script(js)

el_button = driver.find_element_by_xpath('/html/body/div[2]/ul/li/a')
el_button.click()

time.sleep(3)
driver.quit()

7.页面等待

页面在加载的过程中需要花费时间等待网站服务器的响应,在这个过程中标签元素有可能还没有加载出来,是不可见的,如何处理这种情况呢?可以使用页面等待方法

页面等待的分类
1.强制等待
2.隐式等待
3.显示等待

7.1强制等待(了解)

其实就是time.sleep()
时间被固定死了
缺点是不智能,设置的时间太短,元素还没有加载出来;设置的时间太长,则会浪费时间

7.2隐式等待

(1)针对的是元素定位,隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步(剩余的时间就不等了)
(2)在设置的时间内没有定位成功,则会报超时加载
(3)较为常用的一种等待方式

有时页面虽然刷新加载完毕了,但是有时会在页面触发一次ajax请求,一旦ajix请求触发就会向服务器发送请求,我们在响应过程中可能会因为网络原因响应速度比较慢,响应速度慢会导致元素定位失败,此时通常设置隐式等待或者强制等待来做相应的处理。

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/3 10:44
#@Author : 招财进宝
#@File : 6.wait_test.py
#@Software: PyCharm


from selenium import webdriver
import time

url='https://www.baidu.com/'

driver = webdriver.Chrome()
#设置位置之后的所有元素定位操作都有最大等待时间十秒,在10秒内会定期进行元素定位,超过设置时间之后将会报错
driver.implicitly_wait(10)

driver.get(url)

#el = driver.find_element_by_xpath('//*[@id="s_lg_img"]')    #此处是可以定位到的不会报错

el = driver.find_element_by_xpath('/[@id="s_lg_img"]')  #此处无法定位会报错,但之前设置了隐式等待,会在10秒后进行报错,若在10秒内定位到了,就直接执行下一步

print(el)
driver.quit()

7.3显式等待(了解)

显式等待就是明确的等待一个元素,和隐式等待不同,隐式等待是所有的定位元素,而显式等待是一个定位元素,此元素不出现就等待在时间内。

显式等待通常用于软件测试,在爬虫中是不用的,了解即可

(1)每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码
(2)如果没有达成就继续等待直到超过规定的时间后,报超时异常

示例代码(比较复杂)

尽量先使用隐式等待,隐式等待不能用了再使用强制等待
在这里插入图片描述

7.4手动实现页面等待

在了解了隐式等待和显式等待以及强制等待之后,我们发现并没有一种通用的方法来解决页面等待的问题,比如“页面需要滑动才能触发ajax异步加载”的场景,那么接下来我们就以淘宝网首页为例,手动实现页面等待

原理
(1)利用强制等待和显示等待的思路手动实现
(2)不停的判断或有次数限制的判断某一个标签对象是否加载完毕(是否存在)

代码如下:

8.selenium开启无界面模式

无头(部署到服务器)
Driver = webdriver.PhantomJS()
有头(开发过程)
Driver = webdriver.Chrome()

有些网站可能就反PhantomJS(),此时我们就使用Chrome(),Chrome在6X版本就支持无头了

绝大多数服务器是没有界面的,selenium控制谷歌浏览器也是存在无界面模式的,这一小节我们就来学习如何开启无界面模式(又称为无头模式)

开启无界面模式的方法
(1)实例化配置对象
opt = webdriver.ChromeOptions()
(2)配置对象添加开启无界面模式的命令
opt.add_argument(’–headless’)
(3)配置对象添加禁用gpu的命令
opt.add_argument(’–disable-gpu’)
(4)实例化带有配置对象的driver对象
#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/3 15:33
#@Author : 招财进宝
#@File : 11.selenium_config.py
#@Software: PyCharm

from selenium import webdriver

url = 'http://www.baidu.com'

#创建配置对象
opt = webdriver.ChromeOptions()

#添加配置参数
opt.add_argument('--headless')
opt.add_argument('--disable-gpu')

#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

driver.get(url)
driver.save_screenshot('百度到此一游.png')

driver.quit()

9.selenium使用代理ip

Selenium控制浏览器也是可以使用代理ip的

代理网站有:
国内高速免费HTTP代理-快代理
无忧代理ip-髙匿HTTP代理ip服务器供应商
免费代理-米扑代理 https://proxy.mimvp.com/freeopen
代理精灵-专业http代理

以前使用requests修改代理,此处使用浏览器如何修改代理,代理服务器可能比较慢或者挂掉了

使用代理ip的方法
(1)实例化配置对象
opt = webdriver.ChromeOptions()
(2)配置对象添加使用代理ip的命令
#更换ip代理,必须重新启动浏览器
opt.add_argument(’–proxy-server=http://36.248.129.239:9999’)
(3)实例化带有配置对象的driver对象
#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

此处使用的米扑代理 https://proxy.mimvp.com/freeopen
在这里插入图片描述
在这里插入图片描述
进行复制黏贴,地址和端口号

175.44.109.170
每次换ip代理的时候都要关掉driver对象,再重新创建对象,麻烦的地方

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/3 15:33
#@Author : 招财进宝
#@File : 11.selenium_config.py
#@Software: PyCharm

from selenium import webdriver

url = 'http://www.baidu.com'

#创建配置对象
opt = webdriver.ChromeOptions()

#添加配置参数
#更换ip代理,必须重新启动浏览器
opt.add_argument('--proxy-server=http://36.248.129.239:9999')

#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

driver.get(url)
#driver.quit()

10.selenium替换user-agent

替换user-agent的方法
(4)实例化配置对象
opt = webdriver.ChromeOptions()
(5)配置对象添加使用代理ip的命令
#更换ip代理,必须重新启动浏览器
opt.add_argument(’–proxy-server=http://36.248.129.239:9999’)
(6)实例化带有配置对象的driver对象
#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

from selenium import webdriver

url = 'http://www.baidu.com'

#创建配置对象
opt = webdriver.ChromeOptions()

#添加配置参数
# opt.add_argument('--headless')
# opt.add_argument('--disable-gpu')
#更换ip代理,必须重新启动浏览器
#opt.add_argument('--proxy-server=http://36.248.129.239:9999')
#更换user-agent
opt.add_argument('--user-agent=Mozilla/5.0 python37')

#创建浏览器对象的时候添加配置对象(最近的版本是options不是chrome_options,否则会警告)
driver = webdriver.Chrome(options=opt)

driver.get(url)
#driver.save_screenshot('百度到此一游.png')

#driver.quit()

在这里插入图片描述
也有其他的配置(如为了加快下载速度不要图片的)

11.案例:斗鱼直播

https://www.douyu.com/directory/all
点击下一页的时候,页面没有看到刷新,应该是ajax
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
检查最后一页与前面的页面之间的区别,得到终止条件,不能写死,不同的时间进行主播的人也是不同的

在这里插入图片描述
发现下一页的属性在最后一页与前面的不同,可以通过此进行定位
//*[@class=“dy-Pagination-next”]

最后发现使用上面的xpath进行定位只会定位到前面的下一页,到最后的时候就定位不到了,此时就会报错结束可以使用try except
在这里插入图片描述

#-*- codeing = utf-8 -*- 
#@Time : 2021/1/3 17:08
#@Author : 招财进宝
#@File : 12.douyu.py
#@Software: PyCharm

from selenium import webdriver


class Douyu(object):
    def __init__(self):
        self.url = 'https://www.douyu.com/directory/all'
        self.driver = webdriver.Chrome()
        # 创建配置对象(无头)
        # self.opt = webdriver.ChromeOptions()
        # self.opt.add_argument('--headless')
        # self.opt.add_argument('--disable-gpu')
        # self.driver = webdriver.Chrome(options=self.opt)


    def parse_data(self):

        #先获取所有房间列表,再逐个得到每个房间的信息
        room_list = self.driver.find_elements_by_xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div')
        #print(len(room_list))      #120

        data_list = []
        #遍历房间列表,从每个房间节点中获取数据
        for room in room_list:
            temp={}
            temp['title'] = room.find_element_by_xpath('./a[1]/div[2]/div[1]/h3').text
            temp['type'] = room.find_element_by_xpath('./a[1]/div[2]/div[1]/span').text
            temp['owner'] = room.find_element_by_xpath('./a[1]/div[2]/div[2]/h2').text
            temp['num'] = room.find_element_by_xpath('./a[1]/div[2]/div[2]/span').text
            temp['img'] = room.find_element_by_xpath('//img').get_attribute('src')
            print(temp)
            data_list.append(temp)

        return data_list

    #此处应该是保存数据了,但没有写,只是先打印
    def save_data(self,data_list):
        for data in data_list:
            print(data)

    def run(self):
        #url
        #driver
        # 全屏显示
        self.driver.maximize_window()   #全屏显示
        #self.driver.set_window_size(2500, 2000)  # 调整到固定大小

        #设置隐式等待(下面定位不到会等待,若在10秒内定位到不报错,超出报错)
        self.driver.implicitly_wait(10)

        #get
        self.driver.get(self.url)

        self.driver.find_element_by_xpath('/html/body/div[2]/span[2]').click()  # 点击取消页面缩放比例不正确,这是导致无法完全获得信息的原因

        #通过下一页不断的换页
        while True:
            # 滚动条的拖动(下滑到最底层,防止下方未加载)
            self.driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')

            #parse
            data_list = self.parse_data()
            #save
            self.save_data(data_list)
            #next
            #定位到下一页
            # el_next = self.driver.find_element_by_class_name('dy-Pagination-next')
            # print(el_next)
            # el_next.click()
            try:
                el_next = self.driver.find_element_by_class_name('dy-Pagination-next')
                print(el_next)
                el_next.click()
            except:
                    break
            
        self.driver.quit()


if __name__ == '__main__':
    douyu = Douyu()
    douyu.run()

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐