Java 网络爬虫基础知识入门解析

前言

说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少。有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬虫而且还能做的非常好,在开源社区中有不少优秀的 Java 网络爬虫框架,例如 webmagic 。我的第一份正式工作就是使用 webmagic 编写数据采集程序,当时参与了一个舆情分析系统的开发,这里面涉及到了大量网站的新闻采集,我们就使用了 webmagic 进行采集程序的编写,由于当时不知道其设计原理,使用起来还是走了不少弯路,其实 webmagic 的设计借鉴了 Scrapy ,所以它也能像 Scrapy 一样强大,关于 webmagic 框架我们将在后续展开详细的讨论。

在后面的几年工作中,也参与了好几个爬虫项目,但是大多数都是使用 Python ,抛开语言不谈,爬虫也是有一套思想的。这些年写爬虫程序,对我个人的技术成长帮助非常大,因为在爬虫的过程中,会遇到各种各样的问题,其实做网络爬虫还是非常考验技术的,除了保证自己的采集程序可用之外,还会遇到被爬网站各种奇奇怪怪的问题,比如整个 HTML 页面有没一个 class 或者 id 属性,你要在这种页面提取表格数据,并且做到优雅的提取,这就是非常考验你的想象力以及技术啦。非常有幸在刚入行的时候就接触到了网络爬虫这一块,它加快了我对互联网的理解和认知,扩宽了我的视野。

这几年来网络爬虫比较火,如果你想学习 Java 网络爬虫,我根据我自己的经验总结了一下,想入门学习 Java 网络爬虫需要知道的四点基础知识。

1、有 “道德” 的爬虫

我为什么会把这一点放在最前面呢?因为我觉得这一点比较重要,什么叫有 “道德” 的爬虫呢?就是遵循被爬服务器的规则,不去影响被爬服务器的正常运行,不把被爬服务搞垮,这就是有 “道德” 的爬虫。

经常有人讨论的一个问题就是爬虫合法吗?知乎一下你看到的将是这样的

答案千千万,在这众多答案中,我个人比较赞同下面的这个回答

爬虫作为一种计算机技术就决定了它的中立性,因此爬虫本身在法律上并不被禁止,但是利用爬虫技术获取数据这一行为是具有违法甚至是犯罪的风险的。所谓具体问题具体分析,正如水果刀本身在法律上并不被禁止使用,但是用来捅人,就不被法律所容忍了。

爬虫为不违法?取决于你做的事情为不违法,网络爬虫的本质是什么?网络爬虫的本质是用机器代替人工去访问页面。我查看公开的新闻肯定不犯法,所以我去采集公开在互联网上的新闻也不犯法,就像各大搜索引擎网站一样,别的网站巴不得别搜索引擎的蜘蛛抓取到。另一种恰恰相反的情况是去采集别人隐私的数据,你自己去查看别人的隐私信息这就是一种违法的行为,所以用程序去采集也是违法的,这就像答案中所说的水果刀本身不违法,但是用来捅人就违法啦。

要做到有 “道德” 的爬虫,Robots 协议是你必须需要了解的,下面是Robots 协议的百度百科

在很多网站中会申明 Robots 协议告诉你哪些页面是可以抓取的,哪些页面是不能抓取的,当然 Robots 协议只是一种约定,就像公交车上的座位一样标明着老弱病残专座,你去坐了也不违法。

除了协议之外,我们的采集行为上也需要克制,在 『数据安全管理办法(征求意见稿)』的第二章第十六条指出:

网络运营者采取自动化手段访问收集网站数据,不得妨碍网站正常运行;此类行为严重影响网站运行,如自动化访问收集流量超过网站日均流量三分之一,网站要求停止自动化访问收集时,应当停止。

这条规定指出了爬虫程序不得妨碍网站正常运行,如果你使用爬虫程序把网站搞垮了,真正的访问者就不能访问该网站了,这是一种非常不道德的行为。应该杜绝这种行为。

除了数据的采集,在数据的使用上同样需要注意,我们即使在得到授权的情况下采集了个人信息数据,也千万不要去出卖个人数据,这个是法律特别指出禁止的,参见:

根据《最高人民法院 最高人民检察院关于办理侵犯公民个人信息刑事案件适用法律若干问题的解释》第五条规定,对“情节严重”的解释:

(1)非法获取、出售或者提供行踪轨迹信息、通信内容、征信信息、财产信息五十条以上的;

(2)非法获取、出售或者提供住宿信息、通信记录、健康生理信息、交易信息等其他可能影响人身、财产安全的公民个人信息五百条以上的;

(3)非法获取、出售或者提供第三项、第四项规定以外的公民个人信息五千条以上的便构成“侵犯公民个人信息罪”所要求的“情节严重”。

