图书检索功能实现---图书馆客户端

今天完成了图书的检索功能。相对来说,还是有点复杂,因为图书检索结果页面的Html并不是那么规范,解析时需要很大的耐心。

首先需要根据查询条件获取结果的HTML,查询条件可以有很多种,这里为了实用、方便,我特意限制了查询条件为:keyword、东校区、可借出

获取结果HTML的方法如下:

	/**
	 * 根据关键字检索图书
	 *
	 * 检索可以是没有登录的情况,也可以是登录后的情况。 目前是声明了一个新的HTTPclient,即不需要登录,
	 * 如果想设置为在登陆后才可以检索,则需要使用全局的HTTPclient,而不能再声明一个
	 *
	 * @param keyword
	 *            关键字
	 * @return 检索结果的html
	 */
	public static String serchBook(String keyword) {

		HttpGet httpGet = null;
		String searchResultHtml = null;
		HttpClient httpclient = new DefaultHttpClient();
		HttpResponse response;
		/**
		 * 字段顺序很重要
		 *
		 * 设置查询条件为:关键字、东校区、可借出
		 */
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("searchtype", "X"));
		params.add(new BasicNameValuePair("searcharg", keyword));// 查询关键字
		params.add(new BasicNameValuePair("searchscope", "1"));// 1代表东区
		params.add(new BasicNameValuePair("sortdropdown", "-"));
		params.add(new BasicNameValuePair("SORT", "DZ"));// 设置排序方式为按日期倒排
		params.add(new BasicNameValuePair("extended", "0"));
		params.add(new BasicNameValuePair("SUBMIT", "检索"));// 查询按钮
		params.add(new BasicNameValuePair("availlim", "1"));// 设置查询条件---可借出
		params.add(new BasicNameValuePair("searchlimits", ""));
		params.add(new BasicNameValuePair("searchorigarg", ""));// 设置上次查询的关键字及排序方式

		// 对参数编码
		String param = URLEncodedUtils.format(params, "UTF-8");
		System.out.println(param);
		try {
			// 将URL与参数拼接
			// http://innopac.lib.xjtu.edu.cn/search~S1*chx/
			String test_url = "http://innopac.lib.xjtu.edu.cn/search~S1*chx/";
			httpGet = new HttpGet(test_url + "?" + param);
			httpGet.setHeader("Host", "innopac.lib.xjtu.edu.cn");
			httpGet.setHeader("Referer", test_url + "?" + param);
			response = httpclient.execute(httpGet);

			int code = response.getStatusLine().getStatusCode();
			System.out
					.println("---------------searchbook------------------------");
			System.out.println(response.getStatusLine());
			if (code == 200) {

				if (response != null) {

					searchResultHtml = EntityUtils.toString(
							response.getEntity(), HTTP.UTF_8);
					return searchResultHtml;
				}
			}
		} catch (ClientProtocolException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		} finally {
			httpGet.abort();
		}
		return "";
	}

这样便得到了检索结果的HTML,下面同样是使用jsoup对其进行解析,并进行封装。

首先来看看,页面上的显示状况:

根据所需解析的信息,我们需要两个封装类。

一个类封装书目信息,另一个封装馆藏信息。这两个类如下:

1.类BookInfo

package com.ali.login.bean;

import java.util.List;

/**
 * 搜索结果中书目的具体信息
 *
 * @author shuyan
 *
 */
public class BookInfo {

	private String imgLink;// 图片链接
	private String briefTitle;// Java JDK 7实例宝典 Java JDK 7 shi li bao dian / 韩雪,
								// 郭天娇编著

	private String year;// 2014 文字印刷资料

	private List<BookAddress> bookAddresses;// 书目馆藏信息

	private String reserveLink;// 预约链接

	public BookInfo() {
		super();

	}

	public BookInfo(String imgLink, String briefTitle, String year,
			List<BookAddress> bookAddresses, String reserveLink) {
		super();
		this.imgLink = imgLink;
		this.briefTitle = briefTitle;
		this.year = year;
		this.bookAddresses = bookAddresses;
		this.reserveLink = reserveLink;
	}

	public String getImgLink() {
		return imgLink;
	}

	public void setImgLink(String imgLink) {
		this.imgLink = imgLink;
	}

	public String getBriefTitle() {
		return briefTitle;
	}

	public void setBriefTitle(String briefTitle) {
		this.briefTitle = briefTitle;
	}

	public String getYear() {
		return year;
	}

	public void setYear(String year) {
		this.year = year;
	}

	public List<BookAddress> getBookAddresses() {
		return bookAddresses;
	}

	public void setBookAddresses(List<BookAddress> bookAddresses) {
		this.bookAddresses = bookAddresses;
	}

	public String getReserveLink() {
		return reserveLink;
	}

	public void setReserveLink(String reserveLink) {
		this.reserveLink = reserveLink;
	}

