Java网络爬虫
一、前言
首先我们把准备工作做好:IDEA 2019.1、JDK1.8、Maven3.5
Jsoup的Maven依赖:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
以及可能用到的Splider工具集合:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.4</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
以及程序员必备的Google的Guava包
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>
基本工具就到这里了,后面需要什么在加什么就行了。
二、操作
我这里就以2种(HTML、JSON)格式作为讲解内容。其他的格式(JS、XML等格式就不做更多说明了,毕竟操作都差不多)
JSON格式
首先,这里我推荐一个JSON在线解析的网站(https://www.json.cn/),毕竟后面很多都要去查结构。
然后我们得了解一下使用JsonPath解析Json的语法。
操作 | 说明 |
---|---|
$ | 查询根元素。这将启动所有路径表达式。 |
@ | 当前节点由过滤谓词处理。 |
* | 通配符,必要时可用任何地方的名称或数字。 |
.. | 深层扫描。 必要时在任何地方可以使用名称。 |
. | 点,表示子节点 |
['' (, '')] | 括号表示子项 |
[ (, )] | 数组索引或索引 |
[start:end] | 数组切片操作 |
[?()] | 过滤表达式。 表达式必须求值为一个布尔值。 |
在官方网站上有更加详细的解说(https://github.com/json-path/JsonPath),这里就不作更多解释了,如果觉得英文麻烦可以百度下JsonPath语法。就会很多相关的博客解释。
这里为了方便给出一点点的解释:
好!前期知识预备工作不多废话了,更多请自行百度。
具体题材自己定,如果使用某些公司的网站作为题材,搞不好要被发律师函,作者就把一些核心代码以及核心思路写出来就行了。
首先想要爬取一个网站的信息必定要有一下几步:
1. 能够获取到的URL(Response只要能获取想要的数据即可)。
2. 能够使用程序链接上,有的网页只能用POST,还要设置必要的参数。
3. 通过自己熟悉的解析方式解析数据,封装数据。
一般来说一个页面的描述都是2种类型(列表页,详情页)
我们就要分3步走:
1. 获取列表页的列表信息,其他不重要的信息基本可以抛弃。
2. 获取列表信息后可以获取完整的URL或者部分URL(部分的话自己拼接下,一般来说大多数前缀都相同)。
3. 获取详情页的信息。
在这个过程中比较繁杂,需要多用浏览器F12或者其他抓包工具,很多网站的内容并不会直接放在页面中,有的是使用JSON作为信息传输,有的是使用XML有的是使用JS
第一步:获取打开链接获取内容
public List<String> getDateFromUrl(String url) throws Exception {
List<String> list = new ArrayList<>();
int page = 1, count = 1;
/**
* 遍历每一页
*/
while(page <= count) {
Map<String,String> map = new HashMap<>();
/**
* 设置传输的参数,如果没有不用设置
*/ String json = http(url).method(Connection.Method.POST).data(map).execute().body();
if(page == 1){
count = Integer.parseInt(JsonPath.parse(json).read("$.body.sns.count", String.class));
if(count % 20 == 0){
count /= 20;
}else{
count = count / 20 + 1;
}
}
page++;
JsonPath.parse(json).read("$.body.sns.list.*", JSONArray.class)
.stream()
.map(JSON::toJSONString)
.forEach(list::add);
}
return list;
}
第二步:解析数据。
public MyData crawlerDetailPage(String itemBody, Map<String, Object> params) throws Exception {
DocumentContext parse = JsonPath.parse(itemBody);
String pageUrl = "https://www.XXX.com/XXX/" + parse.read("$.resourceid", String.class) + ".html"; //拼接URL
String duplicateKey = CommonUtils.md5IdUrl(pageUrl);
if(duplicateKeyDao.containsKey(duplicateKey)){
return null;
}
MyDatamyData= new MyData();
String fromUrl = params.get("link").toString();// 获取父地址
String commentcount = parse.read("$.commentcount", String.class);// 评论数
String id = parse.read("$.id", String.class);// id
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
String time = parse.read("$.publishtime", String.class);// 获取时间
if(time.contains("年")){
time = time.replace("年",":").replace("月",":").replace("日","");
}else{
time = calendar.get(Calendar.YEAR) + ":" + time.replace("月",":").replace("日","");
}
String picUrl = parse.read("$.image.url", String.class);// 封面图的URL
JSONArray read = parse.read("$.list.*", JSONArray.class);
if(read.size() > 0){
Object obj = read.get(0);
String videPicUrl = JsonPath.parse(obj).read("$.image.url", String.class);// 视频封面URL
String videoUrl = JsonPath.parse(obj).read("$.videourl.sdinfo.url", String.class);// 获取视频URL
String playcount = JsonPath.parse(obj).read("$.playcount", String.class);// 播放量
myData.setPlayCount(Long.parseLong(playcount));
myData.setCommentCount(Integer.parseInt(playcount));
myData.setPageLink(videoUrl);
myData.setVideoDynamicCover(videPicUrl);
}
String videoId = parse.read("$.id", String.class);// 视频ID
String title = parse.read("$.title", String.class);// 标题
String username = parse.read("$.user.name", String.class);// 用户名
String praisecount = parse.read("$.praisecount", String.class);// 点赞数
/**
* 封装数据
*/
return myData;
}
针对JSON的入门,基本到这里也就差不多了
HTML格式
其实原理和上面一样,只不过这个是使用Jsoup进行解析,上面是使用JsonPath进行解析。
public List<String> crawlerListPage(String url) throws Exception {
List<String> result = new ArrayList<>();
String body = http(url).execute().parse().html();
return Jsoup.parse(body).select(/*CSS的各种选择器,只要保证绝对定位进行*/)
.stream()
.map(Element::toString)
.collect(Collectors.toList());
} public MyData crawlerDetailPage(String itemBody) throws Exception {
Document parse = Jsoup.parse(itemBody);
String pageUrl = "http:" + parse.select("CSS选择器").attr("href");// 获取文章链接
String title = parse.select("CSS选择器").text();// 获取文章Tile
String username = parse.select("CSS选择器").text();// 获取用户名
String like = parse.select("CSS选择器").text();// 获取点赞数
String id = parse.select("CSS选择器").attr("href");// 用户ID
String body = http(pageUrl).execute().body();
String time = Jsoup.parse(body).select("#content > div.gXB_R8JPG9i5-WDsZpN3C > div._30-dgPMBo3ct-NBvSsFmkq > p > span").text().replace("发布于", "");
String picUrl = "http:" + Jsoup.parse(body).select("#app > div > div.q-container > div:nth-child(4) > div > img").attr("src");// 封面链接
String content = Jsoup.parse(body).select("#textContBox").text();// 内容
MyData my = new MyData();
/*封装数据*/
return my;
}
Java网络爬虫的更多相关文章
- Java 网络爬虫获取网页源代码原理及实现
Java 网络爬虫获取网页源代码原理及实现 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL ...
- java网络爬虫基础学习(三)
尝试直接请求URL获取资源 豆瓣电影 https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort= ...
- java网络爬虫基础学习(一)
刚开始接触java爬虫,在这里是搜索网上做一些理论知识的总结 主要参考文章:gitchat 的java 网络爬虫基础入门,好像要付费,也不贵,感觉内容对新手很友好. 一.爬虫介绍 网络爬虫是一个自动提 ...
- 学 Java 网络爬虫,需要哪些基础知识?
说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少.有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬 ...
- Java 网络爬虫,就是这么的简单
这是 Java 网络爬虫系列文章的第一篇,如果你还不知道 Java 网络爬虫系列文章,请参看 学 Java 网络爬虫,需要哪些基础知识.第一篇是关于 Java 网络爬虫入门内容,在该篇中我们以采集虎扑 ...
- Java网络爬虫笔记
Java网络爬虫笔记 HttpClient来代替浏览器发起请求. select找到的是元素,也就是elements,你想要获取具体某一个属性的值,还是要用attr("")方法.标签 ...
- Java 网络爬虫获取页面源代码
原博文:http://www.cnblogs.com/xudong-bupt/archive/2013/03/20/2971893.html 1.网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网 ...
- 开源的49款Java 网络爬虫软件
参考地址 搜索引擎 Nutch Nutch 是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. Nutch的创始人是Doug Cutting, ...
- 【转】44款Java 网络爬虫开源软件
原帖地址 http://www.oschina.net/project/lang/19?tag=64&sort=time 极简网络爬虫组件 WebFetch WebFetch 是无依赖极简网页 ...
- hadoop中实现java网络爬虫
这一篇网络爬虫的实现就要联系上大数据了.在前两篇java实现网络爬虫和heritrix实现网络爬虫的基础上,这一次是要完整的做一次数据的收集.数据上传.数据分析.数据结果读取.数据可视化. 需要用到 ...
随机推荐
- 【leetcode】1012. Numbers With Repeated Digits
题目如下: Given a positive integer N, return the number of positive integers less than or equal to N tha ...
- 随机验证码生成和join 字符串
函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符) ...
- socket 异步 发送 接收 数据
Socket socketClints = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); / ...
- C# socket异步 服务端
转自: http://blog.csdn.net/qq_20282263/article/details/54310737 private Dictionary<string, Session ...
- THUSC 2017 游记
Day0 早上在家里整理东西. 下午坐飞机去北京.(怎么又去北京,上周刚去的北京) 一开始飞机爬升的时候太无聊就睡着了.醒了以后就开始吃东西.吐槽一句:厦航的飞机就是好啊.上面的点心也比上次海航的好吃 ...
- 彩色图像--色彩空间 CMY(K)空间
学习DIP第63天 转载请标明本文出处:***http://blog.csdn.net/tonyshengtan ***,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:http ...
- touch:创建文件及修改文件时间戳
touch 命令不光可以用来创建文件(当指定操作文件不存在时,该命令会在当前位置建立一个空文件),此命令更重要的功能是修改文件的时间参数(但当文件存在时,会修改此文件的时间参数). Linux 系统中 ...
- TCP序列号和确认号
TCP序列号和确认号详解 在网络分析中,读懂TCP序列号和确认号在的变化趋势,可以帮助我们学习TCP协议以及排查通讯故障,如通过查看序列号和确认号可以确定数据传输是否乱序.但我在查阅了当前很多资料后发 ...
- Python3学习笔记(十二):闭包
闭包定义: 在一个外函数中定义了一个内函数,内函数里引用了外函数的临时变量,并且外函数的返回值是内函数的引用.这样就构成了一个闭包. 我们先来看一个简单的函数: def outer(a): b = 1 ...
- A. Transmigration
A. Transmigration time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...