难道 Java 就玩不了爬虫?

举报
倪平宇 发表于 2019/12/12 10:56:39 2019/12/12
【摘要】 网络抓包是实现网络爬虫必不可少的技能之一,也是网络爬虫开发的起点。

网路爬虫可以搞定“我想要的数据”。为了“活”下去,我决定放手一搏,但在学习准备阶段我就遇到了我的第一个“爬虫难题”。

难道 Java 就玩不了爬虫?我来教你

难道 Java 就玩不了爬虫?我来教你

决定要用网络爬虫去采集数据,面临一个选择就是:是用Java还是Python写网络爬虫呢?对于一个新手,我翻阅了网上各种对比的帖子,各有各的观点,其中不少说Python上手容易,写起来方便。但最终我还是选择了Java,有以下几点原因:

1. Java火了很多年,而且依旧很火,其生态也比较完善。目前,很多大公司的系统皆采用Java设计,足以说明其强大之处。把Java学好了,足够让我找一份不错的工作,即入职大厂。

2. Java严谨规范,对于大型工程、大型程序,如果不规范不严谨维护岂不容易出问题。

3. 对网络爬虫而言,JAVA中也有很多简单易用的类库(如Jsoup、Httpclient等),同时还存在不少易于二次开发的网络爬虫框架(Crawler4J、WebMagic等)。

4. 曾在一个帖子中看到,“世界上99%的人都会选择一条容易走的大路,因为人都喜欢安逸。这也是人的大脑的思维方式决定的,因为大脑的使命是为了让你生存,而不是求知。但成功是总是属于那1%的人,这类人是坚持让大脑做不愿意做的事的人——求知”。哎,这在我看来,还真有一定的道理。如果励志想成为一名真正的程序员,建议先学习Java。在此基础上,如果你对Python感兴趣,也是可以快速上手的。

难道 Java 就玩不了爬虫?我来教你

1 网络爬虫流程

学习网络爬虫之前,先看了普通网络爬虫大致流程,如下图所示:

难道 Java 就玩不了爬虫?我来教你

主要包括5个步骤:

1. 选取部分种子URL(或初始URL),将其放入待采集的队列中。如在Java中,可以放入List、LinkedList以及Queue中。

2. 判断URL队列是否为空,如果为空则结束程序的执行,否则执行步骤3。

3. 从待采集的URL队列中取出一个URL,获取URL对应的网页内容。在此步骤需要使用HTTP响应状态码(如200和403等)判断是否成功获取到了数据,如响应成功则执行解析操作;如响应不成功,则将其重新放入待采集URL队列(注意这里需要过滤掉无效URL)。

4. 针对响应成功后获取到的数据,执行页面解析操作。此步骤根据用户需求获取网页内容中的部分字段,如汽车论坛帖子的id、标题和发表时间等。

5. 针对步骤4解析的数据,执行数据存储操作。

2 需要掌握的Java基础知识

在使用Java构建网络爬虫时,需要掌握很多Java方面的基础知识。例如,Java中基本的数据类型、Java中的数组操作、判断语句的使用、集合操作、对象和类的使用、String类的使用、日期和时间的处理、正则表达式的使用、Maven工程的创建、多线程操作、日志的使用等。

难道 Java 就玩不了爬虫?我来教你

看着知识点很多,但如果将其放入到具体的网络爬虫实战项目中去学习,会发现很简单。下面,我举两个例子。

在网络爬虫中,我们经常需要将待采集的URL放到集合中,然后循环遍历集合中的每个URL去采集数据。比如,我们使用Queue集合操作:

Queue<String> urlQueue = new LinkedList<String>();

//添加要采集的URL

urlQueue.offer("https://ccm.net/download/?page=1");

urlQueue.offer("https://ccm.net/download/?page=2");

urlQueue.offer("https://ccm.net/download/?page=3");

boolean t = true;

while (t) {

//如果队列为空,循环结束

if( urlQueue.isEmpty() ){

t = false;

}else {

//取出每个URL

String url = urlQueue.poll();

//获取HTML

String getHtml = ...;

//判断是否成功请求到HTML

if (成功请求到HTML) {

//解析数据

...;

}else { //如果网页存在但没有请求到数据,重新添加到队列中

urlQueue.offer(url);

}

}

}

