soup介紹
Jsoup是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數據。
Jsoup主要功能
注冊中心:
以實例來講解Jsoup使用
步驟:創建項目、pom.xml引入、創建啟動類、運行項目。
中文偽代碼
需求:我們要爬取Docker技術文章,這個網站頁面左邊為菜單,右邊為內容。
經過分析:菜單里的url,是在css的class:left-navigation下面的a標簽下,并且url以/article/index/開始的。
內容:直接在css的class:article_content下面的html。開始寫代碼了:
pom.xml引入
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version> </dependency>
創建啟動類
們無法在一篇博文里解釋 JavaScript 的所有細節。如果你正或多或少地涉及了 web 應用程序開發,那么,我們的 Java 工具和技術范圍報告揭示了,大多數(71%)Java 開發者被歸到了這一類,只是你對 JavaScript 遇到了阻礙。
毫無疑問,你已經知道了 Java 和 JavaScript,不管它們有著多么類似的命名,彼此沒有共享太多共通之處。Java 的靜態類型、符合直接規律的簡單語法和冗長,與 JavaScript 的動態、缺乏一致性原則和怪異,有著巨大的不同。
然而,JavaScript 是 web 的編程語言,最近由于 Node.js 和 JVM 自己的 Nashorn JavaScript 引擎的發展,在服務器端獲得了相當的注意。
本文,我不想只是漫談 JavaScript 的好與不好,或重復任何人都能免費找到的、不計其數的 JavaScript 教程。我想列出一些有助于理解 JavaScript 做為一種語言的技術點,并從接近 horse的角度來理解。
我們將在本文包含下列語言級別的技術點:
另外,你會找到一些工具方面的推薦,沒有這些工具,你是不想著手 JavaScript 項目的,包含了構建系統的代碼質量分析和測試框架方面的工具。
優點
編寫一次,差不多處處運行!
毋庸置疑 JavaScript 是 web 編程語言,是很多其它語言的編譯目標,也是用來證明有時候人們只是想擁有更多自由時間的終極方式。盡管如此,這不是一件壞事。每一臺能夠瀏覽現代網站的電腦都裝備了具有性能和可用的 JavaScript 引擎。最重要的是,JavaScript 代碼可以在后端運行。
內置到我們喜愛的 JVM 的、輕量級高性能 JavaScript 運行時 Nashorn,完全能夠解釋 JavaScript 腳本,還能夠解釋項目中帶有 Java 代碼的 JavaScript 腳本。
鑒于每臺電腦運行時都可獲得的自由,JavaScript 成為 Java 體驗的完美延續。
函數式編程:一等公民是函數,而不是遞歸
JavaScript 中的函數是第一類公民,它們是值,可被存儲在變量里、傳遞給其它函數、在適當的時候再執行。
這打開了函數式編程世界的大門,這是結構化 JavaScript 編程的完美方式。
注意,JavaScript 里的對象是任何東西的映射,對象的每個特性(attribute)都在同一個映射里:函數、屬性(property)、構造器;易變性帶來了更大的隱患,而對于 Java,你至少能夠確保方法和字段結構在某種程度上是穩定的。
反過來,這使得函數式編程更加有利:涉及到小的、可理解函數和不變的數據結構是在 JavaScript 里運行的方式。
這不是沒有依據的,下面是在 JavaScript 里定義一個 reduce 函數的例子,來自于《Eloquent JavaScript》一書。
function forEach (array, action) { for (var i = 0; i < array.length; i++) { action (array[i]); //apply action to every element of the arra. } } function reduce (combine, base, array) { forEach (array, function (element) { base = combine (base, element); // and here we apply function passed as ‘combine’ parameter to ‘base’ and ‘element’ }); return base; } function add (a, b) { // btw, this is how you define a function in JavaScript return a + b; } function sum (numbers) { return reduce (add, 0, numbers); }
注意:我們沒有在這里使用 reduce 的遞歸版本。JavaScript 沒有以尾調用【注1】為特色,這意味著每個函數的遞歸版本都將用到棧的深度,和 Java 一樣,如果你遞歸太深,程序就崩潰。
繼承:就像真實的世界
JavaScript 的繼承是基于原型的。即,你沒有擴展了其它類型的類型,而實際上,你擁有的實例從其它實例繼承了功能。
想象一下,對象A就像一個映射,我們剛才稍微提到了一些、但是用了不同的視角,然后另一個類似映射的對象B從A繼承了一切。
這說明B可以訪問A所有部分:A的方法、字段等等。
在實踐中,我從來沒有看到有人實際使用簡單的基于原型的繼承。通常當某人需要繼承時,他只是構造類,因此你可以用到所有廣泛的技能,和基于類的繼承的工作模式。
——Rene Saarsoo,XRebel 前端工程師
我不太確定 Java 開發者應該從中吸取什么,但是要當心繼承方式的不同,對于父級對象要格外留意、而不要意外地改變整個程序的行為。
任何時候要避免的
列出不可靠的 JavaScript 設計上的決定比想象中要容易。在 JavaScript 程序中要避免的最明顯的地方就是全局變量的聲明。
注意,在 JavaScript 里,無論什么時候,不使用 var 關鍵詞定義變量,那么定義的變量被推到了它們被定義的作用域頂端。這意味著,每個用這種方式定義的變量將跑到全局范圍頂部,這會引發沖突以及你和同事不可預期的頭痛。
可以開啟 strict 模式。只需在腳本文件頂部寫上“use strict”,那么不經意編寫的全局變量聲明將顯示錯誤。
JavaScript 與 Java 另一個重要的不同點在于,前者是動態類型語言,其真諦是所有東西都可以是任何類型。這很明顯了,實在不能再強調了:不要針對不同類型的值,去復用相同的變量。
跟蹤剛開始是個 string 類型的變量,但是現在它成了浮點數、或者函數了,相信我!
還有,我不想太深入類型和布爾值的討論,但是要警惕 JavaScript 引擎扔給你的隱式類型轉換。
搞定工作的小提示
正如我上面提到的,在編程上要更加注意這種語言的語法和怪癖,而不僅僅是知道。項目很少由于語言的不足而失敗,更多的失敗是與總體項目框架不足有關。下面是有助于你交付項目的一些工具。
靜態代碼分析
大部分項目是不同的,其復雜度和需求導致了大量的細節,你該如何著手代碼庫呢。盡管如此,在所有地方都有一致性的目標,那就是代碼質量。
是的,代碼質量,對于任何開發者來說,最重要的工作就是交付。但是不要在質量上妥協,不要對你提交的代碼感到不自信就不情愿與同事分享。
幸運的是,JavaScript 有一套得體的解決方案——JSHint。JSHint 是為 JavaScript 量身打造的靜態分析工具,與應用于 Java 代碼的 FindBug 類似。JSHint 可以在你的代碼庫運行,并高亮出可疑的或有問題的地方,即使你不會馬上產生 bug,但這些地方將來變得難以維護。在項目中支持它相當簡單。幫自己一個忙——如果你在寫 JavaScript 代碼,就用 JSHint 讓它更安全、少一些尷尬。
REPL
REPL 代表“讀取-求值-輸出”循環(Read-Eval-Print Loop)【注2】,是很多動態語言的強大工具。如果你看過 Scala 或 Groovy,你一定能夠理解這個概念。
激活 JavaScript REPL 的一種途徑是打開瀏覽器的控制臺,它產生了對 JavaScript 代碼求值的界面。
另一個比較方便的工具是 jjs,它捆綁在 JDK1.8。
它是命令行工具,允許你訪問 JDK 中的 Nashorn JavaScript 引擎,完全有能力執行那些甚至最為嚴格的 JavaScript 腳本。
測試
對于任何一個項目,你都想運行一些測試。測試對于動態類型的語言尤為重要,最好選擇一種測試框架。我推薦 Jasmine,它是用于測試 JavaScript 的行為驅動開發框架。
在 Jasmine,你用 describe 描述測試套件,它阻止了你想測試的代碼訪問。在測試中的代碼完成后,你 expect 一些結果。
很明顯這里不是要給出教程,但是我想讓你一瞥 JavaScript 代碼看起來是多么地優雅。Jasmine 是 JavaScript 項目最好的實踐之一,我們私下在產品開發中應用到了 ZeroTurnaround 項目,尤其是對于富含 JavaScript 的不間斷運行的交互分析器 XRebel。
構建工具
最后,你的項目將需要的、比較重要的是構建工具。如果你在 Java 項目中使用 JavaScript,請確保你可以避開 Java 構建工具,這就差不多足夠了。但是,對于獨立的 JavaScript 項目,沒有必要引入龐然大物—Maven【注3】。
可以考慮的 JavaScript 項目用到的構建工具是 GulpJS【注4】。它是基于插件的構建系統,你可以為其指定任務。任務可以是“拷貝 src 目錄下的 .js 文件到 dest”、或“壓縮我的 JavaScript 代碼用于生產環境”。讓人受到震動的是,GulpJS 把任務相關的文件流加入過濾器,因此你可以把上面的兩個任務加入一次有效的清掃中。
還有大量的可用插件,借助適當的構建系統,你將發現項目中的協作會輕松很多。
結論
我們只是看到了 JavaScript 的冰山一角,并盡量介紹一些 Java 開發者在解決 JavaScript 時應該知道的概念和工具。自然地,這里沒有提供要學習的完整的技術清單,但是如果你正準備義無反顧地深入 JavaScript 項目,這會幫助你起步,擁抱 JavaScript 的怪癖將有助于你不會頻繁地沮喪。
你了解讓 JS 開發者走向快樂的秘密或最佳實踐嗎?毫無疑問應該去分享!在下面評論或在 Twitter:@shelajev 上與我交談。我樂于聽到你的想法!
作者:前端小攻略
原文:https://my.oschina.net/u/3972188/blog/2999914
soup是一款Java的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數據。
在爬蟲采集網頁領域主要作用是用HttpClient獲取到網頁后,使用Jsoup提取網頁中需要的信息,Jsoup支持類似Jquery、CSS選擇器,來獲取需要的數據,使用非常方便。
下面結合代碼簡單展示如何使用Jsoup獲取需要的頁面數據。
public class JsoupHello {
public static void main(String[] args) throws Exception{
CloseableHttpClient httpclient = HttpClients.createDefault(); // 創建httpclient實例
HttpGet httpget = new HttpGet("http://www.cnblogs.com/"); // 創建httpget實例
CloseableHttpResponse response = httpclient.execute(httpget); // 執行get請求
HttpEntity entity=response.getEntity(); // 獲取返回實體
String content=EntityUtils.toString(entity, "utf-8");
response.close(); // 關閉流和釋放系統資源
Document doc=Jsoup.parse(content); // 解析網頁 得到文檔對象
Elements elements=doc.getElementsByTag("title"); // 獲取tag是title的所有DOM元素
Element element=elements.get(0); // 獲取第1個元素
String title=element.text(); // 返回元素的文本
System.out.println("網頁標題是:"+title);
Element element2=doc.getElementById("site_nav_top"); // 獲取id=site_nav_top的DOM元素
String navTop=element2.text(); // 返回元素的文本
System.out.println("口號:"+navTop);
}
}
1、使用httpClient 獲取網頁2、使用jsoup parse解析網頁,并根據豐富的getElement方法按照不同的屬性獲取元素值
二、常用查找dom元素方法
1、根據標簽名(tagName)查找dom
Elements elements=doc.getElementsByTag("title"); //獲取tag是title的所有dom元素
Element element= elements.get(0); //獲取第一個
System.out.println(element.text());//輸出元素txt值
2、根據元素Id查找
3、根據class 名查找
4、根據attribute屬性名查找
5、根據attribute和attributeValue共同查找
三、使用Jsoup選擇器查找dom元素1、class類選擇器使用
//class 使用. 中間空格
Elements eleLinks= doc.select(".post_item .post_item_body h3 a");
for(Element el:eleLinks)
{
System.out.println(el.text());
}
*請認真填寫需求信息,我們會在24小時內與您取得聯系。