此外,未经被收集者同意,即使是将合法收集的公民个人信息向他人提供的,也属于刑法第二百五十三条之一规定的“提供公民个人信息”,可能构成犯罪。

2、学会分析 Http 请求

我们每一次与服务端的交互都是通过 Http 协议,当然也有不是 Http 协议的,这个能不能采集我就不知道啦,没有采集过,所以我们只谈论 Http 协议,在 Web 网页中分析 Http 协议还是比较简单,我们以百度检索一条新闻为例

我们打开 F12 调试工具,点击 NetWork 查看版能查看到所有的请求,找到我们地址栏中的链接,主链接一般存在 NetWork 最上面一条链接

在右边headers查看栏中,我们能够看到这次请求所需要的参数,在这里我们需要特别注意 Request Headers 和 Query String Parameters 这两个选项栏。

Request Headers 表示的是该次 Http 请求所需要的请求头的参数,有一些网站会根据请求头来屏蔽爬虫,所以里面的参数还是需要了解一下的,请求头参数中大部分参数都是公用的, User-Agent 和 Cookie 这两个参数使用比较频繁, User-Agent 标识浏览器请求头,Cookie 存放的是用户登录凭证。

Query String Parameters 表示该次 Http 请求的请求参数,对于post 请求来说这个还是非常重要的,因为在这里可以查看到请求参数,对我们模拟登陆等 Post 请求非常有用。

上面是网页版的 HTTP 请求的链接分析,如果需要采集 APP 里面的数据就需要借助模拟器了,因为 APP 里没有调试工具,所以只能借助模拟器,使用较多的模拟器工具有如下两种,有兴趣的可以执行研究。

  • fiddler
  • wireshark

3、学会 HTML 页面解析

我们采集的页面都是 HTML 页面,我们需要在 HTML 页面中获取我们需要的信息,这里面就涉及到了 HTML 页面解析,也就是 DOM 节点解析,这一点是重中之重,如果你不会这一点就像魔术师没有道具一样,只能干瞪眼啦。例如下面这个 HTML 页面

我们需要获取标题 “java user-agent 判断是否电脑访问” ,我们先通过 F12 检查元素

标题所在的 span 标签我已经在图中框出来啦,我们该如何解析这个节点信息呢?方法有千千万万,经常使用的选择器应该是 CSS 选择器 和 XPath ,如果你还不知道这两种选择器,可以点击下方链接学习了解一下:

CSS 选择器参考手册:https://www.w3school.com.cn/cssref/css_selectors.asp

XPath 教程:https://www.w3school.com.cn/xpath/xpath_syntax.asp

使用 CSS 选择器解析的写法为: #wgt-ask > h1 > span

使用 XPath 解析的写法为: //span[@class="wgt-ask"]

这样就获取到了 span 的节点,值需要取出 text 就好了,对于 CSS 选择器 和 XPath 除了自己编写之外,我们还可以借助浏览器来帮我们完成,例如 chrome 浏览器

只需要选中对应的节点,右键找到 Copy ,它提供了几种获取该节点的解析方式,具体的入上图所示,Copy selector 对应的就是 Css 选择器,Copy XPath 对应的是 XPath,这个功能还是非常有用的。

4、了解反爬虫策略

因为现在爬虫非常泛滥,很多网站都会有反爬虫机制,来过滤掉爬虫程序,以便保证网站的可以用,这也是非常有必要的手段,毕竟如果网站不能使用了,就没有利益可谈啦。反爬虫的手段非常多,我们来看看几种常见的反爬虫手段。

基于 Headers 的反爬虫机制

这是一种比较常见的反爬虫机制,网站通过检查 Request Headers 中的 User-Agent 、Referer 参数,来判断该程序是不是爬虫程序。要绕过这种机制就比较简单,我们只需要在网页中先查看该网站所需要的 User-Agent 、Referer 参数的值,然后在爬虫程序的 Request Headers 设置好这些参数就好啦。

基于用户行为的反爬虫机制

这也是一种常见的反爬虫机制,最常用的就是 IP 访问限制,一个 IP 在一段时间内只被允许访问多少次,如果超过这个频次的话就会被认为是爬虫程序,比如豆瓣电影就会通过 IP 限制。

对于这种机制的话,我们可以通过设置代理 IP 来解决这个问题,我们只需要从代理ip网站上获取一批代理ip,在请求的时候通过设置代理 IP 即可。

除了 IP 限制之外,还会有基于你每次的访问时间间隔,如果你每次访问的时间间隔都是固定的,也可能会被认为是爬虫程序。要绕过这个限制就是在请求的时候,时间间隔设置不一样,比例这次休眠 1 分钟,下次 30 秒。

