Python爬虫4.3 — selenium基础用法教程

综述

本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万一一不小心又正好对你有用那就更好了。
Python 版本是3.7.4

在前一章中,我们了解了Ajax的分析和抓取方式,这其实也是JavaScript动态渲染的页面的一种情形,通过直接分析Ajax,我们仍然可以借助requests或urllib来实现数据爬取。

不过JavaScript动态渲染的页面不止Ajax这一种。例如淘宝这种页面,它即使是Ajax获取的数据,但是其Ajax接口含有很多加密参数,我们难以直接找出其规律,也很难直接分析Ajax来抓取。

为了解决这些问题,我们可以直接使用模拟浏览器运行的方式来实现,这样就可以做到在浏览器中看到是什么样,抓取的源码就是什么样,也就是可见即可爬。这样我们就不用再去管网页内部的JavaScript用了什么算法渲染页面,不用管网页后台的Ajax接口到底有哪些参数。

Python提供了许多模拟浏览器运行的库,如Selenium、Splash、PyV8、Ghost等。本章中,我们就来介绍一下Selenium的用法。Selenium+chromedriver(Headless Chrome)可以称为爬虫的终极解决方案。

Selenium + Chromedriver

Selenium 介绍

Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。

可以将Selenium理解相当于一个机器人,可以模拟人类在浏览器上的一切行为,自动处理浏览器上的一些行为。

Chromedriver 介绍

Chromedriver是一个驱动Chrome浏览器的驱动程序,使用它才可以驱动浏览器。

Headless Chrome在Chrome59中开始搭载HeadlessChrome。这是一种在无需显示headless的环境下运行Chrom浏览器的方式。从本质上来说,就是不用chrome浏览器来运行Chrome的功能!

自从SeleniumPhantomJS"分手"之后,使用Selenium+Headless Chrome成为主流。

其他浏览器的driver

  1. Chrome : https://sites.google.com/a/chromium.org/chromedriver/downloads
  2. Firefox : https://github.com/mozilla/geckodriver/releases
  3. Edge : https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
  4. Safari : https://webkit.org/blog/6900/webdriver-support-in-safari-10/

安装Selenium+chromedriver

  1. 安装SeleniumSelenium有很多语言的版本,有java、ruby、python等。我们使用pip安装python版本即可:
    $ pip install selenium
  1. 安装chromedriver:下载相应的chromedriver放到不需要权限的纯英文目录下就可以了。版本号对应描述:http://chromedriver.storage.googleapis.com/2.40/notes.txt

简单使用

获取百度首页

现在我们以一个简单的获取百度首页的例子来讲下Seleniumchromedriver如何快速入门,示例代码如下:

# 引入所需库
from selenium import webdriver

# 声明定义chromedriver路径
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 实例化Chrome
# 如果时其他浏览器需要实例化为对应的对象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打开百度
driver.get('https://www.baidu.com/')
# 获取源码
print(driver.page_source)
# 关闭
driver.close()

Selenium常用操作

更多教程请参考:https://python-selenium-zh.readthedocs.io/zh_CN/latest/

关闭页面

  1. driver.close() : 关闭当前页面。
  2. driver.quit() : 退出整个浏览器。

示例代码如下:

# 引入所需库
import time
from selenium import webdriver

# 声明定义chromedriver路径
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 实例化Chrome
# 如果时其他浏览器需要实例化为对应的对象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打开百度
driver.get('https://www.baidu.com/')
time.sleep(5)
# 关闭当前页面
driver.close()
# 关闭浏览器
driver.quit()

