【实验目的】
- 熟悉从网上爬取数据到将数据进行可视化的全部流程,通过实例了解并掌握每个过程。
- 了解爬虫爬取数据的原理,并选择一种语言编程,将数据获取到数据库。
- 熟练使用 eclipse 中 Java 语言操作数据库数据。
- 了解 ECharts 中各种图的特性,选取合适的图将所获取到的数据进行可视化展示。
【实验原理】
爬虫爬取数据原理:
网络爬虫是捜索引擎抓取系统的重要组成部分。爬虫的主要目的是将互联网上的网页下载到本地形成一个或联网内容的镜像备份。一个通用的网络爬虫的框架如图所示:
网络爬虫的基本工作流程如下:
- 首先选取一部分精心挑选的种子URL;
- 将这些URL放入待抓取URL队列;
- 从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL放进已抓取URL队列。
- 分析已抓取URL队列中的URL,分析其中的其他URL,并且将URL放入待抓取URL队列,从而进入下一个循环。
本次实验只是简单的获取商城中书籍的价格以及名称,所以只需要写相应获取数据的代码就行,并没有循环抓取网页中相关链接以获取更多数据。
操作数据库原理:
新建servlet,通过JDBC连接数据库进行查询。
ECharts实现原理:
echarts页面的开发主要有两部步:
- 设定一个存放图标的div;
- 调用画图方法进行画图;
初始化将要存放echarts图表的DOM对象(div);
myChart = echarts.init(document.getElementById(‘main’));
编写echarts图表需要的属性(option);
var options = { …… };
将属性注入图表
myChart.setOption(options);
【实验环境】
Eclipse 4.5.1
操作系统 win7 64位
MySQL服务
Navicat for MySQL 可视化工具
Python 2.7.13 (Anaconda2 4.3.1 64-bit)
Python 2.7 MySQL-python-1.2.3
tomcat服务器
【实验内容】
- 启动MySQL服务,使用MySQL可视化工具创建数据库,名为python,新建表 ajax_table 和
python_table,在两张表中包含主键id(设置为自增),书籍名称 bookName,书籍价格 bookPrice。
- 现从京东商城中使用python工具获取ajax书籍以及python书籍的书籍名称和书籍价格。
使用eclipse完成数据库访问,获取数据库两张表中的数据。
将获取到的数据使用ECharts中南丁格尔图展示出来,效果如下:
【实验步骤】下载Python工具。
(1)进入Anaconda2下载相应系统相应版本的Python工具。
(2)进入Python 2.7 MySQL-python-1.2.3下载eclipse中python操作数据库的包
(3)进入PyDev插件下载eclipse中的python插件
安装eclipse插件
(1)把下载后的pydev压缩包内的plugins和features文件夹内的内容复制到eclipse的解压目录的相应文件夹中,重启eclipse。(2)打开eclipse中的菜单window,选择Preference.找到左侧边栏的pydev,展开,点击Interpreters->Python Interpreter
(3)点击new,找到python安装路径, ok就行了
利用工具爬取数据
(1)打开命令窗口(cmd),输入如下命令,会自动打开浏览器,点击右上角
new->python2,会进入命令行模式,这里你可以测试代码,查看你爬取的数据是否是你想要的:jupyter notebook
(2)输入以下代码,按ctrl+回车,你将看到相应数据,爬取成功#coding:utf8 import urllib2 from bs4 import BeautifulSoup root_url="http://search.jd.com/Search?keyword=Python&enc=utf-8&book=y&wq=Python&pvid=33xo9lni.p4a1qb" response = urllib2.urlopen(root_url) html_cont = response.read() soup = BeautifulSoup(html_cont,'html.parser', from_encoding='utf-8') res_data = {} links = soup.select('.gl-i-wrap') count = 1 for link in links: if count <= 10: res_data['name']=link.select(".p-name a em")[0].text res_data['price']=float(link.select(".p-price strong i")[0].text) print res_data['name'] count = count +1
(3)新建一个PyDev工程,取名为 bookprice
(4)创建包取名为 book_spider,右击包名 ->new->PyDev Module,取名python_book(ajax_book)。写一个主函数,将测试好的代码粘贴进去,并添加对python对数据库的操作,这样就将所爬取得数据写进了数据库中(我这里限制爬取个数为10条,并且这只是获取到了Python书籍的书籍,进行相同操作获取ajax数据)#coding:utf8 import MySQLdb import urllib2 from bs4 import BeautifulSoup if __name__=="__main__": root_url="http://search.jd.com/Search?keyword=Python&enc=utf-8&book=y&wq=Python&pvid=33xo9lni.p4a1qb" response = urllib2.urlopen(root_url) conn = MySQLdb.Connect(host='127.0.0.1', user='hive', passwd='123456', port=3306, charset='utf8', db='python') cursor = conn.cursor() html_cont = response.read() soup = BeautifulSoup(html_cont,'html.parser', from_encoding='utf-8') res_data = {} links = soup.select('.gl-i-wrap') count = 1 for link in links: if count <= 10: res_data['name']=link.select(".p-name a em")[0].text res_data['price']=float(link.select(".p-price strong i")[0].text) try: sql = "insert into python_table(bookName,bookPrice) values('%s',%f)" % (res_data['name'],res_data['price']) cursor.execute(sql) conn.commit() except: print 'craw failed' count = count-1 count=count+1 cursor.close() conn.close()
4. 切换工作环境,改为javaEE
新建动态WEB项目,取名为 book ,在 Java Resources->src 中创建四个包(cn.lk.Dao , cn.lk.DBUtil , cn.lk.Servlet , cn.lk.VO), 在 WebContent 中创建一个名为 book.jsp 的文件,分别实现各个模块代码的实现
(1)在 cn.lk.VO 中创建实体类,命名为 Book.java 。打开 Book.java 页面,编写实体类代码(属性名及数据类型与建表时一致)
```
package cn.lk.VO;
public class Book {
private String bookName;
private float bookPrice;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public float getBookPrice() {
return bookPrice;
}
public void setBookPrice(float bookPrice) {
this.bookPrice = bookPrice;
}
@Override
public String toString() {
return "book [bookName=" + bookName + ", bookPrice=" + bookPrice + "]";
}
public Book(String bookName, float bookPrice) {
super();
this.bookName = bookName;
this.bookPrice = bookPrice;
}
public Book(){}
}
```
(2)在cn.lk.DBUtil中创建类DBUtil.java,编写代码(实现与数据库的连接)
```
package cn.lk.DBUtil;
import java.sql.DriverManager;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
public class DBUtil {
private static final String DBDriver="org.gjt.mm.mysql.Driver";
private static final String DBURl="jdbc:mysql://localhost:3306/python";
private static final String DBUser="hive";
private static final String DBPassword="123456";
private static Connection conn=null;
static{
try {
Class.forName(DBDriver);
conn=(Connection) DriverManager.getConnection(DBURl,DBUser,DBPassword);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void labManageDButil(){
}
public static Connection getConnection(){
return conn;
}
public void close(){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
```
(3)在cn.lk.Dao包中创建类BookDao.java ,编写代码(实现对数据库的查询操作)
```
package cn.lk.Dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
import cn.lk.DBUtil.DBUtil;
import cn.lk.VO.Book;
public class BookDao {
public List<Book> getPythonData(){
Connection conn = DBUtil.getConnection();
String sql = "select bookName,bookPrice from python_table;";
ResultSet set = null;
Statement stmt = null;
List<Book> list = new ArrayList<Book>();
try {
stmt = (Statement) conn.createStatement();
set = stmt.executeQuery(sql);
while (set.next()) {
Book bean = new Book();
bean.setBookName(set.getString("bookName"));
bean.setBookPrice(set.getFloat("bookPrice"));
list.add(bean);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return list;
}
public List<Book> getAjaxData(){
Connection conn = DBUtil.getConnection();
String sql = "select bookName,bookPrice from ajax_table;";
ResultSet set = null;
Statement stmt = null;
List<Book> list = new ArrayList<Book>();
try {
stmt = (Statement) conn.createStatement();
set = stmt.executeQuery(sql);
while (set.next()) {
Book bean = new Book();
bean.setBookName(set.getString("bookName"));
bean.setBookPrice(set.getFloat("bookPrice"));
list.add(bean);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return list;
}
}
```
(4)在cn.lk.Servlet包中创建类BookServlet.java ,实现代码(调用方法将Dao层获取到的数据传到 jps 界面 )
```
package cn.lk.Servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import cn.lk.Dao.BookDao;
import cn.lk.VO.Book;
/**
* Servlet implementation class PieServlet
*/
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public BookServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
BookDao pd = new BookDao();
List<Book> python = pd.getPythonData();
List<Book> ajax = pd.getAjaxData();
String jsonString = JSON.toJSONString(python);
String jsonString_Java = "#"+JSON.toJSONString(ajax);
System.err.println(jsonString);
//System.err.println(jsonString_Java);
PrintWriter out = response.getWriter();
out.print(jsonString);
out.print(jsonString_Java);
System.out.println(python.toString());
System.out.println(ajax.toString());
out.flush();
out.close();
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
```
(5)打开WebContent->WEB-INF 中的web.xml,配置相关映射,代码如下:
```
<?xml version="1.0" encoding="UTF‐8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display‐name></display‐name>
<servlet>
<servlet-name>BookServlet</servlet-name>
<servlet-class>cn.lk.Servlet.BookServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BookServlet</servlet-name>
<url-pattern>/BookServlet</url-pattern>
</servlet-mapping>
</web‐app>
```
(6)导入相应JAR包与JS包
在lib目录中复制进去相应JAR包,在WebContent中创建目录echarts,将所需js包放入即可
(7)在jps界面编写代码(获取传过来的数据,并使用ECharts技术,实现南丁格尔图可视化)
```
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title></title>
<script type="text/javascript" src="echarts/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="echarts/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width: 100%;height:100%; "></div>
</body>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
myChart.setOption({
title : {
text: '书籍价格',
subtext: '来自京东',
x:'center'
},
tooltip : {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'right',
data: []//不修改,从数据库调取
},
series : [
{
name:'python',
type: 'pie',
radius : [30,110],
center: ['25%', '30%'],
data:[],//不修改,从数据库调取
roseType : 'radius',
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
{
name:'ajax',
type: 'pie',
radius : [30,110],
center: ['25%', '80%'],
data:[],//不修改,从数据库调取
roseType : 'radius',
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
});
// 异步加载数据
var python_price = [];
var python_name = [];
var ajax_price = [];
var ajax_name = [];
var python = [];
var ajax = [];
$.post("./BookServlet", function(datas){
//alert(datas)
var arr = datas.split("#");
/*for(var i=0;i<arr.length;i++){
alert(arr[i])
} */
var pythons = JSON.parse(arr[0]);
var ajaxs = JSON.parse(arr[1]);
for(var m=0;m<pythons.length;m++){
python_name.push(pythons[m].bookName);
python.push({"name":pythons[m].bookName,"value":pythons[m].bookPrice});
python_price.push(pythons[m].bookPrice);
}
for(var n=0;n<ajaxs.length;n++){
ajax_name.push(ajaxs[n].bookName);
ajax.push({"name":ajaxs[n].bookName,"value":ajaxs[n].bookPrice});
ajax_price.push(ajaxs[n].bookPrice);
}
for(var i=0;i<ajax_name.length;i++){
python_name.push(ajax_name[i])
}
// 填入数据
myChart.setOption({
legend: {
//类别
data: python_name
},
series: [{
// 根据名字对应到相应的系列
data: python
},{
data: ajax
}]
});
// 使用刚指定的配置项和数据显示图表。
});
</script>
</html>
```
(8)tomcat服务器上运行book.jsp文件,将链接复制到浏览器中,查看效果图