首頁  >  文章  >  後端開發  >  Selenium+PhantomJs解析渲染Js的基本操作

Selenium+PhantomJs解析渲染Js的基本操作

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼轉載
2019-06-05 17:00:154238瀏覽

有人說Selenium庫和PhantomJ,說他們結合使用是萬能的利器。那麼,他們真的那麼厲害嗎,我們就一起來看看Selenium庫的用法吧。透過這篇文章讓我們來看看Selenium庫結合PhantomJs,Chrome等一些瀏覽器的操作吧。

Selenium+PhantomJs解析渲染Js的基本操作

什麼是Selenium

Selenium是一個自動化測試工具,支援包括Chrome,Firefox,Safari,PhantomJs等一些瀏覽器。如果用於爬蟲中,我們主要用來解決一些JavaScript渲染的問題。

我們在使用Requests函式庫去請求一些網頁的時候,例如 163music,我們獲得的回應資料呢,並不全是我們在瀏覽器中看到的資訊。他可能是透過js渲染出來的。那麼,我們如果使用Selenium庫,就不會再去關心如何解決這種問題了。

因為我們的瀏覽器,例如PhantomJs,他就是一個無介面的瀏覽器,他用來渲染解析js,而Selenium庫就負責給瀏覽器發送一些命令,模擬一些比如下拉,拖拽,翻頁,輸入表單等動作。這樣他們兩個結合,對於那些 JS 的渲染問題是不是完美解決了。

注意

雖然Selenium庫加上PhantomJs很好用,但他畢竟是驅動一個瀏覽器,然後取得資料。所以在我們使用中,會發現他並沒有我們使用一些解析函式庫速度快。這其實就是他的弊端,所以我還是建議大家,不到我找不到解決方法的時候,不去使用他們。

安裝準備

pip直接安裝Selenium庫:

pip install selenium

瀏覽器驅動程式的安裝:

Chrome瀏覽器驅動 

PhantomJs瀏覽器驅動程式

我們需要把安裝好的瀏覽器驅動程式配置到我們的環境變數。對於Windows用戶,配置環境變數比較麻煩。我們需要找到下載好的驅動位置,然後複製他的檔案位置,請參閱他貼上到環境變數。

設定完成,命令列輸入:

phantomjs -v

   

查看是否成功。

使用範例

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()
 
try:
    browser.get('http://www.yukunweb.com')
    input = browser.find_element_by_id('s')
    input.send_keys('Python')
    input.send_keys(Keys.ENTER)
    wait = WebDriverWait(browser, 10)
    wait.until(EC.presence_of_element_located((By.ID, 'main')))
    print(browser.current_url)
    print(browser.page_source)
finally:
    browser.close()

   

如果我們執行上面的程式碼,我們會看到本機開啟了一個Chrome瀏覽器,然後在瀏覽器網址列輸入了我的部落格網址,然後他會自動的在搜尋欄輸入'Python',並且點擊了回車搜尋。並且將結果頁的url和原始碼列印出來。

我們的範例都是使用Chrome瀏覽器來操作,因為PhantomJs是無介面的,不方便查看到效果。如果大家執行錯誤的話,一般情況是瀏覽器並沒有打開,那麼應該是大家沒有安裝好Chrome瀏覽器,或是沒有將驅動設定環境變數。

那麼這幾行程式碼究竟是什麼意思呢,我們究竟賦予了什麼指令呢?

宣告瀏覽器物件

from selenium import webdriver
 
browser = webdriver.Chrome()
# 声明其他浏览器
browser = webdriver.PhantomJs()
browser = webdriver.Firefox()

   

這就相當於我們呼叫了Selenium函式庫的webdriver方法,實例化一個Chrome瀏覽器給我們調用。

造訪頁面

from selenium import webdriver
 
browser = webdriver.Chrome()
browser.get('http://www.yukunweb.com')

   

我們將要存取的url傳給get方法。調用瀏覽器訪問url。

找出元素

input = browser.find_element_by_id('s')

   

這句程式碼呼叫find_element_by_id方法,顧名思義,就是找出id為's'的標籤,那麼如果是操作class為's'的話,就是find_element_by_class('s')。

當然,我們也可以使用 CSS選擇器和xpath選擇器來尋找元素:

input = browser.find_element_by_css_selector("#s")
print(input)
input = browser.find_element_by_xpath('//*[@id="s"]')
print(input)

透過列印結果,可以看到不管使用什麼選擇器,尋找結果都是一樣的。以下是一些查找api:

find_element_by_namefind_element_by_xpathfind_element_by_link_textfind_element_by_partial_link_textfind_element_by_tag_namefind_element_by_class_namefind_element_by_css_selector

尋找多個元素

如果我們尋找的元素是網頁中的li標籤,是很多的元素。那麼我們的查找方式和單一元素是相同的,只是對於查找的api我們需要在element後面加個複數形式 s。即:

find_elements_by_namefind_elements_by_xpathfind_elements_by_link_textfind_elements_by_partial_link_textfind_elements_by_tag_namefind_elements_by_class_namefind_elements_by_css_selector

元素交互操作

即是對於我們所取得的元素下達指令,呼叫互動的方法。

browser.get('http://www.yukunweb.com')
input = browser.find_element_by_id('s')
input.send_keys('Python')
input.send_keys(Keys.ENTER)

   

這段程式碼中,我們先查找到了id為's'的元素,然後傳給他'Python'值,然後呼叫互動方法,敲了回車。

當然,在大多是情況下,我們不能直接使用敲擊回車的方法,因為我們不確定是不是敲了回車,表單就提交了。我們需要使用查找器查找到提交按鈕元素,然後模擬點擊:

