抓取微博數據:使用HtmlUnitDriver實現模擬登陸


前言

作為小白的我而言,對于各種網絡數據抓取也不少了,但是在抓取過程之中坑點也不少的,這里就分享一下對于需要登陸的網頁的處理,我們整體思路是這樣的,我們通過對該網站的登錄之后拿到該網站的Cookie,然后拿著獲取到的Cookie再去我們想要爬取的地址進行數據爬取.


Selenium簡介

Selenium是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。

而我用到的HtmlUnitDriverSelenium眾多工具中一個基于HtmlUnit的無界面實現,即使用HtmlUnit時并不會打開真實的瀏覽器,而是在內存中執行代碼,因此運行速度很快,但是對JavaScript的支持不夠好,當頁面上有復雜的JavaScript元素時,經常捕捉不到。

當我們需要Selenium的時候,我們可以添加Maven依賴.如下所示.

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.4.0</version>
</dependency>


HtmlUnitDriver的鼠標和鍵盤事件

我們平常在普通一個網站登錄的時候都會使用到我們的鍵盤和鼠標來進行一系列的用戶交互操作.那么我們在HtmlUnitDriver該如何實現鍵盤的輸入和鼠標的點擊呢?在其實現的接口類WebDeriver中有一個專門的類來負責實現這些測試場景,那就是 Actions 類,在使用該類的過程中會配合使用到 Keys 枚舉以及 Mouse、 Keyboard、CompositeAction 等類。下面我就分別簡單介紹鼠標事件和鍵盤事件的實現.


鼠標事件

  • 鼠標左鍵點擊
Actions action = new Actions(driver);
action.click();// 鼠標左鍵在當前停留的位置做單擊操作 
action.click(driver.findElement(By.name(element)))// 鼠標左鍵點擊指定的元素
  • 鼠標右鍵點擊
Actions action = new Actions(driver); 
action.contextClick();// 鼠標右鍵在當前停留的位置做單擊操作 
action.contextClick(driver.findElement(By.name(element)))// 鼠標右鍵點擊指定的元素
  • 鼠標雙擊操作
Actions action = new Actions(driver); 
action.doubleClick();// 鼠標在當前停留的位置做雙擊操作 
action.doubleClick(driver.findElement(By.name(element)))// 鼠標雙擊指定的元素
  • 鼠標拖拽動作
Actions action = new Actions(driver); 
// 鼠標拖拽動作,將 source 元素拖放到 target 元素的位置。
action.dragAndDrop(source,target);
// 鼠標拖拽動作,將 source 元素拖放到 (xOffset, yOffset) 位置,其中 xOffset 為橫坐標,yOffset 為縱坐標。
action.dragAndDrop(source,xOffset,yOffset);
  • 釋放鼠標
Actions action = new Actions(driver); 
action.release();// 釋放鼠標


鍵盤事件

對于鍵盤的模擬操作,Actions 類中有提供 keyUp(theKey)、keyDown(theKey)、sendKeys(keysToSend) 等方法來實現。鍵盤的操作有普通鍵盤和修飾鍵盤(Modifier Keys, 下面的章節將講到修飾鍵的概念)兩種 :

  • 普通鍵盤模擬 sendKeys(keysToSend)
Actions action = new Actions(driver); 
action.sendKeys(Keys.TAB);// 模擬按下并釋放 TAB 鍵
action.sendKeys(Keys.SPACE);// 模擬按下并釋放空格鍵
/***
針對某個元素發出某個鍵盤的按鍵操作,或者是輸入操作,
比如在 input 框中輸入某個字符也可以使用這個方法。這個方法也可以拆分成:
action.click(element).sendKeys(keysToSend)。
*/
action.sendKeys(element,keysToSend);
  • 對于修飾鍵(Modifier keys),一般都是跟普通鍵組合使用的。比如 Ctrl+a、Alt+F4、 Shift+Ctrl+F 等等。
Actions action = new Actions(driver); 
action.keyDown(Keys.CONTROL);// 按下 Ctrl 鍵
action.keyDown(Keys.SHIFT);// 按下 Shift 鍵
action.keyDown(Key.ALT);// 按下 Alt 鍵
action.keyUp(Keys.CONTROL);// 釋放 Ctrl 鍵
action.keyUp(Keys.SHIFT);// 釋放 Shift 鍵
action.keyUp(Keys.ALT);// 釋放 Alt 鍵

