1. 程式人生 > >[python爬蟲] Selenium切換視窗控制代碼及呼叫Chrome瀏覽器

[python爬蟲] Selenium切換視窗控制代碼及呼叫Chrome瀏覽器

        因為我的部落格是根據我每個階段自己做的事情而寫的,所以前言可能有點跑題,但它更有利於讓我回憶這個階段自己的所作所為。這篇文章主要介紹Selenium爬蟲獲取當前視窗控制代碼、切換視窗控制代碼以及呼叫Chrome瀏覽器幾個知識點,其中獲取當前控制代碼的方法是非常重要的一個知識點,只有真正遇到的時候才能體會到它的強大。
        最近課程比較多,寫部落格的內容也比較雜,包括網站搭建、HTML設計、計算機圖形學、Python資料探勘、Flash動畫等。同時,這周也有老師讓我幫忙寫幾個爬蟲,自己進一步理解了爬蟲的好處:一方面,人文課題如果運用計算機相關程式設計知識,確實能夠解決很多問題並提升效率;另一方面,我爬蟲主要使用Selenium、BeautifulSoup和Scrapy,其中Selenium能夠結合瀏覽器解決登入驗證碼、掃二維碼、效果預覽、自動測試等問題;BeautifulSoup的優勢是速度,兩種方法都是通過分析DOM樹結構實現的。
        希望這篇文章對你有所幫助,如果有錯誤或不足之處,還請海涵~更多爬蟲主題參考我的專欄:http://blog.csdn.net/column/details/eastmount-spider.html


一. 呼叫Chrome瀏覽器


        首先,假設通過Firefox()瀏覽器定向爬取CSDN首頁導航欄資訊,審查元素程式碼如下圖所示,在div class="menu"路徑的ul、li、a下,同時可以定位ul class="clearfix"。

        程式碼如下所示:

# coding=utf-8  
import os   
from selenium import webdriver

#PhantomJS無介面瀏覽器
##driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe")  

#開啟火狐瀏覽器
driver = webdriver.Firefox()
url = "http://www.csdn.net/"
driver.get(url)

#xpath路徑定位導航欄
elem_dh = driver.find_elements_by_xpath("//div[@class='menu']/ul/li/a")
for elem in elem_dh:
    print elem.text                    #獲取正文
    print elem.get_attribute('href')   #獲取屬性值
    
        然後轉換成chrome瀏覽器,只需要在"C:\Program Files (x86)\Google\Chrome\Application\"路徑下放置個chromedriver.exe驅動,再進行呼叫即可,程式碼如下所示:
# coding=utf-8  
import os   
from selenium import webdriver

#PhantomJS無介面瀏覽器
##driver = webdriver.PhantomJS(executable_path="G:\phantomjs-1.9.1-windows\phantomjs.exe")  

#開啟火狐瀏覽器
#driver = webdriver.Firefox()

#谷歌瀏覽器
chromedriver = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
driver = webdriver.Chrome(chromedriver)

#WebDriverException: Message: unknown error: session deleted because of page crash

url = "http://www.csdn.net/"
driver.get(url)

#xpath路徑定位導航欄
elem_dh = driver.find_elements_by_xpath("//div[@class='menu']/ul/li/a")
for elem in elem_dh:
    print elem.text                    #獲取正文
    print elem.get_attribute('href')   #獲取屬性值
    print '\n'
    
        執行結果如下圖所示:
>>> ================================ RESTART ================================
>>> 
極客頭條
http://geek.csdn.net/
知識庫
http://lib.csdn.net/
學院
http://edu.csdn.net/
論壇
http://bbs.csdn.net/
部落格
http://blog.csdn.net/
下載
http://download.csdn.net/
問答
http://ask.csdn.net/
商城
http://mall.csdn.net/
ITeye
http://www.iteye.com/
CODE
https://code.csdn.net/
活動
http://huiyi.csdn.net/
CTO
http://cto.csdn.net/
外包
http://www.csto.com/
程式設計師
http://special.csdncms.csdn.net/programmer-covers
APP
http://www.csdn.net/app
>>> 


二. 獲取當前控制代碼並切換視窗控制代碼

        在使用Selenium爬取知識過程,通常會遇到_blank彈出新窗體,或窗體是彈出的那種情況,而且有的需要登入,如:新浪微博、微信公眾號、京東等,使用webdriver.Firefox()重新開啟新窗體是無法載入已有資訊的。這時候就需要通過獲取當前控制代碼再進行視窗切換。
        這裡使用該方法實現獲取CSDN導航欄的每條導航的標題資訊,因為它是_blank彈出新窗體。需要注意每次視窗控制代碼移動都需要重新定位它們的主窗體。
        核心程式碼:

#獲取當前視窗控制代碼
now_handle = driver.current_window_handle 
print now_handle 

#獲取所有視窗控制代碼
all_handles = driver.window_handles 
for handle in all_handles:
    if handle!=now_handle:
        #輸出待選擇的視窗控制代碼
        print handle
        driver.switch_to_window(handle)
        time.sleep(1)

        #具體操作
        elem_bt = driver.find_element_by_xpath("...")
        driver.close() #關閉當前視窗

#輸出主視窗控制代碼
print now_handle
driver.switch_to_window(now_handle) #返回主視窗
        如下圖所示:<a href="xxxx" target="_blank">極客頭條</a>



例項程式碼如下所示,它會依次開啟每個導航欄,在爬取關閉。
# coding=utf-8  
import os
import time
from selenium import webdriver

#By:Eastmoun 2016-11-21 凌晨4:26

#開啟火狐瀏覽器
driver = webdriver.Firefox()
url = "http://www.csdn.net/"
driver.get(url)

#xpath路徑定位導航欄
elem_dh = driver.find_elements_by_xpath("//div[@class='menu']/ul/li/a")

#獲取當前視窗控制代碼
now_handle = driver.current_window_handle 
print now_handle


#迴圈獲取介面
for elem in elem_dh:
    print elem.text                    #獲取正文
    print elem.get_attribute('href')   #獲取屬性值
    #點選進入新的介面 _blank彈出
    elem.click()

    #獲取所有視窗控制代碼
    all_handles = driver.window_handles
    
    #彈出兩個介面,跳轉到不是主窗體介面
    for handle in all_handles:
        if handle!=now_handle:   
            #輸出待選擇的視窗控制代碼
            print handle
            driver.switch_to_window(handle)
            time.sleep(1)

            print u'彈出介面資訊'
            print driver.current_url
            print driver.title

            #獲取登入連線資訊
            elem_sub = driver.find_element_by_xpath("//ul[@class='btns']/li/a")
            print elem_sub.text
            print elem_sub.get_attribute('href')
            print ''

            #關閉當前視窗
            driver.close()
            

    #輸出主視窗控制代碼
    print now_handle
    driver.switch_to_window(now_handle) #返回主視窗 開始下一個跳轉
    

        輸出結果如下所示:

>>> ================================ RESTART ================================
>>> 
{833ee0ee-c408-432a-ab54-1222a22f580c}
極客頭條
http://geek.csdn.net/
{50e7dfc6-72d8-4577-99ca-47344a068528}
彈出介面資訊
http://geek.csdn.net/
最新最熱 - 極客頭條 - CSDN.NET
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
知識庫
http://lib.csdn.net/
{4501a3d1-8ab3-4a5e-984b-ace648494f94}
彈出介面資訊
http://lib.csdn.net/
知識庫 - 你身邊的技術百科全書 - CSDN
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
學院
http://edu.csdn.net/
{4525da42-fd77-4f04-b2f9-1687d75c1e19}
彈出介面資訊
http://edu.csdn.net/
CSDN學院 - CSDN.NET
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
論壇
http://bbs.csdn.net/
{c24493c1-c937-4a90-85a1-e11f7be870c4}
彈出介面資訊
http://bbs.csdn.net/home
CSDN論壇首頁 - CSDN.NET-CSDN論壇-CSDN.NET-中國最大的IT技術社群
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
部落格
http://blog.csdn.net/
{a4686eae-b437-4b97-97a2-160024359ade}
彈出介面資訊
http://blog.csdn.net/
部落格頻道 - CSDN.NET
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
下載
http://download.csdn.net/
{42cf058e-e093-4619-beae-4454aaba29a3}
彈出介面資訊
http://download.csdn.net/
下載頻道 - CSDN.NET
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
問答
http://ask.csdn.net/
{cb0633e2-45a5-406d-9aaa-79ea994e1f6a}
彈出介面資訊
http://ask.csdn.net/
程式設計技術問答-CSDN問答頻道
登入 
https://passport.csdn.net/account/login?ref=toolbar

{833ee0ee-c408-432a-ab54-1222a22f580c}
商城
http://mall.csdn.net/
{126f85af-d5e4-4d40-a89e-6fbb575a972b}
彈出介面資訊
http://mall.csdn.net/
CSDN商城
登入 
https://passport.csdn.net/account/login?ref=toolbar
        PS:這段程式碼主要是讓你熟悉獲取當前窗體及切換窗體,真正爬蟲用到的時候是非常方便的,而且必須要使用。