	@Override
	public String toString() {
		return "BookInfo [imgLink=" + imgLink + ", briefTitle=" + briefTitle
				+ ", year=" + year + ", bookAddresses=" + bookAddresses
				+ ", reserveLink=" + reserveLink + "]";
	}

}

2.BookAdress

package com.ali.login.bean;

/**
 * 书目的馆藏信息
 *
 * @author shuyan
 *
 */
public class BookAddress {

	private String holdLand;// 馆藏地
	private String callNumber;// 索书号
	private String status;// 状态

	public BookAddress() {
		super();

	}

	public BookAddress(String holdLand, String callNumber, String status) {

		this.holdLand = holdLand;
		this.callNumber = callNumber;
		this.status = status;
	}

	public String getHoldLand() {
		return holdLand;
	}

	public void setHoldLand(String holdLand) {
		this.holdLand = holdLand;
	}

	public String getCallNumber() {
		return callNumber;
	}

	public void setCallNumber(String callNumber) {
		this.callNumber = callNumber;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public String toString() {
		return "BookAddress [holdLand=" + holdLand + ", callNumber="
				+ callNumber + ", status=" + status + "]";
	}
}

有了这两个类,便可以对HTML进行解析封装了。

这里开始变得有点麻烦,因为这里的标签很是不规范。

代码如下:

/**
	 * 处理查询结果的HTML
	 *
	 * @param searchResultHtml
	 *            html字符串
	 *
	 * @return 书目信息集合
	 */
	public static List<BookInfo> getSearchResult(String searchResultHtml) {
		List<BookInfo> bookInfos = new ArrayList<BookInfo>();
		Document document = Jsoup.parse(searchResultHtml);

		Elements items = document.getElementsByClass("briefCitRow");// 书目集合
		int i = 1;
		for (Element item : items) {
			BookInfo bookInfo = null;
			List<BookAddress> bookAddresses = new ArrayList<>();
			Element ele_par = item.select("a[href]").get(0);
			// http://202.117.24.227/bibimage/zycover.php?isbn=9787121217074
			String imgLink = ele_par.child(0).attr("src");// 图片链接

			Element ele_reserve = item.getElementsByClass("briefcitRequest")
					.get(0);// 预约图书的链接
			Element ele_ahref = ele_reserve.select("a[href]").get(0);
			String reserveLink = ele_ahref.attr("href");// 预约链接
			// 需要添加host在前面
			// /availlim/search~S1*chx?/XJava&searchscope=1&SORT=DZ/XJava&searchscope=1&SORT=DZ&extended=0&SUBKEY=Java/1%2C2973%2C2973%2CC/requestbrowse~b3838346&FF=XJava&searchscope=1&SORT=DZ&1%2C1%2C

			// 注意有两个 class = briefcitDetail
			Elements ele_briefcitDetails = item
					.getElementsByClass("briefcitDetail");
			// 先处理第一个

			String briefTitle = ele_briefcitDetails.get(0)
					.getElementsByClass("briefcitTitle").get(0).text();// 书目简要描述

			// 处理第二个
			String year = ele_briefcitDetails.get(1).text();// 年份

			Elements ele_addresses = item.getElementsByClass("briefcitItems")
					.get(0).getElementsByClass("bibItems").get(0)
					.getElementsByClass("bibItemsEntry");// 书目的馆藏信息

			/**
			 * 预约也在这里面处理
			 */
			for (Element ele_add : ele_addresses) {

				BookAddress address = null;
				// 这里有3个td标签
				Elements ele_tds = ele_add.getElementsByTag("td");
				String bookStore = ele_tds.get(0).text();
				String callNumber = ele_tds.get(1).text();
				String status = ele_tds.get(2).text();

				address = new BookAddress(bookStore, callNumber, status);
				bookAddresses.add(address);

			}

			bookInfo = new BookInfo(imgLink, briefTitle, year, bookAddresses,
					reserveLink);
			bookInfos.add(bookInfo);

		}
		return bookInfos;

	}

这样便得到了封装好的书目信息集合,测试如下:

public static void main(String[] args) {
		String searchResultHtml = LibraryUtil.serchBook("Java");
		List<BookInfo> bookInfos = getSearchResult(searchResultHtml);

		int i = 0;

		for (BookInfo bookInfo : bookInfos) {

			if(i<5)
			{
				System.out.println(bookInfo.toString());
			}
			i++;

		}
	}

结果为:

如此便实现了图书的检索功能...

当然这里还有许多需要考虑的地方,如:检索结果总数,每页需要显示多少条记录,筛选无意义的结果,预约功能等...

时间: 2024-10-12 07:26:04

图书检索功能实现---图书馆客户端的相关文章

续借图书功能实现---图书馆客户端

在上一篇获取个人借阅信息---图书馆客户端已经得到了个人借阅的信息,图书馆对已经借阅的图书还提供了续借的功能. 实现续借功能也不复杂,在上一篇解析个人借阅信息时,添加两个字段即可.即修改getLendBookInfos(String lendInfoHtml)方法. 代码: /** * 获取借阅的数目信息 * * @param lendInfoHtml * 借阅信息详情html * @return 借阅信息列表 */ public static List<LendBookInfo> getLe

使用UISearchBar+UITableView进行的时事检索功能的实现,及TabelView索引的实现

时事检索功能还是挺好实现的,先看效果图. tableView索引实现,还是先看效果图 下面是实际代码,注释基本很详细 CityListViewController.h文件里面,传来一个数组,是城市解析出来后的的数据 // // CityListViewController.h // WisdomShope // // Created by mac on 15/12/26. // Copyright (c) 2015年 ZY. All rights reserved. // #import <UI

百度地图 Android SDK - 检索功能使用的简单示例

百度地图 SDK 不仅为广大开发者提供了炫酷的地图展示效果.丰富的覆盖物图层,更为广大开发者提供了多种 LBS 检索的能力.通过这些接口,开发者可以轻松的访问百度的 LBS 数据,丰富自己的移动端地图应用. 目前百度地图 SDK 为开发者提供的检索服务有: POI 检索:可以检索百度 POI 数据信息: 线路规划:利用百度的引擎帮助开发者规划线路: 在线建议检索.短链接分享.地理编码等等.... 本文将以一个很简单的 POI 城市内检索为例,像广大开发者介绍接口的使用. 第一步,选择并下载 SD

jQuery Validate【为表单提供了强大的验证功能,让客户端表单验证变得更简单】

jQuery Validate jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证,同时提供了一个用来编写用户自定义方法的 API.所有的捆绑方法默认使用英语作为错误信息,且已翻译成其他 37 种语言. 该插件是由 J?rn Zaefferer 编写和维护的,他是 jQuery 团队的一名成员,是 jQuery UI 团队的主要开发人员,是 QUn

在WPF中让ListBox和ComboBox的快速检索功能失效

问题来源: 自定义一个ComboBox,用来显示日期.后台数据使用的是DateTime,经过Converter转化成“2015年01月01日”样子的成字符串用于显示. 但是,在实际使用中,不停的按下“[”键,光标会从以一个元素一下一下的向下移动. 经过调查,这是ComboBox的“快速检索”功能在作祟. 关于快速检索: WPF中ListBox和ComboBox有一个“快速检索”的功能. 比如在ListBox里,按下“a”键,光标会定位到第一个首字母为“a”的Item上. ComboBox也是一样

如何使用ChemBio 3D在线检索功能

大家都知道ChemBio3D主要功能是可以绘制立体化学结构,其实我们在使用ChemFinder时候,还可以用来在线检索结构文件,熟练使用ChemFinder功能可以对分子结构有更多了解,本节教程就教您如何使用ChemBio3D在线检索功能. 通过在线检索,不仅能查找该分子结构的ACX编号,而且还能够查找相关合成路线以及文献来了解该化合物的一些基本的理化性质.如果能够灵活使用ChemFinder在线检索功能,不仅在化学教学上有较大帮助,而且对化学相关的科研工作也大有裨益. 如何使用ChemFind

Node.js 博客实例(十一)文章检索功能

原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第十一章,由于版本等的原因,在原教程基础上稍加改动即可实现. 现在我们来给博客增加文章检索功能,即根据关键字模糊查询文章标题,且字母不区分大小写. 首先,我们修改 header.ejs ,在 </nav> 前添加一行代码: <span><form action="/search" method="GET"><input type

基于node.js的express框架的图书管理功能(2)

之前的图书管理功能的数据是存放在json文件中的,通过读取json文件的内容渲染到页面上,每次读取都要遍历整个文件,当数据量大时很不方便,把数据存放在数据库中才是正确的做法. 1.操作数据库的基本功能 在Mysql中新建一个数据库book,新建一张book的表用来存放图书的数据信息,将id值设为自增. 利用数据库自增功能有一个问题:在执行删除操作后,再添加数据时,id会出现间隔现象,如下图: 数据库搭建好后,创建一个项目测试一下数据库操作的一些基本功能: 新建一个文件夹mydb 准备一个入口文件

apache的优化-日志轮询、错误页面重定向、压缩功能deflate、客户端缓存expire

1.apache日志轮询 1.1)什么是日志轮询 默认情况下apache的日志是写入到一个文件中的,这对日志的备份和分析造成不便.日志轮询就是可以把apache的日志根据时间进行分开,例如按天轮询:即apache会把当天的日志写入到一个独立的文件中. 1.2)下载并安装日志轮询工具 wget http://cronolog.org/download/cronolog-1.6.2.tar.gz tarzxf cronolog-1.6.2.tar.gz  cdcronolog-1.6.2 ./con