爬蟲學習日記(六)完成第一個爬蟲任務

距離上一篇學習日記已通過去了兩個星期,簡單講一下這兩個星期都幹了些什麼吧。html

任務回顧:

  1. 測試SUDU是否能夠用selenium的方式來獲取網頁信息。
  2. 用selenium的方式實現SUDURoute的功能。
  3. 完成SITC Crawler。

由於capture SUDU 的爬蟲出了問題,估計是頻繁爬對面數據,被對面給block掉了,而Cindy就想讓我試試用selenium+phantomJS的方式,看看行的通嗎,以前用的是httpclient的方式。而後我就參照以前本身自學的方式,還有百度,用selenium獲取了對面的首頁,證實這種方式是能夠的。因此咱們Team決定改用selenium來實現SUDU,並且要我來寫。剛開始我是一位不難的,可是真正寫起來才發現真的很複雜,各類xpath獲取element,並且有不少業務的知識,那些要記錄,那些不用記錄,有進行不少的判斷,寫了兩天發現進度緩慢,並且Cindy也在催,感受本身作不完了,就讓東哥去作了。後面一個星期,被安排了另一個task,也是要寫一個crawler,用httpclient的方式,網站結構比SUDU簡單不少,完成較快,已經初步寫完,能實現功能,本身測試也沒什麼問題。git

總結

  1. 用selenium來獲取SUDU首頁

由於只是獲取首頁,因此並無什麼難度。
首先在本地配置了一個driver。web

//本地測試driver路徑
    private static WebDriver getWebDriver() {
        ChromeOptions options = new ChromeOptions();
        Map<String, Object> contentSettings = new HashMap<>();
        contentSettings.put("images", 2);

        Map<String, Object> preferences = new HashMap<>();
        preferences.put("profile.default_content_settings", contentSettings);

        DesiredCapabilities caps = DesiredCapabilities.chrome();
        caps.setCapability("chrome.prefs", preferences);
        caps.setCapability(ChromeOptions.CAPABILITY, options);

//		options.addArguments("headless");// headless mode
//		options.addArguments("disable-gpu");
        options.setBinary("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
        System.setProperty("webdriver.chrome.driver", "D:\\phantomjs-2.0.0-windows\\chromedriver.exe");
//		ChromeDriver driver = new ChromeDriver(caps);


        System.setProperty("phantomjs.binary.path", "D:\\phantomjs-2.0.0-windows\\bin\\phantomjs.exe");
        ArrayList<String> args = new ArrayList<>();
        args.add("--ignore-ssl-errors=true");
        args.add("--ssl-protocol=any");
        DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
        capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, args);
        PhantomJSDriver driver = new PhantomJSDriver(capabilities);

        return driver;
    }
複製代碼
caps.setCapability(ChromeOptions.CAPABILITY, options);
複製代碼

這一句配置是用模擬手機登陸,我以前也有點不明白爲何要設置成這樣,後來在別人的blog中發現這樣子設置不容易被對面反爬蟲。chrome

配置好Chrome和ChromeDriver的路徑,要注意版本號要對應。 配置好phantomjs的路徑。json

String url = "https://www.hamburgsud-line.com/linerportal/pages/hsdg/p2p.xhtml?lang=en";
			driver.get(url);
			String html = driver.getPageSource();
複製代碼

調用driver的get方法,他就回去打開這個url,用getPageSource就能獲取這個網頁的源碼,輸出這個html,發現裏面是有內容的,用selenium方式可行 。windows

  1. 用selenium的方式實現SUDURoute的功能。

才發現本身以前寫的沒有保存,上傳git被還原回去了。瀏覽器

就只能簡單講一下如今還記得的幾個有印象的點。bash

首先由於是用的phantomjs,並且它設置成手機模式,在原先的crawler中,不能沿用他以前用的ChromeDriver的方式,由於兩種打開方式,頁面裏面各類element的ID是有一些是不同的。
如,當時我在debug的時候,發現按鈕事件一直無效,回去頁面裏面看,發現按鈕的ID已經變了。其實發現按鈕ID變了這個也有點曲折,由於那時候我不知道瀏覽器已經被設置成了手機瀏覽的方式,因此我仍是回去原先他的網站上看的,用的是pc端瀏覽器打開的頁面裏面的按鈕的ID,可是就是一直跑不通,後來纔想到應該去看我獲取的html裏面的,才發現按鈕的ID換了的,把按鈕的ID換回來就能夠實現點擊事件了。less

實現點擊事件後,他會執行一個判斷,判斷網頁是否出現了某些元素,這裏指的就是搜索結果,出現了搜索結果他就會中止等待。post

中止等待之後,他會將獲取的html用jsoup轉換成document對象,就能夠用DOM經過id或者其餘東西來查找節點來轉換成element,這裏是找到routeList。

作到routeList都一直聽順利,後來要對routeList作解析的時候,就一直遇到問題。
首先我第一個問題是對業務的不理解,在代碼裏面有transhipment進行判斷的,0或者1有不同的解析方式,若是是0的話,是能夠成功執行的,點開裏面嵌套的內容都是能夠獲取到,可是在1的時候,就一直獲取不到,就一直卡在這裏。

對SUDU的開發就停留在這裏了。

  1. 完成SITC Crawler。

先講講需求,獲取route而後記錄。

由於用的是httpclient,因此並不像以前用selenium同樣擔憂ID的問題。

經過這個爬蟲的開發,也逐漸瞭解到用selenium和用httpclient的區別:
1.selenium其實就是模仿用戶操做,來實現各類點擊操做,而後獲取執行後的頁面,對頁面進行解析獲取,經過jsoup轉成ducument,用DOM獲取各個element中我想要的元素。

2.httpclient則是模擬放鬆post和get請求,無論執行什麼操做,歸根結底都是往requestURL發送請求去後臺。經過httpclient就能夠拼接發送請求的頭部還有body,而後解析它返回來的response。

二者各有各的好處,selenium對於一些獲取動態頁面的比較適合,httpclient則比較適合獲取靜態頁面的。

如今來說講我作SITC的一些心得:

首先以爲要作一個爬蟲,就要先從瞭解他的各個請求開始。
以前我一直用的是selenium的思惟去作httpclient,想要說實現點擊查找這個方法,而後獲取整個頁面,然而顯示信息那裏都是動態生成的,用httpclient是獲取不到顯示的信息的,返回回來的都是空的。
這裏我用的是Chrome調試界面裏面的network,發現當我點擊查找的時候,會有一個請求發送到後臺:

而這個請求返回來的是一個json:

這就是最主要的一個request了,我只要模擬這個POST請求,把我想搜索的參數設置進去,就能返回我所要的信息,而後對這些信息進行解析就好了。

成功獲取到我想要的信息之後,剩下的就是解析。
由於返回來的是一個String,我要把它轉成能操做的list,就必須先把String轉成list。
個人作法是:
把string轉成jsonobject

JSONObject Json = JSONObject.fromObject(response);

複製代碼

在Json裏面經過get到list:

JSONArray routeArray = (JSONArray) Json.get("list");
複製代碼

這樣就能對list進行操做了。

SITC大體的心得就是這樣,第一次作考慮的狀況還不是不少,估計後續會有一些bug。

和狗子一塊兒成爲更好的人。
複製代碼
相關文章
相關標籤/搜索