数据抓取的问题,涉及到1 用URLConnection 读取页面信息,用httpclient也行2 用Pattern 解析页面并拿到你要的信息3 显示数据4 存入数据库这个是一个综合的考试,涉及的知识面比较广。1 我这里只给出关键的部分,使用java程序实现,而不是JSP的代码。移植工作请自行完成。2 我使用自己的数据库连接,请替换为应用服务器提供的数据源为好3 代码分三部分,数据库结构,POJO类和应用程序,当然还有一个辅助类,也是我自己写的

4 欢迎光临老紫竹的JAVA世纪网 http://www.java2000.net, 呵呵,广告放里面了一、数据库结构 AmazonGoods.sql 使用的是MySQL的数据库

[java] 
    view plain 
     copy 
     print 
    ? 
   
 
  
1. -- ----------------------------  
2. -- Table structure for
3. -- ----------------------------  
4. CREATE TABLE `amazongoods` (  
5. int(11) NOT NULL AUTO_INCREMENT,  
6. 10,0) NOT NULL,  
7. 10,0) NOT NULL,  
8.   `Seller` text NOT NULL,  
9.   PRIMARY KEY (`id`)  
10. ) ENGINE=InnoDB AUTO_INCREMENT=11
-- ------------------------------ 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
 
 
[java] 
    view plain 
     copy 
     print 
    ? 
   
 
  
1. package
2. import
3. /**
4.  * 某一行的商品数据
5.  * 
6.  * @author 老紫竹的家(laozizhu.com)
7.  * 
8.  */
9. class
10. public long
11. return
12.   }  
13. public void setId(long
14. this.id = id;  
15.   }  
16. public
17. return
18.   }  
19. public void
20. this.price = price;  
21.   }  
22. public
23. return
24.   }  
25. public void
26. this.shipping = shipping;  
27.   }  
28. public
29. return
30.   }  
31. public void
32. this.seller = seller;  
33.   }  
34. // 序列号,主键
35. private long
36. // 价格
37. private
38. // 运费
39. private
40. // 商家信息
41. private
42. }  
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;} 
 
  
 
三、应用类
 
 
[java] 
    view plain 
     copy 
     print 
    ? 
   
 
  
