03 请求库之selenium
目录
一、selenium库介绍
1.selenium最初是一个自动化测试工具,它可以自动的帮我们打开(驱动)浏览器
2.而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题
1.selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器
2.实际上就是通过python代码取代人为,操作浏览器
二、selenium优缺点
优点:
1.不需要分详细分析目标网站的请求流程
2.可以帮我们做 绕过 登录滑动认证
缺点:
爬虫的效率较低(相比requests来说)
三、requests库的优缺点
优点:
1.爬虫效率高、模拟浏览器,可以只获取一个user-Agent即可,不需要等待css/js/视频等文件的加载,爬取的效率相比selenium库较高
缺点:
每一个网站都需要,详细分析请求流程,分析时间非常耗时
四、安装selenium
pip3 install selenium
由于selenium可以帮我们驱动打开浏览器,所以我们需要安装驱动
'''
selenium支持多种浏览器,但是在使用前必须去下载与浏览器相对应的驱动。
'''
from selenium import webdriver
# 谷歌浏览器
browser=webdriver.Chrome()
# 火狐浏览器
browser=webdriver.Firefox()
# 无界面浏览器
browser=webdriver.PhantomJS()
# 苹果浏览器
browser=webdriver.Safari()
# IE浏览器
browser=webdriver.Edge()
'''
安装selenium与谷歌驱动:
selenium + chromedriver
下载chromed浏览器驱动:
把下载好的chromedriver.exe放到python安装路径的scripts目录中即可,注意最新版本是2.38,并非2.9
- 国内镜像网站地址:
http://npm.taobao.org/mirrors/chromedriver/2.38/
- 最新的版本去官网找:
https://sites.google.com/a/chromium.org/chromedriver/downloads
验证安装:
- 进入python解释器:
>>> C:\Users\Administrator>python3
>>> Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
>>> Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver
>>> driver=webdriver.Chrome() #弹出浏览器
>>> driver.get('https://www.baidu.com')
>>> driver.page_source
注意:
selenium3默认支持的webdriver是Firfox,而Firefox需要安装geckodriver
下载链接:https://github.com/mozilla/geckodriver/releases
'''
五、基础使用(打开浏览器)
# Author:Cecilia
from selenium import webdriver
import time
# 1.打开浏览器
'''方式一:当你下载的驱动chromedriver.exe没有放在python安装包的script下时
需要将你下载的驱动的本地路劲,给executable_path参数
'''
# driver = webdriver.Chrome(executable_path=r'C:\Users\Administrator\Desktop\chromedriver.exe')
'''方式二:如果你的驱动是放在python安装包中script文件夹中(推荐使用),不用带任何参数'''
driver = webdriver.Chrome()
# 2.往目标网站发送请求
driver.get('https://www.baidu.com')
# 3.获取数据
input_tag = driver.find_element_by_id('kw')# 获取id为kw的input标签
print(input_tag) #返回的是一个对象
#往百度首页输入框中发送参数(对象有一个方法send_keys---发送参数的)
input_tag.send_keys('小狗')
time.sleep(1)
# 找到百度一下的按钮
submit_button = driver.find_element_by_id('su')
submit_button.click() #执行按钮单击事件
六、等待元素被加载
1、selenium只是模拟浏览器的行为,而浏览器解析页面是需要时间的(执行css,js),一些元素可能需要过一段时间才能加载出来,为了保证能查找到元素,必须等待
2、等待的方式分两种:
隐式等待:在browser.get('xxx')前就设置,针对所有元素有效
显式等待:在browser.get('xxx')之后设置,只针对某个元素有效
1. 隐式等待
# Author:Cecilia
from selenium import webdriver
import time
# 简单使用
# webdriver.Chrome('谷歌浏览器的驱动路径') # 指向谷歌浏览器驱动
# webdriver.Firefox('火狐浏览器的驱动路径') # 指向火狐浏览器驱动
# 使用步骤 (*******)
# 1.通过谷歌浏览器驱动,打开谷歌浏览器
driver = webdriver.Chrome()
try:
# 2.往目标网站发送请求
driver.get('https://www.baidu.com/')
# 隐式等待,等待所有标签元素加载
driver.implicitly_wait(10)
# 3.获取数据
# 根据id查找百度的input输入框
input_tag = driver.find_element_by_id('kw')
# 往百度输入输入小狗
input_tag.send_keys('小狗')
# 点击百度一下的按钮
submit_button = driver.find_element_by_id('su')
submit_button.click()
time.sleep(5)
# 当你正在请求的时候,突然断网了,可以捕获一下异常,让你的程序不报错。
# 打印一下错误信息
# 将驱动关闭
except Exception as e:
print(e)
finally:
driver.close()
2. 显示等待
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By #按照什么方式查找,By.ID,By.CSS_SELECTOR
from selenium.webdriver.common.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页面加载某些元素
browser=webdriver.Chrome()
browser.get('https://www.baidu.com')
input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('小狗')
input_tag.send_keys(Keys.ENTER)
#显式等待:显式地等待某个元素被加载
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))
contents=browser.find_element(By.CSS_SELECTOR,'#content_left')
print(contents)
browser.close()
七、选择器
# 所有用法---基础用法
- find_element: 找第一个
- find_elements: 找所有
find_element_by_id() #id
find_element_by_class_name() #class
find_element_by_css_selector() #id .class
find_element_by_link_text() #文本
find_element_by_name() #name属性
find_element_by_partial_link_text() #局部文本
find_element_by_tag_name() # 了解
driver.find_element_by_xpath() xpath解析语法
模拟百度登录操作为例
# Author:Cecilia
from selenium import webdriver
import time
driver = webdriver.Chrome()
try:
# 1.发送请求
driver.get('https://www.baidu.com/')
# 2.隐式等待
driver.implicitly_wait(10)
# 3.开始查找标签元素
'''
*********
- find_element: 找第一个
- find_elements: 找所有
driver.find_element_by_id() id
driver.find_element_by_class_name() class
driver.find_element_by_css_selector() #id .class
driver.find_element_by_link_text() 文本
driver.find_element_by_name() name属性
driver.find_element_by_partial_link_text() 局部文本
driver.find_element_by_tag_name() # 了解
driver.find_element_by_xpath() xpath解析语法
'''
# time.sleep(1)
# driver.find_element_by_name() name属性
# tj_login = driver.find_element_by_name('tj_login')
# 模拟百度登录操作
# 1.根据登录文本查找登录a标签,并点击登录按钮
tj_login = driver.find_elements_by_link_text('登录')#全部文本
# tj_login = driver.find_elements_by_partial_link_text('登')#局部文本
# 2.点击事件
tj_login.click()
# 2.查找用户名与密码登录按钮并点击
# # 根据id查找该按钮
user_and_pwd_button = driver.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn')
user_and_pwd_button.click()
#3.根据name属性选择器查找用户名输入框 (name属性必须唯一)
user_input = driver.find_element_by_name('userName')
user_input.send_keys('cc') # 向文本框中输入值
# 4.根据class属性查找密码输入框 (class必须唯一)
pwd_input = driver.find_element_by_class_name('pass-text-input-password')
pwd_input.send_keys('123456')
# 5.根据id查找确定登录按钮,并点击
submit_login = driver.find_element_by_id('TANGRAM__PSP_10__submit')
submit_login.click()
finally:
driver.close()
八、获取标签属性
# Author:Cecilia
from selenium import webdriver
import time
driver = webdriver.Chrome() # 驱动打开浏览器
try:
# 1.打开百度url
driver.get('https://www.baidu.com')
# 2.隐式等待
driver.implicitly_wait(10)
# 3.通过name属性找到百度的搜索框
search_input = driver.find_element_by_name('wd')
'''获取标签属性'''
print(search_input.id) # 获取标签的id
print(search_input.tag_name)# 获取标签的名称
print(search_input.location)# 获取标签的位置
print(search_input.size)# 获取标签的大小
except Exception as e:
print(e)
finally:
driver.close()
九、百度搜索框多次搜索
# Author:Cecilia
# Author:Cecilia
from selenium import webdriver
import time
driver = webdriver.Chrome() # 驱动打开浏览器
try:
# 1.打开百度url
driver.get('https://www.baidu.com')
# 2.隐式等待
driver.implicitly_wait(10)
# 3.通过name属性找到百度的搜索框
search_input = driver.find_element_by_name('wd')
search_input.send_keys('小狗')
# 4.通过css选择器找到百度一下按钮
submit_button = driver.find_element_by_id('su')
submit_button.click() #执行按钮单击事件# 百度点击搜索小狗
# 5.延时3秒进行下一次搜索
time.sleep(3)
# 6.将搜索框中的内容清除
search_input.clear()
# 7.进行搜索小猫
search_input.send_keys('小猫')
# 延时一下,更像人为的操作
time.sleep(2)
# 8.获取页面中的搜索确定按钮
submit_button.click()
except Exception as e:
print(e)
十、其他操作
1. 模拟浏览器前进后退
# Author:Cecilia
import time
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('https://www.baidu.com') # 先访问百度
time.sleep(2) # 在百度首页停留2秒
browser.get('https://www.taobao.com')# 在访问淘宝页面
time.sleep(3)# 在淘宝首页停留3秒
browser.back() #回到百度首页
time.sleep(5)# 在百度首页再次停留5秒
browser.get('http://www.sina.com.cn/') # 到新浪首页
time.sleep(3)
browser.back()# 在回到百度首页
time.sleep(5) # 在停留5秒后
browser.forward()# 前进到新浪首页
time.sleep(3)
browser.close()# 关闭浏览器
2. cookies
# Author:Cecilia
import time
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('https://www.zhihu.com/explore') # 访问知乎
print(browser.get_cookies())# 打印cookies
3. 选项卡管理(以新的标签页打开)
# Author:Cecilia
import time
from selenium import webdriver
browser=webdriver.Chrome()
browser.get('https://www.baidu.com') # 访问百度url
browser.execute_script('window.open()')
print(browser.window_handles) #获取所有的选项卡
browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.taobao.com')
time.sleep(2)
browser.execute_script('window.open()')
browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.sina.com.cn')
browser.close()
4. iframe标签
# Author:Cecilia
from selenium import webdriver
try:
browser=webdriver.Chrome()
browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
browser.switch_to.frame('iframssseResult')
'''
iframe标签是即将要淘汰的标签
它是在一个html文件中,有一个iframe标签,iframe标签中又有一个html页面,
在整体的HTML页面中是访问不到这个iframe标签里嵌套的html页面的,只能通过switch_to方法切换过去,
两个html页面是没有关系的
'''
except Exception as e:
print(e)
十一、联系小项目
1. 模拟人为输入商品爬取feelunique商品基本信息
# Author:Cecilia
from selenium import webdriver
import time
def good_data(driver,f):
good_all_list = driver.find_elements_by_class_name('m-product-wrapper') # 获取所有的商品
f.write('-----------------------------------------------------------------------------------------------------------------------------------')
for good in good_all_list:# 循环商品列表
'''1.获取商品图片'''
good_img_tag = good.find_element_by_css_selector('.m-product-wrapper a img')#获取商品img标签
good_img = good_img_tag.get_attribute('data-src')# 获取商品data_src属性值,就是图片的数据
print(good_img)
'''2.获取商品英镑价格'''
good_english_price = 'f%s'%good.find_element_by_css_selector('.p-price>span>span').text
print(good_english_price)
'''3.获取商品人民币价格'''
good_china_price = good.find_element_by_css_selector('.p-reference span').text
print(good_china_price)
'''4.获取商品简介'''
good_title = good.find_element_by_css_selector('.m-product-name').text
print(good_title)
'''5.获取商品的生产地址'''
good_bri = good.find_element_by_css_selector('.m-product-warehouse').text
print(good_bri)
f.write(
f'''
商品名称: {good_title}
商品图片: {good_img}
商品英镑价格: {good_english_price}
商品中国价格: {good_china_price}
商品生产地址: {good_bri}
'''
)
'''获取下一页按钮'''
next_button = driver.find_element_by_css_selector('.page-item>.next')
next_button.click()
time.sleep(2)
good_data(driver,f) # 进行递归循环,获取每一页的数据
if __name__ == '__main__':
f = open('kouhong.txt', 'a', encoding='utf-8')
driver = webdriver.Chrome() #驱动打开浏览器
try:
driver.get('https://cn.feelunique.com/') #访问淘宝首页
search_input = driver.find_element_by_id('q')# 通过id属性获取搜索框标签
search_input.send_keys('口红') #向搜索框中输入搜索词
search_button = driver.find_element_by_class_name('btn-search')# 通过class属性获取搜索按钮
search_button.click()
# 调用获取数据的方法
good_data(driver,f)
time.sleep(20)
except Exception as e:
print(e)
finally:
driver.close()
2. 爬取京东商品
from selenium import webdriver
from selenium.webdriver.common.keys import Keys # 可以帮我们操作键盘
import time
def get_data(driver, f):
time.sleep(1)
js_code = '''
window.scrollTo(0, 5500)
'''
# execute_script: 该方法可以执行js代码
driver.execute_script(js_code)
# 执行完js代码后,等待2秒加载数据
time.sleep(2)
# 操控滚动条,向下滑动
# find_elements ---> [element_obj]
goods_list = driver.find_elements_by_class_name('gl-item')
for goods in goods_list:
# print(goods)
# 商品名称
goods_name = goods.find_element_by_css_selector('.p-name em').text
print(goods_name)
# 商品详情页url
# img_tag = goods.find_element_by_class_name('p-img')
# a_tag = img_tag.find_element_by_tag_name('a')
# # 获取a标签中的属性
# href = a_tag.get_attribute('href')
# print(href)
a_tag = goods.find_element_by_css_selector('.p-img a')
# get_attribute:获取标签元素的属性
goods_url = a_tag.get_attribute('href')
print(goods_url)
# 获取商品图片
img_tag = goods.find_element_by_css_selector('.p-img a img')
goods_img = img_tag.get_attribute('src')
print(goods_img)
# 商品价格
goods_price = goods.find_element_by_css_selector('.p-price i').text
print(goods_price)
# 商品评价人数
goods_commit = goods.find_element_by_css_selector('.p-commit a').text
print(goods_commit)
f.write(
f'''
商品名称: {goods_name}
商品详情: {goods_url}
商品图片: {goods_img}
商品价格: {goods_price}
评价人数: {goods_commit}
----------------------------------------------
'''
)
# 注意: 爬取完当前页后,点击下一页
next_tag = driver.find_element_by_class_name('pn-next')
next_tag.click()
time.sleep(2)
# 递归执行爬取当前商品所有数据
get_data(driver, f)
if __name__ == '__main__':
f = open('jd.txt', 'a', encoding='utf-8')
driver = webdriver.Chrome()
# 爬取京东商品信息
try:
# 1.发送请求
driver.get('https://www.jd.com/')
# 2.隐式等待
driver.implicitly_wait(10)
# 3.根据id找到商品输入框
input_tag = driver.find_element_by_id('key')
input_tag.send_keys('坦克')
input_tag.send_keys(
Keys.ENTER # 调用电脑回车键
)
# 4.调用爬取商品信息函数
get_data(driver, f)
time.sleep(1000)
finally:
driver.close()