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是一个很简单的小框架 很好学 只要有前端页面的基础 很容易就能入门实现自己想要的功能



发布了15 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/q690080900/article/details/79072729
今日推荐