1. package
2. import
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. public class
13. /**
14.    * @param args
15.    */
16. public static void
17. // 我这里需要设置代理,如果你能直接访问互联网,则无需这段代码了
18.     initProxy();  
19. // 读取页面数据
20. "http://www.amazon.com/gp/offer-listing/B0012J52OC/", "ISO-8859-1");  
21. // 解析页面,拿到商品信息
22.     List<AmazonGoods> list = parse(str);  
23. // 生成HTML表格
24.     buildTable(list);  
25. // 存入数据库
26.     saveToMySQL(list);  
27.   }  
28. /**
29.    * 简单的代理服务器,无需密码认证
30.    */
31. private static void
32.     Properties prop = System.getProperties();  
33. // prop.put("proxySet", "true");
34. // 设置http访问要使用的代理服务器的地址
35. "http.proxyHost", "10.60.8.20");  
36. // 设置http访问要使用的代理服务器的端口
37. "http.proxyPort", "8080");  
38.   }  
39. // 注意,美元符号要转义
40. // 因为报价都包含小数点,所以用数字+小数点+2位小数即可
41. // 商家信息包含了对应的标签
42. static
43. "<span class=/"price/">//$([//d]+//.[//d]{2})</span>.*?(<ul class=/"sellerInformation/">.+?</ul>)", Pattern.DOTALL);  
44. // 运费
45. // <span class="price_shipping">+ $6.04</span>
46. static
47. "<span class=/"price_shipping/">//+ //$([//d]+//.[//d]{2})</span>", Pattern.DOTALL);  
48. /**
49.    * 解析页面,获得商品列表
50.    * 
51.    * @param page
52.    *          页面
53.    * @return 商品列表
54.    */
55. private static
56. // 首先,把商品分成多个字符串片段
57. // 分割符就是表格里的内容了。这个得查看HTML源代码才能找到合适的
58. "<tbody class=/"result/">");  
59. // 构造结果
60. // 默认长度为片段的长度,呵呵
61. new
62. null;  
63. // 循环解析每个商品片段
64. for
65. // 注意,不是每个商品都有运费,所以正则最好不要写一个
66. // 当然,你愿意弄复杂了也行,我个人不推荐这么做
67.       Matcher m = pPrice.matcher(str);  
68. if
69. new
70. new BigDecimal(m.group(1)));  
71. // 这里面包含了HTML的信息,包括Javascript内容,不过比较难删除
72. // 因为有些页面文字是用js显示的,还是保留的比较好
73. 2));  
74. // 查找运费
75.         m = pShipping.matcher(str);  
76. if
77. new BigDecimal(m.group(1)));  
78.         }  
79. // 将商品加入列表
80.         list.add(goods);  
81. else
82. // 没有找到价格,则这部分不包含商品信息,无需继续
83. continue;  
84.       }  
85.     }  
86. return
87.   }  
88. private static
89. new StringBuilder("<table>");  
90. "<tr><th>价格</th><th>运费</th><th>商家信息</th></tr>");  
91. for
92. "<tr><th>" + goods.getPrice() + "</th><th>" + goods.getShipping() + "</th><th>"
93. "</th></tr>");  
94.     }  
95. "</table>");  
96. return
97.   }  
98. private static void
99. // 这里就用最原始的方法获得数据库连接了。
100. // 数据库结构请参考AmazonGoods.sql
101. // 使用test的数据库
102. null;  
103. null;  
104. "jdbc:mysql://localhost:3306/";  
105. "test";  
106. "com.mysql.jdbc.Driver";  
107. "test";  
108. "test";  
109. new BigDecimal("0");  
110. try
111.       Class.forName(driver);  
112.       con = DriverManager.getConnection(url + db, user, pass);  
113. "insert into AmazonGoods (price,shipping,seller) values(?,?,?)");  
114. for
115. 1, goods.getPrice());  
116. 2, goods.getShipping()==null?ZERO:goods.getShipping());  
117. 3, goods.getSeller());  
118. if (st.executeUpdate() <= 0) {  
119. throw new Exception("保存数据错误!");  
120.         }  
121.         st.clearParameters();  
122.       }  
123. catch
124.       ex.printStackTrace();  
125. finally
126. if (st != null) {  
127. try
128.           st.close();  
129. catch
130.         }  
131.       }  
132. if (con != null) {  
133. try
134.           con.close();  
135. catch
136.         }  
137.       }  
138.     }  
139.   }  
140. }  
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
 
 
[java] 
    view plain 
     copy 
     print 
    ? 
   
 
  
