`
liuxinglanyue
  • 浏览: 564798 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用httpclient+jericho多线程实现抓取网页内容

阅读更多

来自:深沉的船

任务描述:

某图书网站按条件查询得出一页20条记录,每条记录有书目的简要信息和url链接到书的详细信息。
需要抓取网站图书的详细信息,保存到本地数据库中。

任务分析:

用httpclient模拟执行url将网站的信息取回,再用jericho包,分析页面元素,将需要的信息取出,保存到数据库中。

因为数据量比较大,还是采用多线程的方式来执行抓取详细页面,分析获得数据。


处理过程:

 


按条件查询到图书列表信息后,主线程不停的下翻页面,分析每本图书的详细url,将url保存到一个ArrayList中,启多个子线程分别去抓取详细页面的信息。然后利用jericho包分析页面数据并保存到数据库中。

代码实现截取如下:
......

 

public class BookCatcher 
{ 
    private static ArrayList threads= new ArrayList();//存储未处理URL 
    public static boolean isFinished=false; 
    
  public String getUrl() { 
   try { 
    synchronized (threads) { 
     if (threads.size() > 0) { 
      String tmp = String.valueOf(threads.get(0)); 
      threads.remove(0); 
      return tmp; 
     } else 
      return null; 
    } 
   } catch (Exception e) { 
    return null; 
   } 
  } 
    public void process(){ 
        //处理预处理 
       //下面开10个线程等待处理 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
     new Thread(new Processer(this)).start(); 
 
       
     ....    
     for(int j=0;j<pages;j++)//从第一页翻到最后一页 
     { 
    ... 
    source = CommonUtil.getSourceByUrl(url); 
    List<Element> elements = source.getAllElementsByClass("ProductTitle");   
    for (Element element : elements){  
     String href = element.getContent().getFirstStartTag().getAttributeValue("href");   
       
     if (href!=null && !"".equals(href)){   
       synchronized (threads) { 
        threads.add(bookurl);// 把URL存进去      
       }     
     }  
 
     } 
     isFinished=true; //主线程处理完所有的url 
} 
 
class Processer implements Runnable 
{ 
    BookCatcher c; 
    public Processer(BookCatcher c) 
    { 
        this.c = c; 
    } 
    public void run() 
    { 
        String bookUrl = null; 
        while((bookUrl=c.getUrl())!=null || !BookCatcher.isFinished)  //当还有记录时就处理        
        { 
            if(bookUrl!=null) 
            { 
          //处理分析页面数据并将数据保存到数据库 
               
       Source source = CommonUtil.getSourceByUrl(bookUrl); 
       String tmp = ""; 
    
       BookBean bean = new BookBean(); 
       bean.setStoreBookUrl(bookUrl); 
        
       //书名 
       StartTag tag = source.getFirstStartTagByClass("BookTitle"); 
       tmp = tag.getRenderer().toString(); 
       bean.setName(tmp); 
   
       //作者 
       tag = source.getFirstStartTagByClass("bookAuthor"); 
       if (tag!=null){ 
        List<StartTag> list = tag.getElement().getAllStartTags(HTMLElementName.A); 
        if (list.size()>0) 
         bean.setAuthor(list.get(0).getElement().getContent().toString()); 
       } 
        
       //书籍图片 
       tag = source.getFirstStartTag("id", "BookImage", false); 
       if (tag!=null) 
        bean.setPicUrl(tag.getAttributeValue("src").trim()); 
        
       StartTag tagLeft = source.getFirstStartTagByClass("Left"); 
       tmp=tagLeft.getRenderer().toString(); 
       List<String> resList = new ArrayList<String>(); 
       String[] leftArray = tmp.split("·"); 
       for (String str:leftArray){       
        if ("".equals(str)) continue; 
        resList.add(str);       
       } 
       StartTag tagRight = source.getFirstStartTagByClass("Right"); 
       tmp = tagRight.getRenderer().toString();      
       String[] rightArray = tmp.split("·"); 
       for (String str:rightArray){ 
        if ("".equals(str)) continue; 
        resList.add(str);       
       }      
       for (String str:resList){ 
        try{ 
         String name = CommonUtil.getString(str.split(":")[0]); 
         String value = CommonUtil.getString(str.split(":")[1]); 
          if ("ISBN".equals(name)) bean.setIsbn(value);    
         if ("出版社".equals(name)) bean.setPublisherOrg(value); 
         if ("页码".equals(name)) bean.setPageNum(value); 
         if ("出版日期".equals(name)) bean.setPublishDate(value);       
                   
         if ("装帧".equals(name)) bean.setWrapType(value); 
         if ("开本".equals(name)) bean.setFormat(value); 
        }catch(ArrayIndexOutOfBoundsException ee){} 
       } 
        
             
       //定价 
       tag = source.getFirstStartTagByClass("BookPrice"); 
       String price = tag.getElement().getAllStartTags(HTMLElementName.STRIKE).get(0).getRenderer().toString(); 
       price = price.substring(1,price.length()); 
       bean.setPrice(price); 
        
       //零售价格 
       tag = source.getFirstStartTagByClass("DetailPrice"); 
       if (tag!=null) 
        bean.setStorePrice(tag.getElement().getAllStartTagsByClass("OurPrice").get(0).getRenderer().toString()); 
       else 
        bean.setStorePrice("0"); 
                
       List<StartTag> tagList = source.getAllStartTagsByClass("ContentValue"); 
       if(tagList!=null && tagList.size()>1){ 
        // 内容简介 
        tag = tagList.get(0); 
        tmp = tag.getRenderer().toString().trim(); 
        if(tmp.length()>2000) 
         tmp = tmp.substring(0, 1990)+"..."; 
        bean.setContent(tmp); 
   
       } 
       new BookBO().saveBook(bean); 
           
           
            }else//如果没标志处理则休眠一秒再重新开始处理 
            { 
                try 
                { 
                    Thread.sleep(1000); 
                } catch (InterruptedException e) 
                { 
                    e.printStackTrace(); 
                } 
            } 
        } 
        
    } 
} 
 
  
 
  
 
 
//CommonUtil中的方法,通过httpclient提交到url,返回的页面信息装入jericho的source 
 public static Source getSourceByUrl(final String url) { 
  Source source = null; 
  HttpClient httpClient = new HttpClient(); 
  GetMethod getMethod = new GetMethod(url); 
  getMethod.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); 
 
  getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
    new DefaultHttpMethodRetryHandler()); 
  try { 
   int statusCode = httpClient.executeMethod(getMethod); 
   if (statusCode != HttpStatus.SC_OK) { 
    log.error("Method failed: " + getMethod.getStatusLine()); 
   } 
 
   source = new Source(getMethod.getResponseBodyAsStream()); 
  } catch (HttpException e) { 
   log.error("Please check your provided http address!"); 
   e.printStackTrace(); 
  } catch (IOException e) { 
   e.printStackTrace(); 
  } finally { 
   getMethod.releaseConnection(); 
  } 
  return source; 
 } 
分享到:
评论

相关推荐

    基于SSM+maven+httpClient+jsoup实现小说网站项目.zip

    基于SSM+maven+httpClient+jsoup实现小说网站项目 基于SSM+maven+httpClient+jsoup实现小说网站项目 基于SSM+maven+httpClient+jsoup实现小说网站项目 基于SSM+maven+httpClient+jsoup实现小说网站项目 基于SSM+...

    基于SSM+maven+httpClient+jsoup实现小说网站项目源码.zip

    基于SSM+maven+httpClient+jsoup实现小说网站项目源码.zip 基于SSM+maven+httpClient+jsoup实现小说网站项目源码.zip 基于SSM+maven+httpClient+jsoup实现小说网站项目源码.zip 基于SSM+maven+httpClient+jsoup实现...

    HttpClient+ Spring实现多线程

    标题 "HttpClient + Spring 实现多线程" 涉及到的是如何在Spring框架中使用Apache HttpClient库来创建一个支持多线程的HTTP客户端服务。Apache HttpClient是一个强大的HTTP客户端API,它提供了丰富的功能来处理HTTP...

    httpClient+jsoup 抓取网页数据

    在IT领域,网络数据抓取是一项重要的技能,它允许我们从网页中提取所需的信息,用于数据分析、内容聚合或自动化任务。HttpClient和Jsoup是两个Java库,分别专注于HTTP通信和HTML解析,它们常被组合使用来高效地抓取...

    Httpclient+testng接口测试小例子

    在"Httpclient+testng接口测试小例子"中,我们将使用以下步骤进行接口测试: 1. **环境准备**:首先,确保项目中已经添加了Apache HttpClient和TestNG的依赖。这些通常通过Maven或Gradle等构建工具进行管理,通过在...

    httpClient+jsoup抓取网页数据实例和jar包

    在IT领域,网络爬虫是获取网页数据的重要手段,而HttpClient和Jsoup是两种常用的Java库,用于实现这一目的。HttpClient提供了低级别的HTTP通信能力,而Jsoup则是一个解析和操作HTML文档的强大工具。本教程将详细介绍...

    httpclient著名的多线程框架

    在Android系统中,由于主线程不能执行耗时操作,否则会引发ANR(Application Not Responding)错误,因此利用HttpClient的多线程特性,可以将网络请求放到后台线程,保证UI的流畅性。 HttpClient的使用步骤通常包括...

    Jsoup+httpclient模拟登陆和抓取页面.pdf

    Jsoup+httpclient模拟登陆和抓取页面.pdf

    基于SSM+maven+httpClient+jsoup实现的java爬虫项目,一个完整的小说网站.zip

    【标题】中的“基于SSM+maven+httpClient+jsoup实现的java爬虫项目”揭示了这个Java项目的核心技术和用途。下面将详细解释这些技术及其在项目中的作用: 1. **SSM框架**:SSM是Spring、SpringMVC和MyBatis的缩写,...

    爬虫:httpclient+jsoup

    - 对于大型网站,可以考虑分布式爬虫设计,利用多台机器并行抓取。 总之,HttpClient和Jsoup是Java爬虫开发中的两个强大工具,它们结合使用能有效地抓取和解析网页信息。理解它们的工作原理和用法,对于构建高效的...

    HttpClient抓取网页Demo

    在本文中,我们将深入探讨HttpClient的基本用法,以及如何使用它来抓取网页内容。 首先,你需要在项目中引入HttpClient的依赖。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml &lt;groupId&gt;org....

    Jsoup+httpclient 模拟登陆和抓取

    Jsoup+httpclient 模拟...通过上述知识点,可以了解到使用Jsoup和HttpClient进行网页登录和内容抓取的完整流程和关键技术点。在实际开发中,这些知识点可以帮助开发者高效地处理HTML页面数据,实现对网页的自动化操作。

    HTTPClient + MQ + servlet

    开发者可能使用HTTPClient来模拟客户端,发送请求到一个基于servlet的服务器,而服务器则利用MQ来处理这些请求,实现服务间的通信和任务调度。 在实际开发中,这样的架构可以帮助我们构建出高性能、高可用的系统。...

    jsoup+httpclient+jar包

    HttpClient与JSoup结合使用,可以实现更高级的网页访问和数据获取。 **结合使用JSoup和HTTPClient** 将JSoup与HTTPClient结合,可以创建一个高效且灵活的网页爬虫。首先,HTTPClient负责发起HTTP请求,获取网页的...

Global site tag (gtag.js) - Google Analytics