selenium 自動化爬蟲 5分鐘爬取新浪李敖大師1751條微博.

selenium 是一個瀏覽器自動化測試框架.能夠模擬用戶的全部操做.

好久之前就想把李敖大師的全部微博爬取下來.一直沒空,前天看見羣裏有人推薦selenium和phantomjs 就學了selenium作了個demo.大家想爬別人的只要把李敖大師的地址換成你要的就好了.phantomjs我還沒學,不過我猜他就是去掉ui功能的瀏覽器.這樣可讓爬蟲更快.若是專業作爬蟲的能夠看看.我作這個是玩的.php

數據庫結構

clipboard.png

學習地址: 慕課網 selenium 教程
項目地址: spiderSina
環境:
ide:Netbeans
java包:很是多(在lib文件夾中)
瀏覽器驅動:ie,火狐,谷歌隨便選(在res文件夾內)css

爬蟲思路:

  1. 打開新浪微博首頁並登陸
  2. 跳轉到李敖大師主頁
  3. 觸發ajax將一個頁面所有顯示出來
  4. 對每個微博進行判斷解析 只獲取大師本人的微博
    若是有展開全文就點擊點擊一下.而後將微博內容插入數據庫
  5. 判斷是否有下一頁,若是有就到下一頁而後進入第四步

打開微博並登陸

這裏的css選擇器就當jQuery用

baseUrl = "https://weibo.com";
//打開微博主頁面
driver.get(baseUrl);
//設置窗口最大化
driver.manage().window().maximize();
 //輸入用戶名
 driver.findElement(By.cssSelector("#loginname")).clear();
 driver.findElement(By.cssSelector("#loginname")).sendKeys(sinaUsername);
 //輸出密碼
 driver.findElement(By.cssSelector("#pl_login_form .info_list.password input")).clear();
 driver.findElement(By.cssSelector("#pl_login_form .info_list.password input")).sendKeys(password);
 //點擊登陸
 driver.findElement(By.cssSelector("#pl_login_form.login_box div.login_innerwrap div.W_login_form .login_btn")).click();

觸發ajax將一個頁面所有顯示出來

//判斷是否有下一頁那個按鈕 沒的就向下拉
 for (int i = 0, scrollY = 5000; i < 20; i++, scrollY += 5000) {
      //判斷是否有下一頁那個div 若是有就表示到底了
      if (this.isElementPresent(By.cssSelector(".page.next.S_txt1.S_line1"))) {
           break;
          }
           String setscroll = "window.scrollTo(0," + scrollY + ")";
       //執行js代碼 將頁面向下拉
       jse.executeScript(setscroll);
  }

對每個微博進行判斷解析 只獲取大師本人的微博

//獲取李大師全部的微博
List<WebElement> divs = driver.findElements(By.cssSelector("#Pl_Official_MyProfileFeed__23 div>.WB_cardwrap.WB_feed_type"));
//對每一條微博進行判斷是否爲正常微博(非別人的點贊) 並進行展開全文 而後插入數據庫
divs.forEach((WebElement ele) -> {
String isZan = ele.findElement(By.cssSelector("div:first-of-type")).getAttribute("class");
if (!("WB_cardtitle_b S_line2".equals(isZan))) {
    String weiboContent;
    //若是要運行的快一點就把數值改小,數值越小等待的時間越少
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.MILLISECONDS);
    //判斷是否微博中是否有超連接而且超連接內容爲展開全文 若是是就點擊
    if (this.isElementPresent(By.cssSelector(".WB_feed_detail>.WB_detail>.WB_text.W_f14 a"), ele)
            && "展開全文".equals(ele.findElement(By.cssSelector(".WB_feed_detail>.WB_detail>.WB_text.W_f14 a")).getText().trim())) {
        //這裏獲取全文應該是300ms以內 設置過久會浪費時間
        driver.manage().timeouts().implicitlyWait(300, TimeUnit.MILLISECONDS);
        //點擊 展開全文按鈕
        ele.findElement(By.cssSelector(".WB_feed_detail>.WB_detail>.WB_text.W_f14 a")).click();
        //獲取微博內容
        weiboContent = ele.findElement(By.cssSelector(".WB_feed_detail>.WB_detail>div:last-of-type")).getText();
    } else {
    //若是沒有展開全文 獲取微博 這兩種內容不在一個div裏
        weiboContent = ele.findElement(By.cssSelector(".WB_feed_detail>.WB_detail>.WB_text.W_f14")).getText();
    }
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    //獲取大師發微博的時間
    String writeTime = ele.findElement(By.cssSelector(".WB_feed_detail>.WB_detail>.WB_from>a:first-of-type")).getText();
    //這裏我想把微博中偶爾出現的零寬字符去掉可是失敗了,多是版本問題.不想搞
    //weiboContent = weiboContent.replaceAll("\\u200b", "");
    //將微博插入數據庫
    this.insertToMysql(weiboContent, writeTime);
    //這個是獲取到的微博內容調試時候能夠打開看看在哪裏出來問題
    // System.out.println(weiboContent + "\n");
}

});java

判斷是否有下一頁

//查看按鈕的文本是否爲"下一頁" 若是是那就還有下一頁
 WebElement nextPage = driver.findElement(By.cssSelector("#Pl_Official_MyProfileFeed__23 .WB_cardwrap.S_bg2>div>a:last-of-type"));
 String strNext = nextPage.getText();
 if ("下一頁".equals(strNext)) {
      nextPage.click();
      this.getPage();
   }

沒有了... 其實selenium普通玩家應該很快就能上手.高端玩法沒試過.主要就是看一下他重要的幾個api
若是不知道api 就百度還有寫demo猜api用法.
原本想用php寫的,可是php寫得話可能比較麻煩.
我本人對李敖大師十分敬仰,一直就想把他的語錄記下來.待他百年以後,有人在網上吹牛李敖說"xxx"
我能有勇氣發這個圖給他.
clipboard.pnggit

開個玩笑,我是爲了學習.github

相關文章
相關標籤/搜索