Selenium之Chrome

Selenium是一個Web的自動化測試工具沽瘦,最初是為網(wǎng)站自動化測試而開發(fā)的,類型像我們玩游戲用的按鍵精靈良哲,可以按指定的命令自動操作,不同是Selenium 可以直接運行在瀏覽器上筑凫,它支持所有主流的瀏覽器(包括PhantomJS這些無界面的瀏覽器)。 Selenium 可以根據(jù)我們的指令巍实,讓瀏覽器自動加載頁面,獲取需要的數(shù)據(jù)殖属,甚至頁面截屏瓦盛,或者判斷網(wǎng)站上某些動作是否發(fā)生。

Selenium 自己不帶瀏覽器原环,不支持瀏覽器的功能,它需要與第三方瀏覽器結(jié)合在一起才能使用嘱吗。但是我們有時候需要讓它內(nèi)嵌在代碼中運行,所以我們可以用一個叫 PhantomJS 的工具代替真實的瀏覽器俄讹。

可以從 PyPI 網(wǎng)站下載 Selenium庫https://pypi.python.org/simple/selenium 绕德, 也可以用第三方管理器 pip用命令安裝:

pip3 install selenium

selenium 官方參考文檔http://selenium-python.readthedocs.io/index.html

selenium中文文檔http://selenium-python-zh.readthedocs.io

Selenium也分為有界面瀏覽器和無界面瀏覽器

谷歌驅(qū)動(chromedriver)下載地址http://chromedriver.storage.googleapis.com/index.html

PhantomJS無頭瀏覽器下載地址 無界面瀏覽器引擎,無界面可腳本編程的webkit瀏覽器引擎(目前chrom也可以支持無界面請求了) 下載地址:http://phantomjs.org/download.html API使用說明:http://phantomjs.org/api/command-line.html 2.1.1

火狐驅(qū)動下載路徑(GeckoDriver)https://github.com/mozilla/geckodriver/releases (2.3.8是最新的,下載的驅(qū)動版本一定要支持你當(dāng)前的瀏覽器版本)

Selenium 庫里有個叫 WebDriver 的 API。WebDriver 有點兒像可以加載網(wǎng)站的瀏覽器踪蹬,但是它也可以像 BeautifulSoup 或者其他 Selector 對象一樣用來查找頁面元素臣咖,與頁面上的元素進行交互 (發(fā)送文本跃捣、點擊等)夺蛇,以及執(zhí)行其他動作來運行網(wǎng)絡(luò)爬蟲。

注意: 我們使用的有界面瀏覽器愿卸,它雖然方便我們觀察截型,但是在實際運用中是非常消耗性能的 我們也可以使用Chrome的無界面瀏覽器,除了沒有瀏覽器界面以外趴荸,其它的相關(guān)操作都與有界面瀏覽器相同

Chrome的有宦焦、無界面瀏覽器實現(xiàn)代碼如下:

案例:

#-- coding:UTF-8 -*-
#導(dǎo)入 webdriver
from lxml import etree
from selenium import webdriver
from bs4 import BeautifulSoup
# 要想調(diào)用鍵盤按鍵操作需要引入keys包
from selenium.webdriver.common.keys import Keys
import time
#無界面瀏覽器相關(guān)設(shè)置
# 創(chuàng)建chrome參數(shù)對象
opt = webdriver.ChromeOptions()
#把chrome設(shè)置成為無界面模式
opt.set_headless()
#創(chuàng)建chrome無界面對象
driver = webdriver.Chrome(
        options=opt, executable_path='/Users/wxl/Desktop/chromedriver')

#創(chuàng)建chrome有界面對象
driver = webdriver.Chrome(executable_path='/Users/wxl/Desktop/chromedriver')#調(diào)用Chrome瀏覽器創(chuàng)建瀏覽器對像(指定一下位置)
#driver.implicitly_wait(1000)
time.sleep(2)
#打開瀏覽器,模擬瀏覽器請求頁面
driver.get('http://www.baidu.com/')
#獲取頁面的源碼信息
html = driver.page_source
print(html)
#soup = BeautifulSoup(html,“html.parser”)
soup = etree.HTML(html)
# 獲取頁面名為 wrapper的id標簽的文本內(nèi)容
data = driver.find_element_by_id("wrapper").text
#打印數(shù)據(jù)內(nèi)容
print(data)

#打印標題數(shù)據(jù)
print(driver.title)

