系列文章
- 秋名山涧--给班长的开车APP -- 用爬虫webmagic爬取数据(一)
- 秋名山涧--给班长的开车APP -- 用MySql结合JDBC保存数据到数据库(二)
- 秋名山涧--给班长的开车APP -- 用Rest API制作API接口(三)
接下来就是设计数据库了,采用MySql
因为我们想让手机端请求取到的数据是
元数据如图
上图的源代码在此
[{"picInfos":[{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/01.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/02.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/03.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/04.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/05.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/06.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/07.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/08.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/09.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/10.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/18/11.jpg","picTitle":null}],"webTitle":"青春是首歌,好好爱自己,致大家的毕业季"},{"picInfos":[{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/01.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/02.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/03.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/04.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/05.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/06.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/07.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/08.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/09.jpg","picTitle":null},{"picUrl":"http://mm.howkuai.com/wp-content/uploads/2017a/05/17/10.jpg","picTitle":null}],"webTitle":"长腿女神超爱运动,这身材让多少�潘扛∠�"}]
视图化显示展开是这样
经过这般考虑,SQL结构设计为俩个表meiziwebone和picinfos
meiziwebone设计
picinfos表设计
存数据之后的meiziwebone表
存数据之后的picinfos表
其中picInfos字段参数为
- id,表示图片序号,作为主键
- piUrl,表示突变的Url
注:这个表存的是所有图片的信息
meiziweb表中字段参数
- id是序号
- webTitle是MeiziTuModel中的webTitle字段
- picStarTId,代表当前网页图片对应在picInfos表中的起始位置
- size,代表当前网页图片的数量
举个栗子
比如meiziwebone中的数据是
表示的是第2条数据,picStartId是10,size是10张
然后去picInfos表里查数据,就是从第10张开始,然后往后面数10张,就是10到19都是这个2号网页对应的数据。
数据库结构设计好了,现在回到之前的爬虫程序中,
我们之前是直接用
.addPipeline(new ConsolePipeline())
输出的爬取数据到控制台
再后来还定制了一个用来下载图片的
.addPipeline(new PileLineTest())
现在我们重新定制一个PileLineTest11类实现接口Pipeline,用来操作保存数据到数据库中
首先我们先写好数据库操作的工具类
先在pom文件加入依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
存数据的数据库工具类
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 数据库的相关工具类,这个是用来测试数据库基本操作能不能用的
* <p>
* Created by Niwa on 2017/7/4.
*/
public class SqlUtilForSpider {
/**
*
* 连接数据库
* */
public static Connection getConn() {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/meizitu";
String username = "root";
String password = "root";
Connection conn = null;
try {
Class.forName(driver);
conn = (Connection) DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("数据库连接已建立");
return conn;
}
/**
* 查询妹子图表的数据,这里用于测试数据库读取的
*/
public static String getmeiziWebOne() {
Connection connection = getConn();
String sql = "select * from meiziwebone";
PreparedStatement preparedStatement;
try {
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
System.out.println("============================");
while (rs.next()) {
System.out.println(rs.getString("webtitle"));
System.out.println(rs.getInt("id"));
System.out.println(rs.getInt("picStartId"));
System.out.println(rs.getInt("picSize"));
}
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 存数据进meiziwebone表里
*
* @param id 主键,
* @param webtitle 当前网页的标题
* @param startid picinfos表中当前标题的网页存的图片的起始位置
* @param picSize 图片数量
*/
public static void insertDataFormeiziweboneTable(int id, String webtitle, int startid, int picSize) {
Connection connection = getConn();
PreparedStatement preparedStatement = null;
String sql = "insert into meiziwebone value(?,?,?,?)";
try {
connection.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
try {
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
//存数据进数据库,parammeterIndex分别1,2,3,4分别表示上面的四个?号
preparedStatement.setInt(1, id);
preparedStatement.setString(2, webtitle);
preparedStatement.setInt(3, startid);
preparedStatement.setInt(4, picSize);
preparedStatement.executeUpdate();
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("数据-----" + "id:" + id + "," + "webtitle:" + webtitle + "," + "startid:" + startid + "," + "picSize:" + picSize + "插入完成");
}
/**
* 存数据进picinfos表里
*
* @param id 主键,
* @param picUrl 当前图片
*/
public static void insertDataForpicinfosTable(int id, String picUrl) {
Connection connection = getConn();
PreparedStatement preparedStatement = null;
String sql = "insert into picinfos value(?,?)";
try {
connection.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
try {
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
//存数据进数据库
preparedStatement.setInt(1, id);
preparedStatement.setString(2, picUrl);
preparedStatement.executeUpdate();
connection.commit();
connection.close();
System.out.println("数据库连接已关闭");
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("数据-----" + "id:" + id + "," + "picUrl:" + picUrl + "插入完成");
}
}
测试
在类PileLineTest11编写
import model.MeiTuModel;
import model.PicInfo;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;
import utils.SqlUtilForSpider;
import java.util.ArrayList;
import java.util.List;
/**
* ·
* Created by Niwa on 2017/6/30.
*/
public class PileLineTest11 implements Pipeline {
public PileLineTest11() {
System.out.println("PileLineTest11初始化");
}
private int downLoadPosition = 1;
/**
* 表picInfos中的id
*/
private int picIndex = 1;
/**
* 表meiziwebone中的id
*/
private int webIndex = 1;
/**
* 表meiziwebone中的picStartId
* 某网页图片地址在picInfos中起始位置
*/
private int picStartIndex = 1;
public void process(ResultItems resultItems, Task task) {
//抓取时这里第一个值是空值所以不要第一个值
if (downLoadPosition != 1) {
// System.out.println("图片抓取页为:" + resultItems.getRequest().getUrl());
List<String> urls = resultItems.get("picName");
int urlsSize = urls.size();
for (String url : urls) {
//图片地址数据存入数据库中表picinfos
SqlUtilForSpider.insertDataForpicinfosTable(picIndex++, url);
}
//图片地址数据存入数据库中表meiziwebone
if (!(resultItems.get("webTitle").toString().equals(null))) {
SqlUtilForSpider.insertDataFormeiziweboneTable(webIndex++, resultItems.get("webTitle").toString(), picStartIndex, urlsSize);
}
picStartIndex += urlsSize;
System.out.println("抓取图片序号为" + downLoadPosition + "开始");
//下载图片的for循环,当前存入数据库,不保存在本地,故注释掉了
// try {
// for (int i = 0; i < urls.size(); i++) {
//// DownLoadImage.downLoad(urls.get(i), "pic" + i + ".jpg", "D:\\webmagic\\Spider3\\pic" + downLoadPosition);
// DownLoadImage.downLoad(urls.get(i), "pic" + i + ".jpg", "D:\\webmagic\\Spider4\\" + resultItems.get("webTitle"));
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
try {
//每次抓取一个网页后休眠随机毫秒,模拟用户操作
long random = new Double(Math.random() * 1000).longValue();
Thread.sleep(random);
System.out.println("随机时间:" + random + "毫秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
downLoadPosition++;
}
}
main方法里改为
Spider.create(new MeituRepoProcessor())
.addUrl("http://www.meizitu.com/")
.addPipeline(new PileLineTest11())
.thread(1)
.run();
运行输出控制台结果为
数据库连接已建立
数据库连接已关闭
数据-----id:1,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/01.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:2,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/02.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:3,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/03.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:4,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/04.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:5,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/05.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:6,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/06.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:7,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/07.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:8,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/08.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:9,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/06/02/09.jpg插入完成
数据库连接已建立
数据-----id:1,webtitle:我肯定在这样的健美教室,我可以待一天,startid:1,picSize:9插入完成
抓取图片序号为2开始
随机时间:282毫秒
数据库连接已建立
数据库连接已关闭
数据-----id:10,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/01.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:11,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/02.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:12,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/03.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:13,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/04.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:14,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/05.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:15,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/06.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:16,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/07.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:17,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/08.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:18,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/09.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:19,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/19/10.jpg插入完成
数据库连接已建立
数据-----id:2,webtitle:美呆了!原来女生穿古装这么好看,startid:10,picSize:10插入完成
抓取图片序号为3开始
随机时间:183毫秒
数据库连接已建立
数据库连接已关闭
数据-----id:20,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/01.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:21,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/02.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:22,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/03.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:23,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/04.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:24,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/05.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:25,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/06.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:26,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/07.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:27,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/08.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:28,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/09.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:29,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/10.jpg插入完成
数据库连接已建立
数据库连接已关闭
数据-----id:30,picUrl:http://mm.howkuai.com/wp-content/uploads/2017a/05/18/11.jpg插入完成
数据库连接已建立
```
---
当然这是部分结果,接着打开数据库
![meiziwebone表](http://upload-images.jianshu.io/upload_images/3515789-2b303166be850ca4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![picInfos表](http://upload-images.jianshu.io/upload_images/3515789-7867af9cae16deae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
发现已经存数据成功了
---
######接着是查询数据
---
**创建查询数据的工具类SqlUtilForSelectData**
```
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import model.MeiTuModel;
import model.PicInfo;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 数据库的相关工具类
* <p>
* Created by Niwa on 2017/7/4.
*/
public class SqlUtilForSelectData {
private List<PicInfo> picInfos;
MeiTuModel meiTuModel = new MeiTuModel();
List<MeiTuModel> meiTuModels = new ArrayList<MeiTuModel>();
/**
* 查询picinfos中id为idd到end序号范围内的数据,最后返回List<PicInfo>
*
* @param idd 查询的起始号
* @param end 查询的结束序号
*/
public List<PicInfo> selectDataForpicinfosTable(int idd, int end) {
Connection connection = SqlUtilForSpider.getConn();
PreparedStatement preparedStatement = null;
String sql = "SELECT id, piUrl FROM picinfos WHERE id BETWEEN '" + idd + "' AND '" + end + "'";
PicInfo picInfo;
try {
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println("id:" + resultSet.getInt("id") + ",picUrl:" + resultSet.getString("piUrl"));
picInfo = new PicInfo(resultSet.getString("piUrl"));
// System.out.println("picInfo对象:" + picInfo.getPicUrl());
picInfos.add(picInfo);
}
connection.close();
System.out.println("数据库连接已关闭");
} catch (SQLException e) {
e.printStackTrace();
}
return picInfos;
}
/**
* 查询meiziwebone中id为start到end序号范围内的数据,并嵌套查询picinfos表,封装成MeiTuModel对象,最后返回List<MeiTuModel>
*
* @param start 查询的起始id
* @param end 查询的结束id
*/
public List<MeiTuModel> selectDataFormeiziweboneTable(int start, int end) {
Connection connection = SqlUtilForSpider.getConn();
PreparedStatement preparedStatement = null;
String sql = "SELECT id, webTitle, picStartId, picSize FROM meiziwebone WHERE id BETWEEN '" + start + "'AND '" + end + "'";
try {
preparedStatement = (PreparedStatement) connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println("id:" + resultSet.getInt("id") + ",webTitle:" + resultSet.getString("webTitle") + ",picStartId:" + resultSet.getString("picStartId") + ",picSize:" + resultSet.getString("picSize"));
picInfos = new ArrayList<PicInfo>();
//这里嵌套查询picinfos表查出picInfos信息用来封装成MeiTuModel对象
List<PicInfo> picInfos = selectDataForpicinfosTable(resultSet.getInt("picStartId"), (resultSet.getInt("picStartId") + resultSet.getInt("picSize") - 1));
meiTuModel = new MeiTuModel();
// for (PicInfo picInfo :
// picInfos
// ) {
// System.out.println("对象中的数据有:" + picInfo.getPicUrl());
// }
meiTuModel.setPicInfos(picInfos);
meiTuModel.setWebTitle(resultSet.getString("webTitle"));
meiTuModels.add(meiTuModel);
}
connection.close();
System.out.println("数据库连接已关闭");
} catch (SQLException e) {
e.printStackTrace();
}
return meiTuModels;
}
}
```
**测试**
在main方法中把爬虫的Spider.run()注释掉,然后加上
```
// Spider.create(new MeituRepoProcessor())
// .addUrl("http://www.meizitu.com/")
//// .addPipeline(new ConsolePipeline())
//// .addPipeline(new PileLineTest())
// .addPipeline(new PileLineTest11())
// .thread(1)
// .run();
SqlUtilForSelectData sqlUtilForSelectData = new SqlUtilForSelectData();
List<MeiTuModel> meiTuModels = sqlUtilForSelectData.selectDataFormeiziweboneTable(1, 20);
for (int i = 0; i < meiTuModels.size(); i++) {
System.out.println("meiTuModels序号--" + i + "--title:" + meiTuModels.get(i).getWebTitle());
for (int j = 0; j < meiTuModels.get(i).getPicInfos().size(); j++) {
System.out.println("meiTuModels序号--" + i + "--pic中的图片地址为:" + meiTuModels.get(i).getPicInfos().get(j).getPicUrl());
}
System.out.println("==========================================================");
}
}
```
---
运行,控制台部分结果如下图
![](http://upload-images.jianshu.io/upload_images/3515789-fd18a0efe9e80f23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
说明已查询成功了
---
源代码:**[SpiderDemo](https://github.com/minminaya/SpiderDemo)**
---
**注意事项**:
想不起来了
---
######资料:
[1 通过JDBC进行简单的增删改查(以MySQL为例)](http://www.cnblogs.com/wuyuegb2312/p/3872607.html)
[2 如何使用JDBC实现数据访问对象层(DAO)](http://www.cnblogs.com/yzqm666/p/5910581.html)
[3 java 爬虫实现爬豆瓣电影数据并存入mysql数据库](http://blog.csdn.net/diu_brother/article/details/50866455)
---
The End !