java怎么做爬虫?java网络爬虫实例讲解

阳光 2021-06-02 15:41:25 java常见问答 9563

Java可以应用于很多种领域,当然用java也是可以做爬虫的,做爬虫,逻辑一定要理清,也就是说,一定要有逻辑顺序,那java怎么做爬虫?下面来我们就来给大家讲解一下这方面的实例。

首先,起点是什么?你可能觉得是main方法,其实不然,起点是你要知道你要获取网站中的哪些数据,然后针对要抓取的数据去写model。如下图,我要获取京东上的图书的价格,和图书名,还有图书的id(id是唯一标识,可作为数据表的主键)

java怎么做爬虫?java网络爬虫实例讲解.jpg

model

用来封装对象,我要抓取一本书的数据包括,书籍的id,书名及价格。ecliplse中生成set、get方法的快捷键是shift+alt+s然后选择生成setter、getter

package model;
public class JdModel
{
    private String bookID;
    private String bookName;
    private String bookPrice;
    public String getBookID()
    {
        return bookID;
    }
    public void setBookID(String bookID)
    {
        this.bookID = bookID;
    }
    public String getBookName()
    {
        return bookName;
    }
    public void setBookName(String bookName)
    {
        this.bookName = bookName;
    }
    public String getBookPrice()
    {
        return bookPrice;
    }
    public void setBookPrice(String bookPrice)
    {
        this.bookPrice = bookPrice;
    }
}

main

主方法,尽量要求简单,这里我就这样写了。这里面有注释,很好理解。

package main;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import db.MYSQLControl;
import model.JdModel;
import util.URLFecter;
public class JdongMain
{
    //log4j的是使用,不会的请看之前写的文章 static final Log logger = LogFactory.getLog(JdongMain.class);
    public static void main(String[] args) throws Exception
    {
        //初始化一个httpclient HttpClient client = new DefaultHttpClient();
        //我们要爬取的一个地址,这里可以从数据库中抽取数据,然后利用循环,可以爬取一个URL队列 String url="http://search.jd.com/Search?keyword=Python&enc=utf-8&book=y&wq=Python&pvid=33xo9lni.p4a1qb";
        //抓取的数据 Listbookdatas=URLFecter.URLParser(client, url);
        //循环输出抓取的数据 for (JdModel jd:bookdatas) {
        logger.info("bookID:" + jd.getBookID() + "\t" + "bookPrice:" + jd.getBookPrice() + "\t" + "bookName:" + jd.getBookName());
    }
    //将抓取的数据插入数据库 MYSQLControl.executeInsert(bookdatas);
}
}

util

util中包含两个文件,URLFecter 与HTTPUtils,其中URLFecter 调用了HTTPUtils类。

package util;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.util.EntityUtils;
import model.JdModel;
import parse.JdParse;
public class URLFecter
{
    public static ListURLParser(HttpClient client, String url) throws Exception
    {
        //用来接收解析的数据 ListJingdongData = new ArrayList();
        //获取网站响应的html,这里调用了HTTPUtils类 HttpResponse response = HTTPUtils.getRawHtml(client, url);
        //获取响应状态码 int StatusCode = response.getStatusLine().getStatusCode();
        //如果状态响应码为200,则获取html实体内容或者json文件 if(StatusCode == 200){
        String entity = EntityUtils.toString(response.getEntity(), "utf-8");
        JingdongData = JdParse.getData(entity);
        EntityUtils.consume(response.getEntity());
    }
    else
    {
        //否则,消耗掉实体 EntityUtils.consume(response.getEntity());
    }
    return JingdongData;
}
}

上面程序调用的HTTPUtils这个类,以下是HTTPUtils这个类。

package util;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicHttpResponse;
public abstract class HTTPUtils
{
    public static HttpResponse getRawHtml(HttpClient client, String personalUrl)
    {
        //获取响应文件,即html,采用get方法获取响应数据 HttpGet getMethod = new HttpGet(personalUrl);
        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1
            , HttpStatus.SC_OK, "OK");
        try
        {
            //执行get方法 response = client.execute(getMethod);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            // getMethod.abort(); }
            return response;
        }
    }

parse

