java爬虫的2种爬取方式(HTTP||Socket)简单Demo(一)

转载自 java爬虫的2种爬取方式(HTTP||Socket)简单Demo(一)

最近在找java的小项目自己写着玩,但是找不到合适的,于是写开始学一点爬虫,自己也是感觉爬虫比较有趣。这里自己找了一个教程,这一次写的是基于Socket和http方式爬取.

小项目结构图:


(1)SystemContorl类,实现整个爬虫任务调度,爬取任务

package com.simple.control;  import com.simple.Level.TaskLevel;  
import com.simple.manger.CrawlerManger;  
import com.simple.pojos.CrawlResultPojo;  
import com.simple.pojos.UrlPojo;  import java.util.ArrayList;  /** * * * Created by lewis on 2016/10/15. */  
public class SystemControl {  public static void main(String []args){  ArrayList<UrlPojo> urlPojoArrayList = new ArrayList<>();  urlPojoArrayList.add(new UrlPojo("https://www.taobao.com/", TaskLevel.HIGH));  urlPojoArrayList.add(new UrlPojo("https://www.taobao.com/", TaskLevel.HIGH));  int count=0;  for( UrlPojo urlPojo:urlPojoArrayList){  CrawlerManger crawlerManger = new CrawlerManger(false);  CrawlResultPojo crawlResultPojo = crawlerManger.crawl(urlPojo);  System.out.println(crawlResultPojo.getPageContent());  count++;  System.out.println("已经抓取了:"+count+"个页面");  }  }  
}  

(2)接口Icrawl为2种爬取方式进行统一的规范,2种爬取方式均实现此接口。

package com.simple.Icrawl;  import com.simple.pojos.CrawlResultPojo;  
import com.simple.pojos.UrlPojo;  /** * 实现类接口 * Created by lewis on 2016/10/15. */  
public interface ICrawl {  public CrawlResultPojo crawl(UrlPojo urlpojo);  
}  

(3)为每个任务分优先级

package com.simple.Level;  /** * 抓取任务的level级别 * Created by lewis on 2016/10/15. */  
public enum TaskLevel {  HIGH,MIDDLE,LOW  
}  

(4)爬虫的任务类和结果类

1).爬虫所需的任务类,包含具体的爬取内容url,任务优先级等

package com.simple.pojos;  import com.simple.Level.TaskLevel;  
import com.simple.crawImpl.HttpUrlConnectionCrawlerImpl;  import java.io.IOException;  
import java.io.InputStream;  
import java.net.HttpURLConnection;  
import java.net.MalformedURLException;  
import java.net.URL;  
import java.net.URLConnection;  /** * @author lewis * url任务的类 * Created by lewis on 2016/10/15. */  
public class UrlPojo {  private String url;                          //网页URL  private TaskLevel tasklevel=TaskLevel.MIDDLE;//URL的优先级等级  public UrlPojo(String url) {  this.url = url;  }  public UrlPojo(String url, TaskLevel tasklevel) {  this(url);  this.tasklevel = tasklevel;  }  public String getUrl() {  return url;  }  public void setUrl(String url) {  this.url = url;  }  public TaskLevel getTasklevel() {  return tasklevel;  }  public void setTasklevel(TaskLevel tasklevel) {  this.tasklevel = tasklevel;  }  public String getHost(){            //获得主机名  URL Url=null;  try {  Url= new URL(this.url);  } catch (MalformedURLException e) {  e.printStackTrace();  }  return Url.getHost();  }  public HttpURLConnection getConnection(){  URL Url=null;  try {  Url= new URL(this.url);  URLConnection conn = Url.openConnection();  if(conn instanceof HttpURLConnection)  return  (HttpURLConnection) conn;  else  throw new Exception("打开衔接失败");  } catch (MalformedURLException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  } catch (Exception e) {  e.printStackTrace();  }  return null;  }  }  

2).爬取后的结果集,所有的爬取结果保存在这个类中

package com.simple.pojos;  /** * 抓取结果的封装 * Created by lewis on 2016/10/15. */  
public class CrawlResultPojo {  private boolean isSuccess; //是否已经成功  private String pageContent;//网页内容  private int HttpStatuCode;//HTTP 状态码  public boolean isSuccess() {  return isSuccess;  }  public void setSuccess(boolean success) {  isSuccess = success;  }  public String getPageContent() {  return pageContent;  }  public void setPageContent(String pageContent) {  this.pageContent = pageContent;  }  public int getHttpStatuCode() {  return HttpStatuCode;  }  public void setHttpStatuCode(int httpStatuCode) {  HttpStatuCode = httpStatuCode;  }  
}  

