java 单线程 博客园_java单线程简单爬虫

要求:

1.给定了一个网页网址(URL),这个就是我们爬虫项目的入口网页,从哪开始爬

http://roll.news.sina.com.cn/news/gnxw/gdxw1/index.shtml

2.把当天的新闻内容全部爬取保存到本地文件中

3.方便以后我们可以迅速查找(在本地文件中)某个新闻,供我们做分析使用

这里为了简化,我们的要求就是找到对应的新闻内容打印输出到控制台System.out.println()

4.爬取的数据按天为单位划分目录,一天生成一个文件夹,文件夹下有2个文件,

一个是数据文件(存储爬取的所有新闻),一个是索引文件(存储某个新闻对应的位置,方便我们查找)。

爬取前先分析网页结构,找到自己需要内容的部分,编写正则表达式

一、建立一个maven项目

二、查取网页内容并储存在对应的数据文件和索引文件

1、建立所需工具包

/*** 用于关流

*@authorAdministrator

**/

public classCloseUtil {public static voidclose(AutoCloseable obj) {if (obj != null) {try{

obj.close();

}catch(Exception e) {

e.printStackTrace();

}

}

}

}

importjava.io.BufferedInputStream;importjava.io.BufferedReader;importjava.io.ByteArrayOutputStream;importjava.io.InputStreamReader;importjava.net.URL;importjava.net.URLConnection;/*** 爬取网页内容

*@authorAdministrator

**/

public classWebUtil {/*** 将爬取的内容以字符形式返回

*@paramurlStr

*@paramencoding

*@return

*/

public staticString urlGetString(String urlStr, String encoding) {

StringBuffer sb= newStringBuffer();

URL url= null;

URLConnection conn= null;

BufferedReader br= null;try{

url= newURL(urlStr);

conn=url.openConnection();

br= new BufferedReader(newInputStreamReader(

conn.getInputStream(), encoding));

String line= null;while ((line = br.readLine()) != null) {

sb.append(line).append(System.lineSeparator());

}

}catch(Exception e) {

e.printStackTrace();

}finally{

CloseUtil.close(br);

}returnsb.toString();

}/*** 将爬取内容以字节数组形式返回

* 以便查取对应新闻内容的长度

*@paramurlStr

*@return

*/

public static byte[] urlGetByteArray(String urlStr) {

ByteArrayOutputStream baos= newByteArrayOutputStream();

BufferedInputStream bis= null;byte[] byteArray = new byte[0];try{

URL url= newURL(urlStr);

URLConnection conn=url.openConnection();

bis= newBufferedInputStream(conn.getInputStream());int b = -1;while ((b = bis.read()) != -1) {

baos.write(b);

}

byteArray=baos.toByteArray();

}catch(Exception e) {

e.printStackTrace();

}finally{

CloseUtil.close(bis);

CloseUtil.close(baos);

}returnbyteArray;

}

}

importjava.util.ArrayList;importjava.util.List;importjava.util.regex.Matcher;importjava.util.regex.Pattern;/*** 利用正则表达式从爬去的内容中

* 筛选出需要的内容

*@authorAdministrator

**/

public classRegexUtil {public staticString match(String input, String regex) {

StringBuffer sb= newStringBuffer();

Pattern p=Pattern.compile(regex);

Matcher m=p.matcher(input);while(m.find()) {

String result=m.group();

sb.append(result);

}returnsb.toString();

}public static String match(String input, String regex, intgrpNum) {

String result= "";

Pattern p=Pattern.compile(regex);

Matcher m=p.matcher(input);while(m.find()) {

result=m.group(grpNum);

}returnresult;

}public static ListmatchList(String input, String regex) {

List list = new ArrayList();

Pattern p=Pattern.compile(regex);

Matcher m=p.matcher(input);while(m.find()) {

String result=m.group();

list.add(result);

}returnlist;

}

}

importjava.io.FileOutputStream;importjava.io.OutputStream;importjava.io.PrintWriter;/*** 将爬取的内容输出到硬盘

*@authorAdministrator

**/

public classIOUtil {public static void writeDataFile(String dataFile, byte[] ba){

OutputStream os= null;try{

os= new FileOutputStream(dataFile, true);

os.write(ba);

}catch(Exception e){

e.printStackTrace();

}finally{

CloseUtil.close(os);

}

}public static voidwriteIndexFile(String indexFile,String str){

PrintWriter pw= null;try{

pw= new PrintWriter(new FileOutputStream(indexFile, true));

pw.println(str);

}catch(Exception e){

e.printStackTrace();

}finally{

CloseUtil.close(pw);

}

}

}

