• 关于Java爬虫工程师(初级)应该会的技术与知识多的不再啰嗦,前辈们已经搭好框架,我们只需要站在巨人肩膀上继续前行,继续深造,不然我们会被时代淘汰的。 Java JavaScript web http、抓包 MySQL/Oracle;MongoDB ...

    关于Java爬虫工程师(初级)应该会的技术与知识

    多的不再啰嗦,前辈们已经搭好框架,我们只需要站在巨人肩膀上继续前行,继续深造,不然我们会被时代淘汰的。

    • Java
    • JavaScript
    • web
    • http、抓包
    • MySQL/Oracle;MongoDB
    • Linux/Dos
    • shell/py脚本
    • xpath/Jsoup/正则/数据处理相关的其他辅助类
    • httpClient/selenium/nodejs
    • 简单的渗透工具使用

    先直接搞几个大牛的技术文章来过过瘾:

    爬虫工程师
    经纬纵横-如何成为一名爬虫工程师?(顺带提供工作机会)
    月薪25K的爬虫工程师对爬虫的流程做了一个非常全面的总结!
    最全Python爬虫总结


    好,阅读完上面大牛的文章之后,接下来我们开始进入分析阶段:

    Java

    为什么说Java爬虫工程师一定要懂Java呢?字面上就能看出来了。
    可能会有同学说我写爬虫的话,从目前主流的写法上我应该选择哪一种语言来实现呢?不用着急,老司机已经为我们解释了一些:

    PHP, Python, Node.js 哪个比较适合写爬虫?
    爬虫 第三篇 (语言选择python还是java还是其他)

    那么从上面来看的话,简单的爬虫用nodejs、python、Java都可以。但是业务逻辑多的爬虫呢,就只能在Java于python里面选择了,其实这两个语言呢,都是面向对象的语言,选哪一个都差不多,但是根据目前成熟度来看的话还是用Java来控制好一点。

    那么Java的话,我们需要了解里面的什么内容呢?

    ~Knowledge

    1.基本语法 2.与web结合的语法 3.与数据库结合的语法
    4.正则表达式 5.maven/gradle与至少一种框架

    这么来看的话岂不是已经走的是全栈的路线了?没错,就是你想的那样,因为这本来就是需要全栈技术来实现的。工资也是相对高的。


    JavaScript

    JavaScript这个地方需要讲点什么呢?因为目前主流的爬虫都是web爬虫,所以我们也是一定要了解前端技术,因为你看到的是用户层展示的数据,这个是属于前端的。如果你抓的是后台的数据,那么你就得攻破对方的权限来连接到数据库,这个时候的爬虫呢就不是web爬虫了,而是整个数据库与整个项目的复制。当然后者是违法的,这里就不补充后者的应用了。

    那么JavaScript我们需要了解些什么呢?

    ~Knowledge

    1.ECMAScript 2.Jquery 3.Ajax
    4.webDriver Script语法 5.nodejs Script语法

    简单列举了一些内容,然后我们学习的时候应该把重点放在DOM定位上,因为我们主要看的是数据交互的地方,只需要定位到某个想要定位的标签就好,这样才能根据正则、Jsoup来抽取我们想要的数据。当然,如果你能够把定位DOM这个工作做得非常熟练了,那么你在前后端数据对接接口的时候也是非常快速的,完全可以应聘初级的前端工程师了。


    web

    关于web我想说点什么呢,就是前端技术也是需要我们去掌握的。因为前端技术变革很快,更新很快,从之前的bootstrap,到现在的react,angularjs,vue等火热的前沿技术。如果你不能够快速判断出网站使用的是什么结构式开发的话,那么你破解起来也是非常耗时的,很有可能会搞了半天无功而返。
    ok,进入我们的技术列表:

    ~Knowledge

    1.css语法 2.html布局与使用 3.快速识别前端框架
    4.与后端数据交互的语法 5.与数据库交互的语法

    在前端页面徘徊查找破解方法的时候,很多网站都会把js文件放在另外的位置,这样在调用js方法的时候比较安全。但是这并不能阻止我们的脚步,我这里想强调的调用完js之后的页面效果,与网页源代码的效果是不一样的,第二一个就是”_blank”的破解,有些网站在开发工具上删掉”_blank”之后仍然会跳到另外一标签栏显示,但是这并不妨碍我们的工作。


    http、抓包

    这里我先打一个重点号。身为一个写爬虫的人,如果我们连这个都不知道,都了解不深,那么我只能说你马上就要失业了。现在人工智能上有很多自动化的技术马上就可以使我们集体失业了,因此我们不应该被逼上绝路,而是谋求更高技术的发展,这也是为什么我会写文章的缘由吧,希望有更多志向、意向的同学在我们这些前人的经验分享基础上,让爬虫这种黑科技达到更高的水平,而不是被人工智能取代,人工智能也是有缺陷的,网上各种爬取工具也是很有限制的,一旦爬取源方把你所有的IP以及登录信息记录到黑名单上,你再怎么爬都白搭了,耗时又耗力。在数据部门工作就要讲究效率,只有有效率,才能在数据爆炸的时代突出。
    因此呢,我们要拥抱人工智能,让人工智能来为我们服务,就像OCR识别技术一样,来方便我们通行。OK,接下来讲主要部分。

    ~Knowledge

    1.http里面包含什么呢,这里就先简单列几点吧:http协议,tcp、udp、ftp传输,网络七层,图片、视频、语言传输原理等。在这里面呢,我们还需要深入了解的是cookie与session机制,这个呢就是黑客经常要catch的点。如果因为业务需求非要获取某源的信息时,那么不妨走一下物理层的数据交互。
    2.抓包技术:这个是在整个爬虫里面最最最核心的地方了,如果这个你不会,那么你根本就不配做爬虫工程师。我这里就只介绍web爬虫抓包。OK,抓的是什么呢,http request;http response;post param。这里我要列一下黑科技了,我们也不怕安全工程师来封杀软件使用,因为总会有人站出来共享的,毕竟技术已经宣传出去了。我们需要掌握的东西是什么呢,简单列几个:Anyproxy,Fiddler,Burpsuite,postman,Linux命令curl,再就是最常用的各浏览器自带的开发者工具了。

    ok,为什么我这里会列举渗透攻击所用的工具呢?因为可能在未来我们会把爬虫做得越来越大,并且会应用到分布式,这样的话就无异于DDOS攻击了,所以我们也需要参考攻击端所用的工具,并通过一定的技术手段来伪装请求。


    MySQL/Oracle;MongoDB

    说一下数据库技术,因为业务线的不同,将数据存储的位置也会不同,这里主要讲两种类型的数据库:关系型数据库MySQL/Oracle和非关系型数据库MongoDB。

    ~Knowledge

    1.SQL语法 2.MongoDB语法 3.JDBC等连接技术的语法
    4.结合框架之后的交互语法

    对于初级来说,简单的增删改查会就好,这个是我们存放数据的时候必须要掌握的。存放数据的表我们也要相应的加上业务需要的字段索引,这样方便之后的增量维护。


    Linux/Dos

    为什么会谈到这个呢?因为很多数据公司都是不差钱的,基本都是用Mac开发,那么Mac的话就可以是Mac与Windows双系统,然后我们需要应用这种计算机开发本身自带的命令来实现某些功能。当然,如果你想要建立一套分布式爬虫的话也是必须要会这个语法的,毕竟在云端的服务器是没有图形界面的。
    ok,下面来简单梳理一下需要的内容:

    ~Knowledge

    1.ssh 2.vim/edit 3.基本语法
    4.kill 5.nohup 6.tail 7.scp 8.ps

    ssh呢是远程连接用的,vim与edit来编辑文本,kill主要是杀掉需要停止的爬虫进程,nohup主要是将jar程序输出到指定的日志文件上的命令,tail来查看日志,scp是远程传输,ps主要是查看进程


    shell/py脚本

    到这里呢,假设我们已经写好了一个爬虫,然后准备执行的时候,考虑到session时效性,因此我们可能会需要写一个简单脚本来监控这个进程,多少时间后kill掉,然后多少时间后重启,这就是一个简单的定时任务,当然后期我们会应用框架来实现这个功能的。
    那这里列举就简单了:

    ~Knowledge

    1.bash shell语法
    2.python语法

    如果这里你写一个jar脚本的话是比他们两个占更多内存的,因为后期还要考虑更多的不确定性因素,所以这个脚本没必要用jar来实现。


    xpath/Jsoup/正则/数据处理相关的其他辅助类

    嗯,我想绝大多数开发都会用到这几个技术吧,毕竟这是一个既常用又强大的技术。xpath与Jsoup是用来解析html标签的,xpath还能更方便解析标签式文本,所以看个人熟练哪个就用哪个吧,当然并不是全部的网站只要精通里面一个就能解析下来的,所以还是两个都接触,没有坏处。正则就不用说了,一定要会。那么其他辅助类我这里指的是什么呢?像xxx-parser等针对数据处理诞生的辅助类,我们不妨多了解一下,说不定会有特别适合自己业务的。
    简单介绍一下里面需要掌握的技术:

    ~Knowledge

    1.xpath定位 2.Jsoup定位 3.webDriver里面的xpath定位
    4.正则里面的前中后匹配语法 5.数据清洗、数据解构相关的辅助类

    如果这种文本处理的技术你掌握了,那么我想后端或者是数据库维护的时候应该都会需要你的支持的,毕竟它们的用处很多。


    httpClient/selenium/nodejs

    这相当于爬虫来爬取页面的三种选择方式吧,可以根据业务的不同,优先级的不同来选择。也是希望全部掌握吧。
    简单介绍一下需要掌握的东西:

    ~Knowledge

    1.httpClient里面的get/post连接,response状态码及entity,SSL协议应用方式
    2.selenium自动化语法与Firefox/Phantomjs结合的语法
    3.nodejs基本语法,js请求链接与查看返回数据包的语法

    httpClient底层是由socket实现的,这种方式抓取效率会很快,当然如果你抓的网站反爬策略不严重以及服务器较好的话也可以试试nodejs。selenium这种方式因为要渲染的原因调用起来会很慢,除非是爬的数据质量很高的网站,没有更好的优化方式了,就用这个。


    简单的渗透工具使用

    为什么要强调渗透工具的使用呢,因为现在的爬虫并不是像之前那么简单了,因为反爬策略也是渐渐成熟起来,所以我们需要更强大的技术来支持下去。
    我这里就随便列几个工具吧,因为并不是每一个黑客师傅都会教人的:

    ~Knowledge

    1.nmap 2.sqlmap 3.OWASP系列
    4.metasploit 5.xss扫描与arp工具

    涉及到挖漏洞技术的时候,一般人都是先选择不公开,等待时机成熟了,才会发布出来,总之就是先利益再公益。当然我们不能拿这个来做坏事,因为我们只是在爬取上应用到了这方面的技术,毕竟是对面反爬策略惹的祸嘛,所以拿来简单利用下即可。


    ok,说了这么多,终于到最后的总结了。个人觉得初级要是掌握了上面我列举的内容的话,月薪10k肯定算是少的了。所以还是多多鼓励年轻人要敢于去尝试新技术,这样技术火花的碰撞才能更猛烈,然后我们才不至于失业,而且会有一个更高的突破—站在人工智能上的突破,毕竟我们是发明人工智能来更好的为我们服务,节约我们的时间来研究更多事情的。之后有时间的话我会继续更新新的文章的。

    展开全文
  • 今天了解了一下爬虫技术,对于java爬虫,主要有webmagic,jsoup,httpclient。这些都需要去下载jar包,要么这个包少了,要么那个包少了很麻烦,而且网上也不好下载完整版。  所以了解了爬虫技术思想后,利用java...

      今天了解了一下爬虫技术,对于java爬虫,主要有webmagic,jsoup,httpclient。这些都需要去下载jar包,要么这个包少了,要么那个包少了很麻烦,而且网上也不好下载完整版。

      所以了解了爬虫技术思想后,利用java自带的库写了一个小程序实现从网上爬图(只能爬静态网页)。

    一.分析网页源代码

     我选的是我的女神绫濑遥的图片,按F12打开网页源代码;找到图片容器。


    Error

        找到图片链接

    Error二.下载整个页面

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Pac1 {
    	static String url1="https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&fm=index&pos=history&word=%E7%BB%AB%E6%BF%91%E9%81%A5%E5%89%A7%E7%85%A7";
        public static void main(String[] args) throws FileNotFoundException {
    		File file=new File("C:\\Users\\小负子\\Pictures\\test\\123.txt");
    		try{URL url2=new URL(url1);
    		URLConnection con=url2.openConnection();
    		BufferedReader bu=new BufferedReader(new InputStreamReader(con.getInputStream()));
    		FileOutputStream fi =new FileOutputStream(file);
    		BufferedWriter bf=new BufferedWriter(new OutputStreamWriter(fi));
    		
    		while(bu.readLine() != null) {
    			String str=bu.readLine();
    			bf.write(str);
    			bf.flush();
    		}
    		bf.flush();
    		bu.close();
    		bf.close();
    		}catch (Exception e) {
    			// TODO: handle exception
    		}
    三.提取图片

    通过正则表达式:"https://ss\\d+\\.bdstatic\\.com\\S+\\.jpg",匹配图片链接,并存储到一个set集合中。

    正则表达式教程入口:http://www.runoob.com/regexp/regexp-tutorial.html

    String patter="https://ss\\d+\\.bdstatic\\.com\\S+\\.jpg";
    		BufferedReader bu1=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    		Pattern p = Pattern.compile(patter);
    		int i=0;
    		String str1=null;
    		StringBuilder str2=new StringBuilder();
    		HashSet<String> set=new HashSet<String>();
    		try {
    			while((str1=bu1.readLine())!=null) {
    				str2.append(str1);
    				
    			}
    			Matcher m = p.matcher(str2);
    			while(m.find()) {
    	        	m.start();
    	        	set.add(m.group());
    	        	i++;
    			}
    	        bu1.close();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}	
    四.下载图片

    从存储的set集合中读取图片URL并下载到本地。

    先写一张下载IO类,从set集合中取一个出来就new 一个下载类。

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    public class Matchtest {
    
    	public Matchtest(String str1,int i) throws IOException {
    		// TODO Auto-generated method stub
    		File test=new File("C:\\Users\\小负子\\Pictures\\test\\绫濑遥图片");
    		if(!test.exists()) {
    			test.mkdir();
    		}
            File file=new File("C:\\Users\\小负子\\Pictures\\test\\绫濑遥图片\\"+"第"+i+"张"+".jpg");
            URL url = null;
    		try {
    			url = new URL(str1);
    		} catch (MalformedURLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		URLConnection con = null;
    		try {
    			con = url.openConnection();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		 InputStream io=con.getInputStream();
    		FileOutputStream fi = null;
    		try {
    			fi = new FileOutputStream(file);
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		try {
    			byte[] buf = new byte[1024];
    			int len = 0;
    			while((len=io.read(buf)) != -1) {
    				
    				fi.write(buf, 0, len);
    				
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		fi.close();
    		io.close();
            
    	}
    
    }
    set集合遍历

     Iterator<String>  it = set.iterator();
    		 int cout=0;
    		while(it.hasNext()) {
    			cout++;
    			try {
    				String string=it.next().toString();
    				new Matchtest(string, cout);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}

    成果:

    Error
    收工。



    展开全文
  • 爬虫技术入门视频。另外附带有solor视频教程。我也是爬虫技术的初学者,愿大家能共同进步
  • 互联网以及移动技术的飞速发展,使得全球数据量呈现前所未有的爆炸式增长态势。例如,用户在互联网上的搜索数据、交易数据、评论数据、社交数据等。这些网络大数据蕴含着丰富的可挖掘知识,是一种极具竞争力的人造...

    引言

    互联网以及移动技术的飞速发展,使得全球数据量呈现前所未有的爆炸式增长态势。例如,用户在互联网上的搜索数据、交易数据、评论数据、社交数据等。这些网络大数据蕴含着丰富的可挖掘知识,是一种极具竞争力的人造资源。在此背景下,如何快速有效地提取并利用这些信息成为一个巨大挑战。

    这里写图片描述

    搜索引擎(如Google、百度等)的出现,使得人们能够很快的检索自己想要的信息,基本的搜索引擎包括采集数据的爬虫、索引库的管理以及搜索页面的呈现等部分。其中,网络爬虫是搜索搜索引擎不可或缺的部分,也是目前采集互联网上信息的重要方式

    #什么是网络爬虫?
    网络爬虫(Crawler)又称为机器人(Robot)或者蜘蛛(Spider),是能够自动下载网页、解析网页的程序。网络中的信息分散在数以亿计的网页中,而这些网页中的数据存储于数以百万计的服务器中。现实中的用户只需通过在浏览器中访问超链接便可以获取信息。爬虫便可以通过模拟浏览器的方式,将多个超链接对应的网页信息收集起来。

    #网络爬虫能做什么
    网络爬虫的应用有很多。笔者简单的列了以下几点:
    1.商业分析,包竞争情报分析,用户行为模式分析等。企业或研究者可利用网络爬虫收集竞争对手的情报以及潜在合作信息。同时,基于网络爬虫采集的数据,可以发掘用户感兴趣的内容(网站或产品等)、分析用户的行为偏好,进而做个性化推荐服务。
    2.舆情监控:实时、精准的采集网络数据,发掘用户讨论的内容以及用户行为、实行事件监测与预警、研判事件走势、引导舆情走向。
    3.搜索引擎:爬虫最广泛的应用便是搜索引擎,基于网络爬虫采集的网页,可被搜索引擎用来构建索引。Nutch 便是一个开源Java实现的搜索引擎。它提供了搜索引擎所需的全部工具。包括全文搜索和分布式网络爬虫
    4**.科研工作者的必备技术**:现有很多研究都以网络大数据为基础,而采集网络大数据的必备技术便是网络爬虫。
    5.开发有趣的小应用:就个人而言,网络爬虫可以做很多有趣的事情。例如,使用网络爬虫的模拟登陆抢电商平台的优惠券(尤其是京东的12期免息券、24期免息券);基于爬取的数据做可视化分析,如用户关注的特征(云图分析、网络结构分析等)。

    这里写图片描述

    怎么入门网络爬虫

    作为网络爬虫初学者,首先要掌握网络爬虫的原理以及逻辑。其次,掌握网络爬虫涉及到的编程基础知识(无论是Java还是Python网络爬虫),基础很重要,基础不牢,地动山摇。在掌握基础知识的同时,不断的进行实战。在实战过程中,不可轻易自满,以为爬了几个网站就掌握了。虽然网络爬虫的原理及逻辑较为简单,当深入学习会发现涉及的知识相当多(例如,模拟登陆、破解加密、反扒处理、多线程采集、分布式采集、搜索引擎等),需要在实战中不断的专研。
    为帮助初学网络爬虫的学生或学者,作者以Java语言为例,做了一套详细的课程讲解——《Java网络爬虫基础教学》。本课程共包含14课,五大部分:
    第一部分(第01-03课):介绍网络爬虫的原理、开发逻辑以及 Java 网络爬虫基础知识,网络抓包等内容。
    第二部分(第04-06课):介绍现有的一些页面内容获取及页面解析工具。包括 Jsoup、HttpClient、URLConnection。
    第三部分(第07-08课):针对已获得的页面内容,带大家选择合适的解析工具进行页面解析,包括 HTML、XML、JSON 主流数据格式的解析(HtmlCleaner、Htmlparser 、fastjson等一系列工具的使用)。
    第四部分(第09-11课),针对已解析的内容,介绍如何封装数据并存储数据。包括通过 MySQL 数据库存储数据,以及文本文件存储和 Excel 格式存储。
    第五部分(第12-14课),以典型网站为案例,开启实战演练。
    课程地址https://gitbook.cn/gitchat/column/5b39d79c38f746186a4ecb91

    这里写图片描述

    课程特色

    1.注重基础知识的讲解以及理解:清晰的阐释了网络爬虫的原理以及开发逻辑,详细的介绍了Java 网络爬虫基础知识,强调知其然又知其所以然。
    2.内容结构清晰:根据网络爬虫的开发逻辑,作者设计了清晰了课程结构。具体的包括:网络爬虫原理,网络抓包,网页内容获取,网页内容解析,数据存储。
    3.注重实战,提供源码式学习:在讲解过程中,以具体的网页为案例,实战网络爬虫。并且在提供的核心源码中,作者给出了详细的注释。

    学完本课程能收获什么

    学完本课程,按照课程提供的案例,你将深入理解网络爬虫的原理以及开发逻辑,包括具体的网络爬虫Java开发的基础知识(如集合的使用、maven工程的构建等)、网页请求、网页解析、网页存储以及在网络爬虫开发中遇到的问题(头信息的设置、代理的使用等)。针对一些网站,学完本课程的学生,可以轻松的采集到这些网站的数据。
    学任何一门技术,都该带着目标去学习,有目标的学习才不容易放弃。通过网络爬虫的学习,可以帮助大家入门及掌握一门开发语言,如本课程的Java。再者,学习网络爬虫技术,也会增加大家的就业机会。
    这里写图片描述

    展开全文
  • Java爬虫从入门到精通

    2019-03-14 10:28:14
    本课程是java大数据系列课程的数据采集部分,通过java爬虫技术从互联网进行在线数据采集,存储。对于本课程学习要求具有一定的java编程基础。通过本课的学习,能够掌握爬虫技术原理,数据采集的原则,数据采集的方式...
  • 课程介绍 大数据环境下,数据分析已由业务驱动转变为数据驱动,网络数据...作为网络爬虫的入门教程,本达人课采用 Java 开发语言,内容涵盖了网络爬虫的原理以及开发逻辑,Java 网络爬虫基础知识,网络抓包介绍,...

    课程介绍

    大数据环境下,数据分析已由业务驱动转变为数据驱动,网络数据资源呈指数级增长,且散落在不同的数据源之中。对大多数企业和研究者而言,用“数据说话”仿佛成了大数据时代的重要武器。网络爬虫作为网络数据获取的重要技术,受到了越来越多数据需求者的青睐和追捧。

    作为网络爬虫的入门教程,本达人课采用 Java 开发语言,内容涵盖了网络爬虫的原理以及开发逻辑,Java 网络爬虫基础知识,网络抓包介绍,jsoup 的介绍与使用,HttpClient 的介绍与使用等内容。本课程在介绍网络爬虫基本原理的同时,注重具体的代码实现,加深读者对爬虫的理解,加强读者的实战能力。

    本达人课共计14课,主要包含五大部分。

    第一部分(第01-03课),主要介绍网络爬虫的原理、开发逻辑以及 Java 网络爬虫基础知识,网络抓包等内容。

    第二部分(第04-06课),主要介绍现有的一些页面内容获取及页面解析工具。包括 jsoup、HttpClient、URLConnection。

    第三部分(第07-08课),针对已获得的页面内容,带大家选择合适的解析工具进行页面解析,包括 HTML、XML、JSON 主流数据格式的解析。

    第四部分(第09-11课),针对已解析的内容,介绍如何封装数据并存储数据。包括通过 MySQL 数据库存储数据,以及文本文件存储和 Excel 格式存储。

    第五部分(第12-14课),以典型网站为案例,开启实战演练。

    作者介绍

    钱洋,机器学习方向博士生,CSDN 博客专家,主要从事文本挖掘方面的研究。目前,正参与几个大数据相关项目的研究工作。乐于分享自己的经验,擅长撰写技术类博客。

    课程内容

    第01课:网络爬虫原理

    引言

    随着互联网的迅速发展,网络资源越来越丰富,信息需求者如何从网络中抽取信息变得至关重要。目前,有效的获取网络数据资源的重要方式,便是网络爬虫技术。简单的理解,比如您对百度贴吧的一个帖子内容特别感兴趣,而帖子的回复却有1000多页,这时采用逐条复制的方法便不可行。而采用网络爬虫便可以很轻松地采集到该帖子下的所有内容。

    网络爬虫技术最广泛的应用是在搜索引擎中,如百度、Google、Bing 等,它完成了搜索过程中的最关键的步骤,即网页内容的抓取。下图为简单搜索引擎原理图。

    这里写图片描述

    网络爬虫的作用,我总结为以下几点:

    • 舆情分析:企业或政府利用爬取的数据,采用数据挖掘的相关方法,发掘用户讨论的内容、实行事件监测、舆情引导等。
    • 企业的用户分析:企业利用网络爬虫,采集用户对其企业或商品的看法、观点以及态度,进而分析用户的需求、自身产品的优劣势、顾客抱怨等。
    • 科研工作者的必备技术:现有很多研究都以网络大数据为基础,而采集网络大数据的必备技术便是网络爬虫。利用网络爬虫技术采集的数据可用于研究产品个性化推荐、文本挖掘、用户行为模式挖掘等。

    网络爬虫涉及的领域包括:

    这里写图片描述

    网络爬虫的基本概念

    网络爬虫(Web Crawler),又称为网络蜘蛛(Web Spider)或 Web 信息采集器,是一种按照一定规则,自动抓取或下载网络信息的计算机程序或自动化脚本,是目前搜索引擎的重要组成部分。

    • 狭义上理解:利用标准的 HTTP 协议,根据网络超链接(如https://www.baidu.com/)和 Web 文档检索的方法(如深度优先)遍历万维网信息空间的软件程序。

    • 功能上理解:确定待爬的 URL 队列,获取每个 URL 对应的网页内容(如 HTML/JSON),解析网页内容,并存储对应的数据。

    网络爬虫的分类

    网络爬虫按照系统架构和实现技术,大致可以分为以下几种类型:通用网络爬虫(General Purpose Web Crawler)、聚焦网络爬虫(Focused Web Crawler)、增量式网络爬虫(Incremental Web Crawler)、深层网络爬虫(Deep Web Crawler)。实际的网络爬虫系统通常是几种爬虫技术相结合实现的。

    • 通用网络爬虫:爬行对象从一些种子 URL 扩充到整个 Web,主要为门户站点搜索引擎和大型 Web 服务提供商采集数据

      通用网络爬虫的爬取范围和数量巨大,对于爬行速度和存储空间要求较高,对于爬行页面的顺序要求较低,通常采用并行工作方式,有较强的应用价值。

    • 聚焦网络爬虫,又称为主题网络爬虫:是指选择性地爬行那些与预先定义好的主题相关的页面。

      和通用爬虫相比,聚焦爬虫只需要爬行与主题相关的页面,极大地节省了硬件和网络资源,保存的页面也由于数量少而更新快,可以很好地满足一些特定人群对特定领域信息的需求。

      通常在设计聚焦网络爬虫时,需要加入链接和内容筛选模块。一个常见的案例是基于关键字获取符合用户需求的数据,如下图所示:

      这里写图片描述

    • 增量网络爬虫:对已下载网页采取增量式更新和只爬行新产生的或者已经发生变化网页的爬虫,它能够在一定程度上保证所爬行的页面是尽可能新的页面,历史已经采集过的页面不重复采集。

      增量网络爬虫避免了重复采集数据,可以减小时间和空间上的耗费。通常在设计网络爬虫时,需要在数据库中,加入时间戳,基于时间戳上的先后,判断程序是否继续执行。

      常见的案例有:论坛帖子评论数据的采集(如下图所示论坛的帖子,它包含400多页,每次启动爬虫时,只需爬取最近几天用户所发的帖子);天气数据的采集;新闻数据的采集;股票数据的采集等。

      这里写图片描述

    • Deep Web 爬虫:指大部分内容不能通过静态链接获取,只有用户提交一些表单信息才能获取的 Web 页面。例如,需要模拟登陆的网络爬虫便属于这类网络爬虫。另外,还有一些需要用户提交关键词才能获取的内容,如京东淘宝提交关键字、价格区间获取产品的相关信息。

      这里写图片描述

    网络爬虫的流程

    网络爬虫基本流程可用下图描述:

    这里写图片描述

    具体流程为:

    1. 需求者选取一部分种子 URL(或初始 URL),将其放入待爬取的队列中。如在 Java 网络爬虫中,可以放入 LinkedList 或 List 中。
    2. 判断 URL 队列是否为空,如果为空则结束程序的执行,否则执行第三步骤。
    3. 从待爬取的 URL 队列中取出待爬的一个 URL,获取 URL 对应的网页内容。在此步骤需要使用响应的状态码(如200,403等)判断是否获取数据,如响应成功则执行解析操作;如响应不成功,则将其重新放入待爬取队列(注意这里需要移除无效 URL)。
    4. 针对已经响应成功后获取到的数据,执行页面解析操作。此步骤根据用户需求获取网页内容里的部分数据,如汽车论坛帖子的标题、发表的时间等。
    5. 针对3步骤已解析的数据,将其进行存储。

    网络爬虫的爬行策略

    一般的网络爬虫的爬行策略分为两种:深度优先搜索(Depth-First Search)策略、广度优先搜索(Breadth-First Search)策略

    • 深度优先搜索策略:从根节点的 URL 开始,根据优先级向下遍历该根节点对应的子节点。当访问到某一子节点 URL 时,以该子节点为入口,继续向下层遍历,直到没有新的子节点可以继续访问为止。接着使用回溯的方法,找到没有被访问到的节点,以类似的方式进行搜索。下图给出了理解深度优先搜索的一个简单案例:

      这里写图片描述

    • 广度优先搜索策略:也称为宽度优先,是另外一种非常有效的搜索技术,这种方法按照层进行遍历页面。下图可帮助理解广度优先搜索的遍历方式:

      这里写图片描述

    基于广度优先的爬虫是最简单的爬取网站页面的方法,也是目前使用较为广泛的方法。在本达人课中,所讲的案例皆为宽度优先式的爬虫。

    学习建议

    网络爬虫是入门某一门编程语言的实战技术:很多学习编程语言(如 Java、Python 或 C++ 等)的同学,采用的方式只看书或在网络上看一些视频,而这将导致的后果就是面对一个具体项目时,不知道如何上手,尤其对新手而言。或者,一段时间后,就将之前的书本内容或视频内容遗忘了。

    为此,我建议这些学习者可采用网络爬虫技术入门某一门编程语言(如 Java、Python)。因为爬虫技术是个综合性很强的技术,涉及到编程语言的很多方面。本达人课特别选用了 Java 作为开发语言,将带大家深入了解 Java 网络爬虫背后的核心技术。学完该课程,相信您也已很好地入门 Java 编程语言。

    对于零基础入门 Java 网络爬虫的同学,在学习过程中请注意以下几点:

    • 理解爬虫的基本原理。
    • 学习 Java 网络爬虫涉及的基础知识:基础不牢,地动山摇,学习和掌握网络爬虫的基础知识很重要。
    • 吃透基本的爬虫代码,并在此基础上进行改写。
    • 不断实战,发现爬虫中涉及的新问题,并解决问题。

    最后,提供一些书籍和资料,给入门以及想深入学习 Java 网络爬虫的读者:

    1. 《Java面向对象程序设计》(耿祥义、张跃平编著),由清华大学出版社出版,这是大学的教材,可作为基础学习。
    2. 《Java核心技术》全2册。
    3. 《Effective Java (3rd Edition)》:目前英文版已是第三版,中文版还在第二版,该书是 Java 进阶必备之书,英文比较好的同学可直接看英文版。
    4. 《自己动手写网络爬虫》(罗刚编著),国内第一本专门讲解 Java 网络爬虫的书籍。

    参考文献

    1. 周立柱,林玲.聚焦爬虫技术研究综述[J].计算机应用,2005(09):1965-1969.
    2. 段平.面向web文本挖掘的主题搜索技术研究[D].西安电子科技大学,2008.
    3. 孙立伟, 何国辉, 吴礼发. 网络爬虫技术的研究[J]. 电脑知识与技术, 2010 (15): 4112-4115.
    第02课:Java 网络爬虫基础知识

    引言

    Java 网络爬虫具有很好的扩展性可伸缩性,其是目前搜索引擎开发的重要组成部分。例如,著名的网络爬虫工具 Nutch 便是采用 Java 开发,该工具以 Apache Hadoop 数据结构为依托,提供了良好的批处理支持。

    Java 网络爬虫涉及到 Java 的很多知识。本篇中将会介绍网络爬虫中需要了解的 Java 知识以及这些知识主要用于网络爬虫的哪一部分,具体包括以下内容:

    • Maven 的使用;
    • log4j 的使用;
    • 对象的创建;
    • 集合的使用;
    • 正则表达式的使用;
    • HTTP 状态码;
    • 其他。

    Maven 的使用

    Maven 是什么

    Maven 是由 Apache 软件基金会所提供一款工具,用于项目管理及自动构建。我们知道在构建一个 Java 工程时,需要使用到很多 Jar 包,例如操作数据库需要使用到 mysql-connector-java 以及其相关依赖的 Jar 包。而 Maven 工具便可以很方便的对我们在项目中使用到的开源 Jar 包,进行很好的管理,比如下载某 Java 工程需要的 Jar 包及相关依赖 Java 包。

    Maven 如何使用

    Maven 使用项目对象模型(Project Object Model,POM)来配置,项目对象模型存储在名为 pom.xml 的文件中。以 Java 为例,我们可以在 Eclipse 中创建一个 Maven 工程。其中,Maven Dependencies 便存放着由 Maven 管理的 Jar 包。

    这里写图片描述

    正如前面所说,构建一个 Java 工程需要使用很多 Jar 包,比如,在 Java 网络爬虫中,我们需要用到数据库连接、请求网页内容、解析网页内容的相关 Jar 包时,我们可以在上图所示的 pom 文件中添加如下语句:

    <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>5.1.35</version></dependency><dependency>    <groupId>org.jsoup</groupId>    <artifactId>jsoup</artifactId>    <version>  1.8.2</version></dependency><dependency>    <groupId>org.apache.httpcomponents</groupId>    <artifactId>httpclient </artifactId>    <version>  4.2.3</version></dependency>

    之后,我们会惊讶地发现,工程的 Maven Dependencies 中自动下载了相关 Jar 包以及其依赖的 Jar 包。

    这里写图片描述

    读者可以在 Maven Repository 网站中检索自己想要的 Jar 包,以及 Maven 操作语句。

    这里写图片描述

    log4j 的使用

    log4j 是什么

    log4j 是一个基于 Java 的日志记录工具,曾是 Apache 软件基金会的一个项目。目前,日志是应用软件中不可或缺的部分。

    log4j 怎么使用

    1. 使用 Maven 下载 log4j 的 Jar 包,代码如下:

    <dependency>    <groupId>log4j</groupId>    <artifactId>log4j</artifactId>    <version>1.2.17</version></dependency>

    2. 在 src 目录下创建 log4j.properties 文本文件,并做相关配置(关于每个配置的具体含义,读者可参考博文 《详细的 Log4j 使用教程》):

     ### 设置###log4j.rootLogger = debug,stdout,D,E### 输出信息到控制抬 ###log4j.appender.stdout = org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target = System.outlog4j.appender.stdout.layout = org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n### 输出DEBUG 级别以上的日志到=error.log ###log4j.appender.D = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.D.File = E://logs/log.loglog4j.appender.D.Append = truelog4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayoutlog4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n### 输出ERROR 级别以上的日志到=error.log ###log4j.appender.E = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.E.File =E://logs/error.log log4j.appender.E.Append = truelog4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayoutlog4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

    3. 实例程序,如下所示:

    package log4j;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;public class Test {    static final Log logger = LogFactory.getLog(Test.class);    public static void main(String[] args) {        System.out.println("hello");        logger.info("hello world");        logger.debug("This is debug message.");         logger.warn("This is warn message.");        logger.error("This is error message.");      }}

    基于此程序,我们就可以看到在我们工程的根目录下会产生一个日志文件 error.log 和 log.log。

    这里写图片描述

    在网络爬虫中,我们可以使用日志记录程序可能出错的地方,监控程序的运行状态。

    对象的创建

    在 Java 中,经常使用 new 关键字来创建一个对象。例如,在爬取京东商品的id、product_name(商品名称)、price(价格)时,我们需要将每个商品的信息封装到对象里。

    JdInfoModel jingdongproduct = new JdInfoModel();

    在爬虫中,我们要操作 JdInfoModel 类中的变量(即id、product_name、price),可以使用 private 变量定义的方式。并且,使用 set() 与 get() 方法对数据进行设置(爬取数据的封装)和获取使用(爬取数据的存储)。下面的代码为 JdInfoModel 类:

    package model;public class JdInfoModel {    private int id;    private String product_name;    private double price;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getProduct_name() {        return product_name;    }    public void setProduct_name(String product_name) {        this.product_name = product_name;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    } }

    集合的使用

    网络爬虫离不开对集合的操作,这里涉及到 List、Set、Queue、Map 等集合的操作。

    List 和 Set 集合的使用

    List 的特征是其元素以线性方式存储,集合中可以存放重复对象。对比而言,Set 集合中的对象不按特定的方式排序,并且没有重复对象。在网络爬虫中,可以使用 List<String> 存储待爬的 URL 列表。例如:

    //List集合的创建List<String> urllist = new ArrayList<String>();urllist.add("https://movie.douban.com/subject/27608425");urllist.add("https://movie.douban.com/subject/26968024");//第一种遍历方式for( String url : urllist ){    System.out.println(url);}//第二种遍历方式for( int i=0; i<urllist.size(); i++ ){    System.out.println(i+":"+urllist.get(i));}//第三种遍历方式Iterator<String> it = urllist.iterator();while ( it.hasNext() ){    System.out.println(it.next());}

    同时我们也可以使用上面 List<JdInfoModel> 来封装具体的实例,即爬虫所采集到的数据。Set 集合的使用与 List 集合类似,这里就不过多讲解了。

    Map 的使用

    Map 是一种把键对象和值对象进行映射的集合,它的每一个元素都包含一对键对象和值对象,其中键对象不可以重复。Map 不仅在网络爬虫中常用,也常在文本挖掘算法的编写中使用。在网络爬虫中,可以使用 Map 过滤一些重复数据,但并建议使用 Map 对大规模数据去重过滤,原因是 Map 有空间大小的限制。比如,使用网络爬虫爬取帖子时,可能遇到置顶帖,而置顶帖可能会与下面的帖子重复出现。以下程序为 Map 的使用案例:

     //Map的创建Map<String,Integer> map = new HashMap<String,Integer>();//值的添加,这里假设是爬虫中的产品id以及每个产品id对应的销售量map.put("jd1515", 100);map.put("jd1516", 300);map.put("jd1515", 100);map.put("jd1517", 200);map.put("jd1518", 100);//第一种方法遍历for (String key : map.keySet()) {      Integer value = map.get(key);      System.out.println("Key = " + key + ", Value = " + value);  }  //第二种方法遍历Iterator<Entry<String, Integer>> entries = map.entrySet().iterator();  while (entries.hasNext()) {      Entry<String, Integer> entry = entries.next();      System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  }  //第三种方法遍历for (Entry<String, Integer> entry : map.entrySet()) {      System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  }  

    Queue 的使用

    队列(Queue)使用链表结构存储数据,是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。LinkedList 类实现了 Queue 接口,因此我们可以把 LinkedList 当成 Queue 来用。Queue 常用来存待爬 URL 队列。

    Queue<String> queue = new LinkedList<String>();//添加元素queue.offer("https://www.douban.com/people/46077896/likes/topic/");queue.offer("https://www.douban.com/people/1475408/likes/topic");queue.offer("https://www.douban.com/people/3853295/likes/topic/");boolean t = true;while (t) {    //如果Url队列为空,停止执行程序,否则请求Url    if( queue.isEmpty() ){        t = false;    }else {        //请求的url        String url = queue.poll();        System.out.println(url);        //这里要写请求数据,获取相应状态码,如果状态码为200,则解析数据;如果为404,url移除队列;否则该url重新如列    }

    正则表达式的使用

    正则表达式,是在解析数据(HTML 或 JSON 等)时,常用的方法。举个列子,我想从下面的语句中提取用户的 id(75975500):

    <a href="//i.autohome.com.cn/75975500" target="_blank" class="linkblack">尊少来自沈阳</a>

    后面,我会介绍解析工具 jsoup,其可以解析获得“//i.autohome.com.cn/75975500”。接着,便可以使用正则表达式提取 75975500。

    String url = "//i.autohome.com.cn/75975500";String user_id = url.replaceAll("\\D", "");  //取代所有的非数字字符System.out.println(user_id);  //输出的结果即为75975500

    如下表所示,是 Java 中一些常用的基本正则表达式。

    正则表达式写法含义
    \d代表0-9的任意数字
    \D代表任何非数字字符
    \s代表空格类字符
    \S代表非空格类字符
    \p{Lower}代表小写字母[a-z]
    \p{Upper}代表大写字母[A-Z]
    \p{Alpha}代表字母
    \p{Blank}代表空格或制表符

    HTTP 状态码

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(Server Header)用以响应浏览器的请求。在网络爬虫向后台请求一个 URL 地址时,便会返回状态码,该状态码中包含丰富的信息。例如,200表示请求成功,成功获取到了后台传的数据(HTML 或 JSON 等);301资源(网页等)被永久转移到其它 URL;404请求的资源(网页等)不存在等。以下是 HTTP 状态码的分类。

    分类描述
    1**信息,服务器收到请求,需要请求者继续执行操作。
    2**成功,操作被成功接收并处理。
    3**重定向,需要进一步的操作以完成请求。
    4**客户端错误,请求包含语法错误或无法完成请求。
    5**服务器错误,服务器在处理请求的过程中发生了错误。

    详细的 HTTP 状态码列表,读者可以参考这个地址

    其他

    另外,网络爬虫还涉及到其他方面的 Java 知识,比如说Java 输入输出流、Java 操作数据库、Java 多线程操作、Java 对日期的处理、Java 中的接口与继承。所以,以网络爬虫,入门 Java 编程是非常好的方式。在后面的课程中,我会介绍网络爬虫如何使用这些技术。

    参考内容

    1. 最详细的 Log4j 使用教程
    2. HTTP 状态码
    第03课:数据是如何请求的(网络抓包)
    第04课:网页内容获取工具 jsoup
    第05课:网页内容获取工具 HttpClient
    第06课:网页内容获取工具 URLConnection
    第07课:HTML 和 XML 数据的分析与解析
    第08课:JSON 数据的分析与解析
    第09课:数据存储方式之 MySQL
    第10课:数据存储方式之 TXT 文本
    第11课:数据存储方式之 Excel
    第12课:网络爬虫实战项目(一)
    第13课:网络爬虫实战项目(二)
    第14课:网络爬虫实战项目(三)

    阅读全文: http://gitbook.cn/gitchat/column/5b39d79c38f746186a4ecb91

    展开全文
  • 最近由于工作的需要,独自开始研究爬虫爬取互联网数据;...爬虫技术不是很成熟,如果能有大佬能够不吝赐教那就更好啦~在网上找了许多资料,爬虫工具大多是用python实现的;因为本身是学java出身,虽说python比ja...

    最近由于工作的需要,独自开始研究爬虫爬取互联网数据;经过两周左右的探究,踩过许多坑,也学习到了许多以往不知道的知识。

    一直都在做伸手党,很是惭愧_(:_」∠)_感觉都要脸红了☺,在这里总结一下经验,顺便分享给大家,希望可以帮助到有需要的朋友。爬虫技术不是很成熟,如果能有大佬能够不吝赐教那就更好啦~

    在网上找了许多资料,爬虫工具大多是用python实现的;因为本身是学java出身,虽说python比java容易,但也没更多时间去学习新的语言了。最终还是选择了用java来实现,废话不多说⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄下面进入正题。

    本篇爬虫技术分享是用java+selenium+phantomjswindows环境中运行,实现了爬取百度的搜索结果。

    首先借用网络上的资料来介绍下两个小工具:

    selenium

    Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Mozilla Suite等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建衰退测试检验软件功能和用户需求。支持自动录制动作和自动生成。Net、Java、Perl等不同语言的测试脚本。Selenium 是ThoughtWorks专门为Web应用程序编写的一个验收测试工具。

    selenium的使用:

    maven配置好就可以自动下载,配置如下

    <dependency>

    <groupId>org.seleniumhq.selenium</groupId>

    <artifactId>selenium-java</artifactId>

    <version>2.48.0</version>

    </dependency>

    自动下载了以下jar包,只用到部分

    selenium-java-2.48.0.jar

    selenium-chrome-driver-2.48.0.jar

    selenium-remote-driver-2.48.0.jar

    selenium-edge-driver-2.48.0.jar

    selenium-htmlunit-driver-2.48.0.jar

    selenium-firefox-driver-2.48.0.jar

    selenium-ie-driver-2.48.0.jar

    selenium-safari-driver-2.48.0.jar

    selenium-support-2.48.0.jar

    selenium-leg-rc-2.48.0.jar


    如需直接使用jar包请去seleniumhq.org/download 官网中下载。

    官网被墙可以移步这里下载selenium-release.storage.googleapis.com

    selenium的使用一般搭配浏览器驱动,这里提供chrome浏览器驱动的下载地址chromedriver.storage.googleapis.com

    selenium使用中可能会遇到的调用报错的问题,很大的原因是浏览器驱动与浏览器不兼容,以下是chrome浏览器驱动与浏览器兼容的版本对应关系表,根据本地的chrome浏览器下载对应版本的chromedriver

    下载完后把压缩包中的chromedriver.exe放入正常的谷歌浏览器安装目录,与chrome.exe同目录中就可以了


    phantomjs

    (1)一个基于webkit内核的无头浏览器,即没有UI界面,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现。

    (2)提供JavaScript API接口,即通过编写js程序可以直接与webkit内核交互,在此之上可以结合Java语言等,通过java调用js等相关操作,从而解决了以前c/c++才能比较好的基于webkit开发优质采集器的限制。

    (3)提供windows、Linux、mac等不同os的安装使用包,也就是说可以在不同平台上二次开发采集项目或是自动项目测试等工作。

    phantomjs 的官网api——API | PhantomJS


    phantomjs的使用:


    phantomjs官网下载地址phantomjs.org/download.

    下载完后是一个压缩包,直接解压即可,解压完后把phantomjs的bin路径配置到系统环境变量path中,配置完后cmd测试出现以下信息则已经可以使用

    本篇中的爬虫,整体流程比较简单,细节部分需要多多注意,源码中都有注释,大致如下:

    类中导包信息

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import org.apache.commons.io.FileUtils;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.openqa.selenium.By;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import jxl.Cell;
    import jxl.Sheet;
    import jxl.Workbook;
    

    流程开始

    1.首先读取excel文件,读取excel中的搜索条件

    贴出源码:

    	public static List<String> readExcel(String excelFilePath){
    		List<String> contents = new ArrayList<String>();
                    InputStream in = null;
    		try {
    		// 1、构造excel文件输入流对象  
    	        in = new FileInputStream(excelFilePath);  
    	        // 2、声明工作簿对象  
    	        Workbook rwb = Workbook.getWorkbook(in);  
    	        // 3、获得工作簿的个数,对应于一个excel中的工作表个数  
    	        rwb.getNumberOfSheets(); 
    	        
    	        // 使用索引形式获取第一个工作表,也可以使用rwb.getSheet(sheetName);其中sheetName表示的是工作表的名称
    	        Sheet oFirstSheet = rwb.getSheet(0);  
    	        int rows = oFirstSheet.getRows();//获取工作表中的总行数,排除第一行
    	        int columns = oFirstSheet.getColumns();//获取工作表中的总列数 
    	        for (int i = 1; i < rows; i++) {  
    	            for (int j = 0; j < columns; j++) {  
    	                Cell oCell = oFirstSheet.getCell(j,i);//需要注意的是这里的getCell方法的参数,第一个是指定第几列,第二个参数才是指定第几行
    	                String companyName = oCell.getContents();
    	                
    	                //判断当前文件夹是否已存在(已经完成爬取),如存在则不加入爬取列表中
    	                String txtUrl = ThirdPartyProperties.FILEPROFIX + companyName + "/result";//文件路径
    	                
    	                File file = new File(txtUrl);
    			File fileParent = file.getParentFile();
    			//文件路径存在则跳过
    			if(fileParent.exists()){
    				log.info(companyName+"-已经爬取完成,不再加入爬取列表中");
    			}else{
    				contents.add(companyName);
    			}
    	            }  
    	        }
    		} catch (Exception e) {
    			log.error(e.getMessage(),e);
    		} finally {
    			if(null != in){
    				try {
    					in.close();
    				} catch (Exception e2) {
    					log.error(e2.getMessage(),e2);
    				}
    			}
    		}
    		return contents;
    	}
    

    2.使用selenium调用chrome浏览器访问百度,获取到页面元素后模拟输入搜索条件并且百度一下进入搜索结果页,并且获取前count条查询结果的url

    贴出源码:

           public static String[] getLinkBySelenium(String keyWord, int count){
    		WebDriver driver = null;
    		String[] url = new String[count];
    		try {
    		// 设置 ie 的路径  
    //	        System.setProperty("webdriver.ie.driver", "C:\\Program Files\\Internet Explorer\\IEDriverServer.exe");
    		// 设置 chrome 的路径  
    	        System.setProperty("webdriver.chrome.driver", "你浏览器驱动的全路径");
    	        // 创建一个 ie 的浏览器实例  
    //	        driver = new InternetExplorerDriver();
    	        // 创建一个 chrome 的浏览器实例
    	        driver = new ChromeDriver();
    		//最大化
    		driver.manage().window().maximize();
    		//访问百度
    		driver.get("http://www.baidu.com");
    		//根据页面元素 xpath ,右键元素可获取//*[@id="kw"],这是百度的输入框
    		WebElement element = driver.findElement(By.xpath("//*[@id=\"kw\"]"));
    		element.sendKeys(keyWord);
    		//根据id获取元素 su ,百度一下的按钮
    		element = driver.findElement(By.id("su"));
    		//点击
    		element.click();
    			
    		//等待5秒,等第count条查询结果加载完
    		WebDriverWait wait = new WebDriverWait(driver, 5);
    			
    	        //等待搜索结果加载完毕,如果报错,说明等待时间过长或者没有搜索结果(百度搜索结果div主键为1,2,3...)
    	        try {
    		        wait.until(ExpectedConditions.presenceOfElementLocated(By.id(count+"")));
    		} catch (Exception e) {
    			log.error(keyWord+",该公司百度超时或没有"+count+"条搜索结果---");
    		}
    	        /**截图保存*/
    	        //截图路径
    	        String imageUrl = "你要保存截图的路径" + keyWord + "/screenshot.png";//截图路径
    	        //指定了OutputType.FILE做为参数传递给getScreenshotAs()方法,其含义是将截取的屏幕以文件形式返回。
    	        File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    	        //利用FileUtils工具类的copyFile()方法保存getScreenshotAs()返回的文件对象。
    	        FileUtils.copyFile(srcFile, new File(imageUrl));
    			
    	        for (int i = 1; i <= count; i++) {
    	        	//获取页面加载的第一条搜索结果
    			WebElement div = driver.findElement(By.id(i+"")).findElement(By.tagName("h3")).findElement(By.tagName("a"));
    			//部分公司百度没有搜索结果,在此跳出处理
    			if(null == div){
    				continue;
    			}
    			url[i-1] = div.getAttribute("href");
    			}
    			
    		} catch (Exception e) {
    			log.error(e.getMessage(),e);
    		} finally {
    			//关闭浏览器(这个包括驱动完全退出,会清除内存),close 是只关闭浏览器
    			driver.quit();
    		}
    		return url;
    	}
    

    3.调用phantomjs访问获取到的url,截图,并通过输入流拿回需要的数据,写入文件保存本地。

    贴出源码:

    public static void getParseredHtml2(String companyName, String[] url) throws IOException {
    
    		//获取本地项目路径并处理(windows环境下)
    		String projectPath = ReptilianWork.class.getClassLoader().getResource("/").getPath();
    		projectPath = projectPath.substring(1, projectPath.length()).replace("classes/", "");
    //		String projectPath = "D:/Work/workSpace——eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/JavaReptilian/WEB-INF/";
    		//js路径
    		String jsPath = projectPath + "js/huicong.js";
    		
    		Date date = new Date();
    		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
    		String dateName = formatter.format(date);//名称
    		
    		String imageSuffix = ".png";
    		String txtSuffix = ".txt";
    		
    		for (int i = 1; i <= url.length; i++) {
    			
    			InputStream in = null;
    			FileWriter writer = null;
    			String content = "";
    			
    			try {
    				String imageUrl = "你的存储路径" + companyName + "/result"+i + "/image/";//截图路径
    				String txtUrl = "你的存储路径" + companyName + "/result"+i + "/txt/";//文件路径
    				
    				File file = new File(txtUrl+dateName+txtSuffix);
    				File fileParent = file.getParentFile();
    				//文件路径存在则跳过
    //				if(fileParent.exists()){
    //					log.info(companyName+"-已经爬取完成,不再爬取");
    //					break;
    //				}
    				Runtime rt = Runtime.getRuntime();
    				log.info("phantomjs访问url="+url[i-1]);
    				Process p = rt.exec("phantomjs的安装路径(phantomjs.exe的全路径)" + " " + jsPath + " " + url[i-1] + " " + imageUrl + " " + dateName+imageSuffix);
    				in = p.getInputStream();
    				
    				Document doc = Jsoup.parse(in, "UTF-8", url[i-1]);
    				content = doc.body().text();
    				
    				//文件路径不存在则创建
    				if(!fileParent.exists()){
    					fileParent.mkdirs();
    				}
    				//创建文件
    				file.createNewFile();
    				
    				writer = new FileWriter(file);
    				if(content!=null && !"".equals(content)){
    					writer.write(content);
    					log.info("文件写入成功,路径:"+txtUrl+dateName+txtSuffix);
    				}
    				in.close();
    				writer.flush();
    				writer.close();
    			} catch (Exception e) {
    				log.error(e.getMessage(),e);
    			} finally{
    				if(in!=null){
    					in.close();
    				}
    				if(writer!=null){
    					writer.close();
    				}
    			}
    		}
    	}
    

    以上方法使用了Jsoup来解析java调用phantomjs后拿到的输入流并转成了document对象来操作获取所有文本信息。有关于Jsoup的介绍如下:

    jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

    要使用的话,maven配置如下:

    <!-- jsoup 一款Java的HTML解析器 -->

    <dependency>

    <groupId>org.jsoup</groupId>

    <artifactId>jsoup</artifactId>

    <version>1.8.3</version>

    </dependency>


    步骤3方法中使用到的huicong.js文件。注意(一定要设置超时时间,否则遇到一些访问连接有问题或者网络问题等,会导致phantomjs卡住,程序会一直等待响应)

    system = require('system')  
    address = system.args[1];
    imageUrl = system.args[2];
    imageName = system.args[3];
    var page = require('webpage').create();  
    var url = address;
    var fs = require('fs');
    fs.makeDirectory(imageUrl);
    
    //设置超时时间
    page.settings.resourceTimeout = 5000; // 5 seconds
    page.onResourceTimeout = function(e) {
        console.log(e.errorCode);   // it'll probably be 408
        console.log(e.errorString); // it'll probably be 'Network timeout on resource'
        console.log(e.url);         // the url whose request timed out
        phantom.exit(1);
    };
    
    page.open(url, function (status) {  
        //Page is loaded!  
        if (status !== 'success') {  
            console.log('请求失败!url='+url);
            phantom.exit();
        } else {  
                window.setTimeout(function () {
                  page.render(imageUrl+imageName);  //截图
                  console.log(page.content);
                  phantom.exit();
              }, 5000);   
        } 
      });
    


    源码的缩进由于这边编辑器的问题乱了╮(╯▽╰)╭强迫症将就看吧哈哈

    调用以上方法的代码就不贴了

    大概就是读取到excel中所有的搜索条件后

    循环调用getLinkBySelenium,获取到需要爬取的多个url后,调用getParseredHtml2方法

    ----------------------割一下-----------------------------

    以上,就爬取到了百度的部分数据,谢谢大家的阅读

    如有问题可以直接提问,本人看到会回答的

    这也是第一次分享自己的学习经验~

    如果有人关注考虑贴出后面的多线程调用方法,因为phantomjs的访问速度对于需要爬取大量数据来讲实在太慢了(;´д`)ゞ

    如果没人关注,就当自己的学习笔记了

    如果对你有用,别忘了点赞_( ̄0 ̄)_[哦~] 告辞~~

    展开全文
  • 这是 Java 网络爬虫系列文章的第一篇,如果你还不知道 Java 网络爬虫系列文章,请参看 学 Java 网络爬虫,需要哪些基础知识。第一篇是关于 Java 网络爬虫入门内容,在该篇中我们以采集虎扑列表新闻的新闻标题和...
  • Maven:Maven是一种用于Java的,可以管理Jar包集成调用的工具。用它可以搭建SpringMVC;   爬虫的框架   数据处理层db 主方法层main 对象领域层             ...
  • 我已经分享过了 Java 爬虫的基础和部分进阶的用法,这一次我会会分享 Java 爬虫的高级进阶实战经验,学习过后,也许你就可以使用 Java 模拟登录、下单、抢购、挂号等功能,内容很实用,但同时请大家在使用技术的同时...
  • Java爬虫技术快速入门

    2020-05-12 08:53:40
    作为网络爬虫的入门教程,采用 Java 开发语言,内容涵盖了网络爬虫的原理以及开发逻辑,Java...目前,有效的获取网络数据资源的重要方式,便是网络爬虫技术。简单的理解,比如您对百度贴吧的一个帖子内容特别感兴趣,而
  • Java 爬虫项目实战之爬虫简介 0. 前言 今年三四月份学习Hbase,了解到openTSDB的底层存储使用到了Hbase,于是乎,学习openTSDB,在阅读openTSDB源码【其源码使用java编写】的过程中, 发现里面全是I/O,多线程,...
  • 1.WebMagic 官方文档地址 http://webmagic.io/docs/zh/ 引入WebMagic的jar 这里采用pom形式  &lt;!-- 使用webmagic所用的jar --&gt;  &lt;dependency&gt;  &lt;...we...
  • 基于java实现网络爬虫

    2020-07-11 11:11:51
    基于java实现的java爬虫,是我学习java来练练手的,java基础入门的学生可以考虑参考一下
  • 这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫,就是这么的简单 中,我们简单的学习了一下如何利用 Java 进行网络爬虫。在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录的网站,我们该...
  • private static List films=new ArrayList(); List films=GetData.getData(client, url);(在Test类中) public static List getData(HttpClient client,String url)throws Exception{ 获得Http客户端,生成...
  • 这是 Java 爬虫系列博文的第三篇,在上一篇 Java 爬虫遇到需要登录的网站,该怎么办? 中,我们简单的讲解了爬虫时遇到登录问题的解决办法,在这篇文章中我们一起来聊一聊爬虫时遇到数据异步加载的问题,这也是爬虫...
  • 说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少。有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬虫而且还能做的非常好,在开源社区中...
  • 爬虫技术入门

    2019-03-26 13:20:27
    掌握爬虫技术原理,能够从互联网爬取自己感兴趣的信息 掌握常用的爬虫技术框架,页面分析技术,掌握反爬虫技术对策等。
  • 废话: 第一次学习并尝试分析、爬取一个网站的数据,全部是从零开始的经验,希望对各位看官有帮助,当然,本次爬取的是一个比较简单的网页,没有任何反爬虫措施的网页。 网上查了一下Java爬数据,最原始的方式是用...
1 2 3 4 5 ... 20
收藏数 17,561
精华内容 7,024