当前位置:文档之家› 信息检索期末论文

信息检索期末论文

本科生课程论文基于网络爬虫的房产信息平台原型学生姓名杨宇帆所在专业信息管理与信息系统所在班级信管1111目录摘要 (I)1项目背景 (1)1.1收集房东信息 (1)1.2收集房客信息 (1)1.3通过房源管理软件查看信息 (1)1.4方便移动办公查阅 (1)2平台原型的实现 (1)2.1信息收集与整理 (2)2.2数据库设计 (2)2.2.1概念结构设计 (2)2.2.2逻辑结构设计 (3)2.2.3数据库的实施 (3)2.3下载页面信息到本地计算机 (4)2.4提取网页信息并保存至数据库 (4)3总结 (5)鸣谢 (6)参考文献 (7)附录 (8)摘要本房产信息平台原型基于网络爬虫技术和数据库技术,模拟了从目标网页采集数据、在本地进行信息提取并分类存入数据库的整个流程,体现了网络爬虫技术在信息收集和资源整合方面的独特优势。

本平台主程序采用Java语言进行编写,选用MySQL作为平台的关系型数据库。

关键词:网络爬虫;房产信息;数据提取基于网络爬虫的房产信息平台原型信息管理与信息系统,201111671130,杨宇帆1项目背景目前房地产为中国的支柱性产业,买卖房产是人们关注的一个重要问题。

中家房产公司为一家立足广州市场的房产中介公司,主营业务为买房、卖房、租房、房东提供房产中介服务。

为了能够在激烈的市场竞争中取得长远的发展,目前需要开发一套房产信息综合管理平台,实现以下四项目标:1.1收集房东信息从赶集网、58同城、安居客、搜房网四大平台中,搜集整理其中房东发布的出租房屋、出售房屋信息,保存到MySQL数据库(或sqlite数据库)。

1.2收集房客信息从赶集网、58同城、安居客、搜房网四大平台中,搜集整理其中想购买二手房、租赁房屋的需求,保存到MySQL数据库(或sqlite数据库)。

1.3通过房源管理软件查看信息需要借助一套房源管理软件,查看保存在MySQL数据库中的房源信息,和购买二手房/租赁房屋的需求,供中介从业人员使用,提高交易量,从而创造更多的利润。

1.4方便移动办公查阅移动办公已在现今社会的各行各业变得十分普遍。

由于中介从业人员经常需要带领客户实地看房,因此为了满足工作人员移动办公的需求,仍需开发一套房源管理的安卓版APP。

2平台原型的实现基于网络爬虫的房产信息平台原型的实现有4个主要步骤:信息收集与整理、数据库设计与建立、下载页面信息到本地计算机、提取网页信息并保存至数据库。

由于从各大平台中提取信息的做法在很大程度上是相同的,故本论文中的数据来源仅从赶集网进行获取,介绍本房产信息平台的实现。

2.1信息收集与整理根据项目需求,需要从赶集网、58同城、安居客、搜房网四大平台中,各挑出广州市区的卖房、出租房屋、求购二手房、求租房屋的信息。

以赶集网为例,由于借助了网络爬虫(Spider) 模块,我们只需要将各大网站的各类信息的结果列表(图1)记录下来即可,具体的单项信息将由网络爬虫动态获取。

图1:赶集网广州房产新房出售页面2.2数据库设计规范化数据库设计分为以下六个设计阶段:需求分析阶段、概念结构设计阶段、逻辑结构设计阶段、物理结构设计阶段、数据库实施阶段、数据库运行和维护阶段。

此步骤中我们设计出卖房房源信息表(SellHouseInfo)、出租房屋信息表(RentHouseInfo)、求购二手房需求表(BuyHouseDemand)、求租房屋需求表(RentHouseDemand)共4个数据表,确定了各表中的字段设置;并通过Navicat for MySQL(一款MySQL数据库管理软件)建立名为House的数据库,将上述数据表的结构建立起来。

下面我们对概念结构设计、逻辑结构设计和数据库实施阶段进行详细说明。

2.2.1概念结构设计依据需求分析可知,用户最终需要进行查询的信息分为以下4类:卖房房源信息、出租房屋信息、求购二手房需求信息和求租房屋需求信息,故将此4类信息分别设计成一个实体,且4个实体之间相互没有联系。

2.2.2逻辑结构设计根据概念结构与逻辑概念结构的1对1的转换原则,我们把概念结构中的4个实体分别转化为卖房房源信息表(SellHouseInfo)、出租房屋信息表(RentHouseInfo)、求购二手房需求表(BuyHouseDemand)、求租房屋需求表(RentHouseDemand)这4个数据表。

各表字段的设置如E-R图(图2)所示。

图2:House数据库E-R图2.2.3数据库的实施使用Navicat for MySQL,新建house数据库,设数据库字符集为UTF-8(图3)。

