记得coding老师讲elasticsearch的时候,有一个简单的项目是使用爬虫爬取jd上的一些商品页面数据放入es,然后从es读取出来展示,更早一些时候自己也接触过使用java爬虫,是一个开源的框架,大概的原理是解析返回来的Document,找到相应的Element拿到数据,这是相对简单的方式,如果网站做了反扒机制就不行了,下面简单了解一下
Jsoup
在介绍这个类之前,肯定先得说说我们通常看到的内容是由什么组成的,现在比如说我们做开发的都知道,至少我们在电脑端访问某东,某宝的数据的时候,他们给我们反馈的数据都是通过 HTML 来进行展示的,比如说这个样子:
在开发的肯定都是知道,这些都是些什么意思,在这里我们就不再进行详细的介绍,说这个 HTML 到底是个啥东西了,阿粉需要介绍的是 Jsoup ,然后告诉大家怎么使用 Jsoup 这个类爬取京东的数据
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);
而这个 Document是什么呢?我们可以输出一下看一眼:
<html>
<head>
<title>First parse</title>
</head>
<body>
<p>Parsed HTML into a doc.</p>
</body>
</html>
Document实际上是给我们输出了一个新的文档,而且是整理之后的,相当于为之后的分析 HTML 做了专业的准备。
Jsoup不单单是能解析我们给的这个字符串,还可以是一个URL,也可以是一个文件。
它把我们给他的 HTML 字符串转换成了一个对象,这个对象就是我们上面看到的 Document,然后我们就可以顺利成章的去使用 Document 对象里面的元素了。
上面是解析字符串,那我们看下面这个解析 URL 的存在:
public static void main(String[] args) {
try {
Document doc = Jsoup.connect("https://www.jd.com/?cu=true&utm_source=baidu-pinzhuan&utm_medium=cpc&utm_campaign=t_288551095_baidupinzhuan&utm_term=0f3d30c8dba7459bb52f2eb5eba8ac7d_0_f38cf584e9fb4328a3e0d2bb515e1458").get();
String title = doc.title();
System.out.println(title);
}catch (IOException e){
e.printStackTrace();
}
}
大家执行以下的话,就一定能够看到这个 title 到底是什么:
和我们在百度搜索的时候是不是不太一样了,因为这个是进入之后的主页。
Element
而在我们看源码的时候,我们能清晰的看到,Document 是继承了 Element 的类,那么必然可以调用 Element 里面的方法,比如说:
getElementById(String id); //是不是有点眼熟,像不像Js里面的ID选择器
getElementsByTag(String tagName);// 通过标签来选择
getAllElements();//获取所有的Element的元素
我们在爬取之前肯定先分析京东的网址,比如说我搜索硬盘:
下面就出来了一堆数据,而我们则需要解析的就是在 HTML 种最有用的那一部分
<div class="p-price">
<strong class="J_54994027563" data-done="1">
<em>¥</em><i>879.00</i>
</strong>
</div>
在这里我们就记下了这个价格,然后我们去找我们要的名字
看,p-name
就是我们需要的名字,那么我们就可以写代码了。
//这是京东的搜索网址,我们把这个keyword关键词提取出来,注意中英文,中文要处理一下
String url = "https://search.jd.com/Search?keyword=" + keyword;
url = url + "&enc=utf-8";
Document document = Jsoup.parse(new URL(url), 40000);
//我们先找这个 List,然后一层一层的遍历
Element element = document.getElementById("J_goodsList");
Elements elements = element.getElementsByTag("li");
for (Element el : elements) {
String img = el.getElementsByTag("img").eq(0).attr("source-data-lazy-img");
String price = el.getElementsByClass("p-price").eq(0).text();
String title = el.getElementsByClass("p-name").eq(0).text();
String shop = el.getElementsByClass("p-shop").eq(0).text();
System.out.println("=========================");
System.out.println("标题:" + title);
System.out.println("图片url:" + img);
System.out.println("店铺:" + shop);
System.out.println("价格:" + price);
}
大家看执行的效果图:
你可以直接在for循环里面新建一个对象,弄一个List集合,然后在最后的的时候,执行一下插入数据库的方法,这样是不是就能完整的把数据都保存下来了呢?