(廿七)Python爬虫:Selenium使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25343557/article/details/82556968

      Selenium是一个自动化测试工具,使用它可以驱动浏览器完成特定的动作(点击,滚动等),同时它可以获取网页源代码,做到可见及可爬。对于一些由AJAX加载的加密数据它也能很好的完成。


相关安装

  • Selenium的安装
          推荐使用pip3 install selenium 安装。

  • ChromeDriver的安装
          Selenium是一个自动化测试工具,它需要浏览器配合使用,首先我们需要安装Chrome浏览器,这个简单,不再赘述。
          同时,我们需要配置ChromeDriver。只有配置了驱动Selenium才能驱动Chrome浏览器进行操作。驱动下载地址:http://chromedriver.chromium.org/。一定要下载和Chrome浏览器版本对应的驱动。
          下载完对应的驱动后我们需要进行环境变量的配置:

    • Windows下建议直接将chromedriver.exe放在Python安装目录下的Script目录中。
    • Linux和Mac下将chromedrive配置到$PATH中。假设目录为:/usr/bin/chromedriver。修改~/.profile文件,添加export PATH = "$PATH:/usr/bin/chromedriver" 。保存后执行source ~/.profile 使设置生效。

验证安装:
这里写图片描述

  • GeckoDriver的安装
          Selenium同样也可以和Firefox进行对接,这需要我们安装GeckoDriver。下载地址:https://github.com/mozilla/geckodriver/releases。请根据自身电脑下载对应版本。下载后需要进行环境变量的配置,方法和前面ChromeDriver的大同小异,这里不赘述。
    验证安装:
    这里写图片描述

访问百度

      首先我们需要创建浏览器对象,Selenium支持非常多的浏览器,以Chrome为例声明浏览器对象:

from selenium import webdriver

brower = webdriver.Chrome()
#selenium还支持以下浏览器
# webdriver.Firefox()
# webdriver.PhantomJS()
# webdriver.Safari()
# webdriver.Edge()

使用webdriver完成了浏览器对象的创建,后续的一切操作都是基于此对象进行了。
创建好浏览器对象后可以调用get() 方法来请求网页,现在访问百度。

from selenium import webdriver

brower = webdriver.Chrome()
brower.get('https://www.baidu.com')#访问百度
print(brower.page_source)#打印网页源码
brower.close()

运行代码我们可以看见自动打开浏览器访问百度,再自动关闭。控制台输出了网页源码。

节点查找

      我们使用Selenium可以进行表单填充,点击操作,这些操作的前提是我们需要获取相应的节点(输入框,点击按钮等)。

单节点选择

      现在我需要打开百度首页并获取两个节点:输入框和搜索按钮

from selenium import webdriver

brower = webdriver.Chrome()
brower.get('http://www.baidu.com')#访问百度
input_kw = brower.find_element_by_id("kw")#根据id查找输入框
# input_kw2 = brower.find_element_by_css_selector("#kw")使用css选择器查找输入框
search_btn = brower.find_element_by_xpath('//*[@id="su"]')#使用xpath查找搜索按钮
print(input_kw,search_btn)
brower.close()

这里写图片描述
可以发现查找到的节点类型为WebElement 类型。
获取单个节点的方法还有以下几个:

find_element_by_name():根据name属性值查找;
find_element_by_link_text():根据a标签的文本内容查找,返回第一个匹配的节点;
find_element_by_partial_link_text():根据a标签的局部文本内容查找,返回第一个匹配的节点;
find_element_by_tag_name():根据标签名查找,返回第一个匹配的节点;
find_element_by_class_name():根据class属性值查找;

除了以上几种特点的方法用于查找节点,Selenium提供了一个通用方法find_element(by=By.ID, value=None) 查找方式by和值,默认根据ID查找。

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

brower = webdriver.Chrome()
brower.get('http://www.baidu.com')#访问百度
input_kw = brower.find_element(By.ID,"kw")#根据id查找输入框
# input_kw2 = brower.find_element(By.CSS_SELECTOR,"#kw")使用css选择器查找输入框
search_btn = brower.find_element(By.XPATH,'//*[@id="su"]')#使用xpath查找搜索按钮
print(input_kw,search_btn)
brower.close()

多节点选择

以上所有方法只能查找单个节点,如果需要查找多个节点使用find_elements(by=By.ID, value=None)
这里写图片描述
查找淘宝网首页左侧导航条的所有信息:

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

brower = webdriver.Chrome()
brower.get('https://www.taobao.com/')
lis = brower.find_elements(By.CSS_SELECTOR,'.service-bd > li')
print(lis)
brower.close()

这里写图片描述

节点交互

获取到指定节点后我们进行模拟操作,一般为输入文本内容和点击按钮。现在我们打开百度首页搜索“python”相关内容。

这里写代码片

执行代码后浏览器自动打开访问百度并搜索Python。
其他交互操作(例如滚动)查看官方文档:https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement

动作链

ActionChains是一种自动执行低级别交互的方法,例如鼠标移动,鼠标按钮操作,按键和上下文菜单交互。 这对于执行更复杂的操作非常有用,例如悬停和拖放。
示例实现一个节点的拖曳动作:

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

brower = webdriver.Chrome()
brower.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
brower.switch_to.frame('iframeResult')
source = brower.find_element(By.ID,'draggable')
target = brower.find_element(By.ID,'droppable')
actions = ActionChains(brower)#创建ActionChains对象
actions.drag_and_drop(source,target)#按住源元素上的鼠标左键,然后移动到目标元素并释放鼠标按钮。模拟拖曳操作
actions.perform()#执行调用的操作,如果有多个按照调用顺序执行。
time.sleep(5)
brower.close()