并建立数据表,设置其字段名、字段属性和字段长度(图4)。

图3:使用Navicat for MySQL新建数据库图4:设置数据表字段信息2.3 下载页面信息到本地计算机在Eclipse 的Java 工程中,我们引入了开源搜索引擎Lucene 的网络爬虫(Spider )模块(图5)。

借助该模块下的Spider ,初始化我们需要爬取的网页地址(下面简称url )集合;此时Dispatcher 开始分配器管理url 负责保存着url池,当Spider 爬取完某个网页的信息后分配其一个新的url ;然后通过Gather (网页收集器)调用URLClient ,与目标网站建立HTTP 链接并获取其网页的htmlString ,之后解析html ;同时调用WebAnalyzer 进行网页的解析和数据的提取;接下来Gather 将提取出来的数据以文本文档的形式保存到本地RawData 文件夹中,实现了将目标页面的下载到本地计算机的功能。

2.4 提取网页信息并保存至数据库为了实现JAVA 程序和MySQL 数据库的交互,我们使用了JDBC 的连接方式。

如图6,首先导入MySQL 的JDBC 驱动包;然后在共用的工具类com.house.util.DBHelper 中实现加载数据库驱动、建立连接、创建SQL 语句、执行语句等操作(DBHelper 程序见附录1)。

接着,Gather (网页收集器)在以文本文档形式保存网页信息的同时,调用DAO层图5:Spider 模块图6:在Java 工程内引入MySQL 的JDBC 驱动包(数据库访问层)数据库分配器(com.house.ctrl.GanJiCtrl,程序见附录2)。

数据库分配器调用DBHelper和com.house.dao.impl包下的方法,最终实现依据信息类型(指买房、出租房、求购二手房、求租房)的不同而将信息存入不同的数据表中(见图7)。

图7:求购二手房需求表中新增的数据3总结基于网络爬虫的房产信息平台原型实现了以赶集网为例,从网页进行信息的爬取、在本地进行信息的提取并分类存入数据库的功能,若要完全满足项目需求,仍需进一步的完善和修改。

纵观整个流程,我体会到在搜索引擎中广泛运用的网络爬虫在各行各业的信息采集工作中也起到了极其重要的作用。

这同时启发我们在日后的软件开发中,善于利用爬虫技术和数据库技术,它们不失为一个提取信息、整合网络资源的好方法。

然而,虽然互联网是一个开放的信息平台,但是爬虫技术也不能被不加限制地使用。

信息所涉及的隐私和版权问题也需要引起我们足够的重视。

鸣谢衷心感谢丁又专老师在我最初接触网络爬虫的时候给以耐心的指导和无私的帮助,在课程论文撰写阶段为我提供了格式上的指导与提醒。

除了在专业知识方面,丁老师教会了我如何管理时间,培养了我的终生学习的观念,以及更多地以切身行动教诲我们做人之道。

最后对老师再次表示衷心的感谢。