示例:通過 Alt+F4 來關閉當前的活動窗口,可以通過下面語句來實現.

action.keyDown(Keys.ALT).keyDown(Keys.F4).keyUp(Keys.ALT).perform();`


使用 HtmlUnitDriver 模擬登錄微博賬號(基于Selenium:3.4.0實現)

上面我們對HtmlUnitDriver的使用有了初步的了解,下面我們就要模擬登錄微博賬號.由于數據抓取是通過www.weibo.cn而不是www.weibo.com.所以我們要通過https://passport.weibo.cn/signin/login這個登錄地址來登錄.我們首先要打開這個網站地址,分析這個網站有什么是我們需要.網站上的元素很少.我們需要賬號輸入框密碼輸入框登錄按鈕的點擊事件.

然后我們通過控制臺來獲取這個三個元素.如下所示.(因為我先前登陸過,所以Cookie里面會有我的信息)

好了,準備工作已經做完了,那么接下來我們就需要搞我們的代碼了.代碼比較簡單,這里就不過多解釋了.

            //初始化一個HtmlUnitDriver對象
            HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_52);
            driver.setJavascriptEnabled(true);//允許JS操作
            driver.get("https://passport.weibo.cn/signin/login");
            driver.executeScript("document.getElementById('loginWrapper').style.display = 'block'");//隱藏新浪微博登錄的驗證碼
            //找到賬號輸入框,輸入用戶賬號
            WebElement mobile = driver.findElementByCssSelector("input#loginName");
            mobile.sendKeys(username);
            //找到密碼輸入框,輸入用戶密碼
            WebElement pass = driver.findElementByCssSelector("input#loginPassword");
            pass.sendKeys(password);
            //輸入完成之后,點擊登錄按鈕
            WebElement submit = driver.findElementByCssSelector("a#loginAction");
            submit.click();
            driver.close();//關閉瀏覽器

那么我們該如何拿到Cookie字符串呢?這里登錄完成之后,HtmlUnitDriver就存儲了Cookie信息,我們直接拿出來就行,代碼如下所示.

            Set<Cookie> cookieSet = driver.manage().getCookies();
            StringBuilder sb = new StringBuilder();
            for (Cookie cookie : cookieSet) {
                sb.append(cookie.getName() + "=" + cookie.getValue() + ";");
            }
            String result = sb.toString();//拼接好的Cookie信息

整體代碼如下所示.

     public static String getSinaCookie(String username, String password) throws Exception {
            //初始化一個HtmlUnitDriver對象
            HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.FIREFOX_52);
            driver.setJavascriptEnabled(true);//允許JS操作
            driver.get("https://passport.weibo.cn/signin/login");
            driver.executeScript("document.getElementById('loginWrapper').style.display = 'block'");//隱藏新浪微博登錄的驗證碼
            //找到賬號輸入框,輸入用戶賬號
            WebElement mobile = driver.findElementByCssSelector("input#loginName");
            mobile.sendKeys(username);
            //找到密碼輸入框,輸入用戶密碼
            WebElement pass = driver.findElementByCssSelector("input#loginPassword");
            pass.sendKeys(password);
            //輸入完成之后,點擊登錄按鈕
            WebElement submit = driver.findElementByCssSelector("a#loginAction");
            submit.click();
            String result = concatCookie(driver);
            System.out.println("Get Cookie: " + result);
            driver.close();//關閉瀏覽器

            if (result.contains("SUB")) {
                return result;
            } else {
                throw new Exception("weibo login failed");
            }
        }

        public static String concatCookie(HtmlUnitDriver driver) {
            Set<Cookie> cookieSet = driver.manage().getCookies();
            StringBuilder sb = new StringBuilder();
            for (Cookie cookie : cookieSet) {
                sb.append(cookie.getName() + "=" + cookie.getValue() + ";");
            }
            String result = sb.toString();
            return result;
        }

通過控制臺的打印,我們就能獲得我們所需要的Cookie字符串了.如下所示.


總結

這篇博客寫到這就到了尾聲了,有一點要注意,那就是使用HtmlUnitDriver時候,可能會鏈接失敗,現在未找到原因,希望有知道的大佬能提點下.文章很多點都可能模糊不清,所以如果有錯誤,歡迎指導批評,非常感謝各位大佬.

本文參考文章:
Selenium WebDriver 中鼠標和鍵盤事件分析及擴展
Java開源爬蟲框架WebCollector教程——爬取新浪微博



最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容