Home

韧桂

思考,总结

Selenium 库是一个自动化测试工具,支持多种浏览器。在爬虫中主要解决 JavaScript 渲染的问题。

用法讲解:

0.基本用法

from selenium import webdriver
from selenium.webdriver.common.by import By
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()  #声明一个浏览器对象,.Chrome声明浏览器驱动对象也可是Firefox,Edge,PhantomJS,Safari。需下载ChromeDriver,并配置环境变量。
try:
    browser.get('https://www.baidu.com')
    input = browser.find_element_by_id('kw')
    input.send_keys('Python')  #send_keys,敲入一些键/元素
    input.send_keys(Keys.ENTER)  #回车
    wait = WebDriverWait(browser, 10)
    wait.until(EC.presence_of_element_located((By.ID,'content_left')))
    print(browser.current_url)
    print (browser.get_cookies())
    print (browser.page_source)  #网页源代码
finally:
    browser.close()  #关掉浏览器

1.访问页面

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print (browser.page_source)
browser.close()

2.查找元素

2.1 单个元素

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first = browser.find_element_by_id('J_SearchTab')   #find_element_by_id方法,用id来寻找一个元素  id名称是J_SearchTab。导航栏id
#input_first = browser.find_element(By.ID, 'banner-slider')  #利用find_element通用的方式。第一个参数传入By,后面跟它的类型,类型所有字母需大写。第二个参数传要查找的元素。
input_second = browser.find_element_by_css_selector('#J_SearchTab')  #find_element_by_css_selector方法。 用css选择器来选择一个元素
input_third = browser.find_element_by_xpath('//*[@id="J_SearchTab"]')  #三次选择内容相同。属WebElement类型。
print (input_first, input_second, input_third)
browser.close()

#find_element_by_css_selector
#find_element_by_xpath
#find_element_by_name   通过name方法查找
#find_element_by_link_text
#find_element_by_partial_link_text
#find_element_by_tag_name
#find_element_by_class_name

2.2 多个元素查找

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
#lis = browser.find_elements_by_css_selector('.content div')  #elements多了一个s。用法同上。
lis = browser.find_elements(By.CSS_SELECTOR,'.content div')
print(lis)
browser.close()

3.元素交互操作

对获取的元素调用交互方法

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')   #搜索输入框id
input.send_keys('iPone')   #send_keys方法输入iPone
time.sleep(1)   #延时1s
input.clear()  #clear清空输入框
input.send_keys('iPad')
button = browser.find_element_by_class_name('btn-search')  #点击搜索
button.click()  #调用click转到搜索页面
#跳不到产品搜索页面了,现在必须登录后才能搜索。

更多操作 https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement

4.交互动作

将动作附加到动作链中串行执行。调用相应的API即可。

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()  #模拟拖拽
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')  #选择拖拽目标。选择 frame标签,id为iframeResult
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)   #声明一个动作链
actions.drag_and_drop(source, target)  #把source拖拽到target
actions.perform()  #提醒动作

更多操作 https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

5.执行JavaScript

有一些操作没有API,如进度条下拉等,或者交互动作API难以实现,都可以用这种方法。

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')  #execute_script()  API 传一些 JavaScript语句。完成js的执行,通过js对浏览器的操作。这里是下拉到网页的最下端。
browser.execute_script('alert("To Bottom")')   #提示一个alert,

6.获取元素信息

获取属性,获取文本值;和获取ID、位置、标签名、大小。

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')

logo = browser.find_element_by_id('zh-top-link-logo')  #获取知乎logo信息,
print (logo)
print (logo.get_attribute('class'))  #再把属性值打印出来。
input = browser.find_element_by_class_name('zu-top-add-question')  #匹配提问按钮。
print (input.text)  #把文本值打印出来。
print (input.id)    #获取ID
print (input.location)   #获取位置
print (input.tag_name)  #获取标签名
print (input.size)  #大小

7.Frame

Frame在网页出现比较频繁,但是,如果出现Frame,我们在做元素筛选的时候,有可能会导入一些不太方便的问题。 比如说,这个Frame相当于一个独立的网页。我们在父级的Frame里面查找这个子元素的Frame,实际上必须切换到Frame才可以查找,否则是不能完成这个元素的查找的。 这里我们演示切换父元素的Frame以及子元素的Frame。

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult')  #切换子元素的Frame。
source = browser.find_element_by_css_selector('#draggable')
print (source)
try:
    logo = browser.find_element_by_class_name('logo')
except NoSuchElementException:   #找不到这个元素时报错。
    print ('NO LOGO')
browser.switch_to.parent_frame()   #切换父元素的Frame。
logo = browser.find_element_by_class_name('logo')
print (logo)
print (logo.text)

8.等待

防止浏览器没有完全加载一些Ajax请求时,便进行下一步操作。 8.1 隐式等待 当使用了隐式等待执行测试的时候,如果WebDriver 没有在 DOM 中找到元素,将继续等待,超过设定时间后则抛出找不到元素的异常,换句话说,当查找元素或元素并没有立即出现大的时候,隐式等待将等待一段时间再查找DOM,默认的时间是0。

from selenium import webdriver

browser = webdriver.Chrome()
browser.implicitly_wait(10)  #传入一个等待时间
browser.get('https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('zu-top-add-question')
print (input)

8.2 显示等待 指定一个等待时间,再加一个等待条件。那么,它会在这个最长等待时间内判断这个条件是否成立。 如果成立,它就会立即返回,否则,它会一直等待,然后等待到这个最长的等待时间,如果还是不满足这个条件,它就会抛出异常,

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('https://www.taobao.com/')
wait = WebDriverWait(browser, 10)  #声明WebDriverWait对象。第二个参数是最长等待时间
input = wait.until(EC.presence_of_element_located((By.ID,'q')))  #等待条件,判断搜索框是否出现。并赋值给input
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))  #判断是否是可点击
print (input, button)

#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

更多操作https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions

9.前进后退

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()   #关闭浏览器

10.Cookies

保持登录状态

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
print (browser.get_cookies())
browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germey'})   #加一些信息进去
print (browser.get_cookies())
browser.delete_all_cookies()   #清空cookies
print (browser.get_cookies())

11.选项卡管理

管理多选项卡,通过执行一个js,执行window.open()。

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.execute_script('window.open()')
print (driver.window_handles)   #返回所有选项卡,所有窗口的引用
driver.switch_to.window(driver.window_handles[1])  #切换到第二个选项卡
driver.get('https://www.taobao.com')
time.sleep(1)
driver.switch_to.window(driver.window_handles[0])  #切换到第一个选项卡
driver.get('https://python.org')

12.异常处理

点击异常,加载异常

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException

browser = webdriver.Chrome()
try:
    browser.get('https://www.taobao.com')
except TimeoutException:   #超时异常
    print ('Time Out')
try:
    browser.find_element_by_id('hello')
except NoSuchElementException:   #元素不存在时异常
    print ('No Element')
finally:
    browser.close()

更多操作https://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions

欢迎关注我的公众号:「韧桂」

韧桂 2019-02-20