(5)爬虫管理,包括爬取方式的选择,查询查询爬取结果

package com.simple.manger;  import com.simple.Icrawl.ICrawl;  
import com.simple.Level.TaskLevel;  
import com.simple.crawImpl.CrawlerImpl;  
import com.simple.crawImpl.HttpUrlConnectionCrawlerImpl;  
import com.simple.pojos.CrawlResultPojo;  
import com.simple.pojos.UrlPojo;  import java.net.Socket;  
import java.util.Objects;  /** * @author lewis * 包含业务逻辑的抓取管理器 * Created by lewis on 2016/10/15. */  
public class CrawlerManger {  private ICrawl crawler;  public CrawlerManger(boolean isSocket) {  if(isSocket){  this.crawler = new CrawlerImpl();  }else {  this.crawler = new HttpUrlConnectionCrawlerImpl();  }  }  public CrawlResultPojo crawl(UrlPojo urlPojo){  return this.crawler.crawl(urlPojo);  }  
}  

(6)2种爬取方式:

  1).Socket方式:

package com.simple.crawImpl;  import com.simple.Icrawl.ICrawl;  
import com.simple.Level.TaskLevel;  
import com.simple.pojos.CrawlResultPojo;  
import com.simple.pojos.UrlPojo;  import java.io.*;  
import java.net.Socket;  /** * *  实现接口类 * Created by lewis on 2016/10/15. */  
public class CrawlerImpl implements ICrawl{                 //Socket抓取方式  @Override  public CrawlResultPojo crawl(UrlPojo urlpojo) {                 //爬取url的内容,返回结果集合  CrawlResultPojo crawlResultPojo = new CrawlResultPojo();  if(urlpojo==null||urlpojo.getUrl()==null) {                  //若url为空,或URLpojo  crawlResultPojo.setPageContent(null);  crawlResultPojo.setSuccess(false);  return crawlResultPojo;  }  String host=urlpojo.getHost();  BufferedWriter bw = null;  BufferedReader br = null;  Socket socket=null;  if(host!=null){  try {  /** *  socket编程一般步骤 *(1) 创建Socket; *(2) 打开连接到Socket的输入/出流; *(3) 按照一定的协议对Socket进行读/写操作; *(4) 关闭Socket. * 其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号, * stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号, * localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址) * */  socket=new Socket(host,80);  bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));  /** * HTTP1.1 * 它支持持续连接. * 与之相对的 * HTTP1.0 * 当连接建立起来以后,浏览器发送一个请求,之后一个回应消息被送回来.然后TCP连接被释放. * 所以发生了阻塞 * */  bw.write("GET "+urlpojo.getUrl()+" HTTP/1.0\r\n");//HTTP/1.1会发生组成  bw.write("HOST:"+host+"\r\n");  bw.write("\r\n");//在行的结束符\r\n之前没有任何数据,代表http head输出给服务器端的数据结束并完成  bw.flush();      //清空缓冲区  br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));  String line = null ;  StringBuilder stringBuilder = new StringBuilder();  while((line=br.readLine())!=null){  stringBuilder.append(line+"\n");  }  crawlResultPojo.setSuccess(true);  crawlResultPojo.setPageContent(stringBuilder.toString());  return crawlResultPojo;  } catch (IOException e) {  e.printStackTrace();  } finally {  try {  if (socket!=null)//防止出现空指针异常  socket.close();//释放资源,防止内存泄漏  if(br!=null)  br.close();  if(bw!=null)  bw.close();  } catch (IOException e) {  e.printStackTrace();  System.out.println("流关闭失败");  }  }  }  return null;  }  public static void main(String []args){  CrawlerImpl cl = new CrawlerImpl();  System.out.println(cl.crawl(new UrlPojo("https://www.taobao.com/", TaskLevel.HIGH)).getPageContent());  System.out.println("done");  }  
}  

2).HTTP方式:

