基于Java HttpClient和Htmlparser实现网络爬虫代码

开发环境的搭建,在工程的 Build Path 中导入下载的Commons-httpClient3.1.Jar,htmllexer.jar 以及 htmlparser.jar 文件。

图 1. 开发环境搭建

HttpClient 基本类库使用

HttpClinet 提供了几个类来支持 HTTP 访问。下面我们通过一些示例代码来熟悉和说明这些类的功能和使用。 HttpClient 提供的 HTTP 的访问主要是通过 GetMethod 类和 PostMethod 类来实现的,他们分别对应了 HTTP Get 请求与 Http Post 请求。

GetMethod

使用 GetMethod 来访问一个 URL 对应的网页,需要如下一些步骤。
生成一个 HttpClinet 对象并设置相应的参数。
生成一个 GetMethod 对象并设置响应的参数。
用 HttpClinet 生成的对象来执行 GetMethod 生成的 Get 方法。
处理响应状态码。
若响应正常,处理 HTTP 响应内容。
释放连接。

清单 1 的代码展示了这些步骤,其中的注释对代码进行了较详细的说明。

清单 1.

/* 1 生成 HttpClinet 对象并设置参数*/
 HttpClient httpClient=new HttpClient();
 //设置 Http 连接超时为5秒
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

 /*2 生成 GetMethod 对象并设置参数*/
 GetMethod getMethod=new GetMethod(url);
 //设置 get 请求超时为 5 秒
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000);
 //设置请求重试处理,用的是默认的重试处理:请求三次
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
     new DefaultHttpMethodRetryHandler());

 /*3 执行 HTTP GET 请求*/
 try{
   int statusCode = httpClient.executeMethod(getMethod);
   /*4 判断访问的状态码*/
   if (statusCode != HttpStatus.SC_OK)
   {
System.err.println("Method failed: "+ getMethod.getStatusLine());
   }

   /*5 处理 HTTP 响应内容*/
   //HTTP响应头部信息,这里简单打印
 Header[] headers=getMethod.getResponseHeaders();
   for(Header h: headers)
      System.out.println(h.getName()+" "+h.getValue());*/
   //读取 HTTP 响应内容,这里简单打印网页内容
   byte[] responseBody = getMethod.getResponseBody();//读取为字节数组
System.out.println(new String(responseBody));
   //读取为 InputStream,在网页内容数据量大时候推荐使用
   InputStream response = getMethod.getResponseBodyAsStream();//
   …
}
catch (HttpException e)
{
   // 发生致命的异常,可能是协议不对或者返回的内容有问题
     System.out.println("Please check your provided http address!");
e.printStackTrace();
   }
catch (IOException e)
 {
      // 发生网络异常
    e.printStackTrace();
   } finally {
         /*6 .释放连接*/
      getMethod.releaseConnection();
      } 

这里值得注意的几个地方是:

设置连接超时和请求超时,这两个超时的意义不同,需要分别设置。
响应状态码的处理。

返回的结果可以为字节数组,也可以为 InputStream,而后者在网页内容数据量较大的时候推荐使用。
在处理返回结果的时候可以根据自己的需要,进行相应的处理。如笔者是需要保存网页
到本地,因此就可以写一个 saveToLocaleFile(byte[] data, String filePath) 的方法,将字节数组保存成本地文件。后续的简易爬虫部分会有相应的介绍。

PostMethod

PostMethod 方法与 GetMethod 方法的使用步骤大体相同。但是由于 PostMethod 使用的是HTTP 的 Post 请求,因而请求参数的设置与 GetMethod 有所不同。在 GetMethod 中,请求的参数直接写在 URL 里,一般以这样形式出现:http://hostname:port//file?name1=value1&name2=value …。请求参数是 name,value 对。比如我想得到百度搜索“Thinking In Java”的结果网页,就可以使 GetMethod 的构造方法中的 url 为:http://www.baidu.com/s?wd=Thinking+In+Java 。而 PostMethod 则可以模拟网页里表单提交的过程,通过设置表单里 post 请求参数的值,来动态的获得返回的网页结果。清单 2 中的代码展示了如何创建一个 Post 对象,并设置相应的请求参数。

清单2

