Python爬虫基础2 - Selenium库使用
小马哥正在针对Python的所有常见知识进行汇总,更会有大量实战项目不断补充进来.
点击-->全栈工程师养成---Python内容导航页<--查看所有Python内容
第一个hello world例子
- 声明浏览器对象
- 访问页面
- 关闭webdriver
from selenium import webdriver
import time
# 1, 声明浏览器对象
browser = webdriver.Chrome()
# 2, 访问简书页面
browser.get('https://www.jianshu.com/u/b9eb05db71cf')
# 2, 查看一下页面的源码
print(browser.page_source)
# 3, 睡眠5秒
time.sleep(5)
# 4, 关闭浏览器
browser.close()
(1) DOM操作
主要内容: 元素查找,元素交互,通过执行JavaScript代码获取元素属性,文本值,id,标签名等
1.1 单个元素查找
find_element_by_xxx()
- 通过id查找
- 通过css选择器查找
- 通过xpath查找
- 通过webdriver.common.by.By查找
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.taobao.com')
searchBox1 = browser.find_element_by_id('q')
searchBox2 = browser.find_element_by_css_selector('#q')
searchBox3 = browser.find_element_by_xpath('//*[@id="q"]')
print(searchBox1)
print(searchBox2)
print(searchBox3)
技巧: 这些需要填入的参数,在你已经清楚原理的情况下,就不用手敲了,可以通过F12,在浏览器中直接copy.
比较常用的查找元素方法
- find_element_by_name
- find_element_by_id
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
上面这些方法,使用起来代码比较长,具备"懒"品质的程序员,会使用稍微省事的方案:
By模块提供的属性,用法如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.taobao.com')
searchBox1 = browser.find_element(By.ID,'q')
searchBox2 = browser.find_element(By.CSS_SELECTOR,'#q')
print(searchBox1)
print(searchBox2)
browser.close()
1.2 多个元素查找
find_elements
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('http://www.taobao.com')
searchBox = browser.find_element_by_id('q')
searchBox.send_keys('华为Mate20pro')
searchButton = browser.find_element_by_class_name('btn-search')
searchButton.click()
1.3 交互操作
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('http://www.taobao.com')
# 获取搜索框
searchBox = browser.find_element_by_id('q')
# 输入查询关键字
searchBox.send_keys('Mate20Pro')
# 获取搜索按钮,点击搜索按钮
searchButton = browser.find_element_by_class_name('btn-search')
searchButton.click()
# 清空搜索框
searchBox.clear()
# 输入新的查询关键字,点击搜索按钮
searchBox.send_keys('华为')
searchButton = browser.find_element_by_class_name('btn-search')
searchButtion.click()
# 关闭浏览器
browser.close()
1.4 执行JavaScript
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('http://www.zhihu.com/explore')
# 浏览器执行滚动到页面底端(scrollHeight属性)
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
1.5 获取元素属性
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.zhihu.com/explore')
logo = browser.find_element(By.ID,'zh-top-link-logo')
print(logo)
print(logo.get_attribute('class'))
1.6 获取文本值
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.zhihu.com/explore')
questionButton = browser.find_element(By.CLASS_NAME,'zu-top-add-question')
print(questionButton.text)
1.7 获取ID,位置,标签名,控件大小
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.zhihu.com/explore')
questionButton = browser.find_element(By.CLASS_NAME,'zu-top-add-question')
print(questionButton.id)
print(questionButton.class)
print(questionButton.location)
print(questionButton.tag_name)
print(questionButton.size)
1.8 Frame
一个网页中可能存在多个Frame,一个Frame里面包含一个完整的html文档,在一个网页中的不同Frame中切换是一种必需的操作,涉及下面两个函数
- switch_to.frame()
- switch_to.parent_frame()
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
# 切换到要进行操作的Frame里面去
browser.switch_to.frame('iframeResult')
# 这个时候测试,还能否找到原Frame里面的Logo元素
try:
logo = browser.find_element(By.CLASS_NAME,'logo')
except:
print('navbar-header logo 不存在...')
browser.switch_to.parent_frame()
logo = browser.find_element(By.CLASS_NAME,'logo')
print(logo)
print(logo.text)
(2) 等待加载
使用场景: 有时候,页面的加载需要一定时间之后才会完全加载完成,在此之前,如果就获取某些元素,可能就会由于还未加载到浏览器而造成找到不元素的异常. 于是我们可以给标签的加载设置一个等待时间.
主要内容: 隐式等待,显式等待
2.0 强制等待
我们可以利用python自带的time模块在强制程序到指定位置,休眠n秒,以此来等待页面加载,这样的缺点:
- 页面加载快慢与否,都要到这里等到n秒,对于加载快的控件元素,这样浪费时间;
- 页面在预估的n秒内,没有加载,程序继续执行,但是也拿不到需要抓取的控件元素.
2.1 隐式等待
- 设置一个时间,如果在指定时间内,完成了元素加载,就会执行下一步程序,不会在这里浪费时间了
- 超出预定时间,没有加载完成,那么抛出加载超时异常.
本质: 在创建driver的时候,就为浏览器对象创建一个等待时间,得不到某个元素就等待一段时间,知道拿到某个元素为止.
在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内不断的刷新页面去寻找我们需要的元素.
from selenium import webdriver
browser = webdriver.Chrome()
# 2.0强制等待的话: 这里代码应该是time.sleep(10) 是否加载完成,都要铁等
browser.implicitly_wait(10)
browser.get('http://www.zhihu.com/explore')
questionButton = browser.find_element_by_class_name('zu-top-add-question')
print(questionButton.text)
2.2 显式等待
本质: 是一个条件判断,在规定时间内,检测条件是否满足? 满足,则进行下一步;不满足,抛出超时异常.
明确等到某个元素的出现或者某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没有找到,那么就跳出Exception
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get('http://www.taobao.com')
wait = WebDriverWait(browser,10)
searchBox = wait.until(EC.presence_of_element_located((By.ID,'q')))
searchBox.send_keys('xxx')
searchButton = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))
searchButton.click()
print(browser.page_source)
print(searchBox,searchButton)
常用的判断条件:
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 元素加载出,传入定位元组,如(By.ID, 'p')
visibility_of_element_located 元素可见,传入定位元组
visibility_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 元素可选择,传入定位元组
element_selection_state_to_be 传入元素对象以及状态,相等返回True,否则返回False
element_located_selection_state_to_be 传入定位元组以及状态,相等返回True,否则返回False
alert_is_present 是否出现Alert
(3) 浏览器操作
主要内容: 浏览器的前进后退,cookie操作,选项卡管理,异常处理
3.1 浏览器的前进和后退
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.python.org/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()
3.2 cookie操作
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
No Element
3.3 选显卡管理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
No Element
3.4 异常处理
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()
No Element
小马哥正在针对Python的所有常见知识进行汇总,更会有大量实战项目不断补充进来.
点击-->全栈工程师养成---Python内容导航页<--查看所有Python内容