java爬虫抓取网页数据(空闲时间帮朋友做了个爬取几个电商网站的数据)
优采云 发布时间: 2021-11-24 03:06java爬虫抓取网页数据(空闲时间帮朋友做了个爬取几个电商网站的数据)
最近利用空闲时间帮朋友做了一个小程序,用htmlUnit爬取几个电商网站的数据。感觉htmlUnit爬取的速度和稳定性还是很不错的,所以写了一篇博文介绍了htmlUnit的使用,也记录下来了。
这是网站的主页
具体思路是获取产品所在的div。通过div获取每个商品的tag的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标签(放大后的图片可以右键查看原图)
可以发现product都嵌套在一个id="prdlist"的div中,那么我们就可以通过
// 获取A标签的div
HtmlDivision element = (HtmlDivision) page.getHtmlElementById("prdlist");
这样就得到了产品对应的div标签,然后我们查看每个产品的单独div对应的源代码,得到网页地址
这是每个单独的产品div对应的源代码。我们可以看到每个产品div中只有一个A标签。那么我们只需要拿到A标签,Ok
DomNodeList 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意思是获取类attribute=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 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 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 不完整。
网页地址为:
让我们截取这个。这是网站的根路径加上/upload/save_image/N-1801-318795_1.jpg就构成图片的真实路径
至此,一般的爬取内容就完成了。我把详细的项目案例上传到我的CSDN。你可以下载它。案例下载
其实htmlunit是一个非常简单小巧的框架。只要有前端页面的基础就容易上手,轻松上手,实现自己想要的功能