PostMethod postMethod = new PostMethod("http://dict.cn/");
postMethod.setRequestBody(new NameValuePair[]{new NameValuePair("q","java")}); 

HtmlParser 基本类库使用

HtmlParser 提供了强大的类库来处理 Internet 上的网页,可以实现对网页特定内容的提取和修改。下面通过几个例子来介绍 HtmlParser 的一些使用。这些例子其中的代码,有部分用在了后面介绍的简易爬虫中。以下所有的代码和方法都在在类 HtmlParser.Test.java 里,这是笔者编写的一个用来测试 HtmlParser 用法的类。

迭代遍历网页所有节点

网页是一个半结构化的嵌套文本文件,有类似 XML 文件的树形嵌套结构。使用HtmlParser 可以让我们轻易的迭代遍历网页的所有节点。清单 3 展示了如何来实现这个功能。

清单 3

// 循环访问所有节点,输出包含关键字的值节点
public static void extractKeyWordText(String url, String keyword) {
    try {
      //生成一个解析器对象,用网页的 url 作为参数
      Parser parser = new Parser(url);
      //设置网页的编码,这里只是请求了一个 gb2312 编码网页
      parser.setEncoding("gb2312");
      //迭代所有节点, null 表示不使用 NodeFilter
      NodeList list = parser.parse(null);
      //从初始的节点列表跌倒所有的节点
      processNodeList(list, keyword);
    } catch (ParserException e) {
      e.printStackTrace();
    }
  }

  private static void processNodeList(NodeList list, String keyword) {
    //迭代开始
    SimpleNodeIterator iterator = list.elements();
    while (iterator.hasMoreNodes()) {
      Node node = iterator.nextNode();
      //得到该节点的子节点列表
      NodeList childList = node.getChildren();
      //孩子节点为空,说明是值节点
      if (null == childList)
      {
        //得到值节点的值
        String result = node.toPlainTextString();
        //若包含关键字,则简单打印出来文本
        if (result.indexOf(keyword) != -1)
          System.out.println(result);
      } //end if
      //孩子节点不为空,继续迭代该孩子节点
      else
      {
        processNodeList(childList, keyword);
      }//end else
    }//end wile
  } 

上面的中有两个方法:

private static void processNodeList(NodeList list, String keyword) 

该方法是用类似深度优先的方法来迭代遍历整个网页节点,将那些包含了某个关键字的值节点的值打印出来。

public static void extractKeyWordText(String url, String keyword) 

该方法生成针对 String 类型的 url 变量代表的某个特定网页的解析器,调用 1中的方法实现简单的遍历。

清单 3 的代码展示了如何迭代所有的网页,更多的工作可以在此基础上展开。比如找到某个特定的网页内部节点,其实就可以

在遍历所有的节点基础上来判断,看被迭代的节点是否满足特定的需要。

使用 NodeFilter

NodeFilter 是一个接口,任何一个自定义的 Filter 都需要实现这个接口中的 boolean accept() 方法。如果希望迭代网页节点的时候保留当前节点,则在节点条件满足的情况下返回 true;否则返回 false。HtmlParse 里提供了很多实现了 NodeFilter 接口的类,下面就一些笔者所用到的,以及常用的 Filter 做一些介绍:

对 Filter 做逻辑操作的 Fitler 有:AndFilter,NotFilter ,OrFilter,XorFilter。
这些 Filter 来组合不同的 Filter,形成满足两个 Filter 逻辑关系结果的 Filter。

判断节点的孩子,兄弟,以及父亲节点情况的 Filter 有:HasChildFilterHasParentFilter,HasSiblingFilter。
判断节点本身情况的 Filter 有 HasAttributeFilter:判读节点是否有特定属性;LinkStringFilter:判断节点是否是具有特定模式 (pattern) url 的节点;

TagNameFilter:判断节点是否具有特定的名字;NodeClassFilter:判读节点是否是某个 HtmlParser 定义好的 Tag 类型。在 org.htmlparser.tags 包下有对应 Html标签的各种 Tag,例如 LinkTag,ImgeTag 等。

还有其他的一些 Filter 在这里不一一列举了,可以在 org.htmlparser.filters 下找到。