定位元素

  1. find_element_by_id : 根据id来查找某个元素。等价于:
    input_kw = driver.find_element_by_id('kw')
    input_kw = driver.find_element(By.ID, 'kw')
    
  2. find_element_by_class_name : 根据类名查找元素,等价于:
    input_kw = driver.find_element_by_class_name('s_ipt')
    input_kw = driver.find_element(By.CLASS_NAME, 's_ipt')
    
  3. find_element_by_name : 根据name属性的值来查找元素,等价于:
    input_kw = driver.find_element_by_name('wd')
    input_kw = driver.find_element(By.ID, 'wd')
    
  4. find_element_by_tag_name : 根据标签名来查找元素,等价于:
    input_kw = driver.find_element_by_tag_name('input')
    input_kw = driver.find_element(By.TAG_NAME, 'input')
    
  5. find_element_by_xpath : 根据xpath语法来获取元素,等价于:
    input_kw = driver.find_element_by_xpath('//input[@id="kw"]')
    input_kw = driver.find_element(By.XPATH, '//input[@id="kw"]')
    
    使用selenium中xpath获取元素属性值得时候和真实的xpath语法有些不同,例如获取a标签的href属性值,在真实的xpath语法中使用//a[@seed="bankcard-more"]/@href即可,但是在selenium中这样使用会报错;只能使用//a[@seed="bankcard-more"]先获取标签元素,然后使用get_attribute("href")获取属性值,例如:
    bank_url_ele = driver.find_element_by_xpath('//a[@seed="bankcard-more"]')
    bank_url = bank_url_ele.get_attribute("href")
    
  6. find_element_by_css_selector : 根据css选择器来选择元素,等价于:
    input_kw = driver.find_element_by_css_selector('.s_ipt')
    input_kw = driver.find_element(By.CSS_SELECTOR, '.s_ipt')
    

使用示例代码如下:

# 引入所需库
import time

from selenium import webdriver
from selenium.webdriver.common.by import By

# 声明定义chromedriver路径
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 实例化Chrome
# 如果时其他浏览器需要实例化为对应的对象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 打开百度
driver.get('https://www.baidu.com/')
time.sleep(2)
# 根据id获取元素
# input_kw = driver.find_element_by_id('kw')
# input_kw = driver.find_element(By.ID, 'kw')

# 根据类名获取元素
# input_kw = driver.find_element_by_class_name('s_ipt')
# input_kw = driver.find_element(By.CLASS_NAME, 's_ipt')

# 根据name属性值来获取元素
# input_kw = driver.find_element_by_name('wd')
# input_kw = driver.find_element(By.NAME, 'wd')

# 根据标签名来获取元素
# input_kw = driver.find_element_by_tag_name('input')
# input_kw = driver.find_element(By.TAG_NAME, 'input')

# 根据xpath语法获取元素
# input_kw = driver.find_element_by_xpath('//input[@id="kw"]')
# input_kw = driver.find_element(By.XPATH, '//input[@id="kw"]')

# 根据css选择器来选择元素
input_kw = driver.find_element_by_css_selector('.s_ipt')
# input_kw = driver.find_element(By.CSS_SELECTOR, '.s_ipt')
print(input_kw)

# 获取全部符合元素
# inputs_kw = driver.find_elements_by_css_selector('.s_ipt')[0]
inputs_kw = driver.find_elements(By.CSS_SELECTOR, '.s_ipt')

print(inputs_kw)
time.sleep(2)
# 关闭当前页面
driver.close()

注意:
1. find_element_获取第一个符合条件的元素。find_elements_是获取所有满足条件的元素。
2.如果知识想要解析网页中的数据,那么推荐将网页源代码使用lxml来解析,因为lxml底层使用的是c余言,所以解析效率会更高。
3. 如果想要对元素进行一些操作,比如给一个文本框输入值,或者是点击某个按钮,那么就必须使用selenium给我们提供的查找元素的方法

操作表单元素

常见的表单元素:

  • input : type=‘text | password |email | number | checkbox’
  • button : button | input[type=‘submit’]
  • select : 下拉选择
  1. 操作输入框:分为两步,第一步:找到这个元素;第二步:使用send_key(value)将数据填充进入。使用clear()方法可以清除输入框中的内容。代码如下:
    # 根据id获取元素
    input_kw = driver.find_element_by_id('kw')
    # input表单
    input_kw.send_keys('python')
    # 清除输入框中内容
    input_kw.clear()
    
  2. 操作checkbox:因为要选中checkbox标签,在网页中是通过鼠标点击的,因此想要选中checbox标签,那么先选中这个标签,然后执行click()事件,代码如下:
    # 根据name获取元素
    rememberEle = driver.find_element_by_name('remember')
    rememberEle.click()
    
  3. 选择select:select元素不能直接点击,因为点击后还需要选中元素。这时候selenium就专门为select标签提供了一个类selenium.webdriver.soupport.ui.Select。将获取到的元素当成参数传到这个类中,创建对象。以后就可以使用这个对象进行选择了,代码如下:
    from selenium.webdriver.support.ui import Select
    
    # 根据name获取元素
    select_tag = driver.find_element_by_name('jumpMenu')
    select_btn = Select(select_tag)
    # 根据索引进行选择
    # select_btn.select_by_index(1)
    # 根据值进行选择
    # select_btn.select_by_value('http://www.95you.com')
    # 根据可见文本进行选择
    select_btn.select_by_visible_text('广州东百信息科技有限公司')
    # 取消选中的所有选择
    select_btn.deselect_all()
    # select_btn.deselect_by_index(1)
    # select_btn.select_by_value('http://www.95you.com')
    # select_btn.deselect_by_visible_text('广州东百信息科技有限公司')
    
  4. 操作按钮:操作按钮有很多种方式,比如单击、右击、双击等。这里将一个最简单的,就是点击,直接调用click()函数就可以了,代码如下:
    # 操作按钮
    input_btn = driver.find_element_by_id('reg_btn')
    input_btn.click()
    