package com.simple.crawImpl;  import com.simple.Icrawl.ICrawl;  
import com.simple.Level.TaskLevel;  
import com.simple.pojos.CrawlResultPojo;  
import com.simple.pojos.UrlPojo;  import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.net.HttpURLConnection;  
import java.nio.Buffer;  /** * Created by lewis on 2016/10/15. */  
public class HttpUrlConnectionCrawlerImpl implements ICrawl{            //http 抓取方式  @Override  public CrawlResultPojo crawl(UrlPojo urlpojo) {  CrawlResultPojo crawlResultPojo = new CrawlResultPojo();  if(urlpojo==null||urlpojo.getUrl()==null) {                  //若url为空,或URLpojo  crawlResultPojo.setPageContent(null);  crawlResultPojo.setSuccess(false);  return crawlResultPojo;  }  HttpURLConnection httpURLConnection = urlpojo.getConnection();  if(httpURLConnection!=null){  BufferedReader bufferedReader=null;  try {  bufferedReader= new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));  String line =null;  StringBuilder stringBuilder = new StringBuilder();  while((line=bufferedReader.readLine())!=null){  stringBuilder.append(line+"\n");  }  crawlResultPojo.setPageContent(stringBuilder.toString());  crawlResultPojo.setSuccess(true);  return crawlResultPojo;  } catch (IOException e) {  e.printStackTrace();  }finally {  try {  if (bufferedReader!=null)  bufferedReader.close();  } catch (IOException e) {  e.printStackTrace();  }  }  }  return null;  }  public static void main(String []args){  System.out.println(new HttpUrlConnectionCrawlerImpl().crawl(new UrlPojo("https://www.taobao.com/", TaskLevel.HIGH)).getPageContent());  System.out.println("done");  }  
}  





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux mysql复制一个表结构图_详解Windows和Linux下从数据库导出表结构,以及Linux下如何导入.sql文件到MySQL数据库...

本文首先讲解window下如何使用Navicat for MySQL导出表。1、如下图所示&#xff0c;目标数据库是mydatabase&#xff0c;数据库中有四张表。2、选中该数据库&#xff0c;右键——数据传输。3、左边可以选择要导出哪几张表&#xff0c;右边选择.sql文件的存储位置。4、在高级中&…

基于Jenkins快速搭建持续集成环境

看了园友张善友的博文,尝试成功.便有此作.原网址: 基于 Jenkins 快速搭建持续集成环境 天下事有难易乎?为之,则难者亦易矣&#xff1b;不为,则易者亦难矣. 首先要学会使用MSBuild构建脚本 附网址:http://www.infoq.com/cn/articles/MSBuild-1. 目标:学会用MSBuild编译程序,主要…

零基础写Java知乎爬虫之进阶篇

转载自 零基础写Java知乎爬虫之进阶篇前面几篇文章&#xff0c;我们都是简单的实现了java爬虫抓取内容的问题&#xff0c;那么如果遇到复杂情况&#xff0c;我们还能继续那么做吗&#xff1f;答案当然是否定的&#xff0c;之前的仅仅是入门篇&#xff0c;都是些基础知识&#x…

MySQL导入冲突保留两者_面试被问MySQL 主从复制,怎么破?

一、前言随着应用业务数据不断的增大&#xff0c;应用的响应速度不断下降&#xff0c;在检测过程中我们不难发现大多数的请求都是查询操作。此时&#xff0c;我们可以将数据库扩展成主从复制模式&#xff0c;将读操作和写操作分离开来&#xff0c;多台数据库分摊请求&#xff0…

“.Net 社区虚拟大会”(dotnetConf) 2016 Day 1 Keynote: Scott Hunter

“.Net 社区虚拟大会”(dotnetConf) 2016 今天凌晨在Channel9 上召开&#xff0c;在Scott Hunter的30分钟的 Keynote上没有特别的亮点&#xff0c;所讲内容都是 微软“.Net社区虚拟大会”dotnetConf2015&#xff1a;关键词&#xff1a;.NET 创新、开源、跨平台 的具体化&#x…

Java(enum)枚举用法详解

转载自 Java&#xff08;enum&#xff09;枚举用法详解本篇文章主要介绍了Java 枚举用法详解&#xff0c;枚举的好处&#xff1a;可以将常量组织起来&#xff0c;统一进行管理。有兴趣的可以一起来了解一下。概念 enum的全称为 enumeration&#xff0c; 是 JDK 1.5 中引入的新特…

python处理脑电信号_用ICA去除脑电信号中的眼球链接

你有没有注意到你的“组件”完全是原始信号的比例和颠倒&#xff1f;这是因为你不能得到比信号更多的成分。在您需要执行以下步骤&#xff1a;将所有EEG通道输入ICA手动移除包含眨眼或其他伪影的组件用反变换重构让我们详细了解第2步&#xff1a;为什么要手动删除组件&#xff…

ASP.NET Core 中文文档 第一章 入门

原文&#xff1a;Getting Started翻译&#xff1a;娄宇(Lyrics)校对&#xff1a;刘怡(AlexLEWIS) 1、安装 .NET Core 2、创建一个新的 .NET Core 项目&#xff1a; mkdir aspnetcoreappcd aspnetcoreapp dotnet new 3、编辑 project.json 文件&#xff0c;添加 Kestrel HTTP se…

Properties文件的XML格式