基于动态页面的反爬虫机制

有很多网站,我们需要采集的数据是通过 Ajax 请求的或者通过 JavaScript生成的,对于这种网站是比较蛋疼的,绕过这种机制,我们有两种办法,一种是借助辅助工具,例如 Selenium 等工具获取渲染完成的页面。第二种方式就是反向思维法,我们通过获取到请求数据的 AJAX 链接,直接访问该链接获取数据。

以上就是爬虫的一些基本知识,主要介绍了网络爬虫的使用工具和反爬虫策略,这些东西在后续对我们的爬虫学习会有所帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2019-10-07

分享一个简单的java爬虫框架

反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架 可以自定义的部分有: 请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式 储存方式(默认储存在f盘的html文件夹下),可以通过SaveUtil接口来自定义保存方式 需要保存的资源(默认为整个html页面) 筛选方式(默认所有url都符合要求),通过实现ResourseChooser接口来自定义需要保存的url和资源页面 实现的部分有: html页面的下载方式,通过Htt

hadoop中实现java网络爬虫(示例讲解)

这一篇网络爬虫的实现就要联系上大数据了.在前两篇java实现网络爬虫和heritrix实现网络爬虫的基础上,这一次是要完整的做一次数据的收集.数据上传.数据分析.数据结果读取.数据可视化. 需要用到 Cygwin:一个在windows平台上运行的类UNIX模拟环境,直接网上搜索下载,并且安装: Hadoop:配置Hadoop环境,实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS,用来将收集的数据直接上传保存到HDFS,然后用MapReduce

Java 爬虫数据异步加载如何解决

这是 Java 爬虫系列博文的第三篇,在上一篇Java 爬虫如何爬取需要登录的网站,该怎么办? 中,我们简单的讲解了爬虫时遇到登录问题的解决办法,在这篇文章中我们一起来聊一聊爬虫时遇到数据异步加载的问题,这也是爬虫中常见的问题. 现在很多都是前后端分离项目,这会使得数据异步加载问题更加突出,所以你在爬虫时遇到这类问题不必惊讶,不必慌张.对于这类问题的解决办法总体来说有以下两种: 1.内置一个浏览器内核 内置浏览器就是在抓取的程序中,启动一个浏览器内核,使我们获取到 js 渲染后的页面,这样我们就

Java 网络爬虫新手入门详解

这是 Java 网络爬虫系列文章的第一篇,如果你还不知道 Java 网络爬虫系列文章,请参看Java 网络爬虫基础知识入门解析.第一篇是关于 Java 网络爬虫入门内容,在该篇中我们以采集虎扑列表新闻的新闻标题和详情页为例,需要提取的内容如下图所示: 我们需要提取图中圈出来的文字及其对应的链接,在提取的过程中,我们会使用两种方式来提取,一种是 Jsoup 的方式,另一种是 httpclient + 正则表达式的方式,这也是 Java 网络爬虫常用的两种方式,你不了解这两种方式没关系,后面会有相应

Java多线程及分布式爬虫架构原理解析

这是 Java 爬虫系列博文的第五篇,在上一篇Java 爬虫服务器被屏蔽的解决方案中,我们简单的聊反爬虫策略和反反爬虫方法,主要针对的是 IP 被封及其对应办法.前面几篇文章我们把爬虫相关的基本知识都讲的差不多啦.这一篇我们来聊一聊爬虫架构相关的内容. 前面几章内容我们的爬虫程序都是单线程,在我们调试爬虫程序的时候,单线程爬虫没什么问题,但是当我们在线上环境使用单线程爬虫程序去采集网页时,单线程就暴露出了两个致命的问题: 采集效率特别慢,单线程之间都是串行的,下一个执行动作需要等上一个执行完才能

java实现一个简单的网络爬虫代码示例

目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html).那么就在想,java有没有用户方便解析html页面呢?找到了一个jsoup包,一个非常方便解析html的工具呢. 使用方式也非常简单,引入jar包: <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.8.

Java 爬虫如何爬取需要登录的网站

这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫新手入门详解 中,我们简单的学习了一下如何利用 Java 进行网络爬虫.在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录的网站,我们该怎么办? 在做爬虫时,遇到需要登陆的问题也比较常见,比如写脚本抢票之类的,但凡需要个人信息的都需要登陆,对于这类问题主要有两种解决方式:一种方式是手动设置 cookie ,就是先在网站上面登录,复制登陆后的 cookies ,在爬虫程序中手动设置 HTTP 请求中的 Cookie 属性,这

JAVA超级简单的爬虫实例讲解