1. package
2. import
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. /**
12.  * 读取URL的文本工具
13.  * 
14.  * @author 赵学庆 www.java2000.net
15.  */
16. public class
17. private static final String BR = "/r/n";  
18. /**
19.    * 读取文本。默认使用UTF-8编码
20.    * 
21.    * @param page
22.    *          页面的URL,比如 http://www.java2000.net
23.    * @return 读取到的文本字符串
24.    */
25. public static
26. return getPage(page, "UTF-8");  
27.   }  
28. /**
29.    * 读取文本
30.    * 
31.    * @param page
32.    *          页面的URL,比如 http://www.java2000.net
33.    * @param charset
34.    *          页面的编码
35.    * @return 读取到的文本字符串
36.    */
37. public static
38. null;  
39. int count = 3;  
40. do
41.       str = _getPage(page, charset);  
42. if (str == null || str.length() == 0) {  
43. try
44. 1000);  
45. catch
46.           e.printStackTrace();  
47.         }  
48.       }  
49. while (str == null && count-- > 0);  
50. return
51.   }  
52. private static
53. try
54. new
55.       HttpURLConnection con = (HttpURLConnection) url.openConnection();  
56. // 增加了浏览器的类型,就用Firefox好了,也许
57.       con  
58.           .setRequestProperty(  
59. "User-Agent",  
60. "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");  
61. int index = page.indexOf("/", 10);  
62. "Host", index == -1 ? page.substring(7) : page  
63. 7, index));  
64.       InputStream is = con.getInputStream();  
65. if (con.getContentEncoding() != null
66. "gzip")) {  
67. new
68.       }  
69. new BufferedReader(new
70.           charset));  
71. new
72.       String line;  
73. while ((line = reader.readLine()) != null) {  
74.         b.append(line);  
75.         b.append(BR);  
76.       }  
77.       reader.close();  
78. return
79. catch
80. "NOT FOUND:"
81. return null;  
82. catch
83. "Timeout:"
84. return null;  
85. catch
86.       ex.printStackTrace();  
87. return null;  
88.     }  
89.   }  
90. public static String postPage(String page, String msg) throws
91. new
92.     HttpURLConnection con = (HttpURLConnection) url.openConnection();  
93. true); // POST方式
94.     con  
95.         .setRequestProperty(  
96. "User-Agent",  
97. "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");  
98. int index = page.indexOf("/", 10);  
99. "Host", index == -1 ? page.substring(7) : page  
100. 7, index));  
101. "POST");  
102. "Content-Type", "application/x-www-form-urlencoded");  
103. // 输出流,写数据
104. "UTF-8"));  
105.     InputStream is = con.getInputStream();  
106. if (con.getContentEncoding() != null
107. "gzip")) {  
108. new
109.     }  
110. new BufferedReader(new
111. "UTF-8")); // 读取结果
112. new
113.     String line;  
114. while ((line = reader.readLine()) != null) {  
115.       b.append(line);  
116.       b.append(BR);  
117.     }  
118.     os.close();  
119.     reader.close();  
120. return
121.   }  
122. }  
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 赵学庆 www.java2000.net */public class PageService {  private static final String BR = "/r/n";  /**   * 读取文本。默认使用UTF-8编码   *    * @param page   *          页面的URL,比如 http://www.java2000.net   * @return 读取到的文本字符串   */  public static String getPage(String page) {    return getPage(page, "UTF-8");  }  /**   * 读取文本   *    * @param page   *          页面的URL,比如 http://www.java2000.net   * @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();  }}

给我老师的人工智能教程打call!

你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z 重做:Ctrl/Command + Y 加粗:Ctrl/Command + B 斜体:Ctrl/Command + I 标题:Ctrl/Command + Shift + H 无序列表:Ctrl/Command + Shift + U 有序列表:Ctrl/Command + Shift + O 检查列表:Ctrl/Command + Shift + C 插入代码:Ctrl/Command + Shift + K 插入链接:Ctrl/Command + Shift + L 插入图片:Ctrl/Command + Shift + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。 输入2次#,并按下space后,将生成2级标题。 以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片:

带尺寸的图片:

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block var foo = 'bar';

生成一个适合你的列表

  • 项目
  • 项目
  • 项目
  1. 项目1
  2. 项目2
  3. 项目3

创建一个表格

一个简单的表格是这么创建的:

项目

Value

电脑

$1600

手机

$12

导管

$1

设定内容居中、居左、居右

使用:---------:居中 使用:----------居左 使用----------:居右

第一列

第二列

第三列

第一列文本居中

第二列文本居右

第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPE

ASCII

HTML

Single backticks

'Isn't this fun?'

‘Isn’t this fun?’

Quotes

"Isn't this fun?"

“Isn’t this fun?”

Dashes

-- is en-dash, --- is em-dash

– is en-dash, — is em-dash

创建一个自定义列表

HTML

Authors John Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML。

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 iOS 解析html字段图片慢 java html解析库_iOS 解析html字段图片慢

iOS 解析html字段图片慢 java html解析库_java_02

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

gantt
        dateFormat  YYYY-MM-DD
        title Adding GANTT diagram functionality to mermaid
        section 现有任务
        已完成               :done,    des1, 2014-01-06,2014-01-08
        进行中               :active,  des2, 2014-01-09, 3d
        计划一               :         des3, after des2, 5d
        计划二               :         des4, after des3, 5d
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接

长方形

圆角长方形

菱形

  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入, 继续你的创作。


  1. mermaid语法说明 ↩︎
  2. 注脚的解释 ↩︎