python selenium 用法 和 Chrome headless

ldq_sd發表於2020-12-20

From: http://cuiqingcai.com/2599.html

Selenium教程:https://www.yiibai.com/selenium
selenium 官方參考文件:https://selenium-python.readthedocs.io/index.html
Selenium Documentation:https://www.seleniumhq.org/docs
Selenium 與 PhantomJS:http://www.cnblogs.com/miqi1992/p/8093958.html
自動化測試工具 Selenium:http://www.51testing.com/zhuanti/selenium.html
Selenium :http://www.ltesting.net/ceshi/open/kygncsgj/selenium
Selenium 中文網:http://www.selenium.org.cn
Selenium發展史:https://www.cnblogs.com/fnng/p/7426928.html
Free Selenium Tutorials:https://www.guru99.com/selenium-tutorial.html
Selenium自動化測試教程:http://www.51zxw.net/list.aspx?cid=615
知乎 - Selenium:https://www.zhihu.com/topic/19574589/top-answers
功能測試工具Selenium IDE:https://jingyan.baidu.com/article/ea24bc39bc48dada62b33139.html
Mechanize 和 Selenium:https://blog.csdn.net/u011974639/article/details/73148949
python爬蟲從入門到放棄(八)之 Selenium庫的使用:https://www.cnblogs.com/zhaof/p/6953241.html
python爬蟲 — 基於selenium用火狐模擬登陸爬搜尋關鍵詞的微博:https://blog.csdn.net/u010454729/article/details/51225388
selenium 模擬 fireFox瀏覽器,爬取網頁資訊:https://github.com/wu-yy/myhomeCrawler

前言
前面學習了 PhantomJS 的基本用法,歸根結底它是一個沒有介面的瀏覽器,而且執行的是 JavaScript 指令碼,然而這就能寫爬蟲了嗎?這又和Python有什麼關係?接下來我們介紹的這個工具,統統解決掉你的疑惑。

簡介
Selenium 是什麼?一句話,自動化測試工具。簡單的說就是一個可以用程式碼操所瀏覽器的工具。可以通過selenium進行搜尋關鍵字,點選按鈕等等操作。它支援各種瀏覽器,包括 Chrome,Safari,Firefox 等主流介面式瀏覽器,如果你在這些瀏覽器裡面安裝一個 Selenium 的外掛,那麼便可以方便地實現Web介面的測試。換句話說叫 Selenium 支援這些瀏覽器驅動。當selenium升級到3.0之後,對不同的瀏覽器驅動進行了規範。如果想使用selenium驅動不同的瀏覽器,必須單獨下載並設定不同的瀏覽器驅動(注:部分瀏覽器驅動地址需要科學上網)。話說回來,PhantomJS 不也是一個瀏覽器嗎,那麼 Selenium 支援不?答案是肯定的,這樣二者便可以實現無縫對接了。

    然後又有什麼好訊息呢?Selenium支援多種語言開發,比如 Java,C,Ruby等等,有 Python 嗎?那是必須的!哦這可真是天大的好訊息啊。

    嗯,所以呢?安裝一下 Python 的 Selenium 庫,再安裝好 PhantomJS,不就可以實現 Python+Selenium+PhantomJS 的無縫對接了嘛!PhantomJS 用來渲染解析JS,Selenium 用來驅動以及與 Python 的對接,Python 進行後期的處理,完美的三劍客!

    有人問,為什麼不直接用瀏覽器而用一個沒介面的 PhantomJS 呢?答案是:效率高!

    Selenium 2,又名 WebDriver,主要新功能是整合了 Selenium 1.0 以及 WebDriver(WebDriver 曾經是 Selenium 的競爭對手)。也就是說 Selenium 2 是 Selenium 和 WebDriver 兩個專案的合併,即 Selenium 2 相容 Selenium,它既支援 Selenium API 也支援 WebDriver API。selenium 是一套完整的web應用程式測試系統,包含了測試的錄製(selenium IDE),編寫及執行(Selenium Remote Control)和測試的並行處理(Selenium Grid)。Selenium的核心Selenium Core基於JsUnit,完全由JavaScript編寫,因此用於任何支援JavaScript的瀏覽器上。

selenium可以模擬真實瀏覽器,自動化測試工具,支援多種瀏覽器,爬蟲中主要用來解決JavaScript渲染問題。

更多詳情可以檢視 Webdriver 的簡介。

Webdriver

嗯,通過以上描述,我們應該對 Selenium 有了大概對認識,接下來就讓我們開始進入動態爬取的新世界吧。

本文參考內容來自

Selenium官網 SeleniumPython文件

用python寫爬蟲的時候,主要用的是selenium的Webdriver,我們可以通過下面的方式先看看Selenium.Webdriver支援哪些瀏覽器。首先匯入 webdriver 模組。然後使用help函式

from selenium import webdriver
help(webdriver)

安裝
首先安裝 Selenium

pip install selenium
或者下載原始碼

下載原始碼

然後解壓後執行下面的命令進行安裝

python setup.py install
安裝好了之後我們便開始探索抓取方法了。

快速開始

初步體驗

宣告瀏覽器物件

上面我們知道了selenium支援很多的瀏覽器,但是如果想要宣告並呼叫瀏覽器則需要:

from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
這裡只寫了兩個例子,當然了其他的支援的瀏覽器都可以通過這種方式呼叫

一個例子感受一下 Selenium,這裡用 Chrome 瀏覽器來測試,方便檢視效果,到真正爬取的時候換回 PhantomJS 即可。

from selenium import webdriver