示例代码如下:

# 引入所需库
import time

from selenium import webdriver
from selenium.webdriver.support.ui import Select

# 声明定义chromedriver路径
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 实例化Chrome
# 如果时其他浏览器需要实例化为对应的对象,例如火狐webdriver.firefox()
driver = webdriver.Chrome(path)
# 操作输入框
# driver.get('https://www.baidu.com/')
# time.sleep(2)
# 根据id获取元素
# input_kw = driver.find_element_by_id('kw')
# input表单
# input_kw.send_keys('python')

# 操作checkbox
# driver.get('https://www.douban.com/')
# time.sleep(2)
# # 根据name获取元素
# rememberEle = driver.find_element_by_name('remember')
# rememberEle.click()

# 操作select
driver.get('http://95yueba.com/')
time.sleep(2)
# 根据name获取元素
select_tag = driver.find_element_by_name('jumpMenu')
select_btn = Select(select_tag)
# 根据索引进行选择
# select_btn.select_by_index(1)
# 根据值进行选择
# select_btn.select_by_value('http://www.95you.com')
# 根据可见文本进行选择
select_btn.select_by_visible_text('广州东百信息科技有限公司')
# 取消选中的所有选择
select_btn.deselect_all()
# select_btn.deselect_by_index(1)
# select_btn.select_by_value('http://www.95you.com')
# select_btn.deselect_by_visible_text('广州东百信息科技有限公司')
time.sleep(2)

# 操作按钮
input_btn = driver.find_element_by_id('reg_btn')
input_btn.click()

# 关闭当前页面
driver.close()

获取截屏

我们也可进行截取页面形成图片进行保存,示例代码如下:

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

options = Options()
# 声明定义chromedriver路径
path = r'E:\Python_Code\s1\chromedriver_win32\chromedriver.exe'
# 实例化Chrome
driver = webdriver.Chrome(executable_path=path, options=options)
driver.get('https://httpbin.org/ip')
# 进行截屏保存
driver.save_screenshot('1.png')

其他截屏方法:

  • get_screenshot_as_base64(): 获取当前窗口的截图保存为一个base64编码的字符串。
  • get_screenshot_as_file(filename): 获取当前窗口的截图保存为一个png格式的图片,filename参数为图片的保存地址,最后应该以.png结尾。如果出现IO错误,则返回False。用法: driver.get_screenshot_as_file('/Screenshots/foo.png')
  • get_screenshot_as_png(): 获取当前窗口的截图保存为一个png格式的二进制字符串。

获取窗口信息

  • get_window_position(windowHandle=’current’): 获取当前窗口的x,y坐标。
  • get_window_rect(): 获取当前窗口的x,y坐标和当前窗口的高度和宽度。
  • get_window_size(windowHandle=’current’): 获取当前窗口的高度和宽度。

执行JS代码

  1. execute_async_script(script, *args) : 在当前的window/frame中异步执行JS代码。
    • script:是你要执行的JS代码。
    • *args:是你的JS代码执行要传入的参数。
    • 用法:
    script = "var callback = arguments[arguments.length - 1]; "
    script2 = "window.setTimeout(function(){ callback('timeout') }, 3000);" 
    driver.execute_async_script(script + script2)
    
  2. execute_script(script, *args): 在当前的window/frame中同步执行JS代码。
    • script:是你要执行的JS代码。
    • *args:是你的JS代码执行要传入的参数。

其他博文链接

发布了154 篇原创文章 · 获赞 404 · 访问量 65万+

猜你喜欢

转载自blog.csdn.net/Zhihua_W/article/details/102716277
今日推荐