parse主要是通过Jsoup来解析html文件。并将解析后的数据,封装在List集合中,将数据通过层层返回到main方法中。

package parse;
import java.util.ArrayList;
import java.util.List;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import model.JdModel; /** 用于将上面传下来的html解析,获取我们需要的内容* 解析方式,采用Jsoup解析,有不明白Jsoup的可以上网搜索API文档* Jsoup是一款很简单的html解析器*/
public class JdParse
{
    public static ListgetData(String html) throws Exception
    {
        //获取的数据,存放在集合中 Listdata = new ArrayList();
        //采用Jsoup解析 Document doc = Jsoup.parse(html);
        //获取html标签中的内容 Elements elements=doc.select("ul[class=gl-warp clearfix]").select("li[class=gl-item]");
        for (Element ele: elements)
        {
            String bookID = ele.attr("data-sku");
            String bookPrice = ele.select("div[class=p-price]")
                .select("strong")
                .select("i")
                .text();
            String bookName = ele.select("div[class=p-name]")
                .select("em")
                .text();
            //创建一个对象,这里可以看出,使用Model的优势,直接进行封装 JdModel jdModel=new JdModel();
            //对象的值 jdModel.setBookID(bookID);
            jdModel.setBookName(bookName);
            jdModel.setBookPrice(bookPrice);
            //将每一个对象的值,保存到List集合中 data.add(jdModel);
        }
        //返回数据 return data;
    }
}

db

db中包含两个java文件,MyDataSource,MYSQLControl。这两个文件的作用已在前面说明了。

package db;

import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
public class MyDataSource
{
    public static DataSource getDataSource(String connectURI)
    {
        BasicDataSource ds = new BasicDataSource();
        //MySQL的jdbc驱动 ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUsername("root"); //所要连接的数据库名 ds.setPassword("112233"); //MySQL的登陆密码  ds.setUrl(connectURI);
        return ds;
    }
}

下面是MYSQLControl,主要使用QueryRunner方法操作数据库,使用时是batch方法。

package db;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import model.JdModel; /** Mysql操作的QueryRunner方法* 一个数据库操作类,别的程序直接调用即可*/
public class MYSQLControl
{
    //根据自己的数据库地址修改 static DataSource ds = MyDataSource.getDataSource("jdbc:mysql://127.0.0.1:3306/moviedata");
    static QueryRunner qr = new QueryRunner(ds);
    //第一类方法 public static void executeUpdate(String sql){
    try
    {
        qr.update(sql);
    }
    catch (SQLException e)
    {
        e.printStackTrace();
    }
}
//第二类数据库操作方法 public static void executeInsert(Listjingdongdata) throws SQLException {
/* * 定义一个Object数组,行列 * 3表示列数,根据自己的数据定义这里面的数字 * params[i][0]等是对数组赋值,这里用到集合的get方法 * */
Object[][] params = new Object[jingdongdata.size()][3];
for (int i = 0; i < params.length; p = "")
{
    <= "" >
    params[i][0] = jingdongdata.get(i)
        .getBookID();
    params[i][1] = jingdongdata.get(i)
        .getBookName();
    params[i][2] = jingdongdata.get(i)
        .getBookPrice();
}
qr.batch("insert into jingdongbook (bookID, bookName, bookPrice)" +
    "values (?,?,?)", params);
System.out.println("执行数据库完毕!" + "成功插入数据:" + jingdongdata.size() + "条");
}
}

再看main方法

在main方法中有这样一句程序,这便是调用了操作数据库MYSQLControl程序,将抓取的数据插入到数据库中了

MYSQLControl.executeInsert(bookdatas);

爬虫效果展示

1.jpg

到此,便完成了这个简单网络爬虫的编程工作,下面来看看程序运行的结果吧。

数据库中的结果如下:

2.jpg

做爬虫,一定要有清晰的逻辑,并且抓取算法,将这些都理清之后,利用java就可以做爬虫了。最后大家如果想要了解更多java实例知识,敬请关注奇Q工具网。

推荐阅读:

java如何设计二叉树类结构?用java设计一个二叉树类的结构

java返回值怎么用?return返回值如何应用?

java界面如何添加图片?java图片按钮的大小怎么设置?