参考文献[1] 吴军.数学之美[M]. 北京:人民邮电出版社,2012.06.[2] 董宇. dySE:一个 Java 搜索引擎的实现,第 1 部分: 网络爬虫[CP/OL].https:///developerworks/cn/java/j-lo-dyse1, 2010-07-13 [3] java冒烟. HTTPCLIENT抓取网页内容[CP/OL]./kf/201307/226636.html, 2013-07-10[4] 水慕清风. java 获取网页源代码[CP/OL]./honglei_zh/article/details/8537394, 2013-01-24 [5] 李勇. 传智播客JDBC视频教程[Z/OL]./news/ee7c6ba4/46eb/494f/8656/8327b1d83c0a.shtml, 2012-06附录附录1:public class GanJiCtrl {// 1:购房 2:出租 3:求租 4:求购2手private int business;public GanJiCtrl(int business) {this.business = business;}/*** 描述:通过dao分配器,分配不同的业务存入不同的数据库*/public void daoDispatcher (String htmlDoc) {switch (this.business) {case 1:this.storageInSellHouseDB( AnalyzerGanJiUtil.getHtmlGanJiSellBea n(htmlDoc));break;case 2:this.storageInRentHouseDB( AnalyzerGanJiUtil.getHtmlGanJiRentBea n(htmlDoc));break;case 3:this.storageInRentDemandDB( AnalyzerGanJiUtil.getHtmlGanJiDemandB ean(htmlDoc));break;case 4:this.storageInBuyDemandDB( AnalyzerGanJiUtil.getHtmlGanJiDemandB ean(htmlDoc));break;}}public voidstorageInSellHouseDB(List<SellHousePo> list) {String sql = "insert into sellhouseinfo("+ "title ,housing_estate , housing_address , "+ "total_price ,unit_price , img_url ,"+ " family_situation , belongwhere) "+"values(?,?,?,?,?,?,?,?);";DBHelper.clearTableData("sellhouseinf o");DBHelper.resetAutoIncrement("sellhous einfo");SellHouseDaoImpl.getInstance().insert IntoSellHouse(sql, list);}public voidstorageInRentHouseDB(List<RentHousePo> list) {String sql = "insert into renthouseinfo("+ "title ,housing_estate , housing_address , "+ "rent_price , img_url ,"+ " family_situation , belongwhere) "+"values(?,?,?,?,?,?,?);";DBHelper.clearTableData("renthouseinf o");DBHelper.resetAutoIncrement("renthous einfo");RentHouseDaoImpl.getInstance().insert IntoRentHouse(sql, list);}public void storageInRentDemandDB (List<HouseDemandPo> list) {String sql = "insert into renthousedemand("+"demandContent ,housing_address ,price_range, "+ " publish_time , belongwhere) "+ "values(?,?,?,?,?);";DBHelper.clearTableData("renthousedem and");DBHelper.resetAutoIncrement("renthous edemand");HouseDemandDaoImpl.getInstance().inse rtIntoHouseDemand(sql, list);}public void storageInBuyDemandDB(List<HouseDemandPo> list) {String sql = "insert into buyhousedemand("+"demandContent ,housing_address ,price_range, "+ " publish_time , belongwhere) "+ "values(?,?,?,?,?);";DBHelper.clearTableData("renthousedem and");DBHelper.resetAutoIncrement("renthous edemand");HouseDemandDaoImpl.getInstance().inse rtIntoHouseDemand(sql, list);}}附录2:public class DBHelper {private static Connection con = null;private static PreparedStatement prestmt = null;private static ResultSet rs = null;// 连接数据库的参数private static String url = "";private static String username = "";private static String password = "";private static String driver = "";private static FileInputStream fis = null;private static Properties pp = null;// 加载驱动static {try {pp = new Properties();try {String path = ProjectPath.getProjectPath();fis = newFileInputStream(path + File.separator + "bin"+ File.separator + "dbinfo.properties");} catch(FileNotFoundException e) {e.printStackTrace();}try {pp.load(fis);} catch (IOException e) {e.printStackTrace();}url = pp.getProperty("url");username =pp.getProperty("username");password =pp.getProperty("password");driver =pp.getProperty("driver");Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();System.out.println("加载驱动失败");System.exit(0);} finally {try {fis.close();} catch (IOException e) {e.printStackTrace();}fis = null;}}public static Connection getConnector() {try {// 得到数据源con =DriverManager.getConnection(url, username, password);} catch (SQLException e) {e.printStackTrace();}return con;}// 查询功能public static List<List<Object>> executeQuery(String sql) {List<List<Object>> listRow;try {con = getConnector();listRow = newArrayList<List<Object>>();if (sql.length() != 0)prestmt =con.prepareStatement(sql);rs = prestmt.executeQuery();while (rs.next()) {List<Object> listCol = new ArrayList<Object>();for (int i = 1; i <=rs.getMetaData().getColumnCount(); i++) { listCol.add(rs.getString(i));}listRow.add(listCol);}} catch (Exception e) {e.printStackTrace();throw newRuntimeException(e.getMessage());} finally {close(rs, prestmt, con); // 关闭连接}return listRow;}/*** 描述:清空表中数据* @param tableName要清空的表名字* @return清空成功返回true,否则返回false*/public static booleanclearTableData(String tableName) {boolean result = true;try {con = getConnector();prestmt =con.prepareStatement(" SETforeign_key_checks=0;");prestmt.execute();prestmt = con.prepareStatement(" TRUNCATE TABLE " + tableName + ";");prestmt.execute();prestmt =con.prepareStatement(" SETforeign_key_checks=1 ;");prestmt.execute();} catch (SQLException e) {System.out.println("清空表的数据时发生错误");result = false;e.printStackTrace();} finally {close(null, prestmt, con);}return result;}/*** 描述:重置autoincrement的序号* @param tableName要重置的表* @return成功返回true,否则返回false*/public static boolean resetAutoIncrement(String tableName) {boolean result = true;try {con = getConnector();prestmt =con.prepareStatement("alter table " + tableName+ " auto_increment = 1");prestmt.execute();} catch (SQLException e) {result = false;e.printStackTrace();} finally {close(null, prestmt, con);}return result;}/*** 可进行增删改操作的函数* @param sql* @return操作成功与否的信号*/public static boolean updexecute(String sql) {boolean result = true;try {con = getConnector();if (sql.length() != 0)prestmt =con.prepareStatement(sql);prestmt.executeUpdate();// 执行操作} catch (Exception e1) {result = false;e1.printStackTrace();} finally {close(rs, prestmt, con);}return result;}// 关闭连接public static void close(ResultSet rs, Statement prestmt, Connection con) {try {if (rs != null)rs.close();} catch (SQLException e) {e.printStackTrace();} finally {if (con != null)try {con.close();} catch (SQLException e) {e.printStackTrace();}}}}。

相关主题