(廿七)Python爬虫:Selenium使用
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()
练习
请爬取卡推漫画中任意一部漫画?尝试使用多种方法爬取哦!交流请评论
推荐阅读
-
selenium python虚拟点击网页 爬虫翻页功能 href=javascript:void(0)怎么翻页
-
python使用selenium登录QQ邮箱(附带滑动解锁)
-
零基础写python爬虫之使用urllib2组件抓取网页内容
-
使用Python编写简单网络爬虫抓取视频下载资源
-
零基础写python爬虫之urllib2使用指南
-
零基础写python爬虫之使用Scrapy框架编写爬虫
-
python使用rabbitmq实现网络爬虫示例
-
Python网络爬虫(selenium爬取动态网页、爬虫案例分析、哈希算法与RSA加密)
-
爬虫实战在 Python 中使用正则表达式
-
python3通过selenium爬虫获取到dj商品的实例代码