Python爬虫基础2 - Selenium库使用

小马哥正在针对Python的所有常见知识进行汇总,更会有大量实战项目不断补充进来.
点击-->全栈工程师养成---Python内容导航页<--查看所有Python内容

第一个hello world例子

  1. 声明浏览器对象
  2. 访问页面
  3. 关闭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秒,以此来等待页面加载,这样的缺点:

  1. 页面加载快慢与否,都要到这里等到n秒,对于加载快的控件元素,这样浪费时间;
  2. 页面在预估的n秒内,没有加载,程序继续执行,但是也拿不到需要抓取的控件元素.

2.1 隐式等待

  1. 设置一个时间,如果在指定时间内,完成了元素加载,就会执行下一步程序,不会在这里浪费时间了
  2. 超出预定时间,没有加载完成,那么抛出加载超时异常.

本质: 在创建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内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • selenium用法详解 selenium主要是用来做自动化测试,支持多种浏览器,爬虫中主要用来解决JavaScr...
    陳_CHEN_陈阅读 3,882评论 1 5
  • 这几天一直在调整自己,中途锦明老师和桂军姐都亲自给我指导,群里的姐妹们也都积极的给我出点子,开导我,昨天孩子主动开...
    兰州李慧阅读 339评论 0 6
  • 今天是公元二零一六年十二月二十二日,我还在出生的北方小城上学。 这儿的太阳总是暖洋洋的,但天远远不如北京的蓝。这儿...
    机智的小邻阅读 463评论 4 5
  • 时代的节奏,生活的压力,不是你说了算,也不是我说了算! 长时间的煮妇生活,很少能在早上这个点去挤地铁,七点多要放在...
    panpan盼阅读 430评论 2 6
  • 例如,我在数据库里面有以下字段id name(姓名) phone(电话) city(城市) shop...
    干掉大北兔阅读 8,753评论 0 0