1. 程式人生 > >HtmlUnit java爬蟲入門 真實案例講解 爬取電商網站資料

HtmlUnit java爬蟲入門 真實案例講解 爬取電商網站資料

最近利用空閒時間幫朋友做了個爬取幾個電商網站的資料的小程式 使用的是htmlUnit 自我感覺htmlUnit爬取的速度和穩定性還是很不錯的 所以寫一篇博文介紹下htmlUnit的使用相關 也算記錄一下

這是該網站的主頁面

具體的思路是 獲取商品所在的div 通過div獲取每個商品的<a>標籤的href 進入該網址 爬取該商品的資料 然後匯出EXCEL表 實現自動翻譯等功能

1.首先 我們需要獲取主頁面的資料

WebClient webClient = new WebClient(BrowserVersion.CHROME  );//模擬建立開啟一個谷歌瀏覽器視窗
webClient.getOptions().setTimeout(15000);//設定網頁響應時間
webClient.getOptions().setUseInsecureSSL(true);//是否
webClient.getOptions().setRedirectEnabled(true);//是否自動載入重定向
webClient.getOptions().setThrowExceptionOnScriptError(false);//是否丟擲頁面javascript錯誤
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//是否丟擲response的錯誤 webClient.getOptions().setJavaScriptEnabled(false);// HtmlUnit對JavaScript的支援不好,關閉之 webClient.getOptions().setCssEnabled(false);// HtmlUnit對CSS的支援不好,關閉之 String url = "https://shop.sanrio.co.jp/products/list.php?product_status=1"; HtmlPage page = webClient.getPage(url);//通過url獲取整個頁面
這樣 我們就得到了該頁面 的HtmlPage物件.

通過檢視page物件的方法 能發現 它可以像在寫JS一樣的操作頁面上的元素

2.檢視頁面原始碼 獲取商品對應的div中的A標籤 (縮放過的圖片 可以右鍵檢視原圖)


由此可發現 商品均是巢狀在一個 id="prdlist" 的div中 那麼我們可以通過

// 獲取A標籤的div
HtmlDivision element = (HtmlDivision) page.getHtmlElementById("prdlist"); 
這樣就獲取到了商品所對應的div標籤  然後我們再檢視每個商品單獨的div對應的原始碼 來獲取網頁地址


這就是每個獨立的商品div 所對應的原始碼了 我們能看到 每個商品的div中 只有一個A標籤 那麼 我們只要獲取到該A標籤就Ok

DomNodeList<HtmlElement> list = element.getElementsByTagName("a"); // 獲取頁面上的所有A連線(商品標籤)
out2: for (HtmlElement htmlElement : list) {
   HtmlPage click = htmlElement.click(); // 進入商品頁面
   HtmlDivision div3 = (HtmlDivision) click.getByXPath("//div[@class='box_right_summary']").get(0); // 獲得名字的div
}
這個網址的內容剛好爬取的內容的div有ID  那 沒有ID的div或者其他標籤應該怎麼得到呢 htmlunit封裝好了一個getByXPath方法 專門用來爬取不特殊的標籤 具體寫法如 上圖的獲取名字的DIV 表示獲取class屬性=box_right_summary 的div集合

htmlunit 中自帶的基本包含了所有html的標籤 如 HtmlInput HtmlTable HtmlSpan 等等等等 讀者可以下載一個jar自己試試

另外XPath的語法使用可以參照這篇文章  Xpath語法

另外htmlunit還可以模擬表單的提交 就使用htmlElement的click()方法 獲取表單的輸入框 然後設定值 模擬點選事件

 // 獲取首頁
	    final HtmlPage page1 = (HtmlPage) webClient.getPage("http://htmlunit.sourceforge.net");

	    // 根據form的名字獲取頁面表單,也可以通過索引來獲取:page.getForms().get(0)
	    final HtmlForm form = page1.getFormByName("myform");
	    final HtmlSubmitInput button 
	        = (HtmlSubmitInput) form.getInputByName("submitbutton");
	    final HtmlTextInput textField 
	        = (HtmlTextInput) form.getInputByName("userid");

	    // 設定表單域的值
	    textField.setValueAttribute("root");

	    // 提交表單,返回提交表單後跳轉的頁面
	    final HtmlPage page2 = (HtmlPage) button.click();
這只是一種獲取的方式 還可以通過xpath ID tagNAME 等等方法 都需要讀者自己來探索

3.接下來進入到商品詳情頁面 獲取商品資訊

這就是商品詳情頁面 我們需要獲取到它的名稱 尺寸 圖片 價格 簡介等

然後觀察原始碼

這個div可以獲得到名稱  價格

HtmlDivision div3 = (HtmlDivision) click.getByXPath(
						"//div[@class='box_right_summary']").get(0); // 獲得名字的div

String name = div3.getElementsByTagName("h2").get(0).asText();
excels.setJname(name); // 設定日本名字 (這是自己建立的匯出EXCEL的實體類)
// 獲取商品的價格資訊
HtmlSpan span = (HtmlSpan) click.getByXPath("//span[@class='priceSelect']").get(0);
String cname = getCname(name); // 通過百度翻譯介面獲取中文名字 
excels.setCname(cname);
接下來是商品的編號 尺寸等


如圖 可發現

// 獲取商品的詳細資訊
				HtmlDivision div2 = (HtmlDivision) click.getByXPath(
						"//div[@class='productSummary accordionBlock01']").get(
						0);

				DomNodeList<HtmlElement> ths = div2.getElementsByTagName("tr");
				for (HtmlElement th : ths) {
					if (th.getElementsByTagName("th").get(0).asText().equals("サイズ")) {
						String sizeString = th.getElementsByTagName("td")
								.get(0).asText();
						
						// 設定商品尺寸
						excels.setSize(sizeString);

						
					}
					if (th.getElementsByTagName("th").get(0).asText().equals("商品コード")) {

						// 商品編號
						String nums2 = th.getElementsByTagName("td").get(0)
								.asText();
						// 設定商品編號
						excels.setNums2(nums2);
					}
				}
程式碼寫的不規範  大家湊合看吧

接下來是獲取商品的圖片資訊

HtmlDivision div = (HtmlDivision) click.getByXPath(
						"//div[@class='box_pic']").get(0);
				// System.out.println(div.asXml());
				DomNodeList<HtmlElement> imgs = div.getElementsByTagName("img");
				// 遍歷 下載圖片到本地
				for (HtmlElement img : imgs) {
					download(SANLIOU + img.getAttribute("src"), DOWNDS
							+ filename + "/");//這是自己封裝的下載圖片的方法
				}
那個SANLIOU + img.getAttribute("src") 其實代表的就是圖片的URL 因為一般圖片的地址都不是url的全路徑 這時候就需要我們手動去複製該網站的根路徑 加上img標籤的src屬性來獲取圖片的真實地址了 如:

這是商品的圖片img src就不是完整的

而該網頁的地址是 :https://shop.sanrio.co.jp/products/detail.php?product_id=54355

我們就擷取 https://shop.sanrio.co.jp 這就是該網站的根路徑 再加上/upload/save_image/N-1801-318795_1.jpg 就組成了圖片的真實路徑

至此大致的爬取內容就完成了 詳細的專案案例我上傳到了我的CSDN上 大家可以去下載看看 案例下載

其實htmlunit是一個很簡單的小框架 很好學 只要有前端頁面的基礎 很容易就能入門實現自己想要的功能