本文已獨家受權給腳本之家(jb51net)、新華先後端開發公衆號發佈css
[TOC]html
作技術咱們最重要的是【作】。可是今天咱們來說片【玩】。這句話可能不太好理解。直接開門見山吧。對於外行朋友一談到IT他們對咱們的定位就是黑客。其實咱們和黑客一點關係都沒有。今天的技術是【爬蟲】 。 爲何說爬蟲和黑客有點關聯呢。由於爬蟲能夠將人爲行爲進行機器化。就是實現編寫好代碼讓機器代替咱們人類重複的操做意見事情。java
對於爬蟲了咱們這裏不作基礎的講解了。在平時的開發中咱們偶爾會用到爬蟲。好比說咱們系統須要添加天氣狀況。可是咱們有沒有氣象站給我提供數據。這時候咱們最顯示的作法就是調用網絡上免費的天氣接口API 。 這個時候咱們Java就會經過爬蟲模擬除一個瀏覽器請求去訪問這個天氣接口的API。 而後在經過爬蟲獲取這個API返回的數據。從而進行解析。jquery
對於這些免費的API咱們經過爬蟲(HttpClient)就能夠輕鬆的訪問了。可是想優酷、愛奇藝、掘金這些等級網站他們會有發爬蟲策略。最多見的就是利用爬蟲進行刷票的行爲。他們針對這些刷票作了一些措施。具體措施就不說了(不知道)。更有甚者他們對他們的頁面進行加密。讓你沒法分析他們的html.或者加大你分析的成本。以上就是以前咱們用爬蟲爬取數據遇到的一些問題。下面簡單梳理下咱們遇到爬蟲的問題web
今天咱們帶了一個好東西。它轉變了咱們傳統爬蟲的思路。傳統的爬蟲咱們會去按照開發者的思路去處理邏輯。可是selenium他不須要關注開發者邏輯。只須要咱們關注本身的需求。什麼意思呢?就是說selenium他就是在模擬用戶的行爲,你告訴selenium我須要點擊頁面的某個按鈕了,他就去點擊了。你告訴他我須要在某個輸入框中輸入內容了。他就去給你輸入內容。有了它,你不再用管輸入內容以後提交登陸真正請求了。這樣的好處是下降了爬蟲的學習成本。對於不懂技術的人也能夠很快上手了。chrome
點我下載內核npm
這個是幹嗎的呢?這裏先透露下selenium使用的是瀏覽器的內核操做頁面的。因此這裏須要如今內核。下載內核前提是電腦上有瀏覽器。筆者這裏電腦上瀏覽器是Google 1.73版本 。 因此下載內核就得是對應的版本,不然會報錯的。在notes.txt文件中會列出每一個對應的瀏覽器的版本的。ubuntu
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
複製代碼
想一想咱們平時瀏覽網頁的時候是須要先打開瀏覽器,這裏也是同樣。後端
【咱們須要打開瀏覽器】(個人內核放在/root/Downloads/chromedriver)瀏覽器
ChromeOptions chromeOptions = new ChromeOptions();
File chromeDriverPath = new File("/root/Downloads/chromedriver");
System.setProperty("webdriver.chrome.driver", chromeDriverPath.getAbsolutePath());
chromeOptions.addArguments("--headless");
chromeOptions.addArguments("--disable-gpu");
//ubuntu瀏覽器中須要添加
chromeOptions.addArguments("--no-sandbox");
webDriver = new ChromeDriver(chromeOptions);
複製代碼
headless : 表示隱式打開瀏覽器,由於作爬蟲就不須要顯示界面了。 no-sandbox : 這個是由於個人Ubuntu安裝的google須要這個參數,因此這裏也須要加上 disable-gpu : 同上
【輸入連接地址】(juejin.im/) webDriver.get("https://juejin.im/");
,這樣內核就獲取到了咱們在瀏覽器中看到的效果。那麼咱們這麼獲取咱們須要的頁面數據呢。 findElement
經過這個方法咱們能夠獲取到咱們想要的任何數據。換句話說經過這個方法這個頁面在你面前盡收眼底。包括他的衍生頁面 有的讀者有疑問了。我該怎麼讓他獲取我想要的東西呢。
上面這些方法就是咱們定位元素的方法。什麼意思呢,咱們前段朋友們常常經過jquery操做html的dom對象,在By對象裏cssSelector就是和jquery一樣的操做方法。好多都是和jquery相似的。這裏不懂技術的人會說這裏技術點很難。其實不難。 咱們不懂代碼的怎麼辦呢。咱們在瀏覽器瀏覽頁面 。 好比下圖中我想獲取個人博客名稱(框架原理那點事--不就反射嘛。)
咱們鼠標放在【框架原理那點事--不就反射嘛】上右鍵選擇【檢查】。會自動跳轉到對應的代碼的
後面三種對應By裏面的制定方法。這裏就不說了。
WebElement webElement = webDriver.findElement(By.cssSelector("xxxxxx"));
JavascriptExecutor js = (JavascriptExecutor) webDriver;
js.executeScript("arguments[0].click();",digg);
複製代碼
上面的webElement是頁面中一個按鈕。咱們能夠直接webElement.click()讓按鈕點擊或者webElement.submit()提交Form表單。可是有的時候會不起做用。這個時候用上面的代碼能夠進行點擊。
File source = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
try {
Files.copy(source.toPath(), new FileOutputStream(new File("/root/Downloads/test/1.png")));
} catch (IOException e) {
e.printStackTrace();
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
複製代碼
咱們內核操做由於正常不開瀏覽器界面,可是咱們調試的時候又想知道結果,能夠打印除當前窗口的圖片。就是上述的代碼
Set<String> windowHandles = webDriver.getWindowHandles();
for (String windowHandle : windowHandles) {
if (!windowHandle.equals(webDriver.getWindowHandle())) {
//webDriver.switchTo().window(windowHandle);
}
}
複製代碼
webDriver.navigate().to("https://juejin.im/post/5d76f6585188254cc27b2af4");
webDriver.get("https://juejin.im/post/5d76f6585188254cc27b2af4");
複製代碼
webDriver.get("https://juejin.im/timeline");
webDriver.manage().addCookie(cookie);
webDriver.get("https://juejin.im/post/5d76f6585188254cc27b2af4");
複製代碼
這裏值得注意的是,在添加cookie以前咱們須要先訪問主頁,告訴內核咱們後面添加的cookie是給那個Host下添加的。這樣咱們添加的cookie纔會有效。如上咱們在juejin.im這個Host下都添加了Cookie。
我的網站(zxhtom.oschina.io)
我的微信(zxh870775401)
微信公衆號 : 新華先後端開發