- 浏览: 293388 次
- 性别:
- 来自: 北京
最新评论
-
小牛100:
不错,明白了
equals()对象的比较;hashcode()方法 -
zsw_it_eye:
java缓存实现 -
niuqiang2008:
回顾我的2008 -
charles751:
集群部署环境下不适用。
java缓存实现 -
WLLT:
很好 顶 很好 顶 很好 顶 很好 顶 很好 顶 很好 顶 ...
手写axis实现webservice通讯
写一个jsp页面,访问时显示从下面的页面提取出的销售商详细信息:价格、运费、经销
商基本信息等,并写到一个数据库表里。
http://www.amazon.com/gp/offer-listing/B0012J52OC/
数据抓取的问题,涉及到
1 用URLConnection 读取页面信息,用httpclient也行
2 用Pattern 解析页面并拿到你要的信息
3 显示数据
4 存入数据库
这个是一个综合的考试,涉及的知识面比较广。
1 我这里只给出关键的部分,使用java程序实现,而不是JSP的代码。移植工作请自行完成。
2 我使用自己的数据库连接,请替换为应用服务器提供的数据源为好
3 代码分三部分,数据库结构,POJO类和应用程序
一、数据库结构 AmazonGoods.sql 使用的是MySQL的数据库
- -- ----------------------------
- -- Table structure for amazongoods
- -- ----------------------------
- CREATE TABLE `amazongoods` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `price` decimal(10,0) NOT NULL,
- `shipping` decimal(10,0) NOT NULL,
- `Seller` text NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- ---------------------------- -- Table structure for amazongoods -- ---------------------------- CREATE TABLE `amazongoods` ( `id` int(11) NOT NULL AUTO_INCREMENT, `price` decimal(10,0) NOT NULL, `shipping` decimal(10,0) NOT NULL, `Seller` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
二、POJO类 AmazonGoods.java
- package com.laozizhu.test.amazon;
- import java.math.BigDecimal;
- /**
- * 某一行的商品数据
- *
- * @author 老紫竹的家(laozizhu.com)
- *
- */
- class AmazonGoods {
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public BigDecimal getPrice() {
- return price;
- }
- public void setPrice(BigDecimal price) {
- this.price = price;
- }
- public BigDecimal getShipping() {
- return shipping;
- }
- public void setShipping(BigDecimal shipping) {
- this.shipping = shipping;
- }
- public String getSeller() {
- return seller;
- }
- public void setSeller(String seller) {
- this.seller = seller;
- }
- // 序列号,主键
- private long id;
- // 价格
- private BigDecimal price;
- // 运费
- private BigDecimal shipping;
- // 商家信息
- private String seller;
- }
package com.laozizhu.test.amazon; import java.math.BigDecimal; /** * 某一行的商品数据 * * @author 老紫竹的家(laozizhu.com) * */ class AmazonGoods { public long getId() { return id; } public void setId(long id) { this.id = id; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public BigDecimal getShipping() { return shipping; } public void setShipping(BigDecimal shipping) { this.shipping = shipping; } public String getSeller() { return seller; } public void setSeller(String seller) { this.seller = seller; } // 序列号,主键 private long id; // 价格 private BigDecimal price; // 运费 private BigDecimal shipping; // 商家信息 private String seller; }
三、应用类
- package com.laozizhu.test.amazon;
- import java.math.BigDecimal;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Properties;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import com.laozizhu.tools.PageService;
- public class AmazonFetch {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // 我这里需要设置代理,如果你能直接访问互联网,则无需这段代码了
- initProxy();
- // 读取页面数据
- String str = PageService.getPage("http://www.amazon.com/gp/offer-listing/B0012J52OC/", "ISO-8859-1");
- // 解析页面,拿到商品信息
- List<AmazonGoods> list = parse(str);
- // 生成HTML表格
- buildTable(list);
- // 存入数据库
- saveToMySQL(list);
- }
- /**
- * 简单的代理服务器,无需密码认证
- */
- private static void initProxy() {
- Properties prop = System.getProperties();
- // prop.put("proxySet", "true");
- // 设置http访问要使用的代理服务器的地址
- prop.setProperty("http.proxyHost", "10.60.8.20");
- // 设置http访问要使用的代理服务器的端口
- prop.setProperty("http.proxyPort", "8080");
- }
- // 注意,美元符号要转义
- // 因为报价都包含小数点,所以用数字+小数点+2位小数即可
- // 商家信息包含了对应的标签
- static Pattern pPrice = Pattern.compile(
- "<span class=\"price\">\\$([\\d]+\\.[\\d]{2})</span>.*?(<ul class=\"sellerInformation\">.+?</ul>)", Pattern.DOTALL);
- // 运费
- // <span class="price_shipping">+ $6.04</span>
- static Pattern pShipping = Pattern
- .compile("<span class=\"price_shipping\">\\+ \\$([\\d]+\\.[\\d]{2})</span>", Pattern.DOTALL);
- /**
- * 解析页面,获得商品列表
- *
- * @param page
- * 页面
- * @return 商品列表
- */
- private static List<AmazonGoods> parse(String page) {
- // 首先,把商品分成多个字符串片段
- // 分割符就是表格里的内容了。这个得查看HTML源代码才能找到合适的
- String[] strs = page.split("<tbody class=\"result\">");
- // 构造结果
- // 默认长度为片段的长度,呵呵
- List<AmazonGoods> list = new ArrayList<AmazonGoods>(strs.length);
- AmazonGoods goods = null;
- // 循环解析每个商品片段
- for (String str : strs) {
- // 注意,不是每个商品都有运费,所以正则最好不要写一个
- // 当然,你愿意弄复杂了也行,我个人不推荐这么做
- Matcher m = pPrice.matcher(str);
- if (m.find()) {
- goods = new AmazonGoods();
- goods.setPrice(new BigDecimal(m.group(1)));
- // 这里面包含了HTML的信息,包括Javascript内容,不过比较难删除
- // 因为有些页面文字是用js显示的,还是保留的比较好
- goods.setSeller(m.group(2));
- // 查找运费
- m = pShipping.matcher(str);
- if (m.find()) {
- goods.setShipping(new BigDecimal(m.group(1)));
- }
- // 将商品加入列表
- list.add(goods);
- } else {
- // 没有找到价格,则这部分不包含商品信息,无需继续
- continue;
- }
- }
- return list;
- }
- private static String buildTable(List<AmazonGoods> list) {
- StringBuilder b = new StringBuilder("<table>");
- b.append("<tr><th>价格</th><th>运费</th><th>商家信息</th></tr>");
- for (AmazonGoods goods : list) {
- b.append("<tr><th>" + goods.getPrice() + "</th><th>" + goods.getShipping() + "</th><th>" + goods.getSeller()
- + "</th></tr>");
- }
- b.append("</table>");
- return b.toString();
- }
- private static void saveToMySQL(List<AmazonGoods> list) {
- // 这里就用最原始的方法获得数据库连接了。
- // 数据库结构请参考AmazonGoods.sql
- // 使用test的数据库
- Connection con = null;
- PreparedStatement st = null;
- String url = "jdbc:mysql://localhost:3306/";
- String db = "test";
- String driver = "com.mysql.jdbc.Driver";
- String user = "test";
- String pass = "test";
- BigDecimal ZERO = new BigDecimal("0");
- try {
- Class.forName(driver);
- con = DriverManager.getConnection(url + db, user, pass);
- st = con.prepareStatement("insert into AmazonGoods (price,shipping,seller) values(?,?,?)");
- for (AmazonGoods goods : list) {
- st.setBigDecimal(1, goods.getPrice());
- st.setBigDecimal(2, goods.getShipping()==null?ZERO:goods.getShipping());
- st.setString(3, goods.getSeller());
- if (st.executeUpdate() <= 0) {
- throw new Exception("保存数据错误!");
- }
- st.clearParameters();
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- if (st != null) {
- try {
- st.close();
- } catch (Exception ex) {
- }
- }
- if (con != null) {
- try {
- con.close();
- } catch (Exception ex) {
- }
- }
- }
- }
- }
package com.laozizhu.test.amazon; import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.laozizhu.tools.PageService; public class AmazonFetch { /** * @param args */ public static void main(String[] args) { // 我这里需要设置代理,如果你能直接访问互联网,则无需这段代码了 initProxy(); // 读取页面数据 String str = PageService.getPage("http://www.amazon.com/gp/offer-listing/B0012J52OC/", "ISO-8859-1"); // 解析页面,拿到商品信息 List<AmazonGoods> list = parse(str); // 生成HTML表格 buildTable(list); // 存入数据库 saveToMySQL(list); } /** * 简单的代理服务器,无需密码认证 */ private static void initProxy() { Properties prop = System.getProperties(); // prop.put("proxySet", "true"); // 设置http访问要使用的代理服务器的地址 prop.setProperty("http.proxyHost", "10.60.8.20"); // 设置http访问要使用的代理服务器的端口 prop.setProperty("http.proxyPort", "8080"); } // 注意,美元符号要转义 // 因为报价都包含小数点,所以用数字+小数点+2位小数即可 // 商家信息包含了对应的标签 static Pattern pPrice = Pattern.compile( "<span class=\"price\">\\$([\\d]+\\.[\\d]{2})</span>.*?(<ul class=\"sellerInformation\">.+?</ul>)", Pattern.DOTALL); // 运费 // <span class="price_shipping">+ $6.04</span> static Pattern pShipping = Pattern .compile("<span class=\"price_shipping\">\\+ \\$([\\d]+\\.[\\d]{2})</span>", Pattern.DOTALL); /** * 解析页面,获得商品列表 * * @param page * 页面 * @return 商品列表 */ private static List<AmazonGoods> parse(String page) { // 首先,把商品分成多个字符串片段 // 分割符就是表格里的内容了。这个得查看HTML源代码才能找到合适的 String[] strs = page.split("<tbody class=\"result\">"); // 构造结果 // 默认长度为片段的长度,呵呵 List<AmazonGoods> list = new ArrayList<AmazonGoods>(strs.length); AmazonGoods goods = null; // 循环解析每个商品片段 for (String str : strs) { // 注意,不是每个商品都有运费,所以正则最好不要写一个 // 当然,你愿意弄复杂了也行,我个人不推荐这么做 Matcher m = pPrice.matcher(str); if (m.find()) { goods = new AmazonGoods(); goods.setPrice(new BigDecimal(m.group(1))); // 这里面包含了HTML的信息,包括Javascript内容,不过比较难删除 // 因为有些页面文字是用js显示的,还是保留的比较好 goods.setSeller(m.group(2)); // 查找运费 m = pShipping.matcher(str); if (m.find()) { goods.setShipping(new BigDecimal(m.group(1))); } // 将商品加入列表 list.add(goods); } else { // 没有找到价格,则这部分不包含商品信息,无需继续 continue; } } return list; } private static String buildTable(List<AmazonGoods> list) { StringBuilder b = new StringBuilder("<table>"); b.append("<tr><th>价格</th><th>运费</th><th>商家信息</th></tr>"); for (AmazonGoods goods : list) { b.append("<tr><th>" + goods.getPrice() + "</th><th>" + goods.getShipping() + "</th><th>" + goods.getSeller() + "</th></tr>"); } b.append("</table>"); return b.toString(); } private static void saveToMySQL(List<AmazonGoods> list) { // 这里就用最原始的方法获得数据库连接了。 // 数据库结构请参考AmazonGoods.sql // 使用test的数据库 Connection con = null; PreparedStatement st = null; String url = "jdbc:mysql://localhost:3306/"; String db = "test"; String driver = "com.mysql.jdbc.Driver"; String user = "test"; String pass = "test"; BigDecimal ZERO = new BigDecimal("0"); try { Class.forName(driver); con = DriverManager.getConnection(url + db, user, pass); st = con.prepareStatement("insert into AmazonGoods (price,shipping,seller) values(?,?,?)"); for (AmazonGoods goods : list) { st.setBigDecimal(1, goods.getPrice()); st.setBigDecimal(2, goods.getShipping()==null?ZERO:goods.getShipping()); st.setString(3, goods.getSeller()); if (st.executeUpdate() <= 0) { throw new Exception("保存数据错误!"); } st.clearParameters(); } } catch (Exception ex) { ex.printStackTrace(); } finally { if (st != null) { try { st.close(); } catch (Exception ex) { } } if (con != null) { try { con.close(); } catch (Exception ex) { } } } } }
四、辅助类 PageService.java
- package com.laozizhu.tools;
- import java.io.BufferedReader;
- import java.io.FileNotFoundException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.net.ConnectException;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.zip.GZIPInputStream;
- /**
- * 读取URL的文本工具
- *
- * @author 赵学庆 <A href="www.java2000.net" target=_blank>www.java2000.net</A>
- */
- public class PageService {
- private static final String BR = "\r\n";
- /**
- * 读取文本。默认使用UTF-8编码
- *
- * @param page
- * 页面的URL,比如 <A href="http://www.java2000.net" target=_blank>http://www.java2000.net</A>
- * @return 读取到的文本字符串
- */
- public static String getPage(String page) {
- return getPage(page, "UTF-8");
- }
- /**
- * 读取文本
- *
- * @param page
- * 页面的URL,比如 <A href="http://www.java2000.net" target=_blank>http://www.java2000.net</A>
- * @param charset
- * 页面的编码
- * @return 读取到的文本字符串
- */
- public static String getPage(String page, String charset) {
- String str = null;
- int count = 3;
- do {
- str = _getPage(page, charset);
- if (str == null || str.length() == 0) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- } while (str == null && count-- > 0);
- return str;
- }
- private static String _getPage(String page, String charset) {
- try {
- URL url = new URL(page);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- // 增加了浏览器的类型,就用Firefox好了,也许
- con
- .setRequestProperty(
- "User-Agent",
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
- int index = page.indexOf("/", 10);
- con.setRequestProperty("Host", index == -1 ? page.substring(7) : page
- .substring(7, index));
- InputStream is = con.getInputStream();
- if (con.getContentEncoding() != null
- && con.getContentEncoding().equalsIgnoreCase("gzip")) {
- is = new GZIPInputStream(con.getInputStream());
- }
- BufferedReader reader = new BufferedReader(new InputStreamReader(is,
- charset));
- StringBuilder b = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- b.append(line);
- b.append(BR);
- }
- reader.close();
- return b.toString();
- } catch (FileNotFoundException ex) {
- System.out.println("NOT FOUND:" + page);
- return null;
- } catch (ConnectException ex) {
- System.out.println("Timeout:" + page);
- return null;
- } catch (Exception ex) {
- ex.printStackTrace();
- return null;
- }
- }
- public static String postPage(String page, String msg) throws Exception {
- URL url = new URL(page);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- con.setDoOutput(true); // POST方式
- con
- .setRequestProperty(
- "User-Agent",
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
- int index = page.indexOf("/", 10);
- con.setRequestProperty("Host", index == -1 ? page.substring(7) : page
- .substring(7, index));
- con.setRequestMethod("POST");
- con.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- OutputStream os = con.getOutputStream(); // 输出流,写数据
- os.write(msg.getBytes("UTF-8"));
- InputStream is = con.getInputStream();
- if (con.getContentEncoding() != null
- && con.getContentEncoding().equalsIgnoreCase("gzip")) {
- is = new GZIPInputStream(con.getInputStream());
- }
- BufferedReader reader = new BufferedReader(new InputStreamReader(is,
- "UTF-8")); // 读取结果
- StringBuilder b = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- b.append(line);
- b.append(BR);
- }
- os.close();
- reader.close();
- return b.toString();
- }
- }
相关推荐
Java面试题67:数据库优化之数据库表设计遵循范式.mp4
Java面试题68:选择合适的数据库引擎.mp4
面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程,所有的面试题有视屏讲解, 解答方案....
在Java综合面试中,面试官通常会考察应聘者的语法基础、面向对象编程理解、内存管理、多线程、集合框架、IO流、网络编程、异常处理、JVM原理、设计模式以及数据库操作等多方面技能。以下是对这些知识点的详细说明: ...
常见的java面试题,包括: JAVA面试题集基础篇.pdf JAVA面试题集编程篇.pdf JAVA面试题集高级篇.pdf 就业面试题库(数据库).pdf 数据库.pdf
本资源包"Java 面试全解析:核心知识点与典型面试题.zip"包含了多个关键主题,帮助求职者深入理解和掌握 Java 的核心概念,以及应对面试中的各种问题。 1. **设计模式** - 34-设计模式常见面试题汇总.html 设计...
《可伸缩服务架构:框架与中间件》
Java面试题22.Session和Cookie的区别和使用场景 Java面试题23.mvc模式和mvc各部分的实现 Java面试题24.数据库分类和常用数据库 Java面试题25.关系型数据库的三范式 Java面试题26.事务的四大特征 Java面试题27.mysql...
【Java及数据库面试题 包含SSH,数据库和Java基础】 1. SQL查询与数据库操作: 这一题目考察的是基本的SQL查询能力。在给出的示例中,我们看到如何从`Custom`表中选取特定列并重命名显示。`AS`关键字用于重命名列,...
文件中包含了本人最近在网上总结的面试题,有java面试题,jq面试题,jsp、servlet、ajax面试题,mysql面试题,oracle面试题,redis教案,也有最近时间总结的公司面试题,涉及的层面虽然不是很多,但是应对面试 应该...
JavaOOP面试题 Java集合/泛型面试题 Java异常面试题 Java中的IO与NIO面试题 Java反射面试题 Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 ...
本资源收集了大量的Java面试题,旨在帮助读者熟悉Java编程语言以及相关的编程技术和知识点,从而在面试中更好地展现自己的能力和潜力。本资源主要包括Java基础知识、Java集合、多线程、IO操作、网络编程、数据库等...
"Java数据库面试题" ...Java数据库面试题涵盖了数据库设计、性能优化、事务、触发器和存储过程、锁和批处理、游标和子查询等多个方面的知识点,对于 Java 开发者和数据库管理员来说都是非常重要的参考资料。
在IT行业中,JAVA和数据库是两个至关重要的领域,它们构成了许多企业级应用的...准备充分的面试者不仅能够解答问题,更能展示出对JAVA和数据库领域的深度理解和实践经验,这对于在竞争激烈的IT职场上脱颖而出至关重要。
【计算机和JAVA 面试题大全】 在计算机科学与技术领域,尤其是软件开发行业,Java是一种广泛应用的编程语言,以其跨平台、面向对象和高效性而受到赞誉。本资料集涵盖了丰富的Java面试题,旨在帮助求职者准备Java...
以后会慢慢把Java相关的面试题、计算机网络等都加进来,其实这不仅仅是一份面试题,更是一份面试参考,让你熟悉面试题各种提问情况,当然,项目部分,就只能看自己了,毕竟每个人简历、实习、项目等都不一样。面试题...
Java作为一门广泛使用的编程语言,其面试题涵盖了众多的知识领域,包括基础语法、面向对象、集合框架、多线程、网络编程、IO流、异常处理、JVM内存模型、设计模式、数据库操作、Spring框架等。以下是对这些知识点的...
rabbitmq面试:RabbitMQ相关的面试题和问题解析 rabbitmq面试:RabbitMQ相关的面试题和问题解析 rabbitmq面试:RabbitMQ相关的面试题和问题解析 rabbitmq面试:RabbitMQ相关的面试题和问题解析 rabbitmq面试:...
Java面试题73:数据库优化之缓存.mp4
Java面试题72:数据库的读写分离.mp4