現(xiàn)狀
好久好久沒(méi)有更新博客了,應(yīng)該有一個(gè)月了吧,這段時(shí)間內(nèi),好忙,公司的業(yè)務(wù)在上漲期,但是卻把下面的一個(gè)小朋友砍掉了(換組),所以很多打雜的時(shí)候都讓jb去做了,基本上每天活著跟咸魚一樣~
雖然是咸魚,但是還是要學(xué)習(xí),最近在返璞歸真,做了那么多年的測(cè)試狗,還是要學(xué)習(xí)點(diǎn)理論知識(shí),畢竟得有些料才能吹的更愉快;
這段時(shí)間基本上都是在學(xué)習(xí)測(cè)試相關(guān)的書籍,測(cè)試工作,理論知識(shí)等,也看到不同的測(cè)試書籍,感覺(jué)很多都很差強(qiáng)人意,每本書都總覺(jué)得有所欠缺,如果有機(jī)會(huì),挺想自己擼一本的,哈哈哈;
本篇作為閱讀篇的第一篇,主要來(lái)介紹下selenium,介紹的原因是,最近有些項(xiàng)目是web端的,隨著項(xiàng)目的穩(wěn)定,后面會(huì)考慮自動(dòng)化,而PC的自動(dòng)化,基本上都是用selenium,那就來(lái)圍觀吧~
前言
之前看coder-pig文章時(shí)有大致了解,很早之前也聽(tīng)過(guò)selenium,但是還是想系統(tǒng)看一遍,聽(tīng)說(shuō)蟲(chóng)師的這本書還可以,因此就來(lái)學(xué)習(xí)學(xué)習(xí)下~
雖然這部書叫selenium,但是有大致三分之二的內(nèi)容是測(cè)試跟Python相關(guān)的內(nèi)容,因此會(huì)優(yōu)先介紹selenium相關(guān)內(nèi)容,最后會(huì)貼一些自己覺(jué)得有點(diǎn)用的信息;
說(shuō)明,本篇內(nèi)容是基于coder-pig的原文進(jìn)行補(bǔ)充及介紹,算是一個(gè)整理;
書籍信息
本書全名:Selenium 2 自動(dòng)化測(cè)試實(shí)戰(zhàn),基于Python語(yǔ)言
作者:蟲(chóng)師
出版社:電子工業(yè)出版社
版次:2016年1月第1版
Selenium
簡(jiǎn)介
Selenium是一個(gè)自動(dòng)化測(cè)試框架,通過(guò)他,可以編寫代碼讓瀏覽器:
- 自動(dòng)加載網(wǎng)頁(yè),獲取當(dāng)前呈現(xiàn)頁(yè)面的源碼;
- 模擬點(diǎn)擊和其他交互方式,最常用:模擬表單提交(比如模擬登錄);
- 頁(yè)面截屏;
- 判斷網(wǎng)頁(yè)某些動(dòng)作是否發(fā)生,等等。
Selenium是不支持瀏覽器功能的,需要和第三方的瀏覽器一起搭配使用,支持下述瀏覽器,你需要把對(duì)應(yīng)的瀏覽器驅(qū)動(dòng)下載到Python的對(duì)應(yīng)路徑下:
- Chrome:https://sites.google.com/a/chromium.org/chromedriver/home
- FireFox:https://github.com/mozilla/geckodriver/releases
- PhantomJS:http://phantomjs.org/
- IE:http://selenium-release.storage.googleapis.com/index.html
- Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
- Opera:https://github.com/operasoftware/operachromiumdriver/releases
安裝
直接利用pip命令進(jìn)行安裝,命令如下:
pip install selenium
接著下載瀏覽器驅(qū)動(dòng),大部分用的Chrome瀏覽器,就以此為例,其他瀏覽器可自行搜索相關(guān)文檔,打開(kāi)Chrome瀏覽器鍵入:
chrome://version
即可查看Chrome瀏覽器版本的相關(guān)信息,主要是關(guān)注版本號(hào):
Google Chrome 68.0.3440.106 (正式版本) (32 位) (cohort: Stable)
修訂版本 1c32c539ce0065a41cb79da7bfcd2c71af1afe62-refs/branch-heads/3440@{#794}
操作系統(tǒng) Windows
JavaScript V8 6.8.275.26
Flash 30.0.0.154 C:\Users\jb\AppData\Local\Google\Chrome\User Data\
PepperFlash\30.0.0.154\pepflashplayer.dll
用戶代理 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/68.0.3440.106 Safari/537.36
命令行 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
--flag-switches-begin --flag-switches-end
可執(zhí)行文件路徑 C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
個(gè)人資料路徑 C:\Users\jb\AppData\Local\Google\Chrome\User Data\Default
這里看到,大版本號(hào)是68,接下來(lái)到下面的這個(gè)網(wǎng)站查看對(duì)應(yīng)的驅(qū)動(dòng)版本號(hào):
https://chromedriver.storage.googleapis.com/2.41/notes.txt
可以看到如下的版本號(hào)信息。
----------ChromeDriver v2.41 (2018-07-27)----------
Supports Chrome v67-69
Resolved issue 2458: Chromedriver fails to start with whitelisted-ips option [[Pri-1]]
Resolved issue 2379: Returned capabilities should include remote debugging port [[Pri-2]]
Resolved issue 1005: driver.manage().window().getSize() is not implemented on Android [[Pri-2]]
Resolved issue 2474: desktop launcher error messages are not readable by users [[Pri-]]
Resolved issue 2496: Fail fast when not able to start binary [[Pri-]]
Resolved issue 1990: Close Window return value does not conform with spec [[Pri-]]
ok,那就是下載2.4.1這個(gè)版本驅(qū)動(dòng),鏈接:
https://chromedriver.storage.googleapis.com/index.html?path=2.41/
打開(kāi)后可以看到所示的頁(yè)面,選擇對(duì)應(yīng)的系統(tǒng)下載即可。
下載完成后,把zip文件解壓下,解壓后的chromedriver.exe拷貝到Python的Scripts目錄下,另外這里不用糾結(jié)win32,在64位的瀏覽器上也是可以正常使用的!Mac的話把解壓后的文件拷貝到usr/local/bin目錄下 ,Ubuntu的話則拷貝到usr/bin目錄下。
demo
接下來(lái),來(lái)個(gè)小demo吧:
# coding = utf-8
# 為了防止亂碼問(wèn)題,以及方便的在程序中添加中文注釋,把編碼統(tǒng)一成 UTF-8。
from selenium import webdriver
# 導(dǎo)入 selenium 的 webdriver 包,只有導(dǎo)入 webdriver 包我們才能使用 webdriver API 進(jìn)行自動(dòng)化腳本的開(kāi)發(fā)。
browser = webdriver.Chrome()
#把webdriver的Chrome對(duì)象賦值給變量driver;
#只有獲得了瀏覽器對(duì)象后,才可以啟動(dòng)瀏覽器,打開(kāi)網(wǎng)址,操作頁(yè)面元素,Chrome瀏覽器驅(qū)動(dòng)默認(rèn)已經(jīng)在Selenium WebDriver包里了,可以直接調(diào)用;
#要先安裝相關(guān)的瀏覽器驅(qū)動(dòng)
browser.get("http://www.baidu.com")
#獲得瀏覽器對(duì)象后,通過(guò) get()方法,可以向?yàn)g覽器發(fā)送網(wǎng)址。
html_text = browser.page_source
# 獲得頁(yè)面代碼
browser.quit()
#退出并關(guān)閉窗口
執(zhí)行這段代碼后,會(huì)自動(dòng)調(diào)起Chrome瀏覽器,并訪問(wèn)百度,可以看到瀏覽器頂部有下面的提示。
并且控制臺(tái)會(huì)輸出HTML的代碼,和Chrome的Elements頁(yè)面結(jié)構(gòu)完全一致。
那就可以用selenium這么玩了;
不過(guò),在實(shí)踐之前,再繼續(xù)介紹下selenium其他方法吧;
API
定位元素
- find_element_by_id():根據(jù)id定位
- find_element_by_name():根據(jù)節(jié)點(diǎn)名定位
- find_element_by_class_name():根據(jù)class定位
- find_element_by_tag_name():通過(guò)tag定位
- find_element_by_link_text():根據(jù)鏈接的文本來(lái)定位
- find_element_by_partial_link_text():根據(jù)元素標(biāo)簽對(duì)之間的部分文本信息來(lái)定位
- find_element_by_xpath():使用Xpath進(jìn)行定位
- find_element_by_css_selector():根據(jù)css定位
- find_element(By.XX,value):根據(jù)By來(lái)聲明定位的方法,并且傳入對(duì)應(yīng)定位方法的定位參數(shù),比如By.ID跟By.CLASS_NAME等
另外,如果把element改為elements會(huì)定位所有符合條件的元素,返回一個(gè)List,比如:
find_elements_by_class_name
Selenium定位到結(jié)點(diǎn)位置會(huì)返回一個(gè)WebElement類型的對(duì)象,可以調(diào)用下述方法來(lái)提取需要的信息。
- 獲取屬性:
element.get_attribute()
- 獲取文本:
element.text
- 獲取標(biāo)簽名稱:
element.tag_name
- 獲取結(jié)點(diǎn)id:
element.id
控制窗口大小
# 設(shè)置瀏覽器寬480,高800顯示
driver.set_window_size(480,800):
# 全屏顯示
driver.maximize_window()
頁(yè)面前進(jìn),后退,切換
在頁(yè)面操作過(guò)程中有時(shí)候點(diǎn)擊某個(gè)鏈接會(huì)彈出新的窗口,這時(shí)候需要切換到新打開(kāi)的窗口上進(jìn)行操作;
# 通過(guò)window_handles來(lái)遍歷
for handle in driver.window_handles:
driver.switch_to_window(handle)
# 切換窗口
driver.switch_to.window("窗口名")
# 或通過(guò)window_handles來(lái)遍歷
for handle in driver.window_handles:
driver.switch_to_window(handle)
# 前進(jìn)
driver.forward()
# 后退
driver.back()
刷新動(dòng)作
driver.refresh()
清除文本,模擬按鍵輸入,點(diǎn)擊動(dòng)作
# clear()用于清除文本輸入框中的內(nèi)容
driver.find_element_by_id("idinput").clear()
# send_keys()用于模擬鍵盤向輸入框里輸入內(nèi)容
driver.find_element_by_id("idinput").send_keys("username")
# click()用于進(jìn)行點(diǎn)擊操作
driver.find_element_by_id("loginbtn").click()
提交表單
# 通過(guò)定位搜索框并通過(guò)submit()提交搜索框的內(nèi)容,達(dá)到點(diǎn)擊搜索按鈕的效果
driver.find_element_by_id("query").submit()
鼠標(biāo)動(dòng)作
有時(shí)需要在頁(yè)面上模擬鼠標(biāo)操作,比如:?jiǎn)螕簦p擊,右鍵,按住,拖拽等,可以導(dǎo)入ActionChains類:selenium.webdriver.common.action_chains.ActionChains,使用ActionChains(driver).XXX調(diào)用對(duì)應(yīng)節(jié)點(diǎn)的行為。
- click(element):?jiǎn)螕裟硞€(gè)節(jié)點(diǎn);
- click_and_hold(element):?jiǎn)螕裟硞€(gè)節(jié)點(diǎn)并按住不放;
- context_click(element):右鍵單擊某個(gè)節(jié)點(diǎn);
- double_click(element):雙擊某個(gè)節(jié)點(diǎn);
- drag_and_drop(source,target):按住某個(gè)節(jié)點(diǎn)拖拽到另一個(gè)節(jié)點(diǎn);
- drag_and_drop_by_offset(source, xoffset, yoffset):按住節(jié)點(diǎn)按偏移拖拽
- key_down:按下特殊鍵,只能用(Control, Alt and Shift),比如Ctrl+C
- ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform();
- key_up:釋放特殊鍵;
- move_by_offset(xoffset, yoffset):按偏移移動(dòng)鼠標(biāo);
- move_to_element(element):鼠標(biāo)移動(dòng)到某個(gè)節(jié)點(diǎn)的位置;
- move_to_element_with_offset(element, xoffset, yoffset):鼠標(biāo)移到某個(gè)節(jié)點(diǎn)并偏移;
- pause(second):暫停所有的輸入多少秒;
- perform():執(zhí)行操作,可以設(shè)置多個(gè)操作,調(diào)用perform()才會(huì)執(zhí)行;
- release():釋放鼠標(biāo)按鈕
- reset_actions:重置操作
- send_keys(keys_to_send):模擬按鍵,
比如輸入框節(jié)點(diǎn).send_keys(Keys.CONTROL,'a') 全選輸入框內(nèi)容,
輸入框節(jié)點(diǎn).send_keys(Keys.CONTROL,'x')剪切,
模擬回退:
節(jié)點(diǎn).send_keys(keys.RETURN);
或者直接設(shè)置輸入框內(nèi)容:輸入框節(jié)點(diǎn).send_keys('xxx'); - send_keys_to_element(element, *keys_to_send):和send_keys類似;
鍵盤事件
send_key()雖然可以模擬鍵盤輸入,但除此之外,還需要輸入其他按鍵,比如空格,這時(shí)候就需要用到Keys();
對(duì)應(yīng)類:selenium.webdriver.common.keys.Keys,使用send_keys(Keys.XX)輸入對(duì)應(yīng)的內(nèi)容即可;
- BACK_SPACE:刪除鍵(BackSpace)(send_key(Keys.BACK_SPACE))
- SPACE:空格鍵(Space)
- TAB:制表鍵(TAB)
- ESCAPE:回退鍵(Esc)
- ENTER:回車鍵(Enter)
- CONTROL,'a':全選(Ctrl+A)(send_key(Keys.CONTROL,'a'))
- CONTROL,'c':復(fù)制(Ctrl+C)
- CONTROL,'x':剪切(Ctrl+X)
- CONTROL,'v':粘貼(Ctrl+V)
- F1:鍵盤F1
- ...
- F12:鍵盤F12
頁(yè)面標(biāo)題和鏈接
# 獲取當(dāng)前網(wǎng)頁(yè)的標(biāo)題
driver.title
# 獲取當(dāng)前網(wǎng)頁(yè)的url
driver.current_url
頁(yè)面等待
現(xiàn)在的網(wǎng)頁(yè)越來(lái)越多采用了 Ajax技術(shù),這樣程序便不能確定何時(shí)某個(gè)元素完全加載出來(lái)了。
如果實(shí)際頁(yè)面等待時(shí)間過(guò)長(zhǎng)導(dǎo)致某個(gè)dom元素還沒(méi)出來(lái),但是你的代碼直接使用了這個(gè)WebElement,那么就會(huì)拋出NullPointer的異常。
為了避免這種元素定位困難而且會(huì)提高產(chǎn)生ElementNotVisibleException的概率。
所以Selenium 提供了兩種等待方式,一種是隱式等待,一種是顯式等待。
- 顯式等待:
指定某個(gè)條件,然后設(shè)置最長(zhǎng)等待時(shí)間。
如果在這個(gè)時(shí)間還沒(méi)有找到元素,那么便會(huì)拋出異常,代碼示例如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 庫(kù),負(fù)責(zé)循環(huán)等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 類,負(fù)責(zé)條件出發(fā)
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.PhantomJS()
driver.get("http://www.xxxxx.com/loading")
try:
# 每隔10秒查找頁(yè)面元素 id="myDynamicElement",直到出現(xiàn)則返回
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
如果不寫參數(shù),程序默認(rèn)會(huì)0.5s調(diào)用一次來(lái)查看元素是否已經(jīng)生成,如果本來(lái)元素就是存在的,那么會(huì)立即返回。
下面是一些內(nèi)置的等待條件,你可以直接調(diào)用這些條件,而不用自己寫某些等待條件了。
等待條件 | 描述 |
---|---|
title_is | 標(biāo)題是內(nèi)容 |
title_contains | 標(biāo)題包含某內(nèi)容 |
presence_of_element_located | 結(jié)點(diǎn)加載出來(lái),傳入定位元組 |
visibility_of_element_located | 結(jié)點(diǎn)課件,傳入定位元組 |
visibility_of | 可見(jiàn),傳入結(jié)點(diǎn)對(duì)象 |
presence_of_all_elements_located | 所有結(jié)點(diǎn)加載出來(lái) |
text_to_be_present_in_element | 某個(gè)結(jié)點(diǎn)文本包含某文字 |
text_to_be_present_in_element_value | 某個(gè)結(jié)點(diǎn)值包含某文字 |
frame_to_be_available_and_switch_to_it | 加載并切換 |
invisibility_of_element_located | 結(jié)點(diǎn)不可見(jiàn) |
element_to_be_clickable | 節(jié)點(diǎn)可點(diǎn)擊 |
staleness_of | 判斷結(jié)點(diǎn)是否仍在DOM,常用于判斷頁(yè)面是否已刷新 |
element_to_be_selected | 結(jié)點(diǎn)可選擇,傳入結(jié)點(diǎn)對(duì)象 |
element_located_to_be_selected | 結(jié)點(diǎn)可選擇,傳入定位元組 |
element_selection_state_to_be | 傳入結(jié)點(diǎn)對(duì)象和狀態(tài),相等返回True,否則返回False |
element_located_selection_state_to_be | 傳入定位元組和狀態(tài),相等返回True,否則返回False |
alert_is_present | 是否出現(xiàn)警告 |
- 隱式等待:
隱式等待比較簡(jiǎn)單,就是簡(jiǎn)單地設(shè)置一個(gè)等待時(shí)間,單位為秒,代碼示例如下:
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
如果不設(shè)置,就默認(rèn)等待時(shí)間為0
休眠sleep
有時(shí)候希望腳本執(zhí)行到某個(gè)位置做固定時(shí)間的休眠,這時(shí)候就需要用到sleep(),這個(gè)sleep方法是由Python的time模塊提供,因此使用之前需要from time import sleep;
# 休眠X秒
sleep(X)
多表單切換
在web應(yīng)用中經(jīng)常會(huì)遇到frame/iframe表單嵌套頁(yè)面的應(yīng)用,webdriver只能在一個(gè)頁(yè)面上對(duì)元素識(shí)別與定位,對(duì)于frame/iframe無(wú)法直接定位;
這時(shí)候就需要通過(guò)switch_to.frame()方法將當(dāng)前定位的主體切換為frame/iframe內(nèi)嵌的的頁(yè)面中;
# 切換到iframe(id = "XX")
driver.switch_to.frame("XX")
切換后就能正常操作元素了;
switch_to.frame()默認(rèn)可以直接獲取表單的id或name屬性,但如果iframe沒(méi)有可用的id和name屬性呢?
# 先通過(guò)xpath定位到iframe
xf = driver.find_element_by_xpath("http://*[@class="XX"]")
# 再將定位對(duì)象傳給switch_to.frame()方法
driver.switch_to.frame(xf)
彈窗
對(duì)應(yīng)類:selenium.webdriver.common.alert.Alert,用得不多,如果你觸發(fā)了某個(gè)事件,彈出了對(duì)話框,可以調(diào)用這個(gè)方法獲得對(duì)話框:alert = driver.switch_to_alert(),然后alert對(duì)象可以調(diào)用下述方法:
- accept():確定
- dismiss():關(guān)閉對(duì)話框
- send_keys():傳入值
- text():獲得對(duì)話框文本
上傳文件
一般網(wǎng)頁(yè)上傳文件,都是有一個(gè)瀏覽按鈕,選擇文件點(diǎn)擊上傳即可,但是對(duì)應(yīng)做自動(dòng)化測(cè)試來(lái)說(shuō),在選擇文件那個(gè)過(guò)程是非常麻煩的;
其實(shí),做過(guò)類似功能的同學(xué)會(huì)發(fā)現(xiàn),瀏覽按鈕其實(shí)就是input標(biāo)簽實(shí)現(xiàn)的上傳功能,可以看到是一個(gè)輸入框,居然如此,就可以用send_keys()來(lái)模擬;
driver.find_element_by_name("file").send_keys("C:\\jb.txt")
下載文件
運(yùn)行設(shè)置文件下載路徑;
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': os.getcwd()}
options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=options)
driver.get("http://pypi.Python.org/pypi/selenium")driver.find_element_by_partial_link_text("selenium-3.11.0-py2.py3-none-any").click()
頁(yè)面截圖
driver.save_screenshot("截圖.png")
# 截取當(dāng)前窗口,并指定截圖圖片的保存位置
dirver.get_screenshot_as_file("C:\\jb\\jb.jpg")
Cookies
有些站點(diǎn)需要登錄后才能訪問(wèn),用Selenium模擬登錄后獲取Cookie,
然后供爬蟲(chóng)使用的場(chǎng)景非常常見(jiàn),Selenium提供了獲取,增加,刪除Cookies的函數(shù),代碼示例如下:
# 獲取所有Cookies
browser.get_cookies()
# 獲取name對(duì)應(yīng)的cookie信息
browser.get_cookie(name)
# 增加Cookies,是字典對(duì)象,必須要有name 和value
browers.add_cookie({xxx})
driver.add_cookie({"name":"jb","value":"jbtest"})
# 如果需要遍歷,則如下:
for cookie in driver.get_cookies():
print("%s -> %s " % (cookie["name"],cookie["value"]))
# 刪除所有Cookies
browser.delete_cookies()
# 刪除Cookie信息,name是要?jiǎng)h除的cookie的名稱,optionsString是該cookie的選項(xiàng),目前支持的選項(xiàng)包括“路徑”和“域”
browser.delete_cookie(name,optionsString)
實(shí)踐:
from selenium import webdriver
browser = webdriver.Chrome()
url = "https://www.baidu.com/"
browser.get(url)
# 通過(guò)js新打開(kāi)一個(gè)窗口
newwindow='window.open("https://www.baidu.com");'
# 刪除原來(lái)的cookie
browser.delete_all_cookies()
# 攜帶cookie打開(kāi)
browser.add_cookie({'name':'ABC','value':'DEF'})
# 通過(guò)js新打開(kāi)一個(gè)窗口
browser.execute_script(newwindow)
input("查看效果")
browser.quit()
這里還是需要說(shuō)下,add_cookie方法接受一個(gè)字典,字典中包含name,value,path,domain,secure,expiry,
正確的寫cookie格式:
cookie = {
# "domain": ".58.com", #Firefox瀏覽器不能寫domain,如果寫了會(huì)報(bào)錯(cuò),谷歌需要寫否則也是報(bào)錯(cuò),這里就是一個(gè)坑。其他瀏覽器沒(méi)測(cè)試不知道情況。
'name': name,
'value': value,
"expires": "",
'path': '/',
'httpOnly': False,
'HostOnly': False,
'Secure': False,
}
name:cookie的名稱
value:cookie對(duì)應(yīng)的值,動(dòng)態(tài)生成的
domain:服務(wù)器域名
expiry:Cookie有效終止日期
path:Path屬性定義了Web服務(wù)器上哪些路徑下的頁(yè)面可獲取服務(wù)器設(shè)置的Cookie
httpOnly:防腳本攻擊
secure:在Cookie中標(biāo)記該變量,表明只有當(dāng)瀏覽器和Web Server之間的通信協(xié)議為加密認(rèn)證協(xié)議時(shí)
為什么要構(gòu)造成這樣子,其實(shí)我們看下瀏覽器保存的cookie格式就明白了。下圖就是谷歌瀏覽器的cookie 的截圖。
代碼應(yīng)該這么寫:
這里有個(gè)問(wèn)題,cookie要key:value的格式,是非常麻煩的,尤其是像豆瓣那樣非常非常長(zhǎng)的cookie,再手動(dòng)一個(gè)一個(gè)改格式,這個(gè)工作量還不如重新用selenium寫一個(gè)登陸操作;
fiddler轉(zhuǎn)包的cookie格式是這樣的:
一個(gè)一個(gè)改會(huì)崩潰的;所以遇到cookie很長(zhǎng)的情況,還不如寫一個(gè)登陸腳本保存吧~
執(zhí)行JS語(yǔ)句
雖然webdriver提供瀏覽器的前進(jìn)和后退,但是并不提供滾動(dòng)瀏覽器的操作,因此來(lái)借助JS來(lái)控制瀏覽器的滾動(dòng)條;
driver.execute_script(js語(yǔ)句)
比如滾動(dòng)到底部的代碼示例如下:
js = document.body.scrollTop=10000
driver.execute_script(js)
又如設(shè)置瀏覽器窗口的滾動(dòng)條位置:
js = "window.scrollTo(100,450)"
driver.excute_script(js)
向文本框輸入文本信息:
text = "jbtest"
js = "var sum=document.getElementById("id"); sum.value='"+text+ " ';"
driver.excute_script(js)
處理HTML5 的視頻播放
HTML5定義了一個(gè)新的元素video,指定了一個(gè)標(biāo)準(zhǔn)的方式來(lái)嵌入電影片段;
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://videojs.com/")
video = driver.find_element_by_xpath("body/Setion[1]/div/video")
# 返回播放文件地址
url = driver.execute_script("return arguments[0].currentSrc;",video)
# 播放視頻
driver.execute_script("return arguments[0].play()",video)
# 暫停視頻
driver.execute_script("arguments[0].pause()",video)
JS函數(shù)有個(gè)內(nèi)置的對(duì)象叫做arguments;
arguments對(duì)象包含了函數(shù)調(diào)用的參數(shù)數(shù)組,[0]表示取對(duì)象的第一個(gè)值;
- currentSrc:返回當(dāng)前音頻/視頻的URL,如果未設(shè)置音頻/視頻,則返回空字符串;
- load():控制著視頻的加載
- play():控制著視頻的播放
- pause():控制著視頻的暫停
Headless
在介紹Headless之前,必須介紹下PhantomJS,
PhantomJS是沒(méi)有界面的瀏覽器,特點(diǎn):
會(huì)把網(wǎng)站加載到內(nèi)存并執(zhí)行頁(yè)面上的JavaScript,因?yàn)椴粫?huì)展示圖形界面,所以運(yùn)行起來(lái)比完整的瀏覽器要高效
而上面的例子,每次執(zhí)行后,都會(huì)打開(kāi)瀏覽器,很麻煩,這么看,PhantomJs是剛需啊;
但這里不打算介紹PhantomJs,因?yàn)?8年4月份,維護(hù)者宣布退出PhantomJs,意味著這個(gè)項(xiàng)目不再維護(hù)了;而同時(shí),Chrome和FireFox也開(kāi)始 提供Headless模式(無(wú)需調(diào)起瀏覽器),所以,后面的phantomjs小伙伴會(huì)遷移到這兩個(gè)瀏覽器上;
注意:Windows Chrome需要60以上的版本才支持 Headless模式,linux,unix系統(tǒng)需要 chrome瀏覽器 >= 59
啟用Headless模式也很簡(jiǎn)單,以上面打開(kāi)百度的代碼舉例,代碼如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_option = Options()
chrome_option.add_argument("--headless")
chrome_option.add_argument("--disable-gpu")
browser = webdriver.Chrome(chrome_options=chrome_option) # 調(diào)用本地的Chrome瀏覽器
browser.get('http://www.baidu.com') # 請(qǐng)求頁(yè)面,會(huì)打開(kāi)一個(gè)瀏覽器窗口
html_text = browser.page_source # 獲得頁(yè)面代碼
browser.quit() # 關(guān)閉瀏覽器
print(html_text)
就是多了設(shè)置chrome_option這幾步,執(zhí)行后,就不會(huì)再?gòu)棾鰹g覽器了,是不是很方便??
設(shè)置自定義請(qǐng)求頭
from selenium import webdriver
# 進(jìn)入瀏覽器設(shè)置
options = webdriver.ChromeOptions()
# 設(shè)置中文
options.add_argument('lang=zh_CN.UTF-8')
# 更換頭部
options.add_argument('user-agent="Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"')
browser = webdriver.Chrome(chrome_options=options)
url = "https://httpbin.org/get?show_env=1"
browser.get(url)
browser.quit()
溫馨提示:遇到JS加載的問(wèn)題,建議先嘗試破解JS,不行再用selenium,selenium屬于無(wú)腦類型,而且效率比較差,假如你有1W個(gè)網(wǎng)站,都跑一趟,估計(jì)要一天了;
大部分selenium相關(guān)的操作都介紹完了,先留個(gè)印象,那接下來(lái),讓我們看看怎么用selenium來(lái)獲取豆瓣驗(yàn)證碼captcha這個(gè)屬性吧;
"Cookie":"your cookie" #這里需要輸入你自己的cookie信息,如果遇到轉(zhuǎn)義字符,轉(zhuǎn)
義字符前面加\即可
Selenium詳細(xì)介紹
什么是Selenium
Selenium主要用于Web應(yīng)用程序的自動(dòng)化測(cè)試;
特點(diǎn):
- 開(kāi)源,免費(fèi);
- 多瀏覽器支持:Firefox、Chrome、IE、Opera、Edge;
- 多平臺(tái)支持:Linux、Windows、MAC;
- 多語(yǔ)言支持:Java、Python、Ruby、C#、JavaScript、C++;
- 對(duì)Web頁(yè)面有良好的支持;
- API簡(jiǎn)單、靈活(用開(kāi)發(fā)語(yǔ)言驅(qū)動(dòng))
- 支持分布式測(cè)試用例執(zhí)行
Selenium有兩個(gè)版本:Selenium 1.0 和Selenium 2.0;
Selenium不是由單獨(dú)一個(gè)工具構(gòu)成的,而是由一些插件、類庫(kù)組成,每個(gè)部分都有起特點(diǎn)和應(yīng)用場(chǎng)景;
Selenium 1.0家譜:
Selenium IDE
Selenium IDE是嵌入到Firefox瀏覽器中的一個(gè)插件,實(shí)現(xiàn)簡(jiǎn)單的瀏覽器操作的錄制與回放功能;
官方給出它自身作用的定位:
快速地創(chuàng)建bug重現(xiàn)腳本,在測(cè)試人員測(cè)試過(guò)程中,發(fā)現(xiàn)bug之后可以通過(guò)IDE將重現(xiàn)的步驟錄制下來(lái),以幫助開(kāi)發(fā)人員
更容易的重現(xiàn)bug;
那就可以理解,IDE的重點(diǎn)在于錄制,避免不會(huì)寫代碼的同學(xué),而且每次寫xpath也會(huì)很煩;
安裝
在線安裝
通過(guò) firefox 瀏覽器訪問(wèn) selenium;
下載頁(yè)面:http://docs.seleniumhq.org/download/
在 selenium IED 下載介紹部分,點(diǎn)擊版本號(hào)鏈接;
firefox 瀏覽器將自動(dòng)識(shí)別需要下載的 selenium IED 插件,,點(diǎn)擊 Install Now 按鈕,安裝 selenium IED 插件。
安裝完成后重啟 firefox 瀏覽器,通過(guò)菜單欄“Tools(工具)”---> selneium IDE 可以打開(kāi),或通過(guò) Ctrl+Alt+S 快捷鍵打開(kāi)。
但是實(shí)際,上面的url,試了半天都訪問(wèn)不了,另外還有,如果非Firefox瀏覽器是不是就用不了IDE?
插件安裝
非也,還有個(gè)插件安裝的方法,此方法來(lái)自小敏同學(xué)親測(cè)可行,Python2.7版本,F(xiàn)irefox40.0版本;
1)python2.7
mac/Linux自帶,不用裝;
Windows需要手動(dòng)安裝,要裝的小伙伴自行百度,so easy ~
2)selenium
由于selenium IDE在新版本firefox上并不支持,沒(méi)有錄制功能寫起來(lái)還是挺費(fèi)神的,建議保守的都選擇舊版本。
如果已經(jīng)安裝了selenium3,需要先卸載;
查看selenium版本命令:
pip show selenium
卸載selenium命令:
pip uninstall selenium
selenium用命令行pip install selenium==2.53.6安裝時(shí),由于被墻了,選擇下載安裝包自行安裝,步驟如下:
- 下載安裝包selenium-2.53.6.tar.gz
- 將安裝包放到python2.7的site-packages目錄下,解壓,比如目錄是/Library/Python/2.7/site-packages/
- cd到上一步解壓后的selenium目錄下,python setup.py install,安裝完成,查看版本號(hào)確認(rèn)安裝成功
3)下載安裝firefox 40.0版本
4)下載selenium_ide-2.9.1-fx.xpi,拖到firefox里面安裝好后,firefox右上角多出selenium IDE插件入口
5)下載firebug-2.0.16-fx.xpi,拖到firefox里面安裝好后,firefox右上角多出firebug插件入口
至此,環(huán)境安裝完成。
6)錄制自動(dòng)化腳本
點(diǎn)擊firefox右上角selenium IDE插件圖標(biāo),進(jìn)入selenium IDE主界面;
- 在下圖序號(hào)1紅框中,輸入你要測(cè)試的web url;
- 在下圖序號(hào)2紅框中,調(diào)節(jié)你要執(zhí)行用例的速度,一般建議調(diào)到中間;
- 在下圖序號(hào)3紅框中,點(diǎn)擊錄制按鈕開(kāi)始錄制;
- 在下圖序號(hào)4紅框中,對(duì)錄制結(jié)果進(jìn)行調(diào)節(jié),可以增刪改事件、參數(shù);
- 在下圖序號(hào)3紅框中,點(diǎn)擊停止錄制按鈕停止錄制;
- 在下圖序號(hào)5紅框中,點(diǎn)擊按鈕開(kāi)始執(zhí)行用例;
- 可以在菜單中選擇文件——export test case as——python 2/unittest/web driver,將腳本導(dǎo)出為python,本地編輯直接腳本調(diào)用。
7)優(yōu)化腳本
上步中最后導(dǎo)出的腳本,只包含了操作,沒(méi)有包含斷言結(jié)果判斷,也缺少容錯(cuò),想要持續(xù)集成自動(dòng)生成結(jié)果,還需要自己按需補(bǔ)充。
Selenium Grid
是一種自動(dòng)的測(cè)試輔助功能,Grid通過(guò)利用現(xiàn)有的計(jì)算機(jī)基礎(chǔ)設(shè)施,能加快Web-App的功能測(cè)試;
利用Grid可以很方便地實(shí)現(xiàn)在多臺(tái)機(jī)器上和異構(gòu)環(huán)境中運(yùn)行測(cè)試用例;
聽(tīng)上去會(huì)一臉懵逼,簡(jiǎn)單說(shuō),Selenium Grid可以解決重復(fù)執(zhí)行測(cè)試和多瀏覽器兼容測(cè)試的亮點(diǎn),并且是使用分布式執(zhí)行測(cè)試;
那分布式是什么概念?簡(jiǎn)單的說(shuō)就是老大收到任務(wù),分發(fā)給手下去干;
通過(guò)Selenium Grid的可以控制多臺(tái)機(jī)器多個(gè)瀏覽器執(zhí)行測(cè)試用例,分布式上執(zhí)行的環(huán)境在Selenium Grid中稱為node節(jié)點(diǎn)。
舉例說(shuō)明一下,比如用例上萬(wàn),一臺(tái)機(jī)器執(zhí)行全部測(cè)試用例耗時(shí)5個(gè)小時(shí),而如果需要覆蓋主流瀏覽器比如Chrome、Firefox,加起來(lái)就是10個(gè)小時(shí);
最笨的辦法就是另外拿臺(tái)機(jī)器,然后部署環(huán)境,把測(cè)試用例分開(kāi)去執(zhí)行然后合并結(jié)果即可。
而Selenium也想到了這點(diǎn),所以有了Selenium Grid的出現(xiàn),它就是解決分布式執(zhí)行測(cè)試的痛點(diǎn)。
工作原理
Selenium Grid實(shí)際它是基于Selenium RC的,而所謂的分布式結(jié)構(gòu)就是由一個(gè)hub節(jié)點(diǎn)和若干個(gè)node代理節(jié)點(diǎn)組成。
Hub用來(lái)管理各個(gè)代理節(jié)點(diǎn)的注冊(cè)信息和狀態(tài)信息,并且接受遠(yuǎn)程客戶端代碼的請(qǐng)求調(diào)用,然后把請(qǐng)求的命令轉(zhuǎn)發(fā)給代理節(jié)點(diǎn)來(lái)執(zhí)行。
下面結(jié)合環(huán)境部署來(lái)理解Hub與node節(jié)點(diǎn)的關(guān)系。
環(huán)境部署
1)下載selenium-server-standalone-2.53.1.jar
下載地址:http://selenium-release.storage.googleapis.com/index.html
2)啟動(dòng)hub
使用快捷鍵WIN+R打開(kāi)運(yùn)行對(duì)話框,輸入cmd確定,進(jìn)入命令窗口
進(jìn)入selenium-server-standalone-2.53.1.jar包的位置,如E:\selenium;
啟動(dòng)hub,命令如下:
java -jar selenium-server-standalone-2.53.1.jar -role hub -maxSession 10 -port 4444
參數(shù) | 解釋 |
---|---|
role hub | 啟動(dòng)運(yùn)行hub |
port | 設(shè)置端口號(hào),hub的默認(rèn)端口是4444,這里使用的是默認(rèn)的端口,當(dāng)然可以自己配置 |
maxSession | 最大會(huì)話請(qǐng)求,這個(gè)參數(shù)主要要用并發(fā)執(zhí)行測(cè)試用例,默認(rèn)是1,建議設(shè)置10及以上 |
瀏覽器打開(kāi)地址:http://localhost:4444/grid/console,出現(xiàn)如下圖表示hub啟動(dòng)成功。
啟動(dòng)hub后,就需要運(yùn)行節(jié)點(diǎn)啦,最少都要有一個(gè)node節(jié)點(diǎn),不然hub就成空頭司令了;而node節(jié)點(diǎn)可以與hub在同一臺(tái)機(jī)器上運(yùn)行,演示一個(gè)node節(jié)點(diǎn)與hub同機(jī),另一個(gè)node節(jié)點(diǎn)啟動(dòng)了一臺(tái)虛擬機(jī)。
名稱 | IP |
---|---|
hub機(jī) | 192.168.0.245 |
node1機(jī) | 192.168.0.245 |
node2機(jī) | 192.168.0.183 |
3)啟動(dòng)node節(jié)點(diǎn)1
node1節(jié)點(diǎn),配置firefox瀏覽器,運(yùn)行下面命令:
java -jar selenium-server-standalone-2.53.1.jar -role node -port 5555 -hub http://192.168.0.245:4444/grid/register -maxSession 5 -browser browserName=firefox,seleniumProtocol=WebDriver,maxInstances=5 ,platform=WINDOWS,version=45.0.2
沒(méi)有報(bào)錯(cuò)則再次刷新一下http://localhost:4444/grid/console的訪問(wèn)會(huì)發(fā)現(xiàn)node節(jié)點(diǎn)已經(jīng)顯示,表示啟動(dòng)成功;
參數(shù) | 解釋 |
---|---|
role node | 啟動(dòng)運(yùn)行node節(jié)點(diǎn) |
port 555 | 指定node節(jié)點(diǎn)端口 |
hub http://192.168.0.245:4444/grid/register | hub機(jī)地址 |
maxSession 5 | node節(jié)點(diǎn)最大會(huì)話請(qǐng)求 |
browser browserName=firefox,seleniumProtocol=WebDriver, maxInstances=5,platform=WINDOWS,version=45.0.2 | 這個(gè)就是設(shè)置瀏覽器的參數(shù)啦 |
browserName表示瀏覽器名字,maxInstances表示最大實(shí)例,可以理解為最多可運(yùn)行的瀏覽器數(shù),不能大于前面maxSession的值,否則可能會(huì)出錯(cuò);platform表示操作系統(tǒng);version表示瀏覽器版本。
4)啟動(dòng)node節(jié)點(diǎn)2
node2節(jié)點(diǎn),在目錄放了chromedriver.exe文件,這里要提示一下,這個(gè)chromedriver.exe文件前面說(shuō)過(guò)下載地址了,主要是版本需要與系統(tǒng)中安裝的chrome瀏覽器匹配;
運(yùn)行下面命令:
java -jar selenium-server-standalone-2.53.1.jar -role node -port 6666 -hub http://192.168.0.245:4444/grid/register -Dwebdriver.chrome.driver=chromedriver.exe -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5,platform=WINDOWS
沒(méi)有報(bào)錯(cuò)則再次刷新一下http://localhost:4444/grid/console的訪問(wèn)會(huì)發(fā)現(xiàn)node節(jié)點(diǎn)已經(jīng)顯示,表示啟動(dòng)成功;
如果使用的chromedriver.exe與selenium-server-standalone-2.53.1版本或者瀏覽器chrome版本不匹配都會(huì)報(bào)錯(cuò)提示,具體原因需要具體解決。
參數(shù) | 解釋 |
---|---|
Dwebdriver.chrome.driver=chromedriver.exe | 瀏覽器插件,如果是其他瀏覽器就寫對(duì)應(yīng)的名字 |
如firefox: -Dwebdriver.firefox.driver=geckodriver.exe
注意多了這個(gè)參數(shù)注意是chromedriver.exe需要指定,而對(duì)于Webdriver2是支持geckodriver所以不需要指定geckodriver,但前提是firefox瀏覽器版本不能大于46,所以看到node節(jié)點(diǎn)1使用的是45版本的瀏覽器。
使用
當(dāng)實(shí)例化Hub遠(yuǎn)程時(shí),會(huì)根據(jù)配置去匹配Hub上注冊(cè)的node代理節(jié)點(diǎn),匹配成功后轉(zhuǎn)發(fā)給代理節(jié)點(diǎn),這時(shí)候代理節(jié)點(diǎn)會(huì)生成sessionid啟動(dòng)瀏覽器,然后響應(yīng)給Hub說(shuō)一切準(zhǔn)備就緒,Hub也會(huì)把這個(gè)sessionid響應(yīng)給客戶端,接下來(lái)的客戶端的代碼發(fā)來(lái)的請(qǐng)求都會(huì)被Hub轉(zhuǎn)發(fā)給這個(gè)代理節(jié)點(diǎn)來(lái)執(zhí)行。這里實(shí)際上整個(gè)流程與Selenium1.0的原理是一樣的,只是多了Hub這一層。
DesiredCapabilities capability = new DesiredCapabilities();
capability.setBrowserName("chrome");
capability.setPlatform(Platform.WINDOWS);
try {
WebDriver driver = new RemoteWebDriver(new URL("http://192.168.0.245:4444/wd/hub"), capability);
driver.get("http://www.baidu.com");
driver.quit();
} catch (MalformedURLException e) {
e.printStackTrace();
}
根據(jù)上面代碼會(huì)發(fā)現(xiàn)node節(jié)點(diǎn)2執(zhí)行,如果把setBrowserName()方法里面的傳參改了firefox就會(huì)在node節(jié)點(diǎn)1執(zhí)行。表示Selenium Grid環(huán)境搭建完成。
另外客戶端還可以直接使用node節(jié)點(diǎn)運(yùn)行代碼,這樣的方式就與selenium1.0一模一樣啦,看下面代碼:
DesiredCapabilities capability = new DesiredCapabilities();
capability.setBrowserName("chrome");
capability.setPlatform(Platform.WINDOWS);
try {
WebDriver driver = new RemoteWebDriver(new URL("http://192.168.0.183:6666/wd/hub"), capability);
driver.get("http://www.baidu.com");
driver.quit();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
要注意實(shí)例化driver對(duì)象時(shí)填寫的服務(wù)地址是node節(jié)點(diǎn)的地址,這樣就會(huì)直接去節(jié)點(diǎn)運(yùn)行;還有一個(gè)注意的就是DesiredCapabilities配置,一定要設(shè)置該節(jié)點(diǎn)運(yùn)行參數(shù)正確的瀏覽器、瀏覽器版本、系統(tǒng),如果參數(shù)不對(duì)都會(huì)出現(xiàn)報(bào)錯(cuò)。
Selenium RC
Selenium RC(Remote Control)是Selenium家族的核心部分;
支持多種不同語(yǔ)言編寫的自動(dòng)化測(cè)試腳本,通過(guò)Selenium RC的服務(wù)器作為代理服務(wù)器去訪問(wèn)應(yīng)用,從而達(dá)到測(cè)試目的;
selenium RC 分為 Client Libraries 和 Selenium Server;
Client Libraries 庫(kù)主要主要用于編寫測(cè)試腳本,用來(lái)控制 selenium Server 的庫(kù)。
Selenium Server 負(fù)責(zé)控制瀏覽器行為;
總的來(lái)說(shuō),Selenium Server 主要包括 3 個(gè)部分:
Launcher、Http Proxy、Core。
其中 Selenium Core 是被 Selenium Server 嵌入到瀏覽器頁(yè)面中的。
其實(shí) Selenium Core
就是一堆 JS 函數(shù)的集合,就是通過(guò)這些 JS 函數(shù),我們才可以實(shí)現(xiàn)用程序?qū)g覽器進(jìn)行操作。
Launcher 用于啟動(dòng)瀏覽器,把 selnium Core 加載到瀏覽器頁(yè)面當(dāng)中,并把瀏覽器的代理設(shè)置為 Selenium Server 的Http Proxy。
Selenium 2.0
Selenium 2.0 是把 WebDriver 加入到了這個(gè)家族中;
簡(jiǎn)單用公式表示為:
selenium 2.0 = selenium 1.0 + WebDriver
在 selenium 2.0 中主推的是 WebDriver ,WebDriver 是 selenium RC 的替代品;
那么 selenium RC 與 webdriver 主要有什么區(qū)別呢?
Selenium RC 在瀏覽器中運(yùn)行 JavaScript 應(yīng)用,使用瀏覽器內(nèi)置的 JavaScript 翻譯器來(lái)翻譯和執(zhí)行
selenium 命令)。
WebDriver 通過(guò)原生瀏覽器支持或者瀏覽器擴(kuò)展直接控制瀏覽器。
WebDriver 針對(duì)各個(gè)瀏覽器而開(kāi)發(fā),取代了嵌入到被測(cè) Web 應(yīng)用中的 JavaScript。與瀏覽器的緊密集成支持創(chuàng)建更高級(jí)的測(cè)試,避免了JavaScript 安全模型導(dǎo)致的限制。
除了來(lái)自瀏覽器廠商的支持,WebDriver 還利用操作系統(tǒng)級(jí)的調(diào)用模擬用戶輸入。
WebDriver原理
WebDriver是按照Server-Client的設(shè)計(jì)模式設(shè)計(jì)的;
Server端就是Remote Server,可以是任意的瀏覽器;
當(dāng)我們的腳本啟動(dòng)瀏覽器后,該瀏覽器就是Remote Server,職責(zé)就是等待Client發(fā)送請(qǐng)求并做出響應(yīng);
Client端簡(jiǎn)單理解就是測(cè)試代碼;
腳本的行為是以http請(qǐng)求的方式發(fā)送給被測(cè)試的瀏覽器,瀏覽器接受請(qǐng)求,執(zhí)行相應(yīng)操作,并在response中返回執(zhí)行狀態(tài),返回等信息;
WebDriver的工作流程:
- WebDriver啟動(dòng)目標(biāo)瀏覽器,并綁定到指定端口;啟動(dòng)的瀏覽器實(shí)例將作為WebDriver的Remote Server;
- Client端通過(guò)CommandExcuter發(fā)送HTTPRequest給Remote Server 的偵聽(tīng)端口;
- Remote Server需要依賴原生的瀏覽器組件來(lái)轉(zhuǎn)化瀏覽器的native調(diào)用;
小結(jié)
斷斷續(xù)續(xù)的看了這本書很久很久,還是因?yàn)樽约簯校?/p>
看完這本書,對(duì)selenium的api至少留個(gè)印象,最重要的還是找控件的8種方式,一般如果Jb去面試,也會(huì)問(wèn)這個(gè)問(wèn)題,當(dāng)然也會(huì)有selenium的原理以及2.0跟1.0的區(qū)別,不過(guò)后面幾點(diǎn)只是做簡(jiǎn)單了解,不做任何評(píng)價(jià);
可別忘記了,selenium對(duì)于是可以獲取JS加載后的頁(yè)面內(nèi)容,如果想爬一個(gè)網(wǎng)頁(yè),而且內(nèi)容是JS加載的,如果不想研究JS,就用selenium吧,賊好用的玩意;
立個(gè)flag,之前太忙了,導(dǎo)致一個(gè)月沒(méi)更新博客,感覺(jué)人都廢了,因此立一個(gè),一周更新一篇的flag,看能堅(jiān)持多久吧~
最后,貼這個(gè)這本書電子版的鏈接:
https://pan.baidu.com/s/1b8T6Iq?errno=0&errmsg=Auth%20Login%20Sucess&&bduss=&ssnerror=0&traceid=
這里說(shuō)明下,電子版跟實(shí)體書還是有點(diǎn)不一樣,如果只是用來(lái)查api,看這篇文章或者看電子書就好了,主要的內(nèi)容沒(méi)什么變化;
謝謝大家~