清单 4 展示了如何使用上面提到过的一些 filter 来抽取网页中的 <a> 标签里的 href属性值,<img> 标签里的 src 属性值,以及 <frame> 标签里的 src 的属性值。

清单4

// 获取一个网页上所有的链接和图片链接
public static void extracLinks(String url) {
    try {
      Parser parser = new Parser(url);
      parser.setEncoding("gb2312");
//过滤 <frame> 标签的 filter,用来提取 frame 标签里的 src 属性所、表示的链接
      NodeFilter frameFilter = new NodeFilter() {
        public boolean accept(Node node) {
          if (node.getText().startsWith("frame src=")) {
            return true;
          } else {
            return false;
          }
        }
      };
    //OrFilter 来设置过滤 <a> 标签,<img> 标签和 <frame> 标签,三个标签是 or 的关系
   OrFilte rorFilter = new OrFilter(new NodeClassFilter(LinkTag.class), new
NodeClassFilter(ImageTag.class));
   OrFilter linkFilter = new OrFilter(orFilter, frameFilter);
  //得到所有经过过滤的标签
  NodeList list = parser.extractAllNodesThatMatch(linkFilter);
  for (int i = 0; i < list.size(); i++) {
    Node tag = list.elementAt(i);
    if (tag instanceof LinkTag)//<a> 标签
    {
      LinkTag link = (LinkTag) tag;
      String linkUrl = link.getLink();//url
      String text = link.getLinkText();//链接文字
      System.out.println(linkUrl + "**********" + text);
    }
    else if (tag instanceof ImageTag)//<img> 标签
    {
      ImageTag image = (ImageTag) list.elementAt(i);
      System.out.print(image.getImageURL() + "********");//图片地址
      System.out.println(image.getText());//图片文字
    }
    else//<frame> 标签
    {
//提取 frame 里 src 属性的链接如 <frame src="test.html"/>
      String frame = tag.getText();
      int start = frame.indexOf("src=");
      frame = frame.substring(start);
      int end = frame.indexOf(" ");
      if (end == -1)
        end = frame.indexOf(">");
      frame = frame.substring(5, end - 1);
      System.out.println(frame);
    }
  }
} catch (ParserException e) {
      e.printStackTrace();
}
} 

简单强大的 StringBean
如果你想要网页中去掉所有的标签后剩下的文本,那就是用 StringBean 吧。以下简单的代码可以帮你解决这样的问题:

清单5

StringBean sb = new StringBean();
sb.setLinks(false);//设置结果中去点链接
sb.setURL(url);//设置你所需要滤掉网页标签的页面 url
System.out.println(sb.getStrings());//打印结果

HtmlParser 提供了强大的类库来处理网页,由于本文旨在简单的介绍,因此只是将与笔者后续爬虫部分有关的关键类库进行了示例说明。感兴趣的读者可以专门来研究一下 HtmlParser 更为强大的类库。

简易爬虫的实现

HttpClient 提供了便利的 HTTP 协议访问,使得我们可以很容易的得到某个网页的源码并保存在本地;HtmlParser 提供了如此简便灵巧的类库,可以从网页中便捷的提取出指向其他网页的超链接。笔者结合这两个开源包,构建了一个简易的网络爬虫。

爬虫 (Crawler) 原理

学过数据结构的读者都知道有向图这种数据结构。如下图所示,如果将网页看成是图中的某一个节点,而将网页中指向其他网页的链接看成是这个节点指向其他节点的边,那么我们很容易将整个 Internet 上的网页建模成一个有向图。理论上,通过遍历算法遍历该图,可以访问到Internet 上的几乎所有的网页。最简单的遍历就是宽度优先以及深度优先。以下笔者实现的简易爬虫就是使用了宽度优先的爬行策略

图 2. 网页关系的建模图

简易爬虫实现流程

在看简易爬虫的实现代码之前,先介绍一下简易爬虫爬取网页的流程。

图 3. 爬虫流程图

各个类的源码以及说明

对应上面的流程图,简易爬虫由下面几个类组成,各个类职责如下:

Crawler.java:爬虫的主方法入口所在的类,实现爬取的主要流程。

LinkDb.java:用来保存已经访问的 url 和待爬取的 url 的类,提供url出对入队操作。

