好久之前就想把李敖大師的全部微博爬取下來.一直沒空,前天看見羣裏有人推薦selenium和phantomjs 就學了selenium作了個demo.大家想爬別人的只要把李敖大師的地址換成你要的就好了.phantomjs我還沒學,不過我猜他就是去掉ui功能的瀏覽器.這樣可讓爬蟲更快.若是專業作爬蟲的能夠看看.我作這個是玩的.php
學習地址: 慕課網 selenium 教程
項目地址: spiderSina
環境:
ide:Netbeans
java包:很是多(在lib文件夾中)
瀏覽器驅動:ie,火狐,谷歌隨便選(在res文件夾內)css
- 打開新浪微博首頁並登陸
- 跳轉到李敖大師主頁
- 觸發ajax將一個頁面所有顯示出來
- 對每個微博進行判斷解析 只獲取大師本人的微博
若是有展開全文就點擊點擊一下.而後將微博內容插入數據庫- 判斷是否有下一頁,若是有就到下一頁而後進入第四步
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();
//判斷是否有下一頁那個按鈕 沒的就向下拉 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"
我能有勇氣發這個圖給他.
git
開個玩笑,我是爲了學習.github