browser = webdriver.Chrome()
browser.get(‘http://www.baidu.com/’)
執行這段程式碼,會自動開啟瀏覽器,然後訪問百度。

如果程式執行錯誤,瀏覽器沒有開啟,那麼應該是沒有裝 Chrome 瀏覽器或者 Chrome 驅動沒有配置在環境變數裡。下載驅動,然後將驅動檔案路徑配置在環境變數即可。

安裝三大瀏覽器驅動driver
1. chromedriver 下載地址:http://chromedriver.chromium.org
chromedriver 映象下載地址 :http://npm.taobao.org/mirrors/chromedriver
2. Firefox 的驅動 geckodriver 下載地址:https://github.com/mozilla/geckodriver/releases
3. IE 的驅動 IEdriver 下載地址:http://www.nuget.org/packages/Selenium.WebDriver.IEDriver

注意:下載解壓後,將chromedriver.exe , geckodriver.exe , Iedriver.exe發到Python的安裝目錄,例如 D:\python 。 然後再將Python的安裝目錄新增到系統環境變數的Path下面。

爬蟲 Selenium Chromium 與 Chromedriver對應版本( 注意是 chromium,不是 Chrome ):
淘寶映象地址在每個資料夾的 notes.txt 中存有 chromium 和 Chromedriver 的版本對應(一般3個chromium版本對應1個Chromedriver 版本)。

chromium chromedriver
v64-66 v2.37
v63-65 v2.36
v62-64 v2.35
v61-63 v2.34
v60-62 v2.33
然後開啟Python IDLE分別輸入以下程式碼來啟動不同的瀏覽器

啟動谷歌瀏覽器
from selenium import webdriver
browser = webdriver.Chrome()
browser.get(‘http://www.baidu.com/’)

啟動火狐瀏覽器
from selenium import webdriver
browser = webdriver.Firefox()
browser.get(‘http://www.baidu.com/’)

啟動IE瀏覽器
from selenium import webdriver
browser = webdriver.Ie()
browser.get(‘http://www.baidu.com/’)

模擬提交

下面的程式碼實現了“模擬百度提交搜尋”的功能。首先等頁面載入完成,然後輸入關鍵字到搜尋框文字,最後點選提交。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get(“http://www.baidu.com”)
print driver.title
elem = driver.find_element_by_name(“wd”) # 百度首頁搜尋框 name=“wd”
elem.send_keys(“MM”) # 輸入關鍵字
elem.send_keys(Keys.RETURN) # 模擬 點選 enter鍵,提交
print driver.page_source # 列印 js 渲染後的網頁

    其中 driver.get 方法會開啟請求的URL,WebDriver 會等待頁面完全載入完成之後才會返回,即程式會等待頁面的所有內容載入完成,JS渲染完畢之後才繼續往下執行。注意:如果這裡用到了特別多的 Ajax 的話,程式可能不知道是否已經完全載入完畢。

    WebDriver 提供了許多尋找網頁元素的方法,譬如 find_element_by_* 的方法。例如一個輸入框可以通過  find_element_by_name 方法尋找 name 屬性來確定。

    然後我們輸入來文字然後模擬點選了回車,就像我們敲擊鍵盤一樣。我們可以利用 Keys 這個類來模擬鍵盤輸入。

    注意:獲取網頁渲染後的原始碼。輸出 page_source 屬性即可。這樣,就可以做到網頁的動態爬取了。        

               如果想知道更過程式碼中driver物件有那些方法,可以通過 dir(driver) 檢視

測試用例

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class PythonOrgSearch(unittest.TestCase):

def setUp(self):
    self.driver = webdriver.Chrome()

def test_search_in_python_org(self):
    driver = self.driver
    driver.get("http://www.python.org")
    self.assertIn("Python", driver.title)
    elem = driver.find_element_by_name("q")
    elem.send_keys("pycon")
    elem.send_keys(Keys.RETURN)
    assert "No results found." not in driver.page_source

def tearDown(self):
    self.driver.close()

if name == “main”:
unittest.main()
執行程式,同樣的功能,我們將其封裝為測試標準類的形式。

    The test case class is inherited from unittest.TestCase. Inheriting from TestCase class is the way to tell unittest module that this is a test case. The setUp is part of initialization, this method will get called before every test function which you are going to write in this test case class. The test case method should always start with characters test. The tearDown method will get called after every test method. This is a place to do all cleanup actions. You can also call quit method instead of close. The quit will exit the entire browser, whereas close will close a tab, but if it is the only tab opened, by default most browser will exit entirely.

    測試用例是繼承了 unittest.TestCase 類,繼承這個類表明這是一個測試類。setUp方法是初始化的方法,這個方法會在每個測試類中自動呼叫。每一個測試方法命名都有規範,必須以 test 開頭,會自動執行。最後的 tearDown 方法會在每一個測試方法結束之後呼叫。這相當於最後的析構方法。在這個方法裡寫的是 close 方法,你還可以寫 quit 方法。不過 close 方法相當於關閉了這個 TAB 選項卡,然而 quit 是退出了整個瀏覽器。當你只開啟了一個 TAB 選項卡的時候,關閉的時候也會將整個瀏覽器關閉。

driver = webdriver.Chrome()
driver.maximize_window() # 最大化瀏覽器
driver.implicitly_wait(20) # 設定隱式時間等待
access_url = ‘https://www.baidu.com’
driver.get(access_url)

element_login = driver.find_element_by_id(‘login’) # 網頁的登入按鈕
element_login.click() # 點選登入按鈕
sleep(2) # 顯式等待 2s

links = driver.find_element_by_tag_name(‘a’) # 查詢所有的 a 標籤
link = links[3] # 提取 第四個 a 標籤
link.click() # 點選 提取 的 a 標籤

Selenium常見元素定位方法和操作的學習介紹:https://blog.csdn.net/eastmount/article/details/48108259

Selenium切換視窗控制程式碼及呼叫Chrome瀏覽器:https://blog.csdn.net/eastmount/article/details/53253278

頁面操作

訪問頁面

from selenium import webdriver

browser = webdriver.Chrome()

browser.get(“http://www.baidu.com”)
print(browser.page_source)
browser.close()
上述程式碼執行後,會自動開啟Chrome瀏覽器,並登陸百度列印百度首頁的原始碼,然後關閉瀏覽器

查詢元素

查詢單個元素

from selenium import webdriver

browser = webdriver.Chrome()

browser.get(“http://www.taobao.com”)
input_first = browser.find_element_by_id(“q”)
input_second = browser.find_element_by_css_selector("#q")
input_third = browser.find_element_by_xpath(’//*[@id=“q”]’)
print(input_first)
print(input_second)
print(input_third)
browser.close()
這裡通過三種不同的方式去獲取響應的元素,第一種是通過id的方式,第二個中是CSS選擇器,第三種是xpath選擇器,結果都是相同的。

查詢元素的方法

Selenium提供了8種定位方式:id、name、class name、tag name、link text、partial link text、xpath、css selector。

這8種定位方式在Python selenium中所對應的方法為:

查詢 單個元素 的 方法

find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()

查詢 多個元素 的 方法
find_elements_by_name
find_elements_by_id
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模組所以需要匯入

from selenium.webdriver.common.by import By

from selenium import webdriver

from selenium.webdriver.common.by import By

browser = webdriver.Chrome()

browser.get(“http://www.taobao.com”)
input_first = browser.find_element(By.ID,“q”)
print(input_first)
browser.close()
當然這種方法和上述的方式是通用的,browser.find_element(By.ID,“q”)這裡By.ID中的ID可以替換為其他幾個

多個元素查詢

其實多個元素和單個元素的區別,舉個例子:find_elements,單個元素是find_element,其他使用上沒什麼區別,通過其中的一個例子演示:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get(“http://www.taobao.com”)
lis = browser.find_elements_by_css_selector(’.service-bd li’)
print(lis)
browser.close()
這樣獲得就是一個列表

當然上面的方式也是可以通過匯入from selenium.webdriver.common.by import By 這種方式實現

lis = browser.find_elements(By.CSS_SELECTOR,’.service-bd li’)

頁面互動

玩轉python selenium滑鼠鍵盤操作(ActionChains):https://www.jb51.net/article/92682.htm
Selenium滑鼠與鍵盤事件常用操作方法示例:https://www.jb51.net/article/145502.htm

    僅僅抓取頁面沒有多大卵用,我們真正要做的是做到和頁面互動,比如點選,輸入等等。那麼前提就是要找到頁面中的元素。WebDriver提供了各種方法來尋找元素。例如下面有一個表單輸入框。
我們可以這樣獲取它

element = driver.find_element_by_id(“passwd-id”)
element = driver.find_element_by_name(“passwd”)
element = driver.find_elements_by_tag_name(“input”)
element = driver.find_element_by_xpath("//input[@id=‘passwd-id’]")
你還可以通過它的文字連結來獲取,但是要小心,文字必須完全匹配才可以,所以這並不是一個很好的匹配方式。

    而且你在用 xpath 的時候還需要注意的是,如果有多個元素匹配了 xpath,它只會返回第一個匹配的元素。如果沒有找到,那麼會丟擲 NoSuchElementException 的異常。

    獲取了元素之後,下一步當然就是向文字輸入內容了,可以利用下面的方法

element.send_keys(“some text”)
同樣你還可以利用 Keys 這個類來模擬點選某個按鍵。

element.send_keys(“and some”, Keys.ARROW_DOWN)
你可以對任何獲取到到元素使用 send_keys 方法,就像你在 GMail 裡面點選傳送鍵一樣。不過這樣會導致的結果就是輸入的文字不會自動清除。所以輸入的文字都會在原來的基礎上繼續輸入。你可以用下面的方法來清除輸入文字的內容。

element.clear()
這樣輸入的文字會被清除。

對於獲取的元素呼叫互動方法

from selenium import webdriver

import time

browser = webdriver.Chrome()
browser.get(“http://www.taobao.com”)
input_str = browser.find_element_by_id(‘q’)
input_str.send_keys(“ipad”)
time.sleep(1)
input_str.clear()
input_str.send_keys(“MakBook pro”)
button = browser.find_element_by_class_name(‘btn-search’)
button.click()
執行的結果可以看出程式會自動開啟Chrome瀏覽器並開啟淘寶輸入ipad,然後刪除,重新輸入MakBook pro,並點選搜尋

Selenium所有的api文件:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

互動動作

將動作附加到動作鏈中序列執行

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’)
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)
actions.perform()

actions.drag_and_drop_by_offset(source, 400, 0).perform()
更多操作參考:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

執行JavaScript
這是一個非常有用的方法,這裡就可以直接呼叫js方法來實現一些操作,下面的例子是通過登入知乎然後通過js翻到頁面底部,並彈框提示

from selenium import webdriver
browser = webdriver.Chrome()
browser.get(“http://www.zhihu.com/explore”)
browser.execute_script(‘window.scrollTo(0, document.body.scrollHeight)’)
browser.execute_script(‘alert(“To Bottom”)’)
獲取元素屬性

get_attribute(‘class’)

from selenium import webdriver

browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
logo = browser.find_element_by_id(‘zh-top-link-logo’)
print(logo)
print(logo.get_attribute(‘class’))
獲取文字值

text

from selenium import webdriver

browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
input = browser.find_element_by_class_name(‘zu-top-add-question’)
print(input.text)
獲取ID,位置,標籤名

id、location、tag_name、size

from selenium import webdriver

browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
input = browser.find_element_by_class_name(‘zu-top-add-question’)
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)

填充表單

我們已經知道了怎樣向文字框中輸入文字,但是其它的表單元素呢?例如下拉選項卡的的處理可以如下

element = driver.find_element_by_xpath("//select[@name=‘name’]")
all_options = element.find_elements_by_tag_name(“option”)
for option in all_options:
print(“Value is: %s” % option.get_attribute(“value”))
option.click()
首先獲取了第一個 select 元素,也就是下拉選項卡。然後輪流設定了 select 選項卡中的每一個 option 選項。你可以看到,這並不是一個非常有效的方法

        其實 WebDriver 中提供了一個叫 Select 的方法,可以幫助我們完成這些事情。

from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_name(‘name’))
select.select_by_index(index)
select.select_by_visible_text(“text”)
select.select_by_value(value)
如你所見,它可以根據索引來選擇,可以根據值來選擇,可以根據文字來選擇。是十分方便的。

全部取消選擇怎麼辦呢?很簡單

select = Select(driver.find_element_by_id(‘id’))
select.deselect_all()
這樣便可以取消所有的選擇。

另外我們還可以通過下面的方法獲取所有的已選選項。

select = Select(driver.find_element_by_xpath(“xpath”))
all_selected_options = select.all_selected_options
獲取所有可選選項是

options = select.options
如果你把表單都填好了,最後肯定要提交表單對吧。怎嗎提交呢?很簡單

driver.find_element_by_id(“submit”).click()
這樣就相當於模擬點選了 submit 按鈕,做到表單提交。

當然你也可以單獨提交某個元素

element.submit()
方法,WebDriver 會在表單中尋找它所在的表單,如果發現這個元素並沒有被表單所包圍,那麼程式會丟擲 NoSuchElementException 的異常。

元素拖拽

要完成元素的拖拽,首先你需要指定被拖動的元素和拖動目標元素,然後利用 ActionChains 類來實現

element = driver.find_element_by_name(“source”)
target = driver.find_element_by_name(“target”)

from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element, target).perform()
actions.drag_and_drop_by_offset(element, 400, 0).perform()
這樣就實現了元素從 source 拖動到 target 的操作

Frame

在很多網頁中都是有Frame標籤,所以我們爬取資料的時候就涉及到切入到frame中以及切出來的問題,通過下面的例子演示
這裡常用的是switch_to.from()和switch_to.parent_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’)
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()
logo = browser.find_element_by_class_name(‘logo’)
print(logo)
print(logo.text)

頁面切換 和 開啟新視窗

如果在一個頁面上點選一個連結之後,並不是在當前頁面上開啟,而是重新開啟一個新頁面;這種情況下如何跳轉到新的頁面上操作?首先,需要了解的是每個視窗都有控制程式碼的,可以理解為瀏覽器視窗的唯一識別符號,根據這個識別符號來確定新開啟的視窗。開啟新頁面後,selenium 的 focus 還是在 原來的頁面上,所以需要使用 switch_to.window 方法把 焦點(focus) 切換到新頁面上

如果是新開啟的 iframe 就使用 switch_to_frame(‘xxx’)
如果是新開啟的 tab 就使用 switch_to_window(’’)

一個瀏覽器肯定會有很多視窗,所以我們肯定要有方法來實現視窗的切換。切換視窗的方法如下

driver.switch_to_window(“windowName”)
switch_to_window 方法現在已經廢棄,滑鼠放在這個方法上提示 使用 switch_to.window 代替

另外你可以使用 window_handles 方法來獲取每個視窗的操作物件。例如

for handle in driver.window_handles:
driver.switch_to_window(handle)
另外切換 frame 的方法如下

driver.switch_to_frame(“frameName.0.child”)
這樣焦點會切換到一個 name 為 child 的 frame 上。

開啟新視窗主要使用 JavaScript 實現:

新標籤頁開啟這個url

js=“window.open(“url”)”
driver.execute_script(js)
time.sleep(2)
Python+Selenium練習篇之27-多視窗之間切換 :https://blog.csdn.net/u011541946/article/details/70132672
python selenium開啟新視窗,多視窗切換:https://blog.csdn.net/DongGeGe214/article/details/52169761
python/selenium/chrome開啟新視窗並實現視窗切換: https://blog.csdn.net/zwq912318834/article/details/79206953

selenium之 定位以及切換frame(iframe):https://blog.csdn.net/huilan_same/article/details/52200586

selenium iframe 切換

chrome瀏覽器開啟標籤頁的快捷鍵是ctrl+t,那把ctrl+t的按鍵事件傳入即可,很多種實現方式,以下只列出兩種:

1:
Actions actionOpenLinkInNewTab = new Actions(driver);
actionOpenLinkInNewTab.keyDown(Keys.CONTROL).sendKeys(“t”).keyUp(Keys.CONTROL).perform();

2:
driver.findElement(By.cssSelector(“body”)).sendKeys(Keys.CONTROL +“t”);

示例程式碼:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox() # 預設的火狐瀏覽器
for i in range(5):
# 這句程式碼相當於在瀏覽器視窗下按下ctrl+t開啟一個新的標籤頁
driver.find_element_by_tag_name(‘body’).send_keys(Keys.CONTROL + ‘t’)
time.sleep(10) # 等待所有視窗完全開啟,10秒夠用了, 如果不開啟得不到所有控制程式碼,只能得到部分。
handles = driver.window_handles
print(len(handles))
print(handles)
通常要確保頁面載入完成,可以使用 selenium.webdriver.support.ui.WebDriverWait

開啟新視窗示例程式碼:

from selenium import webdriver

開啟谷歌瀏覽器

browser = webdriver.Chrome()

開啟視窗

browser.get(“https://www.baidu.com/”)

開啟新視窗

newwindow_js = ‘window.open(“https://www.baidu.com”);’ # js
browser.execute_script(newwindow_js) # 執行 js 開啟新的頁面

切換到新的視窗

handles = browser.window_handles # 得到 所有頁面 控制程式碼
browser.switch_to_window(handles[-1]) # 切換焦點到 對應頁面

選項卡管理
通過執行js命令實現新開選項卡window.open()
不同的選項卡是存在列表裡browser.window_handles
通過browser.window_handles[0]就可以操作第一個選項卡

import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(‘https://www.baidu.com’)
browser.execute_script(‘window.open()’)
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])
browser.get(‘https://www.taobao.com’)
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get(‘https://python.org’)

彈窗處理

當你出發了某個事件之後,頁面出現了彈窗提示,那麼你怎樣來處理這個提示或者獲取提示資訊呢?

alert = driver.switch_to_alert()
通過上述方法可以獲取彈窗物件。

歷史記錄

那麼怎樣來操作頁面的前進和後退功能呢?(前進 和 後退 針對的是 瀏覽器瀏覽的網頁 的 歷史記錄)

driver.forward()
driver.back()

Cookies處理

get_cookies()
delete_all_cookes()
add_cookie()

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’: ‘zhaofan’})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
為頁面新增 Cookies,用法如下

Go to the correct domain

driver.get(“http://www.example.com”)

Now set the cookie. This one’s valid for the entire domain

cookie = {‘name’ : ‘foo’, ‘value’ : ‘bar’}
driver.add_cookie(cookie)
獲取頁面 Cookies,用法如下

Go to the correct domain

driver.get(“http://www.example.com”)

And now output all the available cookies for the current URL

driver.get_cookies()
以上便是 Cookies 的處理,同樣是非常簡單的。

元素選取

關於元素的選取,有如下的API。

單個元素選取

find_element_by_id
find_element_by_name
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
多個元素選取

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 類來確定哪種選擇方式

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH, ‘//button[text()=“Some text”]’)
driver.find_elements(By.XPATH, ‘//button’)
By 類的一些屬性如下

ID = “id”
XPATH = “xpath”
LINK_TEXT = “link text”
PARTIAL_LINK_TEXT = “partial link text”
NAME = “name”
TAG_NAME = “tag name”
CLASS_NAME = “class name”
CSS_SELECTOR = “css selector”
更詳細的元素選擇方法參見官方文件

元素選擇

頁面等待

Python selenium 三種等待方式詳解(必會):https://www.jb51.net/article/92672.htm

    這是非常重要的一部分,現在的網頁越來越多采用了 Ajax 技術,這樣程式便不能確定何時某個元素完全載入出來了。這會讓元素定位困難而且會提高產生 ElementNotVisibleException 的概率。所以 Selenium 提供了兩種等待方式,一種是隱式等待,一種是顯式等待。

    隱式等待 是 等待特定的時間。顯式等待 是 指定某一條件直到這個條件成立時繼續執行。當使用了隱式等待執行測試的時候,如果 WebDriver沒有在 DOM中找到元素,將繼續等待,超出設定時間後則丟擲找不到元素的異常, 換句話說,當查詢元素或元素並沒有立即出現的時候,隱式等待將等待一段時間再查詢 DOM,預設的時間是0

顯式等待

首先指定一個等待條件,並且再指定一個最長等待時間,然後在這個時間段內進行判斷是否滿足等待條件,如果成立就會立即返回,如果不成立,就會一直等待,直到等待你指定的最長等待時間,如果還是不滿足,就會丟擲異常,如果滿足了就會正常返回

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

driver = webdriver.Chrome()
driver.get(“http://somedomain/url_that_delays_loading”)
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, “myDynamicElement”))
)
finally:
driver.quit()
程式預設會 500ms 呼叫一次來檢視元素是否已經生成,如果本來元素就是存在的,那麼會立即返回。

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)
input = wait.until(EC.presence_of_element_located((By.ID, ‘q’)))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ‘.btn-search’)))
print(input, button)
上述的例子中的條件:EC.presence_of_element_located()是確認元素是否已經出現了
EC.element_to_be_clickable()是確認元素是否是可點選的

下面是一些內建的等待條件,你可以直接呼叫這些條件,而不用自己寫某些等待條件了。

常用的判斷條件:
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

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

from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID,‘someid’)))

隱式等待

隱式等待比較簡單,就是簡單地設定一個等待時間,單位為秒。到了一定的時間發現元素還沒有載入,則繼續等待我們指定的時間,如果超過了我們指定的時間還沒有載入就會丟擲異常,如果沒有需要等待的時候就已經載入完畢就會立即執行

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get(“http://somedomain/url_that_delays_loading”)
myDynamicElement = driver.find_element_by_id(“myDynamicElement”)
當然如果不設定,預設等待時間為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)

瀏覽器的前進和後退

back()
forward()

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()

異常處理
這裡的異常比較複雜,官網的參考地址:
http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions
這裡只進行簡單的演示,查詢一個不存在的元素

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()

程式框架

對於頁面測試和分析,官方提供了一個比較明晰的程式碼結構,可以參考。

頁面測試架構

API

到最後,肯定是放鬆最全最重要的API了,比較多,希望大家可以多加練習。

API

Selenium 用法詳解

來源:https://www.cnblogs.com/themost/p/6900852.html

selenium用法詳解

selenium主要是用來做自動化測試,支援多種瀏覽器,爬蟲中主要用來解決JavaScript渲染問題。模擬瀏覽器進行網頁載入,當requests,urllib無法正常獲取網頁內容的時候

一、宣告瀏覽器物件

     注意點一,Python檔名或者包名不要命名為selenium,會導致無法匯入

from selenium import webdriver
#webdriver可以認為是瀏覽器的驅動器,要驅動瀏覽器必須用到webdriver,支援多種瀏覽器,這裡以Chrome為例
browser = webdriver.Chrome()
二、訪問頁面並獲取網頁html

from selenium import webdriver
browser = webdriver.Chrome()
browser.get(‘https://www.taobao.com’)
print(browser.page_source)#browser.page_source是獲取網頁的全部html
browser.close()
三、查詢元素

# 單個元素 常用的查詢方法
    find_element_by_name
    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
# 多個元素,elements多個s
    input_first = browser.find_elements_by_id('q')

from selenium import webdriver
browser = webdriver.Chrome()
browser.get(‘https://www.taobao.com’)
input_first = browser.find_element_by_id(‘q’)
input_second = browser.find_element_by_css_selector(’#q’)
input_third = browser.find_element_by_xpath(’//*[@id=“q”]’)
print(input_first,input_second,input_third)
browser.close()

也可以使用通用的方法

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,‘q’)#第一個引數傳入名稱,第二個傳入具體的引數
print(input_first)
browser.close()
四、元素互動操作-搜尋框傳入關鍵詞進行自動搜尋

from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get(‘https://www.taobao.com’)
input = browser.find_element_by_id(‘q’) # 找到搜尋框
input.send_keys(‘iPhone’) # 傳送入關鍵詞
time.sleep(5)
input.clear() # 清空搜尋框
input.send_keys(‘MM’)
button = browser.find_element_by_class_name(‘btn-search’) # 找到搜尋按鈕
button.click()
更多操作: http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement#可以有屬性、截圖等等

五、互動動作,驅動瀏覽器進行動作,模擬拖拽動作,將動作附加到動作鏈中序列執行

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’)#切換到iframeResult框架
source = browser.find_element_by_css_selector(’#draggable’)#找到被拖拽物件
target = browser.find_element_by_css_selector(’#droppable’)#找到目標
actions = ActionChains(browser)#宣告actions物件
actions.drag_and_drop(source, target)
actions.perform()#執行動作
更多操作: http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.action_chains

六、執行JavaScript

有些動作可能沒有提供api,比如進度條下拉,這時,我們可以通過程式碼執行JavaScript

from selenium import webdriver
browser = webdriver.Chrome()
browser.get(‘https://www.zhihu.com/explore’)
browser.execute_script(‘window.scrollTo(0, document.body.scrollHeight)’)
browser.execute_script(‘alert(“To Bottom”)’)
七、獲取元素資訊

獲取屬性

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
logo = browser.find_element_by_id(‘zh-top-link-logo’)#獲取網站logo
print(logo)
print(logo.get_attribute(‘class’))
browser.close()

獲取文字值

from selenium import webdriver
browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
input = browser.find_element_by_class_name(‘zu-top-add-question’)
print(input.text)#input.text文字值
browser.close()

獲取Id,位置,標籤名,大小

from selenium import webdriver
browser = webdriver.Chrome()
url = ‘https://www.zhihu.com/explore’
browser.get(url)
input = browser.find_element_by_class_name(‘zu-top-add-question’)
print(input.id) # 獲取id
print(input.location) # 獲取位置
print(input.tag_name) # 獲取標籤名
print(input.size) # 獲取大小
browser.close()
八、Frame操作(即 一個html網頁中 巢狀 另一個html網頁)

frame相當於獨立的網頁,如果在父類網frame查詢子類的,則必須切換到子類的frame,子類如果查詢父類也需要先切換

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’)
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()
logo = browser.find_element_by_class_name(‘logo’)
print(logo)
print(logo.text)
九、等待

隱式等待:當使用了隱式等待執行測試的時候,如果 WebDriver沒有在 DOM中找到元素,將繼續等待,超出設定時間後則丟擲找不到元素的異常。換句話說,當查詢元素或元素並沒有立即出現的時候,隱式等待將等待一段時間再查詢 DOM,預設的時間是0

from selenium import webdriver

browser = webdriver.Chrome()
browser.implicitly_wait(10)#等待十秒載入不出來就會丟擲異常,10秒內載入出來正常返回
browser.get(‘https://www.zhihu.com/explore’)
input = browser.find_element_by_class_name(‘zu-top-add-question’)
print(input)
顯式等待:指定一個等待條件,和一個最長等待時間,程式會判斷在等待時間內條件是否滿足,如果滿足則返回,如果不滿足會繼續等待,超過時間就會丟擲異常

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)
input = wait.until(EC.presence_of_element_located((By.ID, ‘q’)))
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

詳細內容:http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.support.expected_conditions

十一、前進後退-實現瀏覽器的前進後退以瀏覽不同的網頁

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()
十二、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()
print(browser.get_cookies())
選項卡管理 增加瀏覽器視窗

import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get(‘https://www.baidu.com’)
browser.execute_script(‘window.open()’)
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])
browser.get(‘https://www.taobao.com’)
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get(‘http://www.fishc.com’)
十三、異常處理

from selenium import webdriver

browser = webdriver.Chrome()
browser.get(‘https://www.baidu.com’)
browser.find_element_by_id(‘hello’)

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()

詳細文件:http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions

Chrome headless

什麼是 Headless Chrome

Headless Chrome 是 Chrome 瀏覽器的無介面形態,可以在不開啟瀏覽器的前提下,使用所有 Chrome 支援的特性執行你的程式。相比於現代瀏覽器,Headless Chrome 更加方便測試 web 應用,獲得網站的截圖,做爬蟲抓取資訊等。相比於較早的 PhantomJS,SlimerJS 等,Headless Chrome 則更加貼近瀏覽器環境。

Headless Chrome作用

為了提高selenium指令碼的執行速度,我們可能會考慮使用PhantomJS這類的Headless 瀏覽器,但這些工具對JavaScript支援不好或者對web的支援不好,佔用資源多,跟真實瀏覽器存在一定的差異等等問題。Chrome 瀏覽器提供的Headless Chrome,簡單說我們也可以在不開啟chrome GUI的情況在Chrome下執行我們的Selenium指令碼,可提升指令碼的執行效率。

Headless Chrome 對Chrome版本要求

官方文件中介紹,mac 和linux 環境要求 chrome 版本是 59+,而 windows 版本的 chrome 要求是 60+

如果想進一步瞭解 headless,請移步官網:https://developers.google.cn/web/updates/2017/04/headless-chrome

使用

1. 首先需要下載 Chrome 瀏覽器(推薦使用 Chrome Canary版本) 。

2. 下載 selenium 驅動 Chrome 的驅動(chromedriver 映象 :http://npm.taobao.org/mirrors/chromedriver/)

     注意 版本問題,可以根據時間下載最新的 Chrome 驅動

3. 新增 Chrome 驅動的環境變數,或者直接把 Chrome 驅動放在 python 的安裝目錄下

    (因為 python 已經設定環境變數,所以可以直接放在 python安裝目錄下即可)

示例程式碼:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import selenium.webdriver.support.ui as ui

from selenium.webdriver.common.action_chains import ActionChains

chrome_options = webdriver.ChromeOptions()

chrome_options.add_argument(’–headless’)

browser = webdriver.Chrome(chrome_options=chrome_options)

開啟瀏覽器 設定等待載入時間 訪問URL

wait = ui.WebDriverWait(browser, 10)

def test_1():
browser.get(‘https://www.baidu.com/’)
print(‘開啟瀏覽器’)
print(browser.title)
browser.find_element_by_id(‘kw’).send_keys(‘測試’)
print(‘關閉’)
browser.quit()
print(‘測試完成’)

def test_2():
url = “https://www.newrank.cn/public/info/list.html?period=pgcweek&type=data”
browser.get(url)
print(browser.page_source) # 列印渲染後的頁面程式碼

def test_3():
url = ‘http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable’
browser.get(url)
browser.switch_to.frame(‘iframeResult’) # 切換到 巢狀的 html 頁面
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() # 返回到父 html 頁面
logo = browser.find_element_by_class_name(‘logo’)
print(logo)
print(logo.text)

if name == “main”:
test_1()
test_2()
test_3()
pass
執行結果截圖:

使用 示例 :

#!/usr/bin/python3

-- coding: utf-8 --

@Author :

@File : test.py

@Software : PyCharm

@description : XXX

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

from selenium.common.exceptions import

from selenium.webdriver.support.ui import WebDriverWait # available since
from selenium.webdriver.common.keys import Keys

def is_element_exist(driver, css):
find_elements = driver.find_elements_by_css_selector(css_selector=css)
if len(find_elements) == 0:
print(“元素未找到:%s” % css)
return False
elif len(find_elements) == 1:
return True
else:
print(“找到%s個元素:%s” % (len(find_elements), css))
return False

def test():

driver = webdriver.Chrome()
print("載入驅動完成..")

#  設定 隱式等待時間
driver.implicitly_wait(10)
driver.get("https://ww.baidu.com")  # 載入頁面
print("載入頁面完成..")
time.sleep(1)

# 方法一
try:
    assert "百度一下" in driver.title
    print('斷言 百度 標題 成功')
except Exception as e:
    print('斷言 百度 標題 失敗', format(e))
driver.maximize_window()  # 瀏覽器全屏顯示
print("最大化頁面視窗完成..")

elem = driver.find_element_by_name("wd")  # Find the query box
elem.send_keys("今日頭條" + Keys.RETURN)
# elem.submit()  提交表單方法
print("輸入搜尋關鍵字...")
time.sleep(1)  # Let the page load, will be added to the API

'''
    # driver.find_element_by_id("kw").clear()
    # driver.find_element_by_id("kw").send_keys(u"pyse自動化測試")
    # driver.type("//*[@id='kw']",u"pyse自動化測試")
    # driver.find_element_by_id("su").send_keys(Keys.ENTER)
    # driver.click("//*[@id='su']")
    # 也可定位登陸按鈕,通過enter(回車)代替click()
    # driver.find_element_by_id("su").send_keys(Keys.ENTER)
'''
# 方法一  採用包含判斷,建議第一種
try:
    driver.find_element_by_xpath("//*[@id='su']")
    print("校驗通過,百度一下按鈕存在")
except NoSuchElementException:
    assert 0, "校驗不通過"
# raw_input()  # 停止在當前游標處;

# 方法二
time.sleep(1)
# 驗證 今日頭條_百度搜尋 標題是否存在
if "今日頭條_百度搜尋" == driver.title:
    print('斷言 今日頭條 標題 成功')
else:
    print('斷言 今日頭條 標題 失敗')
print(driver.title)
# raw_input()  # 停止在當前游標處;
# 更多驗證方法
try:
    assert "今日頭條_百度搜尋" in driver.title
    print(u"標題驗證 Pass")
except AssertionError as e:
    print("找不到這個標題")

# 判斷頁面上有無 id 為 kw 的元素
if is_element_exist(driver, "#kw"):
    driver.find_element_by_id("kw").send_keys("")
# 判斷頁面有無標籤為 input元素
if is_element_exist(driver, "input"):
    driver.find_element_by_tag_name("input").send_keys("今日頭條 新聞")

try:
    # we have to wait for the page to refresh, the last thing that seems to be updated is the title
    WebDriverWait(driver, 10).until(lambda driver: driver.title.lower().startswith(""))
    # You should see "cheese! - Google Search"
    print(u"等待時間,列印當前頁面的標題 :" + driver.title)
finally:
    print(u"-----> 請按Enter 鍵進行下一步操作...")
    input('press any key continue')  # 停止在當前游標處;
    # driver.close()
    print(u"執行完成,即將關閉驅動...")
    driver.close()
    driver.quit()  # 與close方法相同

if name == ‘main’:
test()

登入百度賬號,並在 貼吧發帖:

import time
from selenium import webdriver
import selenium.webdriver.support.ui as ui
from selenium.webdriver import ActionChains

from selenium.webdriver.common.keys import Keys

from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

class LoginBD(object):
def init(self):
super(LoginBD, self).init()
self.browser = None
self.wait = None
self.action_chains = None
pass

def __del__(self):
    pass

def init_chrome_browser(self):
    """
        初始化 Chrome 瀏覽器
    :return:
    """
    chrome_options = webdriver.ChromeOptions()
    # 啟動引數
    # chrome_options.add_argument('--headless')
    chrome_options.add_argument('disable-infobars')
    chrome_options.add_argument('--disable-gpu')
    chrome_options.add_argument("window-size=1024,768")
    chrome_options.add_argument("--no-sandbox")

    # mobile_emulation = {'deviceName': 'iPhone 6'}
    # chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)

    # proxy_ip = 'http://127.0.0.1:8080'
    # chrome_options.add_argument("--proxy-server={0}".format(proxy_ip))

    #########################################################################
    # http_proxy = "http://127.0.0.1:8080"
    # # 代理引數
    # desired_capabilities = options.to_capabilities()
    # desired_capabilities['acceptSslCerts'] = True
    # desired_capabilities['acceptInsecureCerts'] = True
    # desired_capabilities['proxy'] = {
    #     "httpProxy": http_proxy,
    #     "ftpProxy": http_proxy,
    #     "sslProxy": http_proxy,
    #     "noProxy": None,
    #     "proxyType": "MANUAL",
    #     "class": "org.openqa.selenium.Proxy",
    #     "autodetect": False,
    # }
    #########################################################################

    # 啟動瀏覽器
    self.browser = webdriver.Chrome(options=chrome_options)
    self.browser.maximize_window()
    # self.browser = webdriver.Chrome(chrome_options=options, desired_capabilities=desired_capabilities)

    # 開啟瀏覽器 設定等待載入時間 訪問URL
    self.wait = WebDriverWait(self.browser, 10)
    # self.wait = ui.WebDriverWait(self.browser, 10)

    self.action_chains = ActionChains(self.browser)
    self.browser.delete_all_cookies()
    pass

def login_bd(self):
    bd_url = 'https://www.baidu.com'
    self.init_chrome_browser()
    self.browser.get(bd_url)
    time.sleep(2)

    login_href_xpath = '//div[@id="u1"]/a[@name="tj_login"]'
    self.wait.until(EC.presence_of_all_elements_located((By.XPATH, login_href_xpath)))
    login_href = self.browser.find_element_by_xpath(login_href_xpath)
    login_href.click()

    p_element_xpath = '//p[@class="tang-pass-footerBarULogin pass-link"]'
    self.wait.until(EC.presence_of_all_elements_located((By.XPATH, p_element_xpath)))
    p_element = self.browser.find_element_by_xpath(p_element_xpath)
    p_element.click()

    input_username = self.browser.find_element_by_id('TANGRAM__PSP_10__userName')
    username = input('input username :')
    input_username.send_keys(username)

    input_password = self.browser.find_element_by_id('TANGRAM__PSP_10__password')
    password = input('input password :')
    input_password.send_keys(password)

    btn = self.browser.find_element_by_id('TANGRAM__PSP_10__submit')
    btn.click()

    a_span_element_xpath = '//a[@id="s_username_top"]/span'
    login_result = self.wait.until(EC.text_to_be_present_in_element((By.XPATH, a_span_element_xpath), username))
    if login_result:
        print('login success')
    else:
        print('login fail')
    pass

def test(self):
    bar_url = 'https://tieba.baidu.com/f?ie=utf-8&kw={0}'.format('美女')
    self.browser.get(bar_url)
    js = "window.scrollTo(0, document.body.scrollHeight)"
    self.browser.execute_script(js)

    tie_tittle_xpath = '//input[@name="title"]'
    self.wait.until(EC.presence_of_all_elements_located((By.XPATH, tie_tittle_xpath)))
    tie_element = self.browser.find_element_by_xpath(tie_tittle_xpath)
    tittle_text = input('input tie tittle :')
    tie_element.send_keys(tittle_text)

    tie_content_xpath = '//div[@id="ueditor_replace"]'
    tie_content = self.browser.find_element_by_xpath(tie_content_xpath)
    tie_content_text = input('input tie content :')
    tie_content.send_keys(tie_content_text)

    btn_commit_xpath = '//button[@class="btn_default btn_middle j_submit poster_submit"]'
    btn_commit = self.browser.find_element_by_xpath(btn_commit_xpath)
    btn_commit.click()

    input('press any key to continue...')
    pass

def main():
temp = LoginBD()
temp.login_bd()
temp.test()

if name == “main”:
main()
pass
執行截圖:

手動登入淘寶後,用程式抓取商品資訊。

使用 selenium 登入淘寶時,可以被淘寶檢測 出來,所以手動登入。

import time
from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException

def test_selenium():
option = ChromeOptions()
option.add_experimental_option(‘excludeSwitches’, [‘enable-automation’])
browser = Chrome(options=option)
browser.maximize_window()
action_chains = ActionChains(browser)
wait = WebDriverWait(browser, 5)

username = '淘寶賬號'
pwd = '淘寶密碼'
url = 'https://login.taobao.com/member/login.jhtml'
browser.get(url)

# 滑鼠移動,模擬人的行為
action_chains.move_by_offset(random.randint(10, 60), random.randint(10, 60)).perform()
qr_code_element = browser.find_element_by_xpath('//i[@id="J_Quick2Static"]')
qr_code_element.click()

user_name_element = browser.find_element_by_xpath('//input[@name="TPL_username"]')
for ch in username:
    user_name_element.send_keys(ch)
    time.sleep(0.5)

password_element = browser.find_element_by_xpath('//input[@name="TPL_password"]')
for ch in pwd:
    password_element.send_keys(ch)
    time.sleep(0.5)

btn_submit = wait.until(EC.element_to_be_clickable((By.XPATH, '//div[@class="submit"]/button[@data-ing]')))
btn_submit.click()
# action_chains.click(btn_submit)
# while True:
#     try:
#         user_name = wait.until(EC.element_to_be_clickable((By.XPATH, '//a[@class="site-nav-login-info-nick "]')))
#         if user_name:
#             user_name_info = user_name.text
#             print(user_name_info)
#             break
#     except TimeoutException as te:
#         pass
#     # action_chains.click(btn_submit)
#     slide_bar = browser.find_element_by_xpath('//span[@class="nc_iconfont btn_slide"]')
#     if slide_bar:
#         print('滑動驗證碼')
#
#         # tracks = get_track(500)
#         action_chains.click_and_hold(slide_bar).perform()
#         for x in (50, 100, 200, 400):
#             action_chains.move_by_offset(xoffset=x, yoffset=random.randint(1, 10)).perform()
#         # for i in range(10):
#         #     x = i * 10 + random.randint(1, 50)
#         #     action_chains.move_by_offset(xoffset=x, yoffset=random.randint(1, 10)).perform()
#         #     time.sleep(0.2)
#         # action_chains.release().perform()
#         # action_chains.drag_and_drop_by_offset(slide_bar, 400, random.randint(1, 10)).perform()
#         time.sleep(random.randint(3, 5))
#
#     user_name_element = browser.find_element_by_xpath('//input[@name="TPL_username"]')
#     user_name_element.clear()
#     user_name_element.send_keys(username)
#
#     password_element = browser.find_element_by_xpath('//input[@name="TPL_password"]')
#     password_element.clear()
#     password_element.send_keys(pwd)
#     password_element.send_keys(Keys.ENTER)
#
#     btn_submit = wait.until(EC.element_to_be_clickable((By.XPATH, '//div[@class="submit"]/button[@data-ing]')))
#     btn_submit.click()
#     # action_chains.click(btn_submit)
input('登入淘寶後按任意鍵繼續......')
user_name = wait.until(EC.element_to_be_clickable((By.XPATH, '//a[@class="site-nav-login-info-nick "]')))
if user_name:
    user_name_info = user_name.text
    print(user_name_info)
# input('按任意鍵繼續......')
# browser.get('https://www.taobao.com')
browser.get('https://s.taobao.com/search?initiative_id=tbindexz_20170306&ie=utf8&spm=a21bo.2017.201856-taobao-item.2&sourceId=tb.index&search_type=item&ssid=s5-e&commend=all&imgfile=&q=鐳射燈&suggest=0_2&_input_charset=utf-8&wq=鐳射&suggest_query=鐳射&source=suggest')
# input('按任意鍵繼續......')
produce_info_xpath = '//div[contains(@class, "J_MouserOnverReq")]//div[@class="row row-2 title"]/a'
produce_info = browser.find_elements_by_xpath(produce_info_xpath)
for produce in produce_info:
    print(produce.text.replace(' ', ''))

if name == ‘main’:
test_selenium()

相關文章