信息检索期末论文.docx
《信息检索期末论文.docx》由会员分享,可在线阅读,更多相关《信息检索期末论文.docx(19页珍藏版)》请在冰点文库上搜索。
![信息检索期末论文.docx](https://file1.bingdoc.com/fileroot1/2023-6/4/eeb90d2a-cce2-4a88-a82e-c873e541766d/eeb90d2a-cce2-4a88-a82e-c873e541766d1.gif)
信息检索期末论文
本科生课程论文
基于网络爬虫的房产信息平台原型
学生姓名
杨宇帆
所在专业
信息管理与信息系统
所在班级
信管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收集房东信息
从赶集网、58同城、安居客、搜房网四大平台中,搜集整理其中房东发布的出租房屋、出售房屋信息,保存到MySQL数据库(或sqlite数据库)。
2收集房客信息
从赶集网、58同城、安居客、搜房网四大平台中,搜集整理其中想购买二手房、租赁房屋的需求,保存到MySQL数据库(或sqlite数据库)。
3通过房源管理软件查看信息
需要借助一套房源管理软件,查看保存在MySQL数据库中的房源信息,和购买二手房/租赁房屋的需求,供中介从业人员使用,提高交易量,从而创造更多的利润。
4方便移动办公查阅
移动办公已在现今社会的各行各业变得十分普遍。
由于中介从业人员经常需要带领客户实地看房,因此为了满足工作人员移动办公的需求,仍需开发一套房源管理的安卓版APP。
平台原型的实现
基于网络爬虫的房产信息平台原型的实现有4个主要步骤:
信息收集与整理、数据库设计与建立、下载页面信息到本地计算机、提取网页信息并保存至数据库。
由于从各大平台中提取信息的做法在很大程度上是相同的,故本论文中的数据来源仅从赶集网进行获取,介绍本房产信息平台的实现。
5
6
2.1信息收集与整理
根据项目需求,需要从赶集网、58同城、安居客、搜房网四大平台中,各挑出广州市区的卖房、出租房屋、求购二手房、求租房屋的信息。
以赶集网为例,由于借助了网络爬虫(Spider)模块,我们只需要将各大网站的各类信息的结果列表(图1)记录下来即可,具体的单项信息将由网络爬虫动态获取。
图1:
赶集网广州房产新房出售页面
6.1
7数据库设计
规范化数据库设计分为以下六个设计阶段:
需求分析阶段、概念结构设计阶段、逻辑结构设计阶段、物理结构设计阶段、数据库实施阶段、数据库运行和维护阶段。
此步骤中我们设计出卖房房源信息表(SellHouseInfo)、出租房屋信息表(RentHouseInfo)、求购二手房需求表(BuyHouseDemand)、求租房屋需求表(RentHouseDemand)共4个数据表,确定了各表中的字段设置;并通过NavicatforMySQL(一款MySQL数据库管理软件)建立名为House的数据库,将上述数据表的结构建立起来。
下面我们对概念结构设计、逻辑结构设计和数据库实施阶段进行详细说明。
2.2
3概念结构设计
依据需求分析可知,用户最终需要进行查询的信息分为以下4类:
卖房房源信息、出租房屋信息、求购二手房需求信息和求租房屋需求信息,故将此4类信息分别设计成一个实体,且4个实体之间相互没有联系。
4逻辑结构设计
根据概念结构与逻辑概念结构的1对1的转换原则,我们把概念结构中的4个实体分别转化为卖房房源信息表(SellHouseInfo)、出租房屋信息表(RentHouseInfo)、求购二手房需求表(BuyHouseDemand)、求租房屋需求表(RentHouseDemand)这4个数据表。
各表字段的设置如E-R图(图2)所示。
图2:
House数据库E-R图
5数据库的实施
使用NavicatforMySQL,新建house数据库,设数据库字符集为UTF-8(图3)。
并建立数据表,设置其字段名、字段属性和字段长度(图4)。
图3:
使用NavicatforMySQL新建数据库
图4:
设置数据表字段信息
5.1下载页面信息到本地计算机
在Eclipse的Java工程中,我们引入了开源搜索引擎Lucene的网络爬虫(Spider)模块(图5)。
图5:
Spider模块
借助该模块下的Spider,初始化我们需要爬取的网页地址(下面简称url)集合;
此时Dispatcher开始分配器管理url负责保存着url池,当Spider爬取完某个网页的信息后分配其一个新的url;
然后通过Gather(网页收集器)调用URLClient,与目
标网站建立HTTP链接并获取其网页的htmlString,之后解析html;同时调用WebAnalyzer进行网页的解析和数据的提取;
接下来Gather将提取出来的数据以文本文档的形式保存到本地RawData文件夹中,实现了将目标页面的下载到本地计算机的功能。
5.2提取网页信息并保存至数据库
图6:
在Java工程内引入MySQL的JDBC驱动包
为了实现JAVA程序和MySQL数据库的交互,我们使用了JDBC的连接方式。
如图6,首先导入MySQL的JDBC驱动包;
然后在共用的工具类
com.house.util.DBHelper中实现加载数据库驱动、建立连接、创建SQL语句、执行语句等操作(DBHelper程序见附录1)。
接着,Gather(网页收集器)在以文本文档形式保存网页信息的同时,调用DAO层(数据库访问层)数据库分配器(com.house.ctrl.GanJiCtrl,程序见附录2)。
数据库分配器调用DBHelper和com.house.dao.impl包下的方法,最终实现依据信息类型(指买房、出租房、求购二手房、求租房)的不同而将信息存入不同的数据表中(见图7)。
图7:
求购二手房需求表中新增的数据
总结
基于网络爬虫的房产信息平台原型实现了以赶集网为例,从网页进行信息的爬取、在本地进行信息的提取并分类存入数据库的功能,若要完全满足项目需求,仍需进一步的完善和修改。
纵观整个流程,我体会到在搜索引擎中广泛运用的网络爬虫在各行各业的信息采集工作中也起到了极其重要的作用。
这同时启发我们在日后的软件开发中,善于利用爬虫技术和数据库技术,它们不失为一个提取信息、整合网络资源的好方法。
然而,虽然互联网是一个开放的信息平台,但是爬虫技术也不能被不加限制地使用。
信息所涉及的隐私和版权问题也需要引起我们足够的重视。
鸣谢
衷心感谢丁又专老师在我最初接触网络爬虫的时候给以耐心的指导和无私的帮助,在课程论文撰写阶段为我提供了格式上的指导与提醒。
除了在专业知识方面,丁老师教会了我如何管理时间,培养了我的终生学习的观念,以及更多地以切身行动教诲我们做人之道。
最后对老师再次表示衷心的感谢。
参考文献
[1]吴军.数学之美[M].北京:
人民邮电出版社,2012.06.
[2]董宇.dySE:
一个Java搜索引擎的实现,第1部分:
网络爬虫
[CP/OL].
2010-07-13
[3]java冒烟.HTTPCLIENT抓取网页内容[CP/OL].
2013-07-10
[4]水慕清风.java获取网页源代码[CP/OL].
2013-01-24
[5]李勇.传智播客JDBC视频教程[Z/OL].
2012-06
附录
附录1:
publicclassGanJiCtrl{
//1:
购房2:
出租3:
求租4:
求购2手
privateintbusiness;
publicGanJiCtrl(intbusiness){
this.business=business;
}
/**
*描述:
通过dao分配器,分配不同的业务存入不同的数据库
*/
publicvoiddaoDispatcher(StringhtmlDoc){
switch(this.business){
case1:
this.storageInSellHouseDB(
AnalyzerGanJiUtil.getHtmlGanJiSellBean(htmlDoc));
break;
case2:
this.storageInRentHouseDB(
AnalyzerGanJiUtil.getHtmlGanJiRentBean(htmlDoc));
break;
case3:
this.storageInRentDemandDB(
AnalyzerGanJiUtil.getHtmlGanJiDemandBean(htmlDoc));
break;
case4:
this.storageInBuyDemandDB(
AnalyzerGanJiUtil.getHtmlGanJiDemandBean(htmlDoc));
break;
}
}
publicvoidstorageInSellHouseDB(Listlist){
Stringsql="insertintosellhouseinfo("
+"title,housing_estate,housing_address,"
+"total_price,unit_price,img_url,"
+"family_situation,belongwhere)"
+"values(?
?
?
?
?
?
?
?
);";
DBHelper.clearTableData("sellhouseinfo");
DBHelper.resetAutoIncrement("sellhouseinfo");
SellHouseDaoImpl.getInstance().insertIntoSellHouse(sql,list);
}
publicvoidstorageInRentHouseDB(Listlist){
Stringsql="insertintorenthouseinfo("
+"title,housing_estate,housing_address,"
+"rent_price,img_url,"
+"family_situation,belongwhere)"
+"values(?
?
?
?
?
?
?
);";
DBHelper.clearTableData("renthouseinfo");
DBHelper.resetAutoIncrement("renthouseinfo");
RentHouseDaoImpl.getInstance().insertIntoRentHouse(sql,list);
}
publicvoidstorageInRentDemandDB(Listlist){
Stringsql="insertintorenthousedemand("
+"demandContent,housing_address,price_range,"
+"publish_time,belongwhere)"
+"values(?
?
?
?
?
);";
DBHelper.clearTableData("renthousedemand");
DBHelper.resetAutoIncrement("renthousedemand");
HouseDemandDaoImpl.getInstance().insertIntoHouseDemand(sql,list);
}
publicvoidstorageInBuyDemandDB(Listlist){
Stringsql="insertintobuyhousedemand("
+"demandContent,housing_address,price_range,"
+"publish_time,belongwhere)"
+"values(?
?
?
?
?
);";
DBHelper.clearTableData("renthousedemand");
DBHelper.resetAutoIncrement("renthousedemand");
HouseDemandDaoImpl.getInstance().insertIntoHouseDemand(sql,list);
}
}
附录2:
publicclassDBHelper{
privatestaticConnectioncon=null;
privatestaticPreparedStatementprestmt=null;
privatestaticResultSetrs=null;
//连接数据库的参数
privatestaticStringurl="";
privatestaticStringusername="";
privatestaticStringpassword="";
privatestaticStringdriver="";
privatestaticFileInputStreamfis=null;
privatestaticPropertiespp=null;
//加载驱动
static{
try{
pp=newProperties();
try{
Stringpath=ProjectPath.getProjectPath();
fis=newFileInputStream(path+File.separator+"bin"
+File.separator+"dbinfo.properties");
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
try{
pp.load(fis);
}catch(IOExceptione){
e.printStackTrace();
}
url=pp.getProperty("url");
username=pp.getProperty("username");
password=pp.getProperty("password");
driver=pp.getProperty("driver");
Class.forName(driver);
}catch(ClassNotFoundExceptione){
e.printStackTrace();
System.out.println("加载驱动失败");
System.exit(0);
}finally{
try{
fis.close();
}catch(IOExceptione){
e.printStackTrace();
}
fis=null;
}
}
publicstaticConnectiongetConnector(){
try{
//得到数据源
con=DriverManager.getConnection(url,username,password);
}catch(SQLExceptione){
e.printStackTrace();
}
returncon;
}
//查询功能
publicstaticList>executeQuery(Stringsql){
List>listRow;
try{
con=getConnector();
listRow=newArrayList>();
if(sql.length()!
=0)
prestmt=con.prepareStatement(sql);
rs=prestmt.executeQuery();
while(rs.next()){
List
for(inti=1;i<=rs.getMetaData().getColumnCount();i++){
listCol.add(rs.getString(i));
}
listRow.add(listCol);
}
}catch(Exceptione){
e.printStackTrace();
thrownewRuntimeException(e.getMessage());
}finally{
close(rs,prestmt,con);//关闭连接
}
returnlistRow;
}
/**
*描述:
清空表中数据
*@paramtableName要清空的表名字
*@return清空成功返回true,否则返回false
*/
publicstaticbooleanclearTableData(StringtableName){
booleanresult=true;
try{
con=getConnector();
prestmt=con.prepareStatement("SETforeign_key_checks=0;");
prestmt.execute();
prestmt=con
.prepareStatement("TRUNCATETABLE"+tableName+";");
prestmt.execute();
prestmt=con.prepareStatement("SETforeign_key_checks=1;");
prestmt.execute();
}catch(SQLExceptione){
System.out.println("清空表的数据时发生错误");
result=false;
e.printStackTrace();
}finally{
close(null,prestmt,con);
}
returnresult;
}
/**
*描述:
重置autoincrement的序号
*@paramtableName要重置的表
*@return成功返回true,否则返回false
*/
publicstaticbooleanresetAutoIncrement(StringtableName){
booleanresult=true;
try{
con=getConnector();
prestmt=con.prepareStatement("altertable"+tableName
+"auto_increment=1");
prestmt.execute();
}catch(SQLExceptione){
result=false;
e.printStackTrace();
}finally{
close(null,prestmt,con);
}
returnresult;
}
/**
*可进行增删改操作的函数
*@paramsql
*@return操作成功与否的信号
*/
publicstaticbooleanupdexecute(Stringsql){
booleanresult=true;
try{
con=getConnector();
if(sql.length()!
=0)
prestmt=con.prepareStatement(sql);
prestmt.executeUpdate();//执行操作
}catch(Exceptione1){
result=false;
e1.printStackTrace();
}finally{
close(rs,prestmt,con);
}
returnresult;
}
//关闭连接
publicstaticvoidclose(ResultSetrs,Statementprestmt,Connectioncon)