#向百度的搜索框輸入搜索關(guān)鍵字
driver.find_element_by_id('kw').send_keys('美女')
#百度搜索按鈕酝豪,click() 是模擬點擊
driver.find_element_by_id('su').click()

#獲取當(dāng)前頁面的cookies()
cookies = driver.get_cookies()

cookie = ''

for item in cookies:

    cookie += item['name']+item['value']+' ;'

    print(cookie[:-1])

#全選輸入框中的內(nèi)容ctrl+a 
print(driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a'))

# ctrl+x 剪切輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')

#清空輸入框內(nèi)容
driver.find_element_by_id('kw').clear()
#輸入框重新輸入內(nèi)容
driver.find_element_by_id('kw').send_keys('風(fēng)景')
#模擬回車鍵
driver.find_element_by_id('su').send_keys(Keys.RETURN)
#獲取當(dāng)前的url
currentUrl = driver.current_url
print(currentUrl)

#截取網(wǎng)頁頁面(生成當(dāng)前的頁面快照并保存)
driver.save_screenshot('baidu.png')

#睡眠7秒
time.sleep(7)
# 關(guān)閉瀏覽器
driver.quit()

# 關(guān)閉當(dāng)前頁面,如果只有一個頁面蒲障,會關(guān)閉瀏覽器
driver.close()

頁面的相關(guān)操作:

Selenium 的 WebDriver提供了各種方法來尋找元素瘫证,假設(shè)下面有一個表單輸入框:

<input type="text" name="user-name" id="passwd-id">
取id標簽值
element = driver.find_element_by_id("passwd-id")
獲取name標簽值
element = driver.find_element_by_name("user-name")
獲取標簽名值
element = driver.find_elements_by_tag_name("input")
也可以通過XPath來匹配
element = driver.find_element_by_xpath("http://input[@id='passwd-id']")

定位UI元素 (WebElements)

關(guān)于元素的選取,有如下的API 單個元素選取

find_element_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector

By ID

假設(shè)有一個div的毙籽,他的id為coolestWidgetEvah毡庆,我們可以通過下面的方式來找到這個div

    <div id="coolestWidgetEvah">...</div>

方式一:
element = driver.find_element_by_id("coolestWidgetEvah")

方式二:倒入相關(guān)模塊
from selenium.webdriver.common.by import By
##### 使用如下
element = driver.find_element(by=By.ID, value="coolestWidgetEvah")

By Class Name

    <div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>

實現(xiàn)
cheeses = driver.find_elements_by_class_name("cheese")
----------------or-------------------
from selenium.webdriver.common.by import By

cheeses = driver.find_elements(By.CLASS_NAME, "cheese")

By Tag Name

    <iframe src="..."></iframe>

實現(xiàn)
frame = driver.find_element_by_tag_name("iframe")

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

frame = driver.find_element(By.TAG_NAME, "iframe")

By Name

    <input name="cheese" type="text"/>

實現(xiàn)
cheese = driver.find_element_by_name("cheese")

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

cheese = driver.find_element(By.NAME, "cheese")

By Link Text

    <a >下一頁</a>

實現(xiàn)
cheese = driver.find_element_by_link_text("下一頁")

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

cheese = driver.find_element(By.LINK_TEXT, "下一頁")

By Partial Link Text

通過局部的Link Text實現(xiàn)查找

<a >search for cheese</a>

實現(xiàn)
cheese = driver.find_element_by_partial_link_text("cheese")

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

cheese = driver.find_element(By.PARTIAL_LINK_TEXT, "cheese")

By CSS

<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>

實現(xiàn)
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")

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

cheese = driver.find_element(By.CSS_SELECTOR, "#food span.dairy.aged")

By XPath

<input type="text" name="example" />
<input type="text" name="other" />

inputs = driver.find_elements_by_xpath("http://input")
------------------------ or -------------------------
from selenium.webdriver.common.by import By

inputs = driver.find_elements(By.XPATH, "http://input")

頁面等待

注意:這是非常重要的一部分C纯埂毅否! 現(xiàn)在的網(wǎng)頁越來越多采用了 Ajax 技術(shù)蝇刀,這樣程序便不能確定何時某個元素完全加載出來了熊泵。如果實際頁面等待時間過長導(dǎo)致某個dom元素還沒出來甸昏,但是你的代碼直接使用了這個WebElement,那么就會拋出NullPointer的異常施蜜。 為了避免這種元素定位困難而且會提高產(chǎn)生 ElementNotVisibleException 的概率。所以 Selenium 提供了兩種等待方式缸沃,一種是隱式等待,一種是顯式等待趾牧。 隱式等待是等待特定的時間肯污,顯式等待是指定某一條件直到這個條件成立時繼續(xù)執(zhí)行吨枉。

隱式等待

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

顯式等待

顯式等待指定某個條件哄芜,然后設(shè)置最長等待時間貌亭。如果在這個時間還沒有找到元素认臊,那么便會拋出異常了。

from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 庫剧腻,負責(zé)循環(huán)等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 類师坎,負責(zé)條件出發(fā)
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
    ##### 會在這里等待,如果10秒內(nèi) id="myDynamicElement" 出現(xiàn)則返回胯陋,如果不出現(xiàn)則報異常
    element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit()

如果不寫參數(shù),程序默認會 0.5s 調(diào)用一次來查看元素是否已經(jīng)生成遏乔,如果本來元素就是存在的,那么會立即返回凉翻。 下面是一些內(nèi)置的等待條件捻激,你可以直接調(diào)用這些條件制轰,而不用自己寫某些等待條件了胞谭。

title_is    標題是某內(nèi)容  
title_contains   標題包含某內(nèi)容
presence_of_element_located 確保節(jié)點在本地加載出來傳入元組(By.ID,'password')
visibility_of_element_located  節(jié)點可見,傳入定位元組
presence_of_all_elements_located 所有節(jié)點加載出來
text_to_be_present_in_element 某個節(jié)點的文本包含某文字
text_to_be_present_in_element_value 某個節(jié)點的值包含某文字
frame_to_be_available_and_switch_to_it 加載并切換
invisibility_of_element_located 節(jié)點不可見
element_to_be_clickable – 節(jié)點可點擊.
staleness_of 判斷某個節(jié)點是否在文本中
element_located_to_be_selected 節(jié)點可選擇调俘,傳入定位元組
alert_is_present 是否出現(xiàn)警告

https://www.cnblogs.com/peng-lan/p/9604672.html

鼠標動作鏈

有些時候旺垒,我們需要再頁面上模擬一些鼠標操作,比如雙擊先蒋、右擊、拖拽甚至按住不動等竞漾,我們可以通過導(dǎo)入 ActionChains 類來做到:

#-*- coding:UTF-8 -*-

##### 導(dǎo)入ActionChains類

from selenium.webdriver import ActionChains

from selenium import webdriver

from selenium.webdriver.common.keys import Keys

import time

driver = webdriver.Chrome(executable_path='/Users/ljh/Desktop/chromedriver')

driver.get('http://www.baidu.com')

##### 鼠標移動到ac位置,移動到搜索的位置

action = driver.find_element_by_xpath('//div[@id="u1"]/a[4]')

ActionChains(driver).move_to_element(action).perform()

##### 在action上單擊

ActionChains(driver).move_to_element(action).click(action).perform()

##### 在 ac 位置雙擊

ActionChains(driver).move_to_element(action).double_click(action).perform()

##### 在 ac 位置右擊

ActionChains(driver).move_to_element(action).context_click(action).perform()

##### 在 ac 位置左鍵單擊hold住

ActionChains(driver).move_to_element(action).click_and_hold(action).perform()

##### 將 ac1 拖拽到 ac2 位置

time.sleep(5)

ac1 = driver.find_element_by_id("su")

ac2 = driver.find_element_by_class_name('mnav')

ActionChains(driver).drag_and_drop(ac1,ac2).perform()

time.sleep(5)

driver.quit()

填充表單

我們已經(jīng)知道了怎樣向文本框中輸入文字,但是有時候我們會碰到標簽的下拉框坦仍。直接點擊下拉框中的選項不一定可行。

    <select id="status" class="form-control valid" name="status">
        <option value=""></option>
        <option value="0">未審核</option>
        <option value="1">初審?fù)ㄟ^</option>
        <option value="2">復(fù)審?fù)ㄟ^</option>
        <option value="3">審核不通過</option>
    </select>

