爬虫
爬虫一般值网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取网络信息的程序或者脚本,可以自动采集所有其能够访问到的页面内容,以获取相关数据。
网络爬虫合法吗?
网络爬虫技术目前已经广泛应用。虽然互联网世界已经通过自身的协议建立起一定的道德规范(Robots协议),但法律部分还在建立和完善中。从目前的情况来看,如果抓取的数据属于个人使用或科研范畴,基本不存在问题;但如果数据属于商业盈利范畴,就要就事而论,有可能属于违法行为,也有可能不违法。
Robots协议(爬虫协议)的全称是网络爬虫排除标准(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。该协议是国际互联网界通行的道德规范,虽然没有写入法律,但是每一个爬虫都应该遵守这项协议。
除了Robots协议之外,我们是以网络爬虫的时候还要对自己进行约束:
- 过于快速或者频密的网络爬虫都会对服务器产生巨大的压力,网站可能封锁你的IP,甚至采取进一步的法律行动。因此,你需要约束自己的网络爬虫行为,将请求的速度限定在一个合理的范围之内;
- 在爬取网站的时候需要限制自己的爬虫,遵守Robots协议和约束网络爬虫程序的速度;
- 使用爬取的数据时必须遵守网站的知识产权。如果违反了这些规定,需要承担一定的法律责任(败诉的概率相当高)。
注意:本教程中的爬虫仅用于学习、研究用途,请不要用于非法用途。任何由此引发的法律纠纷请自行负责。
爬虫简介
随着网络的迅速发展,万维网成为大量信息的载体,而信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,搜索的成本也会提高。那么如何有效地提取并利用这些信息成为一个巨大的挑战。
从功能上来说,爬虫一般分为数据采集、处理、存储三部分。
爬虫能解决哪些问题?
- 大数据时代,可以让我们获取更多的数据源
- 实现私人的搜索引擎
- 优化搜索引擎
Jsoup爬虫技术栈
Jsoup是一个Java HTML Parse,能够从URL、文件或者字符串中解析HTML。它提供了一套非常省力的API,可通过DOM、CSS、以及类似于jQuery的操作方法来取出和操作数据。
注意:Jsoup是基于MIT协议发布的,可以放心使用于商业项目。
引入Jsoup
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
</dependency>
解析
Jsoup支持解析:
- urlDocument doc = Jsoup.connect("https://www.baidu.com/").get();
- html字符串String html = "<html><head><title>示例</title></head><body><h2>Hello World</h2></body></html>";
Document doc = Jsoup.parse(html); - html文件Document doc = Jsoup.parse(new File("index.html"), "UTF-8");
选择器
Jsoup支持类似于CSS(或jQuery)的选择器语法,来实现非常强大和灵活的查找功能。
Jsoup提供了select(String selector)方法来实现指定元素的过滤,或链式选择访问,该方法返回一个Elements集合对象,并提供一组方法来抽取和处理结果。
爬取百度数据
在百度首页,显示的有“百度热搜”数据,需要爬取该数据的第一条信息的标题。
代码如下:
Document doc = Jsoup.connect("https://www.baidu.com/").get();
Elements elements = doc.select("#hotsearch_data"); // 根据ID查询
if(!elements.isEmpty()) { // 是否匹配成功,为空则没有找到对应的内容
Element firstElement = elements.first();
String data = firstElement.text(); // 获取的为JSON格式数据
// 数据格式为: {"hotsearch": [{"pure_title": "","linkurl": "","views": "", "isViewed": "","isNew": "","heat_score": "","hotTags": "","pre_tag": ""}, ...]}
// 解析JSON
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(data);
JsonNode hotsearch = jsonNode.get("hotsearch");
List<JsonNode> titles = hotsearch.findValues("pure_title"); // 获取 标题字段 集合
String title = titles.get(0).asText(); // 第一个标题
System.out.println(title);
}