2、准备就绪开始爬取

import java.io.File;

import java.util.List;

import cn.dd.util.IOUtil;

import cn.dd.util.RegexUtil;

import cn.dd.util.WebUtil;public classSpider {public static voidmain(String[] args) {

Spider.crawler();

}public static voidcrawler() {

String urlStr= "http://roll.news.sina.com.cn/news/gnxw/gdxw1/index.shtml";

String encoding= "gb2312";

String input= WebUtil.urlGetString(urlStr, encoding);//爬取列表页内容

String ulRegex = "

  • [\\s\\S]*?
";//正则表达式

String ulResult =RegexUtil.match(input, ulRegex);

String liRegex= "

[\\s\\S]*?";//正则表达式

List list =RegexUtil.matchList(ulResult, liRegex);for(String str : list) {

String grpRegex= "

([\\S\\s]*?) \\(([\\S]*?) [\\S]*?\\)";

String liUrlStr= RegexUtil.match(str, grpRegex, 1);

String liTitle= RegexUtil.match(str, grpRegex, 2);

String liDate= RegexUtil.match(str, grpRegex, 3);

Spider.detailProcessor(liUrlStr, liTitle, liDate);

}

}public static voiddetailProcessor(String liUrlStr, String liTitle,

String liDate) {byte[] ba = WebUtil.urlGetByteArray(liUrlStr);//爬取详情页

String fileBaseDir = "F:" + File.separator + "something"

+ File.separator + liDate +File.separator;

File fileBaseDirObj= newFile(fileBaseDir);if (!fileBaseDirObj.exists()) {

fileBaseDirObj.mkdirs();

}

String dataPath= fileBaseDir + "spider_data.dat";

String indexPath= fileBaseDir + "spider_index.dat";

File dataFile= newFile(dataPath);long pos =dataFile.length();

StringBuffer sb= newStringBuffer();char c = '\u0001';//将储存的索引文件各部分用分隔符间隔开。

sb.append(liTitle).append(c).append(pos).append(c).append(ba.length)

.append(c).append(liUrlStr);

IOUtil.writeDataFile(dataPath, ba);

IOUtil.writeIndexFile(indexPath, sb.toString());

}

}

爬取内容基本完成,运行可生成对应要求的数据文件和索引文件

三、客户端的建立

1、编写所需工具包

importjava.io.RandomAccessFile;public classIndexUtil {public staticString index(String pos, String size, String dataFile) {

String encoding= "utf-8";

String str= "";

RandomAccessFile raf= null;try{

raf= new RandomAccessFile(dataFile, "r");

Long po=Long.valueOf(pos);

raf.seek(po);

Integer si=Integer.valueOf(size);byte[] b = new byte[si];

raf.read(b);

str= newString(b, encoding);

}catch(Exception e) {

e.printStackTrace();

}finally{

CloseUtil.close(raf);

}returnstr;

}public staticString index(String pos, String size, String dataFile,String encoding) {

String str= "";

RandomAccessFile raf= null;try{

raf= new RandomAccessFile(dataFile, "r");

Long po=Long.valueOf(pos);

raf.seek(po);

Integer si=Integer.valueOf(size);byte[] b = new byte[si];

raf.read(b);

str= newString(b, encoding);

}catch(Exception e) {

e.printStackTrace();

}finally{

CloseUtil.close(raf);

}returnstr;

}

}

2、编写客户端

importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.InputStreamReader;importcn.dd.util.CloseUtil;importcn.dd.util.IndexUtil;public classSpiderIndex {public static voidmain(String[] args) {

String str= "http://news.sina.com.cn/c/nd/2018-08-23/doc-ihicsiav8438010.shtml";

SpiderIndex.input(str);

}public static voidinput(String str) {

String indexFile= "F:" + File.separator+ "/something/08月23日/spider_index.dat";

String dataFile= "F:" + File.separator+ "/something/08月23日/spider_data.dat";

BufferedReader bu= null;try{

bu= new BufferedReader(new InputStreamReader(new FileInputStream(indexFile), "utf-8"));

String len= null;while ((len = bu.readLine()) != null) {

String[] st= len.split("\u0001");if (str.equals(st[3])) {

String s= IndexUtil.index(st[1], st[2], dataFile);

System.out.println(s);break;

}

}

}catch(Exception e) {

e.printStackTrace();

}finally{

CloseUtil.close(bu);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值