Queue.java: 实现了一个简单的队列,在 LinkDb.java 中使用了此类。

FileDownloader.java:用来下载 url 所指向的网页。

HtmlParserTool.java: 用来抽取出网页中的链接。

LinkFilter.java:一个接口,实现其 accept() 方法用来对抽取的链接进行过滤。

下面是各个类的源码,代码中的注释有比较详细的说明。

清单6 Crawler.java

package com.ie;
 import java.util.Set;
public class Crawler {
  /* 使用种子 url 初始化 URL 队列*/
  private void initCrawlerWithSeeds(String[] seeds)
  {
    for(int i=0;i<seeds.length;i++)
      LinkDB.addUnvisitedUrl(seeds[i]);
  }

  /* 爬取方法*/
  public void crawling(String[] seeds)
  {
    LinkFilter filter = new LinkFilter(){
      //提取以 http://www.twt.edu.cn 开头的链接
      public boolean accept(String url) {
        if(url.startsWith("http://www.twt.edu.cn"))
          return true;
        else
          return false;
      }
    };
    //初始化 URL 队列
    initCrawlerWithSeeds(seeds);
    //循环条件:待抓取的链接不空且抓取的网页不多于 1000
    while(!LinkDB.unVisitedUrlsEmpty()&&LinkDB.getVisitedUrlNum()<=1000)
    {
      //队头 URL 出对
      String visitUrl=LinkDB.unVisitedUrlDeQueue();
      if(visitUrl==null)
        continue;
      FileDownLoader downLoader=new FileDownLoader();
      //下载网页
      downLoader.downloadFile(visitUrl);
      //该 url 放入到已访问的 URL 中
      LinkDB.addVisitedUrl(visitUrl);
      //提取出下载网页中的 URL

      Set<String> links=HtmlParserTool.extracLinks(visitUrl,filter);
      //新的未访问的 URL 入队
      for(String link:links)
      {
          LinkDB.addUnvisitedUrl(link);
      }
    }
  }
  //main 方法入口
  public static void main(String[]args)
  {
    Crawler crawler = new Crawler();
    crawler.crawling(new String[]{"http://www.twt.edu.cn"});
  }
}

清单7 LinkDb.java

package com.ie;
import java.util.HashSet;
import java.util.Set;
/**
 * 用来保存已经访问过 Url 和待访问的 Url 的类
 */
public class LinkDB {
  //已访问的 url 集合
  private static Set<String> visitedUrl = new HashSet<String>();
  //待访问的 url 集合
  private static Queue<String> unVisitedUrl = new Queue<String>();
  public static Queue<String> getUnVisitedUrl() {
    return unVisitedUrl;
  }
  public static void addVisitedUrl(String url) {
    visitedUrl.add(url);
  }
  public static void removeVisitedUrl(String url) {
    visitedUrl.remove(url);
  }
  public static String unVisitedUrlDeQueue() {
    return unVisitedUrl.deQueue();
  }
  // 保证每个 url 只被访问一次
  public static void addUnvisitedUrl(String url) {
    if (url != null && !url.trim().equals("")
 && !visitedUrl.contains(url)
        && !unVisitedUrl.contians(url))
      unVisitedUrl.enQueue(url);
  }
  public static int getVisitedUrlNum() {
    return visitedUrl.size();
  }
  public static boolean unVisitedUrlsEmpty() {
    return unVisitedUrl.empty();
  }
}

清单8 Queue.java

package com.ie;
import java.util.LinkedList;
/**
 * 数据结构队列
 */
public class Queue<T> {
  private LinkedList<T> queue=new LinkedList<T>();
  public void enQueue(T t)
  {
    queue.addLast(t);
  }
  public T deQueue()
  {
    return queue.removeFirst();
  }
  public boolean isQueueEmpty()
  {
    return queue.isEmpty();
  }
  public boolean contians(T t)
  {
    return queue.contains(t);
  }
  public boolean empty()
  {
    return queue.isEmpty();
  }
} 

清单 9 FileDownLoader.java

