selenium
介绍
在本### 小结我们会开始系统的了解常见的反爬措施和解决思路,通过在学习selenium模块,它能够帮助我们控制浏览器,能够起到很大程度的反反爬的效果
内容
selenium的使用
打码平台的使用
常见的反爬措施和解决思路
无头浏览器
学习目标
1.了解 selenium的作用
2.了解 driver的安装过程
我们如果想在python爬虫操作动态的数据,就必须学习selenium自动化测试工具, 而使用selenium的前提是需要无头浏览器(无界面浏览器)
1 什么是selenium
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏
2 PhantomJS的介绍
PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript
下载地址:http://phantomjs.org/download.html
3 Chromedriver的介绍
Chromedriver 是一个的浏览器驱动,主要用于将python指令转换成浏览器操作动作,从而操作浏览器,但是和PhantomJS的区别在于它是有界面的
下载地址:http://blog.csdn.net/huilan_same/article/details/51896672
4 driver的安装
最简单的安装方式是:解压后把bin目录下的可执行文件移动到环境变量下,比如/usr/bin 或者是/usr/local/bin下面
5 PhantomJS安装示例
5.1 下载PhantomJS:
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
5.2 解压并创建软连接:
tar -xvjf phantomjs-2.1.1-linux-x86_64.tar.bz2
sudo cp -R phantomjs-2.1.1-linux-x86_64 /usr/local/share/
sudo ln -sf /usr/local/share/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/
6 chromedriver安装示例
----- Linux 下安装方式
chromedriver_linux64.zip : 版本 ChromeDriver v2.22 (2016-06-06)
(支持 Chrome v49-52,当前Ubuntu虚拟机下的Chrome版本为50.0)
- unzip chromedriver_linux64.zip
- sudo chmod +x chromedriver
- sudo mv chromedriver /usr/local/bin/
----- MacOS X 下安装方式
chromedriver_mac64.zip : 版本 ChromeDriver v2.32 (2017-08-30)
(支持 Chrome v59-61)
- 安装 同Linux
----- Windows 下安装方式
chromedriver_win32.zip : 版本 ChromeDriver v2.32 (2017-08-30)
(支持 Chrome v59-61)
- 解压 chromedriver_win32.zip
- 将 chromedriver 移动到 Python安装目录下
(其实放哪都可以,但是需要配环境变量,放Python安装目录下省事)
注意:Chromedriver和电脑上的chrome版本有对应关系,建议使用最新的Chromedriver版本并且更新chrome浏览器到最新版
小结
1.能够安装PhtantomJs和Chromedriver浏览器
2.能够知道selenium是自动化测试工具
selenium的基本使用
学习目标
掌握 selenium发送请求,加载网页的方法
掌握 selenium简单的元素定位的方法
掌握 selenium的基础属性和方法
掌握 selenium退出的方法
当我们安装完毕无界面浏览器之后, 再学习下 selenium中drvier的使用操作
1 加载网页:
selenium通过控制浏览器,所以对应的获取的数据都是elements中的内容
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get("http://www.baidu.com/")
driver.save_screenshot("baidu.png")
2 定位和操作:
driver.find_element_by_id("kw").send_keys("长城")
driver.find_element_by_id("su").click()
3 查看请求信息:
driver.page_source
driver.get_cookies()
driver.current_url
4 退出
driver.close() #退出当前页面
driver.quit() #退出浏览器
5 练习
模拟登陆豆瓣网
小结
selenium的导包:from selenium import webdriver
selenium创建driver对象:webdriver.PhantomJS()
selenium请求数据:driver.get(“http://www.baidu.com/”)
selenium查看数据: driver.page_source
关闭无界面浏览器: driver.quit()
根据id定位元素: driver.find_element_by_id(“kw”)
操作点击事件: click()
给输入框赋值:send_keys()
元素定位的方法
学习目标
掌握 selenium定位元素的方法
掌握 selenium从元素中获取文本和属性的方法
通过selenium的基本使用可以简单定位元素和获取对应的数据,接下来我们再来学习下 定位元素的其他方法
1 selenium的定位操作
1.元素定位的两种写法:
直接调用型(推荐方式)
el = driver.find_element_by_xxx(value)
# xxx是定位方式,后面我们会讲,value为该方式对应的值
使用By类型(需要导入By)
from selenium.webdriver.common.by import By
driver.find_element(By.xxx,value)
直接掉用的方式会在底层翻译成这种方式,一般用
不到,但是遇见别人这样写要知道这是在干什么
2.元素定位的两种方式:
精确定位一个元素,返回结果为一个element对象,定位不到则报错
driver.find_element_by_xxx(value)
定位一组元素,返回结果为element对象列表,定位不到返回空列表
driver.find_elements_by_xxx (value)
3.元素定位的八种方法:
以下方法在element之后添加s就变成能够获取一组元素的方法
el = driver.find_element_by_id 使用id值定位
el = driver.find_element_by_xpath 使用xpath定位
el = driver.find_element_by_tag_name 使用标签名定位
el = driver.find_element_by_link_text(‘登录’) 使用文本定位
el = driver.find_element_by_partial_link_text 使用部分文本定位
el = driver.find_element_by_name 使用name属性值定位
el = driver.find_element_by_class_name 使用class属性值定位
el = driver.find_element_by_css_selector 使用css选择器定位
注意: find_element和find_elements的区别 by_link_text和by_partial_link_text的区别:
全部文本和包含某个文本
使用: 以豆瓣首页为例:https://www.douban.com/
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.douban.com/")
ret1 = driver.find_element_by_id("anony-nav")
print(ret1)
# 输出为:<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>
ret2 = driver.find_elements_by_id("anony-nav")
print(ret2)
#输出为:[<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>]
ret3 = driver.find_elements_by_xpath("//*[@id='anony-nav']/h1/a")
print(len(ret3))
#输出为:1
ret4 = driver.find_elements_by_tag_name("h1")
print(len(ret4))
#输出为:1
ret5 = driver.find_elements_by_link_text("下载豆瓣 App")
print(len(ret5))
#输出为:1
ret6 = driver.find_elements_by_partial_link_text("豆瓣")
print(len(ret6))
#输出为:28
driver.close()
2.元素的操作
find_element_by_xxx方法仅仅能够获取元素对象,接下来就可以对元素执行以下操作 从定位到的元素中提取数据的方法
1.从定位到的元素中获取数据
el.get_attribute(key) 获取key属性名对应的属性值
el.text 获取开闭标签之间的文本内容
1.对定位到的元素的操作
el.click() 对元素执行点击操作
el.submit() 对元素执行提交操作
el.clear() 清空可输入元素中的数据
el.send_keys(data) 向可输入元素输入数据
使用示例:
from selenium import webdriver
driver =webdriver.Chrome()
driver.get("https://www.douban.com/")
ret4 = driver.find_elements_by_tag_name("h1")
print(ret4[0].text)
#输出:豆瓣
ret5 = driver.find_elements_by_link_text("下载豆瓣 App")
print(ret5[0].get_attribute("href"))
#输出:https://www.douban.com/doubanapp/app?channel=nimingye
driver.close()
小结
根据xpath定位元素:driver.find_elements_by_xpath("//*[@id=‘s’]/h1/a")
根据class定位元素:driver.find_elements_by_class_name(“box”)
根据link_text定位元素:driver.find_elements_by_link_text(“下载豆瓣 App”)
根据tag_name定位元素:driver.find_elements_by_tag_name(“h1”)
获取元素文本内容:element.text
获取元素标签属性: element.get_attribute(“href”)
向输入框输入数据: element.send_keys(data)
selenium的其他方法
学习目标
1.掌握 selenium处理cookie等方法
2.掌握 selenium中switch的使用
1 selenium 处理cookie
通过driver.get_cookies()能够获取所有的cookie
# 把cookie转化为字典
{cookie["name"]: cookie["value"] for cookie in driver.get_cookies()}
#删除一条cookie
driver.delete_cookie("CookieName")
# 删除所有的cookie
driver.delete_all_cookies()
2 页面等待
为什么需要等待
如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定,这个时候就可以设置一个等待时间,强制等待指定时间,等待结束之后进行元素定位,如果还是无法定位到则报错
页面等待的三种方法
1.强制等待
import time
time.sleep(n) 阻塞等待设定的秒数之后再继续往下执行
2.显式等待(自动化web测试使用,爬虫基本不用)
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10,0.5).until( EC.presence_of_element_located((By.ID, “myDynamicElement”))
显式等待指定某个条件,然后设置最长等待时间10,在10秒内每隔0.5秒使用指定条件去定位元素,如果定位到元素则直接结束等待,如果在10秒结束之后仍未定位到元素则报错
3.隐式等待 隐式等待设置之后代码中的所有元素定位都会做隐式等待
driver.implicitly_wait(5) # 在指定的n秒内每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错
3 switch方法切换的操作
3.1 一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。切换窗口的方法如下:
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
# 1. 获取当前所有的窗口
current_windows = driver.window_handles
# 2. 根据窗口索引进行切换
driver.switch_to.window(current_windows[1])
动手:获取58同城租房列表
3.2iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是
driver.switch_to.frame(el/id) 传入的参数可以使iframe对应的id值,也可以是用元素定位之后的元素对象
动手:模拟登陆qq邮箱
在使用selenium登录qq邮箱的过程中,我们会发现,无法在邮箱的登录input标签中输入内容,通过观察源码可以发现,form表单在一个frame中,所以需要切换到frame中
3.3 当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()
- 页面前进和后退
driver.forward() #前进
driver.back() # 后退
4 selenium的优缺点
优点
selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易
使用难度简单
爬取速度慢,爬取频率更像人的行为,天生能够应对一些反爬措施
缺点
由于selenium操作浏览器,因此会将发送所有的请求,因此占用网络带宽
由于操作浏览器,因此占用的内存非常大(相比较之前的爬虫)
速度慢,对于效率要求高的话不建议使用
小结
获取cookie: get_cookies()
删除cookie: delete_all_cookies()
切换窗口:switch_to.window()
切换iframe: switch_to.frame()