转载自 Properties文件的XML格式 想必大家都用过*.properties文件&#xff0c;作为配置文件。但是&#xff0c;如果该文件写入了中文&#xff0c;待编译后内容就会成为乱码&#xff0c;使用native命令也好、使用ant执行编码转换也好&#xff0c;多少有点麻烦&#xff0c;与其如…

python简单爬虫课题_VS2019python爬虫入门

VS2019新建python项目在vs2019中添加python编译环境创建python控制台应用程序项目配置python环境安装requests第三方库管理程序包&#xff0c;执行安装requests包命令pip install requests导入第三方包import requests简单爬虫编写import requestsif __name__ "__main__&…

“.Net 社区虚拟大会”(dotnetConf) 2016 Day 2 Keynote: Miguel de Icaza

美国时间 6月7日--9日&#xff0c;为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开&#xff0c;美国时间6.8 是第二天&#xff0c; Miguel de Icaza 做Keynote&#xff0c;Miguel 在波士顿Xamarin的办公室&#xff0c;所以使用了Skype。 class"video_iframe" …

Java泛型总结

转载自 Java泛型总结 Java泛型是JDK5引入的一个新特性&#xff0c;允许在定义类和接口的时候使用类型参数&#xff08;type parameter&#xff09;。声明的类型参数在使用的时候使用具体的类型来替换。泛型最主要的应用是在JDK5中的新集合类框架中。对于泛型概念的引入&#xf…

用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序

原文&#xff1a;Your First ASP.NET Core Application on a Mac Using Visual Studio Code作者&#xff1a;Daniel Roth、Steve Smith 以及 Rick Anderson翻译&#xff1a;赵志刚校对&#xff1a;何镇汐、刘怡(AlexLEWIS) 本节将展示如何在 macOS 平台上创建首个 ASP.NET Core…

linux安装mysql遇到的问题_Linux下安装MySQL5.7及遇到的问题解决方法

一、下载地址本文安装的版本&#xff1a;或者使用wget下载&#xff1a;[rootlocalhost opt]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.32-el7-x86_64.tar.gz[rootlocalhost opt]# tar -xvf mysql-5.7.32-el7-x86_64.tar.gz二、检查是否已经安装过mysql[…

Java 8 新特性:扩展注解(类型注解和重复注解)

转载自 Java 8 新特性&#xff1a;扩展注解&#xff08;类型注解和重复注解&#xff09;&#xff08;注&#xff1a;先回顾下JDK1.5版本出现的注解 &#xff0c;然后再解释JDK 8的注解 更新内容。&#xff09; 一.注解&#xff08;JDK1.5&#xff09; 1.注解&#xff08;&…

框架写mysql插入为空_学习springMVC框架配置遇到的问题-数据写入不进数据库时的处理办法...

Idea简单SpringMVC框架配置前边已经介绍过了Struts在Idea上的配置,相对于Struts来说,我觉得SpringMVC有更多的优势,首先Struts是需要对action进行配置,页面发送不同的请求,就需要配置不同的acti ...hibernate学习之一 框架配置hibernate 框架 1.hibernate框架应用在javaee三层结…

“.Net 社区虚拟大会”(dotnetConf) 2016 Day 3 Keynote: Scott Hanselman

美国时间 6月7日--9日&#xff0c;为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开&#xff0c;美国时间6.9 是第三天&#xff0c; Scott Hanselman 做Keynote。今天主题围绕的是.NET OpenSource 展开&#xff0c;Hanselman通过PowerBI分析了.NET社区这两年的发展&#…

Java注释@interface的用法

转载自 Java注释interface的用法java用 interface Annotation{ } 定义一个注解 Annotation&#xff0c;一个注解是一个类 Override&#xff0c;Deprecated&#xff0c;SuppressWarnings为常见的3个注解。注解相当于一种标记&#xff0c;在程序中加上了注解就等于为程序加上了某…

RPC的发展历史

服务器通讯原理就是一台socket服务器A,另一台socket客户端B,现在如果要通讯的话直接以流方式写入或读出。 这样能实现通讯&#xff0c;但有个问题。如何知道更多信息&#xff1f;比如需要发送流大小&#xff0c;编码&#xff0c;Ip等。 这样就有了协议&#xff0c;协议就是规范…

类的继承python 简明_[简明python教程]学习笔记2014-05-04

今天学习的内容&#xff1a;1.面向对象编程的概念1)面向对象的三个基本特征&#xff1a;封装、继承、多态2)类和对象是面向对象编程的2个主要方面。类使用class关键字创建。类的域和方法被列在一个缩进块中。2.类[rootreed 0504]# cat simpleclass.py#!/usr/bin/pythonclass Pe…