这里写图片描述

执行JS

Selenium可以使用execute_script() 方法执行JS代码。Selenium并没有提供下拉进度条的操作,这时候就需要我们执行JS代码来完成下拉操作了。

from selenium import webdriver
import time

brower = webdriver.Chrome()
brower.get('https://www.baidu.com/s?wd=Python')
time.sleep(2)
brower.execute_script('window.scrollTo(0,document.body.scrollHeight)')#下拉到最底部
time.sleep(2)
brower.execute_script('alert("To Bottom")')
time.sleep(2)
brower.close()

获取节点相关信息

      虽然我们通过调用page_source获取网页源码再通过解析库获取节点信息,但是Selenium提供了获取节点的方法,并且返回WebElement对象,此对象有对应的方法和属性获取节点信息。

获取属性

使用get_attribute() 方法来获取节点属性。

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

brower = webdriver.Chrome()
brower.get('https://www.baidu.com')
input_kw = brower.find_element(By.ID,'kw')
print(input_kw.get_attribute('class'))
print(input_kw.get_attribute('name'))
brower.close()

这里写图片描述

获取文本内容

每个WebElement节点都有text属性,调用此属性可以得到节点的文本内容。

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

brower = webdriver.Chrome()
brower.get('https://www.baidu.com')
node = brower.find_element(By.CSS_SELECTOR,'#u1 > a:nth-child(1)')
print(node.text)
brower.close()

这里写图片描述

延时等待

      在爬取过程中由于网络等因素导致网页还没加载出来,如果这时候我们获取节点当然是无法实现的,所以我们需要等待一段时间确保节点已经加载出来。等待方式有两种:隐式等待和显示等待

隐式等待

      调用implicitly_wait() 使用隐式等待。使用隐式等待时,如果Selenium无法再DOM树中找到节点则等待,超出等待时间后抛出异常信息。

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

brower = webdriver.Chrome()
brower.implicitly_wait(10)#等待10秒,默认0
brower.get('https://www.baidu.com')
input_kw = brower.find_element(By.ID,'kw')
input_kw.send_keys('阿里巴巴')
brower.close()

显式等待

      隐式等待需要等待页面加载完成,但是我们其实只需要某几个节点而已,这未免太浪费时间了,并且由于网络的影响我们很难把控应该等待多长时间是合理的。
      显示等待可以指定等待目标节点的最长时间,如果在规定时间内加载出来了这个节点就返回,否则抛异常。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC#等待条件
from selenium.webdriver.support.ui import WebDriverWait

brower = webdriver.Chrome()
brower.get('https://www.baidu.com')
wait = WebDriverWait(brower,10)#设置最长等待时间
input_kw = wait.until(EC.presence_of_element_located((By.ID,'kw')))#传入元组,等待id为kw的节点加载出来
print(input_kw)
brower.close()

如果是等待一个按钮我们不应该简简单单的等待节点出现,而应该等待至节点可点击才行,对应的条件为element_to_be_clickable

btn = wait.until(EC.element_to_be_clickable((By.ID,'su')))

      关于等待条件根据官网我们总结出以下几个常用的条件:

等待条件 描述
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 节点加载出来,传入定位元组
visibility_of_element_located 节点可见,传入定位元组
presence_of 节点可见,传入节点对象
presence_of_all_elements_located 所有节点加载出来
text_to_be_present_in_element 某个节点文本包含某文字
text_to_be_present_in_element_value 某个节点值包含某文字
frame_to_be_available_and_switch_to_it frame加载完成并切换
invisibility_of_element_located 节点不可见,传入定位元组
element_to_be_clickable 节点可点击,传入定位元组
staleness_of 判断某个节点是否仍在DOM中,可判断页面是否已经刷新
element_to_be_selected 节点可选择,传入节点对象
element_located_to_be_selected 节点可选择,传入定位元组

前进和后退

使用forward()back()可以实现页面前进和后退功能。

from selenium import webdriver
import time

brower = webdriver.Chrome()
brower.get('https://www.taobao.com')
brower.get('https://blog.csdn.net/qq_25343557')
time.sleep(2)
brower.back()
time.sleep(2)
brower.forward()
time.sleep(2)
brower.close()

Cookie操作

使用get_cookies() 获取cookie,delete_all_cookies() 删除所有cookie,add_cookie() 添加cookie。

from selenium import webdriver

brower = webdriver.Chrome()
brower.get('https://blog.csdn.net/qq_25343557')
print(brower.get_cookies())#获取cookies
brower.delete_all_cookies()#删除cookies
print(brower.get_cookies())
brower.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure':True})#添加cookie,必须包含name和value
print(brower.get_cookies())
brower.close()

这里写图片描述

选项卡切换

使用switch_to.window() 切换到指定的选项卡,参数为选项卡代号。使用window_handles获取当前开启的所有选项卡。
示例:

from selenium import webdriver
import time

brower = webdriver.Chrome()
brower.get('https://www.baidu.com')
time.sleep(1)
brower.execute_script('window.open()')#执行js开启新的选项卡
handle = brower.window_handles
brower.switch_to.window(handle[1])#切换到新的选项卡
brower.get('https://www.taobao.com')
time.sleep(1)
brower.switch_to.window(handle[0])
time.sleep(1)
brower.switch_to.window(handle[1])
time.sleep(1)
brower.close()

练习

请爬取卡推漫画中任意一部漫画?尝试使用多种方法爬取哦!交流请评论

猜你喜欢

转载自blog.csdn.net/qq_25343557/article/details/82556968