三. 一段程式碼 線上筆記

        下面這段程式碼是我的線上筆記,由於程式碼非常有用,所以我隱藏了些東西,但絕對好用,而且是結合上面的內容。同時,在登入過程中,我建議大家time.sleep()函式暫停,輸入驗證碼、掃描二維碼都是可行的。

# -*- coding: utf-8 -*-
# By: Eastmount 2016-11-21 凌晨4點半

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

#模擬登陸
chromedriver = "C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
driver = webdriver.Chrome(chromedriver)
now_handle = driver.current_window_handle #獲取當前視窗控制代碼

#driver = webdriver.Firefox()
#暫停10秒手動輸入網址
time.sleep(3)   
  
#使用者名稱 密碼
driver.get("xxxxxxxxxxx")
elem_user = driver.find_element_by_id("account")  
elem_user.send_keys("******")  
elem_pwd = driver.find_element_by_id("pwd")  
elem_pwd.send_keys("******")  
elem_pwd.send_keys(Keys.RETURN)
#暫定60秒掃二維碼 跳轉到定向頁面
time.sleep(60)  

#登入使用者管理 獲取相關標籤
print driver.current_url
elem_user = driver.find_elements_by_xpath("//td[@class='table_cell user']/div/a[1]")  
now_handle = driver.current_window_handle #獲取當前視窗控制代碼
print now_handle   #輸出當前獲取的視窗控制代碼

#單擊操作
for elem in elem_user:
    print '########################################'
    print elem.text
    #點選進入檢視詳細使用者
    elem.click()

    """
    NoSuchElementException: Message: no such element
    因為總是獲取當前控制代碼 故找不到相關的介面,需要視窗控制代碼轉換
    """
    all_handles = driver.window_handles #獲取所有視窗控制代碼
    for handle in all_handles:
        if handle!=now_handle:
            #輸出待選擇的視窗控制代碼
            print handle
            driver.switch_to_window(handle)
            time.sleep(1)
            
            #點選"圖文訊息"
            elem_tw = driver.find_element_by_xpath("//li[@class='tab_nav tab_appmsg width5']/a")
            #elem_tw = driver.find_element_by_xpath("//div[@class='tab_navs_wrp']/ul/li/a")

            print elem_tw.text
            print elem_tw.get_attribute("href")
            elem_tw.click()
            time.sleep(1)

            #點選 '從素材庫中選擇'按鈕
            elem_sc = driver.find_element_by_xpath("//span[@class='create_access']/a")
            print elem_sc.text
            print elem_sc.get_attribute("href")
            elem_sc.click()
            time.sleep(1)

            #點選素材 '11-14 星期二中獎名單' 注意是id
            #elem_dj = driver.find_element_by_xpath("//div[@class='edit_mask appmsg_mask']")
            #elem_dj = driver.find_element_by_xpath("//div[@id='appmsg503811334']/div/div[2]")
            elem_dj = driver.find_element_by_xpath("//div[@id='appmsg503811334']")
            print elem_dj.text
            print elem_dj.get_attribute("href")
            elem_dj.click()
            time.sleep(1)
            
            #SyntaxError: Failed to execute 'evaluate' on 'Document': The string
            #'//div[@class='appmsg503811334']/div/' is not a valid XPath expression.

            #WebDriverException: Message: unknown error: Element is not clickable
            #at point (473, 361). Other element would receive the click:
            #<div class="appmsg_content">...</div>

            #獲取'確定按鈕'
            elem_bt = driver.find_element_by_xpath("//div[@class='dialog_ft']/span[1]/button")
            print elem_bt.text
            print elem_bt.get_attribute("class")
            elem_bt.click()
            time.sleep(1)

            #點選 '傳送'
            elem_fs = driver.find_element_by_xpath("//span[@id='js_submit']/button")
            print elem_fs.text
            print elem_fs.get_attribute("class")
            elem_fs.click()
            time.sleep(1)

            #關閉當前視窗
            driver.close() 
            

    #輸出主視窗控制代碼
    print now_handle
    driver.switch_to_window(now_handle) #返回主視窗
    #break

    print '\n\n'
    

#暫停換頁
#登入使用者管理 獲取相關標籤
print '********************************************'
print '********************************************'
print u'換頁操作1'
#elem_next = driver.find_elements_by_xpath("//a[@class='btn page_next']")
#elem_next.click()

time.sleep(10)
elem_user = driver.find_elements_by_xpath("//td[@class='table_cell user']/div/a[1]")  
now_handle = driver.current_window_handle #獲取當前視窗控制代碼
print now_handle   #輸出當前獲取的視窗控制代碼