爬取整个页面的数据,并进行有效的提取信息,注释都有就不废话了: public class Reptile { public static void main(String[] args) { String url1=""; //传入你所要爬取的页面地址 InputStream is=null; //创建输入流用于读取流 BufferedReader br=null; //包装流,加快读取速度 StringBuffer html=new StringBuffer(); //用来保存读取页

python3之微信文章爬虫实例讲解

前提: python3.4 windows 作用:通过搜狗的微信搜索接口http://weixin.sogou.com/来搜索相关微信文章,并将标题及相关链接导入Excel表格中 说明:需xlsxwriter模块,另程序编写时间为2017/7/11,以免之后程序无法使用可能是网站做过相关改变,程序较为简单,除去注释40多行. 正题: 思路:打开初始Url --> 正则获取标题及链接 --> 改变page循环第二步 --> 将得到的标题及链接导入Excel 爬虫的第一步都是先手工操作一遍(

Java成员变量的隐藏(实例讲解)

一.如果子类与父类中有一个相同名称的成员变量,那么子类的成员变量会不会覆盖父类的成员变量?我们看下在的例子: public class A { public int x=10; } public class B extends A { public int x=20; } public class C { public static void main(String[] args) { A a=new B(); System.out.println(a.x); //1 B b=new B();

java RMI详细介绍及实例讲解

java本身提供了一种RPC框架--RMI(即RemoteMethodInvoke远程方法调用),在编写一个接口需要作为远程调用时,都需要继承了Remote,Remote接口用于标识其方法可以从非本地虚拟机上调用的接口,只有在"远程接口"(扩展java.rmi.Remote的接口)中指定的这些方法才可远程使用,下面通过一个简单的示例,来讲解RMI原理以及开发流程: 为了真正实现远程调用,首先创建服务端工程rmi-server,结构如下: 代码说明: 1.User.java:用于远程调用

java发送email一般步骤(实例讲解)

java发送email一般步骤 一.引入javamail的jar包: 二.创建一个测试类,实现将要发送的邮件内容写入到计算机本地,查看是否能够将内容写入: public static void main(String[] args) throws Exception { // 1. 创建一封邮件 Properties props = new Properties(); // 用于连接邮件服务器的参数配置(发送邮件时才需要用到) Session session= Session.getDefaul

java 动态生成SQL的实例讲解

代码如下: /** * 动态生成SQ及SQL参数L * @param ve 接收到的消息的CHGLIST * @param paramList MQ消息中的SQL参数 * @param t 泛型对象 * @param table 数据表 * @param list 可执行SQL语句集合 * @return */ public <T> String updateSqlAndParamList(Vector<String> ve,List<String> paramList

Scrapy爬虫实例讲解_校花网

学习爬虫有一段时间了,今天使用Scrapy框架将校花网的图片爬取到本地.Scrapy爬虫框架相对于使用requests库进行网页的爬取,拥有更高的性能. Scrapy官方定义:Scrapy是用于抓取网站并提取结构化数据的应用程序框架,可用于广泛的有用应用程序,如数据挖掘,信息处理或历史存档. 建立Scrapy爬虫工程 在安装好Scrapy框架后,直接使用命令行进行项目的创建: E:\ScrapyDemo>scrapy startproject xiaohuar New Scrapy projec

JavaScript实现简单的双色球(实例讲解)

如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>双色球</title> <link rel="stylesheet" type="text/css" href="css/twoToneClass.css" rel="e

java对象类型转换和多态性(实例讲解)

对象类型转换 分为向上转型和向下转型(强制对象转型). 向上转型是子对象向父对象转型的过程,例如猫类转换为动物类:向下转型是强制转型实现的,是父对象强制转换为子对象. 这和基础数据类型的转换是类似的,byte在需要时会自动转换为int(向上转型),int可以强制转型为byte(向下转型). 对于对象转型来说, 向上转型后子对象独有的成员将不可访问 . 意思是,在需要一只动物时,可以把猫当作一只动物传递,因为猫继承自动物,猫具有动物的所有属性.但向上转型后,猫不再是猫,而是被当作动物看待,它自己独

Java分页查询--分页显示(实例讲解)

当数据库中数据条数过多时,一个页面就不能显示,这是要设置分页查询,首先要使用的是数据库sql语句的limit条件实现分组查询 sql语句大概形式为: select * from table limit 开始索引,显示条数 用该语句就会实现分块查询,并且每页显示固定条数. 首先要实现后台分页,我们需要知道它有多少页,每页有多少行,这就需要知道一共多少行,调用sql语句时还需要知道每一页的开始索引,开始索引是根据当前页数算出来的,所以还需要知道当前页数,查询后会返回一个列表存储当前页数据.将这些属性