button = browser.find_element_by_class_name('xxxx')
button.click()
# 清除表单信息
button.clear()

   

那麼,我們可以看到在模擬登陸時候,直接讓我們手動的輸入帳號,密碼,如果有驗證碼的話直接給一個input方法,我們手動輸入驗證碼傳給表單,是不是很簡單的就模擬登入了。

互動動作

#

元素交互动作与上面的操作是不同的。上面的操作需要获得一个特定的元素。然后对这个特定的元素调用一些指令,才可以完成交互。而这个交互是将这些动作附加到动作链中串行执行。

我们以拖拽元素为例(我们需要导入ACtionChains方法):

from selenium import webdriver
from selenium.webdriver import ActionChains
 
browser = webdriver.Chrome()
 
browser.get(url)
source = browser.find_element_by_name("source")
target = browser.find_element_by_name("target")
actions = ActionChains(browser)
actions.drag_and_drop(source, target).perform()

   

这里的sourcs是我们要拖拽的元素,我们使用查找器找到他,target就是我们要拖拽到的位置元素。然后调用ActionChains方法,实现拖拽操作。

执行JavaScript

有些动作呢,Selenium库并没有为我们提供特定的api,比如说将浏览器进度条下拉,这个实现起来是很难的。那么我们就可以通过让Selenium执行JS来实现进度条的下拉,这个得需要一些js的知识,不过还是很简单的。

from selenium import webdriver
 
browser = webdriver.Chrome()
browser.get('http://www.yukunweb.com')
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("到达底部")')

   

这就相当于我们将一些JS命令传给Selenium的execute_script这个api,我们运行就可以看到浏览器下拉到底部,然后弹出会话框。

获取元素文本值

如果我们查找得到一个元素,我们要怎样获得元素的一些属性和文本信息呢?

from selenium import webdriver
 
browser = webdriver.Chrome()
 
browser.get('http://www.yukunweb.com')
name = browser.find_element_by_css_selector('#kratos-logo > a')
print(name.text)
print(name.get_attribute('href'))

   

运行结果可以看到,他打印出了‘意外’和他的url。

Frame框架

有些网页在我们直接使用Selenium驱动浏览器打印源码的时候,并没有如期获得想要的数据,那在我们查看网页源码的时候,可以看到网页的iframe标签包裹的一个一个的框架。那么这就需要我们请求对应框架,拿到源码了。

我们以网易云音乐的歌手栏为例。

from selenium import webdriver
 
browser = webdriver.Chrome()
browser.get('https://music.163.com/#/discover/artist/signed/')
 
print(browser.page_source)

   

可以查看结果,并没有我们想要的信息。

from selenium import webdriver
 
browser = webdriver.Chrome()
browser.get('https://music.163.com/#/discover/artist/signed/')
browser.switch_to.frame('contentFrame')
 
print(browser.page_source)

   

这次打印,我们就可以看到我们需要的信息了,是不是很简单。

显示等待

在文章开始的时候,我们运行的那段代码中有一段代码是不是还没有说。那就是我们命令浏览器等待的操作。

等待有两种方式,一种是隐士等待,一种是显示等待。当使用了隐士等待执行时,如果浏览器没有找到指定元素,将继续等待,如果超出设定时间就会抛出找不到元素的异常。而大多数情况我们建议使用显示等待。

显示等待是你指定一个等待的条件,还指定一个最长等待时间。那么程序会在最长等待时间内,判断条件是否成立,如果成立,立即返回。如果不成立,他会一直等待,直到最长等待时间结束,如果条件仍然不满足,就返回异常。

wait = WebDriverWait(browser, 10)
wait.until(EC.presence_of_element_located((By.ID, 'main')))

   

这里的By.ID方法实际上就是一个查找的万能方法,而我们直接查找或者使用CSS、xpath查找足够满足,我也不过多介绍,想要了解可以查看官方文档。

这里是知道查找到id为‘main’就返回。

显示等待的一些条件还有:

title_is 标题是某内容

title_contains 标题包含某内容

presence_of_element_located 元素加载出,传入定位元组,如(By.ID, ‘p’)

visibility_of_element_located 元素可见,传入定位元组

visibility_of_element_located 元素可见,传入定位元组

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


窗口选择

如果我们在表单输入关键词,提交表单后浏览器新打开了一个窗口,那么我们要怎么去操作新的窗口呢?索性Selenium为我们提供了对应的api.

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
 
browser = webdriver.Chrome()
browser.get('http://www.23us.cc/')
input = browser.find_element_by_id('bdcs-search-form-input')
input.send_keys('斗破苍穹')
input.send_keys(Keys.ENTER)
browser.switch_to_window(browser.window_handles[1])
print(browser.current_url)
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
print(browser.current_url)

   

通过打印结果,不难看出先打印了搜索结果窗口url,然后打印了索引页url。要注意窗口的索引是从 0 开始的哦,这个大家都明白。

异常处理

异常处理和普通的异常处理一样,没有什么要说的,大家自己查看官方异常 api.地址

最后

好了,透過這篇文章希望大家可以基本上了解Selenium庫結合瀏覽器驅動的一些使用方法。我們例子裡使用的是Chrome,但大家在實際的程式碼裡最好是使用PhantomJs,因為他是無介面的,運作起來相對好一點。

文章開始說過一般情況下不建議大家使用Selenium,因為他很慢。但是即使是慢,也很爽啊,是不是。

以上是Selenium+PhantomJs解析渲染Js的基本操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除