#單擊操作
for elem in elem_user:
    print '########################################'
    print elem.text
    #點選進入檢視詳細使用者
    elem.click()

    all_handles = driver.window_handles #獲取所有視窗控制代碼
    for handle in all_handles:
        if handle!=now_handle:
            #輸出待選擇的視窗控制代碼
            print handle
            driver.switch_to_window(handle)
            time.sleep(1)
            
            #點選"圖文訊息"
            elem_tw = driver.find_element_by_xpath("//li[@class='tab_nav tab_appmsg width5']/a")
            print elem_tw.text
            print elem_tw.get_attribute("href")
            elem_tw.click()
            time.sleep(1)

            #點選 '從素材庫中選擇'按鈕
            elem_sc = driver.find_element_by_xpath("//span[@class='create_access']/a")
            print elem_sc.text
            print elem_sc.get_attribute("href")
            elem_sc.click()
            time.sleep(1)

            #點選素材 注意是id
            elem_dj = driver.find_element_by_xpath("//div[@id='appmsg503811334']")
            print elem_dj.text
            print elem_dj.get_attribute("href")
            elem_dj.click()
            time.sleep(1)
            
            #獲取'確定按鈕'
            elem_bt = driver.find_element_by_xpath("//div[@class='dialog_ft']/span[1]/button")
            print elem_bt.text
            print elem_bt.get_attribute("class")
            elem_bt.click()
            time.sleep(1)

            #點選 '傳送'
            elem_fs = driver.find_element_by_xpath("//span[@id='js_submit']/button")
            print elem_fs.text
            print elem_fs.get_attribute("class")
            elem_fs.click()
            time.sleep(1)

            driver.close() #關閉當前視窗
            

    #輸出主視窗控制代碼
    print now_handle
    driver.switch_to_window(now_handle) #返回主視窗
    #break
    print '\n\n'
    

        最後希望這篇文章對你有所幫助,因為第三部分程式碼涉密,消除了些東西,但原理和方法更重要,希望你也能靈活應用。同時明天評估專家就來了,雖然幹活到2點,但還是想寫一篇文章,記錄最近兩天研究的東西,很重要的一個知識點。繼續享受部落格和教學吧,同時期待我最近欣賞的某個人吧!楊老師加油~
       (By:Eastmount 2016-11-21 凌晨4點半http://blog.csdn.net/eastmount/)


相關推薦

[python爬蟲] Selenium切換視窗控制呼叫Chrome瀏覽器

        因為我的部落格是根據我每個階段自己做的事情而寫的,所以前言可能有點跑題,但它更有利於讓我回憶這個階段自己的所作所為。這篇文章主要介紹Selenium爬蟲獲取當前視窗控制代碼、切換視窗控制代碼以及呼叫Chrome瀏覽器幾個知識點,其中獲取當前控制代碼的方法是非常

python爬蟲Selenium切換視窗控制呼叫Chrome瀏覽器

  一. 呼叫Chrome瀏覽器 首先,假設通過Firefox()瀏覽器定向爬取CSDN首頁導航欄資訊,審查元素程式碼如下圖所示,在div class="menu"路徑的ul、li、a下,同時可以定位ul class="clearfix"。  

python win32api win32gui win32con 視窗控制 傳送訊息 常用方法 鍵盤輸入

推薦微軟的Spy++來檢視視窗類名等資訊。 import win32gui import win32con import win32api # 從頂層視窗向下搜尋主視窗,無法搜尋子視窗 # FindWindow(lpClassName=None, lpW

web自動化-視窗控制位置變化

在進行web自動化時,很容易會遇到多視窗進行切換測試,下面就對多視窗的一些控制代碼和切換及視窗控制代碼順序簡單總結一下 1 from selenium import webdriver 2 driver = webdriver.Firefox() 3 driver.get("https://www.b

C#獲得windows工作列視窗控制一些操作(放大、縮小、關閉、隱藏……)

需呼叫API函式 需在開頭引入名稱空間using System.Runtime.InteropServices; 1、通過視窗名字查詢 [DllImport("user32.dll", EntryPoint = "FindWindow")] public static extern In

Selenium:多視窗切換(獲取視窗控制handle)

我們在操作網頁的時候,點選有些頁面的連結,會重新開啟一個視窗,我們要在新頁面上操作,就得切換視窗 比如在百度首頁的登入框點選註冊,會重新開啟一個註冊的新頁面,要在新頁面註冊,就得先切進新頁面 那我們怎麼在這兩個視窗之間進行切換呢?每個瀏覽器視窗都有一個唯一的屬性控制代碼(handle)來表示,我們就可

python selenium 獲得當前視窗控制/獲得當前視窗

1. 獲得當前視窗控制代碼:    driver.current_window_handles2. 獲得當前所有一開啟的視窗控制代碼:   driver.window_handles3.切換視窗:    driver.switch_to.window()        #引數

【轉】python win32api win32gui win32con 簡單操作教程(視窗控制 傳送訊息 常用方法 鍵盤輸入)

import win32gui import win32con import win32api # 從頂層視窗向下搜尋主視窗,無法搜尋子視窗 # FindWindow(lpClassName=None, lpWindowName=None)  視窗類名 視窗標題名 hand

WPF 視窗控制獲取和設定

WPF 視窗控制代碼設定和獲取 1、控制代碼類 WHwnd.cs public class WHwnd { /// <summary> /// 主窗體控制代碼 /// </summar

MFC 獲取當前視窗控制,或者父子視窗控制

父子視窗 在子視窗中,需要用到父視窗的控制代碼: AfxGetMainWnd()->m_hWnd 注:在父視窗中,也可以這麼用來呼叫自己視窗的控制代碼 在子視窗中,需要用到自己視窗的控制代碼 ChildDlg *pChildDlg ; pChildDlg->m_h

按鍵精靈 -獲取視窗控制

MessageBox "視窗右下角座標:" get_window_pos //得到當前最前面的視窗控制代碼-就是把需要的視窗啟用在最前面 Hwnd = Plugin.Window.Foreground() //得到滑鼠指向的視窗控制代碼Hwnd = Plugin.Window.Mo

獲取ArcMap視窗控制,通過WinAPI獲取工作空間中點選要素的系統桌面座標

這裡用了個“桌面座標”,是希望區分一下ArcGis的“螢幕座標”(與之對應的還有一個“地理座標”)。 什麼是“螢幕座標”呢?使用ITool介面的OnMouseDown方法獲取的“x,y”值即是,其原點值在“工作空間”窗體左上角。 什麼是我所稱謂的“工作空間”呢?它是資料編輯區域,用Spy++檢視一下其窗體

C#獲取當前活動視窗控制

c# 獲取當前活動視窗控制代碼,獲取視窗大小及位置 2018年04月26日 13:48:21 漂泊_人生 閱讀數:1889   需呼

GetWindow、GetTopWindow和GetNextWindow(視窗控制獲取!!!)

GetWindow //uCmd 可選值:   GW_HWNDFIRST = 0; {同級別第一個}   GW_HWNDLAST  = 1; {同級別最後一個}   GW_HWNDNEXT  = 2; {同級別下一個}   GW_HWNDPREV  = 3;

VC 各種情況下的視窗控制的獲取

AfxGetMainWnd AfxGetMainWnd獲取自身視窗控制代碼 HWND hWnd = AfxGetMainWnd()->m_hWnd; GetTopWindow 函式功能:該函式檢查與特定父視窗相聯的子視窗z序(Z序:垂直螢幕的方向,即疊放

C# 影象處理: 獲取當前活動視窗控制,獲取視窗大小位置

C# 影象處理: 獲取當前活動視窗控制代碼,獲取視窗大小及位置 需呼叫API函式 需在開頭引入名稱空間 using System.Runtime.InteropServices; 獲取當前視窗控制代碼:GetForegroundWindow() [DllImport("us

C# 在建立視窗控制之前,不能在控制元件上呼叫 Invoke 或 BeginInvoke

http://www.cnblogs.com/fish124423/archive/2012/10/16/2726543.html   在Invoke(....)之前加上1 this.components==null 2 this.IsDisposed 3 IsHandleCreated 來re

根據程序ID 獲取視窗控制

 using namespace System;using namespace System::Diagnostics;using namespace System::ComponentModel; Process *m_pCurProcess = Process::GetProcessById(

幾個ARX取CAD視窗控制的函式

標頭檔案:rxmfcapi.h CWinApp* acedGetAcadWinApp() 返回指向AutoCAD應用程式類例項的指標 當用COM方式操作CAD的選單工具欄時會用到。 CDocument* acedGetAcadDoc() 返回指向AutoCAD檔案

Win32gui 無效視窗控制

在用模擬瀏覽器上傳檔案時,用win32gui查詢視窗,並輸入檔案路徑,點選確定上傳。然而在設定開啟視窗焦點時,報錯了: xx是 無效視窗控制代碼 經過spy++排查,確定視窗類和名稱都無誤,後來經過多次測試,發現問題是:視窗開啟太慢,在視窗開啟之前就開始查詢視窗了,當然就找不到