另外,在采集数据时,不同网站的时间使用格式可能不同。而不同的时间格式,会为数据存储以及数据处理带来一定的困难。例如,下图为某汽车论坛中时间使用的格式,即“yyyy-MM-dd”和“yyyy-MM-dd HH:mm”两种类型。

难道 Java 就玩不了爬虫?我来教你

下图为某新闻网站中的时间使用格式“yyyy-MM-dd HH:mm:ss”。

难道 Java 就玩不了爬虫?我来教你

再如,艺术品网站deviantart的时间使用的是UNIX时间戳的形式。

难道 Java 就玩不了爬虫?我来教你

针对汽车论坛中的“yyyy-MM-dd”和“yyyy-MM-dd HH:mm”格式,可以统一转化成“yyyy-MM-dd HH:mm:ss”格式,以方便数据存储以及后期数据处理。此时,可以写个方法将将字符串类型的时间标准化成指定格式的时间。如下程序:

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class TimeTest {

public static void main(String[] args) {

System.out.println(parseStringTime("2016-05-19 19:17",

"yyyy-MM-dd HH:mm","yyyy-MM-dd HH:mm:ss"));

System.out.println(parseStringTime("2018-06-19",

"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"));

}

/**

* 字符型时间格式标准化方法

* @param inputTime(输入的字符串时间),inputTimeFormat(输入的格式),outTimeFormat(输出的格式).

* @return 转化后的时间(字符串)

*/

public static String parseStringTime(String inputTime,String inputTimeFormat,

String outTimeFormat){

String outputDate = null;

try {

//日期格式化及解析时间

Date inputDate = new SimpleDateFormat(inputTimeFormat).parse(inputTime);

//转化成新的形式的字符串

outputDate = new SimpleDateFormat(outTimeFormat).format(inputDate);

} catch (ParseException e) {

e.printStackTrace();

}

return outputDate;

}

}

针对UNIX时间戳,可以通过如下方法处理:

//将unix时间戳转化成指定形式的时间

public static String TimeStampToDate(String timestampString, String formats) {

Long timestamp = Long.parseLong(timestampString) * 1000;

String date = new SimpleDateFormat(formats,

Locale.CHINA).format(new Date(timestamp));

return date;

}

3 HTTP协议基础与网络抓包

做网络爬虫,还需要了解HTTP协议相关的内容,即要清楚数据是怎么在服务器和客户端传输的。

难道 Java 就玩不了爬虫?我来教你

具体需要了解的内容包括:

1. URL的组成:如协议、域名、端口、路径、参数等。

2. 报文:分为请求报文和响应报文。其中,请求报文包括请求方法、请求的URL、版本协议以及请求头信息。响应报文包括请求协议、响应状态码、响应头信息和响应内容。响应报文包括请求协议、响应状态码、响应头信息和响应内容。

3. HTTP请求方法:在客户端向服务器发送请求时,需要确定使用的请求方法(也称为动作)。请求方法表明了对URL指定资源的操作方式,服务器会根据不同的请求方法做不同的响应。网络爬虫中常用的两种请求方法为GET和POST。

4. HTTP状态码:HTTP状态码由3位数字组成,描述了客户端向服务器请求过程中发生的状况。常使用200判断网络是否请求成功。

5. HTTP信息头:HTTP信息头,也称头字段或首部,是构成HTTP报文的要素之一,起到传递额外重要信息的作用。在网络爬虫中,我们常使用多个User-Agent和多个referer等请求头来模拟人的行为,进而绕过一些网站的防爬措施。

6. HTTP响应正文:HTTP响应正文(或HTTP响应实体主体),指服务器返回的一定格式的数据。网络爬虫中常遇到需要解析的几种数据包括:HTML/XML/JSON。

难道 Java 就玩不了爬虫?我来教你

在开发网络爬虫时,给定 URL,开发者必须清楚客户端是怎么向服务器发送请求的,以及客户端请求后服务器返回的数据是什么。只有了解这些内容,开发者才能在程序中拼接URL,针对服务返回的数据类型设计具体的解析策略。因此,网络抓包是实现网络爬虫必不可少的技能之一,也是网络爬虫开发的起点。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。