package com.ie;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class FileDownLoader {
  /**根据 url 和网页类型生成需要保存的网页的文件名
   *去除掉 url 中非文件名字符
   */
  public String getFileNameByUrl(String url,String contentType)
  {
    url=url.substring(7);//remove http://
    if(contentType.indexOf("html")!=-1)//text/html
    {
      url= url.replaceAll("[\\?/:*|<>\"]", "_")+".html";
      return url;
    }
    else//如application/pdf
    {
return url.replaceAll("[\\?/:*|<>\"]", "_")+"."+ \
     contentType.substring(contentType.lastIndexOf("/")+1);
    }
  }
  /**保存网页字节数组到本地文件
   * filePath 为要保存的文件的相对地址
   */
  private void saveToLocal(byte[] data,String filePath)
  {
    try {
      DataOutputStream out=new DataOutputStream(
new FileOutputStream(new File(filePath)));
      for(int i=0;i<data.length;i++)
      out.write(data[i]);
      out.flush();
      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  /*下载 url 指向的网页*/
  public String downloadFile(String url)
  {
     String filePath=null;
     /* 1.生成 HttpClinet 对象并设置参数*/
     HttpClient httpClient=new HttpClient();
     //设置 Http 连接超时 5s
        httpClient.getHttpConnectionManager().getParams().
setConnectionTimeout(5000);
     /*2.生成 GetMethod 对象并设置参数*/
     GetMethod getMethod=new GetMethod(url);
     //设置 get 请求超时 5s
     getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000);
     //设置请求重试处理
     getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
      new DefaultHttpMethodRetryHandler());
     /*3.执行 HTTP GET 请求*/
     try{
       int statusCode = httpClient.executeMethod(getMethod);
       //判断访问的状态码
       if (statusCode != HttpStatus.SC_OK)
       {
System.err.println("Method failed: "+ getMethod.getStatusLine());
         filePath=null;
       }
       /*4.处理 HTTP 响应内容*/
 byte[] responseBody = getMethod.getResponseBody();//读取为字节数组
       //根据网页 url 生成保存时的文件名
filePath="temp\\"+getFileNameByUrl(url,
      getMethod.getResponseHeader("Content-Type").getValue());
      saveToLocal(responseBody,filePath);
     } catch (HttpException e) {
          // 发生致命的异常,可能是协议不对或者返回的内容有问题
          System.out.println("Please check your provided http
address!");
          e.printStackTrace();
         } catch (IOException e) {
          // 发生网络异常
          e.printStackTrace();
         } finally {
          // 释放连接
          getMethod.releaseConnection();
         }
         return filePath;
  }
  //测试的 main 方法
  public static void main(String[]args)
  {
    FileDownLoader downLoader = new FileDownLoader();
    downLoader.downloadFile("http://www.twt.edu.cn");
  }
} 

清单 10 HtmlParserTool.java

package com.ie;
import java.util.HashSet;
import java.util.Set;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.filters.OrFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
public class HtmlParserTool {
  // 获取一个网站上的链接,filter 用来过滤链接
  public static Set<String> extracLinks(String url,LinkFilter filter) {
    Set<String> links = new HashSet<String>();
    try {
      Parser parser = new Parser(url);
      parser.setEncoding("gb2312");
      // 过滤 <frame >标签的 filter,用来提取 frame 标签里的 src 属性所表示的链接
      NodeFilter frameFilter = new NodeFilter() {
        public boolean accept(Node node) {
          if (node.getText().startsWith("frame src=")) {
            return true;
          } else {
            return false;
          }
        }
      };
      // OrFilter 来设置过滤 <a> 标签,和 <frame> 标签
      OrFilter linkFilter = new OrFilter(new NodeClassFilter(
          LinkTag.class), frameFilter);
      // 得到所有经过过滤的标签
      NodeList list = parser.extractAllNodesThatMatch(linkFilter);
      for (int i = 0; i < list.size(); i++) {
        Node tag = list.elementAt(i);
        if (tag instanceof LinkTag)// <a> 标签
        {
          LinkTag link = (LinkTag) tag;
          String linkUrl = link.getLink();// url
          if(filter.accept(linkUrl))
            links.add(linkUrl);
        } else// <frame> 标签
        {
        // 提取 frame 里 src 属性的链接如 <frame src="test.html"/>
          String frame = tag.getText();
          int start = frame.indexOf("src=");
          frame = frame.substring(start);
          int end = frame.indexOf(" ");
          if (end == -1)
            end = frame.indexOf(">");
          String frameUrl = frame.substring(5, end - 1);
          if(filter.accept(frameUrl))
            links.add(frameUrl);
        }
      }
    } catch (ParserException e) {
      e.printStackTrace();
    }
    return links;
  }
  //测试的 main 方法
  public static void main(String[]args)
  {
Set<String> links = HtmlParserTool.extracLinks(
"http://www.twt.edu.cn",new LinkFilter()
    {
      //提取以 http://www.twt.edu.cn 开头的链接
      public boolean accept(String url) {
        if(url.startsWith("http://www.twt.edu.cn"))
          return true;
        else
          return false;
      }
    });
    for(String link : links)
      System.out.println(link);
  }
} 

清单11 LinkFilter.java

package com.ie;
public interface LinkFilter {
  public boolean accept(String url);
} 

这些代码中关键的部分都在 HttpClient 和 HtmlParser 介绍中说明过了,其他部分也比较容易,请感兴趣的读者自行理解。

(0)

相关推荐

  • java实现简单的爬虫之今日头条

    前言 需要提前说下的是,由于今日头条的文章的特殊性,所以无法直接获取文章的地址,需要获取文章的id然后在拼接成url再访问.下面话不多说了,直接上代码. 示例代码如下 public class Demo2 { public static void main(String[] args) { // 需要爬的网页的文章列表 String url = "http://www.toutiao.com/news_finance/"; //文章详情页的前缀(由于今日头条的文章都是在group这个目

  • Java爬虫抓取视频网站下载链接

    本篇文章抓取目标网站的链接的基础上,进一步提高难度,抓取目标页面上我们所需要的内容并保存在数据库中.这里的测试案例选用了一个我常用的电影下载网站(http://www.80s.la/).本来是想抓取网站上的所有电影的下载链接,后来感觉需要的时间太长,因此改成了抓取2015年电影的下载链接. 一 原理简介 其实原理都跟第一篇文章差不多,不同的是鉴于这个网站的分类列表实在太多,如果不对这些标签加以取舍的话,需要花费的时间难以想象. 分类链接和标签链接都不要,不通过这些链接去爬取其他页面,只通过页底的

  • JAVA使用爬虫抓取网站网页内容的方法

    本文实例讲述了JAVA使用爬虫抓取网站网页内容的方法.分享给大家供大家参考.具体如下: 最近在用JAVA研究下爬网技术,呵呵,入了个门,把自己的心得和大家分享下 以下提供二种方法,一种是用apache提供的包.另一种是用JAVA自带的. 代码如下: // 第一种方法 //这种方法是用apache提供的包,简单方便 //但是要用到以下包:commons-codec-1.4.jar // commons-httpclient-3.1.jar // commons-logging-1.0.4.jar

  • Java 从互联网上爬邮箱代码示例

    网页爬虫:其实就是一个程序用于在互联网中获取符合指定规则的数据. package day05; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; impor

  • Java爬虫实战抓取一个网站上的全部链接

    前言:写这篇文章之前,主要是我看了几篇类似的爬虫写法,有的是用的队列来写,感觉不是很直观,还有的只有一个请求然后进行页面解析,根本就没有自动爬起来这也叫爬虫?因此我结合自己的思路写了一下简单的爬虫. 一 算法简介 程序在思路上采用了广度优先算法,对未遍历过的链接逐次发起GET请求,然后对返回来的页面用正则表达式进行解析,取出其中未被发现的新链接,加入集合中,待下一次循环时遍历. 具体实现上使用了Map<String, Boolean>,键值对分别是链接和是否被遍历标志.程序中使用了两个Map集

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

    说到爬虫,使用Java本身自带的URLConnection可以实现一些基本的抓取页面的功能,但是对于一些比较高级的功能,比如重定向的处理,HTML标记的去除,仅仅使用URLConnection还是不够的. 在这里我们可以使用HttpClient这个第三方jar包. 接下来我们使用HttpClient简单的写一个爬去百度的Demo: import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStr

  • 基于Java HttpClient和Htmlparser实现网络爬虫代码

    开发环境的搭建,在工程的 Build Path 中导入下载的Commons-httpClient3.1.Jar,htmllexer.jar 以及 htmlparser.jar 文件. 图 1. 开发环境搭建 HttpClient 基本类库使用 HttpClinet 提供了几个类来支持 HTTP 访问.下面我们通过一些示例代码来熟悉和说明这些类的功能和使用. HttpClient 提供的 HTTP 的访问主要是通过 GetMethod 类和 PostMethod 类来实现的,他们分别对应了 HTT

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

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

  • java编程实现简单的网络爬虫示例过程

    本项目中需要用到两个第三方jar包,分别为 jsoup 和 commons-io. jsoup的作用是为了解析网页, commons-io 是为了把数据保存到本地. 1.爬取贴吧 第一步,打开eclipse,新建一个java项目,名字就叫做 pachong: 然后,新建一个类,作为我们程序的入口. 这个作为入口类,里面就写一个main方法即可. public class StartUp { public static void main(String[] args) { } } 第二步,导入我们

  • Java HttpClient实现socks代理的示例代码

    HttpClient 实现 socks 代理 使用的环境 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.4.1</version> </dependency> <dependency> <groupId>org.apache.

  • 基于Java实现扫码登录的示例代码

    目录 基本介绍 原理解析 1. 身份认证机制 2. 流程概述 代码实现 1. 环境准备 2. 主要依赖 3. 生成二维码 4. 扫描二维码 5. 确认登录 6. PC 端轮询 7. 拦截器配置 效果演示 1. 工具准备 2. 数据准备 3. 扫码登录流程展示 结语 基本介绍 相信大家对二维码都不陌生,生活中到处充斥着扫码登录的场景,如登录网页版微信.支付宝等.最近学习了一下扫码登录的原理,感觉蛮有趣的,于是自己实现了一个简易版扫码登录的 Demo,以此记录一下学习过程. 实际上是面试的时候被问到

  • 基于Java实现中文分词系统的示例代码

    目录 1.问题描述 2.相关工作 3.系统框架和算法设计 3.1系统整体框架 1.问题描述 中文分词 (Chinese Word Segmentation) 指的是将一个汉字序列切分成一个一个单独的词.分词就是将连续的字序列按照一定的规范重新组合成词序列的过程.我们知道,在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字.句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂的多.困难的多. 而对于中文

  • 基于JAVA的短信验证码api调用代码实例

    本文实例为大家分享了JAVA的短信验证码api调用代码,供大家参考,具体内容如下 import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import jav

  • C#网络爬虫代码分享 C#简单的爬取工具

    公司编辑妹子需要爬取网页内容,叫我帮忙做了一简单的爬取工具 这是爬取网页内容,像是这对大家来说都是不难得,但是在这里有一些小改动,代码献上,大家参考 private string GetHttpWebRequest(string url) { HttpWebResponse result; string strHTML = string.Empty; try { Uri uri = new Uri(url); WebRequest webReq = WebRequest.Create(uri);

  • java网络爬虫连接超时解决实例代码

    本文研究的主要是java网络爬虫连接超时的问题,具体如下. 在网络爬虫中,经常会遇到如下报错.即连接超时.针对此问题,一般解决思路为:将连接时间.请求时间设置长一下.如果出现连接超时的情况,则在重新请求[设置重新请求次数]. Exception in thread "main" java.net.ConnectException: Connection timed out: connect 下面的代码便是使用httpclient解决连接超时的样例程序.直接上程序. package da

  • python教程网络爬虫及数据可视化原理解析

    目录 1 项目背景 1.1Python的优势 1.2网络爬虫 1.3数据可视化 1.4Python环境介绍 1.4.1简介 1.4.2特点 1.5扩展库介绍 1.5.1安装模块 1.5.2主要模块介绍 2需求分析 2.1 网络爬虫需求 2.2 数据可视化需求 3总体设计 3.1 网页分析 3.2 数据可视化设计 4方案实施 4.1网络爬虫代码 4.2 数据可视化代码 5 效果展示 5.1 网络爬虫 5.1.1 爬取近五年主要城市数据 5.1.2 爬取2019年各省GDP 5.1.3 爬取豆瓣电影

随机推荐