Selenium專門提供了Select類來處理下拉框幔荒。 其實 WebDriver 中提供了一個叫 Select 的方法梳玫,可以幫助我們完成這些事情:

導(dǎo)入 Select 類

from selenium.webdriver.support.ui import Select

#### 找到 name 的選項卡
select = Select(driver.find_element_by_name('status'))

#### 選擇
select.select_by_index(1)

select.select_by_value("0")

select.select_by_visible_text(u"未審核")

以上是三種選擇下拉框的方式,它可以根據(jù)索引來選擇提澎,可以根據(jù)值來選擇,可以根據(jù)文字來選擇盼忌。注意:

  • index 索引從 0 開始
  • value是option標簽的一個屬性值,并不是顯示在下拉框中的值
  • visible_text是在option標簽文本的值看成,是顯示在下拉框的值

全部取消選擇怎么辦呢跨嘉?很簡單:

select.deselect_all()

彈窗處理

當(dāng)你觸發(fā)了某個事件之后,頁面出現(xiàn)了彈窗提示祠乃,處理這個提示或者獲取提示信息方法如下:

alert = driver.switch_to_alert()

(選項卡管理)頁面切換

一個瀏覽器肯定會有很多窗口,所以我們肯定要有方法來實現(xiàn)窗口的切換亮瓷。切換窗口的方法如下:

js = 'window.open("http://www.baidu.com/")'

driver.execute_script(js)

driver.switch_to.window(driver.window_handles[0])

也可以使用 window_handles 方法來獲取每個窗口的操作對象。例如:

for handle in driver.window_handles:
    driver.switch_to_window(handle)

切換Frame

網(wǎng)頁中有一種節(jié)點叫做iframe,也就是子Frame,我們不能夠直接獲取到子Frame中的節(jié)點艾蓝,要想獲取到需要切換到子frame下

login_frame:為子frame的名稱

driver.switch_to_frame('login_frame')

頁面前進和后退

操作頁面的前進和后退功能:

driver.forward()     #前進

driver.back()        # 后退

Cookies

獲取頁面每個Cookies值斗塘,用法如下

cookies = driver.get_cookies()
for cookie in cookies:
    print("%s -> %s" % (cookie['name'], cookie['value']))

cookie_dict = {i['name']:i['value'] for i in cookies}
print(cookie_dict)

添加cookies

driver.add_cookie(cookie_dict)

刪除Cookies亮靴,用法如下

  • 刪除一個特定的cookie
driver.delete_cookie("CookieName")

  • 刪除所有cookie
driver.delete_all_cookies()

異常處理

  • 請求超時異常處理
from selenium.common.exceptions import TimeoutException

try:
    brower.get(url)
except TimeoutException:
    print('Time out')

  • 找不到標簽的異常處理
from selenium.common.exceptions import NoSuchElementException

try:
    brower.find_element_by_id('').click()
except NoSuchElementException:
    print('沒有這個標簽')
finally:
    print('有標簽')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贞岭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞄桨,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泊交,死亡現(xiàn)場離奇詭異,居然都是意外死亡廓俭,警方通過查閱死者的電腦和手機唉工,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來淋硝,“玉大人,你說我怎么就攤上這事橄唬。” “怎么了仰楚?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵犬庇,是天一觀的道長。 經(jīng)常有香客問我臭挽,道長,這世上最難降的妖魔是什么葬荷? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任纽帖,我火速辦了婚禮宠漩,結(jié)果婚禮上懊直,老公的妹妹穿的比我還像新娘。我一直安慰自己室囊,他們只是感情好魁索,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布盼铁。 她就那樣靜靜地躺著,像睡著了一般支鸡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牧挣,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天醒陆,我揣著相機與錄音,去河邊找鬼刨摩。 笑死,一個胖子當(dāng)著我的面吹牛澡刹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陆赋,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嚷闭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胞锰?” 一聲冷哼從身側(cè)響起灾锯,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗅榕,沒想到半個月后顺饮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡凌那,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年兼雄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片案怯。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡君旦,死狀恐怖澎办,靈堂內(nèi)的尸體忽然破棺而出嘲碱,到底是詐尸還是另有隱情金砍,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布麦锯,位于F島的核電站恕稠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扶欣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一料祠、第九天 我趴在偏房一處隱蔽的房頂上張望骆捧。 院中可真熱鬧,春花似錦髓绽、人聲如沸敛苇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枫攀。三九已至,卻和暖如春株茶,著一層夾襖步出監(jiān)牢的瞬間来涨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工启盛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蹦掐,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓僵闯,卻偏偏與公主長得像笤闯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棍厂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容