爬取京东本周热卖商品基本信息存入MySQL

爬取京东本周热卖商品基本信息存入MySQL

 

 

 

 

网络爬虫介绍


概述

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

 

产生背景

随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。搜索引擎(Search Engine),例如传统的通用搜索引擎AltaVista,Yahoo!和Google等,作为一个辅助人们检索信息的工具成为用户访问万维网的入口和指南。但是,这些通用性搜索引擎也存在着一定的局限性,如:

1、不同领域、不同背景的用户往往具有不同的检索目的和需求,通用搜索引擎所返回的结果包含大量用户不关心的网页。

2、通用搜索引擎的目标是尽可能大的网络覆盖率,有限的搜索引擎服务器资源与无限的网络数据资源之间的矛盾将进一步加深。

3、万维网数据形式的丰富和网络技术的不断发展,图片、数据库、音频、视频多媒体等不同数据大量出现,通用搜索引擎往往对这些信息含量密集且具有一定结构的数据无能为力,不能很好地发现和获取。

4、通用搜索引擎大多提供基于关键字的检索,难以支持根据语义信息提出的查询。

 

为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫(general?purpose web crawler)不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。

 

抓取策略

网页的抓取策略可以分为深度优先、广度优先和最佳优先三种。深度优先在很多情况下会导致爬虫的陷入(trapped)问题,目前常见的是广度优先和最佳优先方法。三种具体的差异大家可以自己查阅,在这里我就不多说了。

 

 

 

项目简介


需求概要

1、按照下面所述进入京东本周热卖页面,抓取本周热卖页面所有商品链接。

2、抓取所有商品链接后,进入商品详情页面,抓取商品ID、名称、图片链接等基本信息。

3、将抓取的所有信息存入设计好的MySQL表中。

 

 

注意事项

1、由于抓取多个页面,所以需要用多线程。

2、京东商品的价格以及评价都是通过JS异步传输的,所以从网页源码中无法获取商品这些信息,需要用调试工具加载页面所有内容,然后找到JS异步传输所请求的URL,然后继续请求并获取Response(商品价格和评价)。

3、我所使用的环境为浏览器(Chrome)、IDE(Eclipse)、项目(Maven)、Maven依赖(junit4.12、httpclient 4.4、htmlcleaner2.10、json 20140107)。

4、依赖中的httpclient、htmlcleaner、json的版本最好使用我所指定的,其他的版本很容易出现问题。同时获取XPath最好用Chrome抓,火狐等容易出错。

5、抓取日期为2016/4/30日,京东页面以后很可能会改动,所以这套代码之后可能抓不到正确数据。所以大家要注重爬取过程和原理。

6、由于我对每个页面用了一个线程,所以爬取的商品超过100的时候,插入商品信息到数据库时,可能会出现超过MySQL最大连接数错(默认100),可以在配置文件my.ini中修改(打开 MYSQL 安装目录,打开 my.ini 找到 max_connections ,默认是 100, 一般设置到500~1000比较合适,然后重启MySQL)。

 

 其他

这篇文章主要演示了爬取京东本周热点的所有商品基本信息,如果要继续了解如何爬取所有用户评价的话,可以参考另一篇文章:

爬取京东本周热卖商品所有用户评价存入MySQL:http://blog.csdn.NET/u011204847/article/details/51292546

 

爬取的页面导航

首先进入京东首页,然后鼠标移到全部商品分类—》电脑、办公—》玩3C—》本周热卖。

 

 

进入本周热卖(要抓取的网页,抓取这个页面所有商品的URL以及商品基本信息)

 

 

点击本周热卖中第一个商品:价格为3499的戴尔电脑链接后,商品详情如下。

 

 

 

工具使用介绍

 

获取商品元素的XPath

 

1、使用Chrome浏览器(其他浏览器获取的XPath可能无法识别)打开商品详情页面,然后按键盘上面的F12键打开开发者工具。接下来操作流程如下图中所示:

 

 

2、选择网页元素中的商品ID,然后右键选择Copy XPath

XPath示例:

[java] view
plain
 copy

 

  1. *[@id="short-share"]/div/span[2]  

3、然后我们就可以用此方法获取商品URL、商品名称。注意,价格和商品评价都是JS异步传输,无法通过XPath方法获取。所以需要特殊处理。

 

查找JS异步传输请求的URL

详细流程如下图中所示:

 

 

现在我们知道如何去查找我们所需要的信息,接下来将使用代码去获取这些信息,最后写入MySQL数据库。

 

 

 

代码实现

 

工具类:

由于接下来代码会使用到工具类,所以先贴出来。为了方便解释代码,一些冗余的代码就不抽取成方法了。

 

[java] view
plain
 copy

 

  1. import java.io.IOException;  
  2. import org.apache.http.HttpEntity;  
  3. import org.apache.http.client.ClientProtocolException;  
  4. import org.apache.http.client.methods.CloseableHttpResponse;  
  5. import org.apache.http.client.methods.HttpGet;  
  6. import org.apache.http.impl.client.CloseableHttpClient;  
  7. import org.apache.http.impl.client.HttpClientBuilder;  
  8. import org.apache.http.impl.client.HttpClients;  
  9. import org.apache.http.util.EntityUtils;  
  10.   
  11. public class SpiderUtils {  
  12.   
  13.     //下载给定URL的网页实体  
  14.     public static String download(String url) {  
  15.         //构建HTTP请求  
  16.         HttpClientBuilder builder = HttpClients.custom();  
  17.         CloseableHttpClient client = builder.build();  
  18.         HttpGet request = new HttpGet(url);  
  19.         String str = "";  
  20.         try {  
  21.             //执行请求  
  22.             CloseableHttpResponse response = client.execute(request);  
  23.             //获取网页实体  
  24.             HttpEntity entity = response.getEntity();  
  25.             //返回网页实体字符串  
  26.             str = EntityUtils.toString(entity);  
  27.         } catch (ClientProtocolException e) {  
  28.             e.printStackTrace();  
  29.         } catch (IOException e) {  
  30.             e.printStackTrace();  
  31.         }  
  32.         return str;  
  33.     }  
  34.   
  35. }  

 

获取热卖页面所有商品的URL


热卖页面:

1、页面示例

 

 

2、分析获取所有商品URL

通过查找页面源码可以发现所有商品URL都类似 //item.jd.com/2717678.html 这种格式,只是2717678这个商品ID不同而已,所以我们可以用正则获取这些URL。

 

3、代码及打印结果

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试 : 获取本周热卖所有商品URL  
  2. public void test6() {  
  3.     //获取本周热卖网页源码  
  4.     String content = SpiderUtils.download("http://sale.jd.com/act/6hd0T3HtkcEmqjpM.html");  
  5.     //匹配这个网页所有商品网址  
  6.     Pattern compile = Pattern.compile("//item.jd.com/([0-9]+).html");  
  7.     //使用正则进行匹配  
  8.     Matcher matcher = compile.matcher(content);  
  9.     //使用正则进行查找,查找过程中可能会出现重复的URL,所以我们需要存入HashSet从而保证URL唯一  
  10.     HashSet<String> hashSet = new HashSet<String>();  
  11.     while (matcher.find()) {  
  12.         String goodURL = matcher.group(0);  
  13.         hashSet.add(goodURL);  
  14.     }  
  15.     for (String url : hashSet) {  
  16.         System.out.println(url);  
  17.     }  
  18. }  

打印的部分结果:(实际代码中使用时需要再添加”http:”前缀)

 

 

 

获取所有商品名称

1、商品名称页面示例

 

 

2、我们可以使用代码加载商品详情页面,然后通过工具获取XPath(获取方法可以参考之前的工具使用介绍),然后使用代码通过XPath获取Path中的商品名称。

 

3、代码及打印结果(所有商品的名称)

 

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试 :获取商品的名称  
  2. public void test7() {  
  3.   
  4.     //获取本周热卖网页源码  
  5.     String content = SpiderUtils.download("http://sale.jd.com/act/6hd0T3HtkcEmqjpM.html");  
  6.     //匹配这个网页所有商品网址  
  7.     Pattern compile = Pattern.compile("//item.jd.com/([0-9]+).html");  
  8.     //使用正则进行匹配  
  9.     Matcher matcher = compile.matcher(content);  
  10.     //使用正则进行查找,查找过程中可能会出现重复的URL,所以我们需要存入HashSet从而保证URL唯一  
  11.     HashSet<String> hashSet = new HashSet<String>();  
  12.     while (matcher.find()) {  
  13.         //获取每个商品对应的URL  
  14.         String goodURL = matcher.group(0);  
  15.         //把URL添加进HashSet  
  16.         hashSet.add(goodURL);  
  17.     }  
  18.   
  19.     for (String goodURL : hashSet) {  
  20.         //获取商品页面源码  
  21.         String contents = SpiderUtils.download("http:" + goodURL);  
  22.         HtmlCleaner htmlCleaner = new HtmlCleaner();  
  23.         //获取所有节点  
  24.         TagNode tn = htmlCleaner.clean(contents);  
  25.         //商品名称的XPath  
  26.         String xpath = "//*[@id=\"name\"]/h1";  
  27.         Object[] objects = null;  
  28.         String name = "";  
  29.   
  30.         try {  
  31.             //通过XPath查找商品名称所在节点  
  32.             objects = tn.evaluateXPath(xpath);  
  33.         } catch (XPatherException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.   
  37.         if (objects != null && objects.length > 0) {  
  38.             //获取商品名称节点  
  39.             TagNode node = (TagNode) objects[0];  
  40.             //获取商品名称  
  41.             name = node.getText().toString();  
  42.         }  
  43.         System.out.println(goodURL);  
  44.     }  
  45. }  

打印的部分结果:

 

 

 

获取所有商品ID

1、商品编号页面

 

 

2、使用Chrome的开发者工具(F12)获取商品编号的XPath,然后通过代码查找到所有的ID。

 

3、代码及打印结果(所有商品ID)

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试 :获取商品的Id  
  2. public void test8(){  
  3.   
  4.     //获取本周热卖网页源码  
  5.     String content = SpiderUtils.download("http://sale.jd.com/act/6hd0T3HtkcEmqjpM.html");  
  6.     //匹配这个网页所有商品网址  
  7.     Pattern compile = Pattern.compile("//item.jd.com/([0-9]+).html");  
  8.     //使用正则进行匹配  
  9.     Matcher matcher = compile.matcher(content);  
  10.     //使用正则进行查找,查找过程中可能会出现重复的URL,所以我们需要存入HashSet从而保证URL唯一  
  11.     HashSet<String> hashSet = new HashSet<String>();  
  12.     while (matcher.find()) {  
  13.         //获取每个商品对应的URL  
  14.         String goodURL = matcher.group(0);  
  15.         //把URL添加进HashSet  
  16.         hashSet.add(goodURL);  
  17.     }  
  18.   
  19.     for (String goodURL : hashSet) {  
  20.         //获取商品页面源码  
  21.         String contents = SpiderUtils.download("http:"+goodURL);  
  22.         HtmlCleaner htmlCleaner = new HtmlCleaner();  
  23.         //获取所有节点  
  24.         TagNode tn = htmlCleaner.clean(contents);  
  25.         //商品名称的XPath  
  26.         String xpath = "//*[@id=\"short-share\"]/div/span[2]";  
  27.         Object[] objects = null;  
  28.         try {  
  29.             objects = tn.evaluateXPath(xpath);  
  30.         } catch (XPatherException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.         TagNode node = (TagNode)objects[0];  
  34.         //获取ID  
  35.         String id = node.getText().toString();  
  36.         System.out.println(id);  
  37.     }  
  38. }  

打印的部分结果:

 

 

 

获取所有商品的图片URL

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试 :获取商品的图片的URL  
  2. public void test9() {  
  3.   
  4.     //获取本周热卖网页源码  
  5.     String content = SpiderUtils.download("http://sale.jd.com/act/6hd0T3HtkcEmqjpM.html");  
  6.     //匹配这个网页所有商品网址  
  7.     Pattern compile = Pattern.compile("//item.jd.com/([0-9]+).html");  
  8.     //使用正则进行匹配  
  9.     Matcher matcher = compile.matcher(content);  
  10.     //使用正则进行查找,查找过程中可能会出现重复的URL,所以我们需要存入HashSet从而保证URL唯一  
  11.     HashSet<String> hashSet = new HashSet<String>();  
  12.     while (matcher.find()) {  
  13.         //获取每个商品对应的URL  
  14.         String goodURL = matcher.group(0);  
  15.         //把URL添加进HashSet  
  16.         hashSet.add(goodURL);  
  17.     }  
  18.   
  19.     //遍历hashSet  
  20.     for (String goodURL : hashSet) {  
  21.         //获取商品页面源码  
  22.         String contents = SpiderUtils.download("http:" + goodURL);  
  23.         HtmlCleaner htmlCleaner = new HtmlCleaner();  
  24.         //获取所有节点  
  25.         TagNode tn = htmlCleaner.clean(contents);  
  26.         //商品名称的XPath  
  27.         String xpath = "//*[@id=\"spec-n1\"]/img";  
  28.         Object[] objects = null;  
  29.         String picUrl = "";  
  30.   
  31.         try {  
  32.             objects = tn.evaluateXPath(xpath);  
  33.         } catch (XPatherException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.   
  37.         if (objects != null && objects.length > 0) {  
  38.             TagNode node = (TagNode) objects[0];  
  39.             //通过节点的属性获取图片URL  
  40.             picUrl = node.getAttributeByName("src").toString();  
  41.         }  
  42.         System.out.println(picUrl);  
  43.     }  
  44. }  

打印的部分结果:

 

 

 

获取所有商品价格

 

1、商品价格是通过JS异步传输的数据,无法通过XPath方法直接获取。所以首先需要我们通过之前工具使用的介绍,找到JS异步请求的URL。

 

 

2、拷贝找到的URL:http://p.3.cn/prices/get?type=1&area=1_72_2799&pdtk=&pduid=1340247559&pdpin=&pdbp=0&skuid=J_1308551&callback=cnp

在浏览器中打开可以看到

 

 

这个URL中还有不需要的东西:&callback=cnp ,去掉之后为:

http://p.3.cn/prices/get?type=1&area=1_72_2799&pdtk=&pduid=1340247559&pdpin=&pdbp=0&skuid=J_1308551

再在浏览器中打开,结果为:(是一个Json格式字符串)

 

这才是我们最终要请求的URL。

 

3、代码及打印结果

单个商品代码:

[java] view
plain
 copy

 

  1. @Test   //单元测试  : 获取所有商品价格  
  2. public void test12() {  
  3.     //拼接JS异步请求的URL  
  4.     String pricURl = "http://p.3.cn/prices/get?type=1&area=1_72_2799&pdtk=&pduid=1340247559&pdpin=&pdbp=0&skuid=J_1308551";  
  5.     //获取响应的内容  
  6.     String con = SpiderUtils.download(pricURl);  
  7.     //把json格式的字符串格式化为Json数组  
  8.     JSONArray jsonArray = new JSONArray(con);  
  9.     //之前获取的结果可用看出是只有一个json元素的json数组。  
  10.     JSONObject jsonObject = jsonArray.getJSONObject(0);  
  11.     //获取Json,并获取其中键为p的值。  
  12.     String priceStr = jsonObject.getString("p");  
  13.     double price = Double.parseDouble(priceStr);  
  14.     System.out.println(price);  
  15. }  

打印结果:

 

 

 

多个商品代码:

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试  : 获取所有商品价格  
  2. public void test11() {  
  3.     //取之前获得ID集合  
  4.     HashSet<String> goodIds = goodId();  
  5.     //遍历ID结合,然后通过每个ID拼接JS异步请求的URL,然后获得响应  
  6.     for (String goodId : goodIds) {  
  7.         //拼接JS异步请求的URL  
  8.         String pricURl = "http://p.3.cn/prices/get?type=1&area=1_72_2799&pdtk=&pduid=1340247559&pdpin=&pdbp=0&skuid=J_" + goodId;  
  9.         //获取响应的内容  
  10.         String con = SpiderUtils.download(pricURl);  
  11.         //把json格式的字符串格式化为Json数组  
  12.         JSONArray jsonArray = new JSONArray(con);  
  13.         //之前获取的结果可用看出是只有一个json元素的json数组。  
  14.         JSONObject jsonObject = jsonArray.getJSONObject(0);  
  15.         //获取Json,并获取其中键为p的值。  
  16.         String priceStr = jsonObject.getString("p");  
  17.         double price = Double.parseDouble(priceStr);  
  18.         System.out.println(price);  
  19.     }  
  20. }  

打印的部分结果示例:

 

 

 

获取商品详情

1、商品介绍页面

 

 

2、代码及打印结果(这里只测试一个商品,之后代码中是获取所有商品)

代码示例:

[java] view
plain
 copy

 

  1. @Test   //单元测试 :获取商品介绍(由于数据比较多,这里就获取单个商品的介绍)  
  2. public void test10(){  
  3.     //获取商品页面源码  
  4.     String contents = SpiderUtils.download("http://item.jd.com/1308551.html");  
  5.     HtmlCleaner htmlCleaner = new HtmlCleaner();  
  6.     //获取所有节点  
  7.     TagNode tn = htmlCleaner.clean(contents);  
  8.     //商品名称的XPath  
  9.     String xpath = "//*[@id=\"parameter2\"]/li";  
  10.     Object[] objects = null;  
  11.     try {  
  12.         objects = tn.evaluateXPath(xpath);  
  13.     } catch (XPatherException e) {  
  14.         e.printStackTrace();  
  15.     }  
  16.   
  17.     for (Object obj : objects) {  
  18.         TagNode node = (TagNode)obj;  
  19.         String val = node.getText().toString();  
  20.         System.out.println(val);  
  21.     }  
  22.   
  23. }  

打印结果:

 

 

 

 

保存爬取的数据到MySQL

 

注意事项

1、由于本周热卖每个页面都用一个线程去跑,每个线程都有一个数据库链接,所以Mysql的数据库连接数需要修改大一点。

解决方式:

打开 MYSQL 安装目录打开my.ini找到max_connections默认是100,
一般设置到500~1000比较合适,然后重启MySQL。

2、这里只是演示爬取数据插入表格,所以表格的设计不是很合理。

 

插入商品信息

 

1、商品信息页面展示

 

2、数据库表设计

数据表说明:

 

 

数据表创建语句:

[sql] view
plain
 copy

 

  1. CREATE TABLE `goodInfo` (  
  2.   `id` int(10) NOT NULL AUTO_INCREMENT,  
  3.   `goodId` varchar(20) DEFAULT NULL,  
  4.   `goodName` varchar(300) DEFAULT NULL,  
  5.   `goodPrice` varchar(10) DEFAULT NULL,  
  6.   `goodUrl` varchar(300) DEFAULT NULL,  
  7.   `goodPicUrl` varchar(300) DEFAULT NULL,  
  8.   `goodDetail` text,  
  9.   `current_time` datetime DEFAULT NULL,  
  10.   PRIMARY KEY (`id`)  
  11. ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;  

 

3、插入的本周热卖所有商品的信息:ID、名称、URL、图片URL、详情、插入日期。

 

4、代码示例和部分执行结果

代码示例:(插入商品信息的功能代码在实际代码中会抽取为方法)

[java] view
plain
 copy

 

  1. //将每个页面的业务逻辑放在Runnable接口的run()方法中,这样可以调用多线程爬取每个页面。  
  2. public void run() {  
  3.   
  4.     String contents = SpiderUtils.download(url);  
  5.     HtmlCleaner htmlCleaner = new HtmlCleaner();  
  6.     //获取所有节点  
  7.     TagNode tn = htmlCleaner.clean(contents);  
  8.     //获取商品ID、名称、价格、URL、图片URL、详情、插入日期,插入到MySQL  
  9.     //个商品ID添加"jd_",这样可以和其他爬取的电商数据区分开来。  
  10.     String goodsId = "jd_" + goodsId(tn);  
  11.     String goodsName = goodsName(tn);  
  12.     String goodsPrice = goodsPrice(tn);  
  13.     //构造函数中的参数,初始化时传入的页面URL  
  14.     String goodsUrl = url;  
  15.     String goodsPicUrl = goodsPicUrl(tn);  
  16.     String goodsDetils = goodsDetils(tn);  
  17.     Date date = new Date();  
  18.     //MyDateUtils是个人封装的工具类  
  19.     String curr_time = MyDateUtils.formatDate2(date);  
  20.   
  21.     //MyDbUtils是个人封装的工具类  
  22.     MyDbUtils.update(MyDbUtils.INSERT_LOG, goodsId, goodsName, goodsPrice, goodsUrl, goodsPicUrl, goodsDetils, curr_time);  
  23. }  

执行结果:

 

 

 

项目代码

注意:MyDbUtils、MyDateUtils这两个工具类的代码就不贴了,项目中用到这两个工具类的方法,大家可以自己实现,比较简单。

 

Pom依赖

[java] view
plain
 copy

 

  1. <dependencies>  
  2.     <dependency>  
  3.         <groupId>junit</groupId>  
  4.         <artifactId>junit</artifactId>  
  5.         <version>4.12</version>  
  6.         <scope>test</scope>  
  7.     </dependency>  
  8.     <dependency>  
  9.         <groupId>org.apache.httpcomponents</groupId>  
  10.         <artifactId>httpclient</artifactId>  
  11.         <version>4.4</version>  
  12.     </dependency>  
  13.     <dependency>  
  14.         <groupId>net.sourceforge.htmlcleaner</groupId>  
  15.         <artifactId>htmlcleaner</artifactId>  
  16.         <version>2.10</version>  
  17.     </dependency>  
  18.     <dependency>  
  19.         <groupId>org.json</groupId>  
  20.         <artifactId>json</artifactId>  
  21.         <version>20140107</version>  
  22.     </dependency>  
  23.     <dependency>  
  24.         <groupId>commons-dbutils</groupId>  
  25.         <artifactId>commons-dbutils</artifactId>  
  26.         <version>1.6</version>  
  27.     </dependency>  
  28.     <dependency>  
  29.         <groupId>mysql</groupId>  
  30.         <artifactId>mysql-connector-java</artifactId>  
  31.         <version>5.1.29</version>  
  32.     </dependency>  
  33. </dependencies>  

工具类

[java] view
plain
 copy

 

  1. import java.io.IOException;  
  2.   
  3. import org.apache.http.HttpEntity;  
  4. import org.apache.http.client.ClientProtocolException;  
  5. import org.apache.http.client.methods.CloseableHttpResponse;  
  6. import org.apache.http.client.methods.HttpGet;  
  7. import org.apache.http.impl.client.CloseableHttpClient;  
  8. import org.apache.http.impl.client.HttpClientBuilder;  
  9. import org.apache.http.impl.client.HttpClients;  
  10. import org.apache.http.util.EntityUtils;  
  11.   
  12. public class SpiderUtils {  
  13.   
  14.     // 下载给定URL的网页实体  
  15.     public staticString download(String url) {  
  16.         HttpClientBuilder builder = HttpClients.custom();  
  17.         CloseableHttpClient client = builder.build();  
  18.         HttpGet request = new HttpGet(url);  
  19.         String str = "";  
  20.         try {  
  21.             CloseableHttpResponse response = client.execute(request);  
  22.             HttpEntity entity = response.getEntity();  
  23.             str = EntityUtils.toString(entity);  
  24.         } catch (ClientProtocolException e) {  
  25.             // TODO Auto-generated catch block  
  26.             e.printStackTrace();  
  27.         } catch (IOException e) {  
  28.             // TODO Auto-generated catch block  
  29.             e.printStackTrace();  
  30.         }  
  31.         return str;  
  32.     }  
  33.   
  34. }  

业务逻辑处理类

[java] view
plain
 copy

 

  1. import java.util.Date;  
  2.   
  3. import org.htmlcleaner.HtmlCleaner;  
  4. import org.htmlcleaner.TagNode;  
  5. import org.htmlcleaner.XPatherException;  
  6. import org.json.JSONArray;  
  7. import org.json.JSONObject;  
  8.   
  9. public class parsePage implements Runnable {  
  10.   
  11.    private String url;  
  12.   
  13.    public parsePage(String url) {  
  14.       this.url= url;  
  15.    }  
  16.   
  17.    // 将每个页面的业务逻辑放在Runnable接口的run()方法中,这样可以调用多线程爬取每个页面。  
  18.    public voidrun() {  
  19.       // 通过构造函数插入的url,然后获取该URL的响应结果  
  20.       String contents = SpiderUtils.download(url);  
  21.       HtmlCleaner htmlCleaner = new HtmlCleaner();  
  22.       // 获取所有节点  
  23.       TagNode tn = htmlCleaner.clean(contents);  
  24.         // 插入商品信息到数据库  
  25.         insertGoodInfo(tn);  
  26.     }  
  27.       
  28.   
  29.    // 插入商品信息到数据库  
  30.    private voidinsertGoodInfo(TagNode tn) {  
  31.       // 获取商品ID、名称、价格、URL、图片URL、详情、插入日期,插入到MySQL  
  32.       // 个商品ID添加"jd_",这样可以和其他爬取的电商数据区分开来。  
  33.       String goodsId = "jd_" + goodsId(tn);  
  34.       String goodsName = goodsName(tn);  
  35.       String goodsPrice = goodsPrice(tn);  
  36.       // 构造函数中的参数,初始化时传入的页面URL  
  37.       String goodsUrl = url;  
  38.       String goodsPicUrl = goodsPicUrl(tn);  
  39.       String goodsDetils = goodsDetils(tn);  
  40.       Date date = new Date();  
  41.       // MyDateUtils是个人封装的工具类  
  42.       String curr_time = MyDateUtils.formatDate2(date);  
  43.   
  44.       // MyDbUtils是个人封装的工具类  
  45.       MyDbUtils.update(MyDbUtils.INSERT_LOG, goodsId, goodsName, goodsPrice,  
  46.             goodsUrl, goodsPicUrl, goodsDetils, curr_time);  
  47.    }  
  48.   
  49.    // 获取商品详情  
  50.    privateString goodsDetils(TagNode tn) {  
  51.       String xpath = "//*[@id=\"parameter2\"]/li";  
  52.       StringBuilder info = new StringBuilder();  
  53.       Object[] objects = null;  
  54.       try {  
  55.          objects = tn.evaluateXPath(xpath);  
  56.       } catch (XPatherException e) {  
  57.          e.printStackTrace();  
  58.       }  
  59.   
  60.       for (Object obj : objects) {  
  61.          TagNode node = (TagNode) obj;  
  62.   
  63.          String goodInfo = node.getText().toString();  
  64.          info.append(goodInfo);  
  65.          info.append("--");  
  66.       }  
  67.       return info.toString();  
  68.    }  
  69.   
  70.    // 获取商品价格  
  71.    privateString goodsPrice(TagNode tn) {  
  72.       String pricURl = "http://p.3.cn/prices/get?type=1&area=1_72_2799&pdtk=&pduid=1340247559&pdpin=&pdbp=0&skuid=J_"+ goodsId(tn);  
  73.       String con = SpiderUtils.download(pricURl);  
  74.       JSONArray jsonArray = new JSONArray(con);  
  75.       JSONObject jsonObject = jsonArray.getJSONObject(0);  
  76.       String priceStr = jsonObject.getString("p");  
  77.       return priceStr;  
  78.    }  
  79.   
  80.    // 获取商品ID  
  81.    privateString goodsId(TagNode tn) {  
  82.       String xpath = "//*[@id=\"short-share\"]/div/span[2]";  
  83.       Object[] objects = null;  
  84.       try {  
  85.          objects = tn.evaluateXPath(xpath);  
  86.       } catch (XPatherException e) {  
  87.          e.printStackTrace();  
  88.       }  
  89.       TagNode node = (TagNode) objects[0];  
  90.       String id = node.getText().toString();  
  91.       return id;  
  92.    }  
  93.   
  94.    // 获取商品图片URL (全URL,包括http:)  
  95.    privateString goodsPicUrl(TagNode tn) {  
  96.       //商品图片的XPath  
  97.       String xpath = "//*[@id=\"spec-n1\"]/img";  
  98.       Object[] objects = null;  
  99.       String picUrl = "";  
  100.   
  101.       try {  
  102.          objects = tn.evaluateXPath(xpath);  
  103.       } catch (XPatherException e) {  
  104.          e.printStackTrace();  
  105.       }  
  106.   
  107.       if (objects != null && objects.length> 0) {  
  108.          TagNode node = (TagNode) objects[0];  
  109.          picUrl = node.getAttributeByName("src").toString();  
  110.       }  
  111.   
  112.       return "http:"+ picUrl;  
  113.    }  
  114.   
  115.    // 获取商品名称  
  116.    privateString goodsName(TagNode tn) {  
  117.       //商品名称的XPath  
  118.       String xpath = "//*[@id=\"name\"]/h1";  
  119.       Object[] objects = null;  
  120.       String name = "";  
  121.   
  122.       try {  
  123.          objects = tn.evaluateXPath(xpath);  
  124.       } catch (XPatherException e) {  
  125.          e.printStackTrace();  
  126.       }  
  127.   
  128.       if (objects != null && objects.length> 0) {  
  129.          TagNode node = (TagNode) objects[0];  
  130.          name = node.getText().toString();  
  131.       }  
  132.       return name;  
  133.    }  
  134.   
  135. }  

项目入口类

[java] view
plain
 copy

 

  1. import org.htmlcleaner.XPatherException;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.regex.Matcher;  
  5. import java.util.regex.Pattern;  
  6.   
  7. public class Spider {  
  8.     public static void main(String[] args)throws XPatherException {  
  9.         Spider spider = new Spider();  
  10.         spider.start();  
  11.     }  
  12.   
  13.     public void start() throws XPatherException {  
  14.         System.out.println("开始启动爬虫");  
  15.         //爬取本周热卖网页  
  16.         String content = SpiderUtils.download("http://sale.jd.com/act/6hd0T3HtkcEmqjpM.html");  
  17.   
  18.         // 匹配这个网页所有商品网址  
  19.         Pattern compile = Pattern.compile("//item.jd.com/([0-9]+).html");  
  20.         // 使用正则进行匹配  
  21.         Matcher matcher = compile.matcher(content);  
  22.         // 使用正则进行查找,查找过程中可能会出现重复的URL,所以我们需要存入HashSet从而保证URL唯一  
  23.         HashSet<String> hashSet =new HashSet<String>();  
  24.         String goodId = "";  
  25.         // 使用正则进行查找  
  26.         while(matcher.find()) {  
  27.             String goodURL = matcher.group(0);  
  28.             hashSet.add(goodURL);  
  29.         }  
  30.         for (String goodUrl : hashSet) {  
  31.             Thread th = new Thread(newparsePage("http:" + goodUrl));  
  32.             th.start();  
  33.         }  
  34.   
  35.     }  
  36.   
  37. }  

 

时间: 2024-10-02 17:07:00

爬取京东本周热卖商品基本信息存入MySQL的相关文章

Python爬取京东的商品分类与链接_python

前言 本文主要的知识点是使用Python的BeautifulSoup进行多层的遍历. 如图所示.只是一个简单的哈,不是爬取里面的隐藏的东西. 示例代码 from bs4 import BeautifulSoup as bs import requests headers = { "host": "www.jd.com", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWe

python实现爬取千万淘宝商品的方法

  本文实例讲述了python实现爬取千万淘宝商品的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

求助大神,爬虫爬取京东评论数据爬一小部分(大概100条评论)就爬不到评论了,返回空值了

问题描述 求助大神,爬虫爬取京东评论数据爬一小部分(大概100条评论)就爬不到评论了,返回空值了 python 爬取评论数据,爬到一百多条评论,就返回空值了,无法继续爬下去了 解决方案 用fiddler调试下,看下是不是京东有限制.比如让你过多少时间再访问,或者要你输入验证码. 解决方案二: 如果要爬京东评论,已经有大牛写出很成熟的代码了,推荐大家去看看,专门讲了怎么突破京东的限制:http://blog.csdn.net/youmumzcs/article/details/51396283

爬取京东上商品的所有详细信息

项目介绍 使用python抓取京东商城商品(以手机为例)的详细信息,并将相应的图片下载下载保存到本地. 爬取步骤 1.选取种子URL:http://list.jd.com/list.html?cat=9987,653,655 2.使用urllib和urllib2下载网页 3.使用BeautifulSoup和re正则表达式解析html 4.保存数据 工具 python2.7 演示效果:   下载的图片:   下载示例: 名称: 摩托罗拉 Moto Z(XT1650-05) 模块化手机 流金黑 移动

python制作爬虫爬取京东商品评论教程_python

本篇文章是python爬虫系列的第三篇,介绍如何抓取京东商城商品评论信息,并对这些评论信息进行分析和可视化.下面是要抓取的商品信息,一款女士文胸.这个商品共有红色,黑色和肤色三种颜色, 70B到90D共18个尺寸,以及超过700条的购买评论. 京东商品评论信息是由JS动态加载的,所以直接抓取商品详情页的URL并不能获得商品评论的信息.因此我们需要先找到存放商品评论信息的文件.这里我们使用Chrome浏览器里的开发者工具进行查找. 具体方法是在商品详情页点击鼠标右键,选择检查,在弹出的开发者工具界

反爬虫-菜鸟求助,大神请进:python爬取某东评论数据遇到的问题

问题描述 菜鸟求助,大神请进:python爬取某东评论数据遇到的问题 python爬取京东评论数据,爬10页的评论没问题,后面的评论就不断重复,到底是什么原因? 解决方案 先看是不是服务器返回的内容 然后就是你请求的参数有问题 所有重复请求 解决方案二: 应该是url没去重吧 解决方案三: 最近看到一个csdn的博客专门讲如何写电商爬虫的,地址是:http://blog.csdn.net/youmumzcs/article/details/51373830,楼主可以参考

java实现爬取知乎用户基本信息_java

本文实例为大家分享了一个基于JAVA的知乎爬虫,抓取知乎用户基本信息,基于HttpClient 4.5,供大家参考,具体内容如下详细内容:抓取90W+用户信息(基本上活跃的用户都在里面)大致思路:1.首先模拟登录知乎,登录成功后将Cookie序列化到磁盘,不用以后每次都登录(如果不模拟登录,可以直接从浏览器塞入Cookie也是可以的). 2.创建两个线程池和一个Storage.一个抓取网页线程池,负责执行request请求,并返回网页内容,存到Storage中.另一个是解析网页线程池,负责从St

python爬取淘宝商品信息并加入购物车

先说一下最终要达到的效果:谷歌浏览器登陆淘宝后,运行python项目,将任意任意淘宝商品的链接传入,并手动选择商品属性,输出其价格与剩余库存,然后选择购买数,自动加入购物车. 在开始爬取淘宝链接之前,咱么要先做一些准备工作,我项目中使用的是 python2.7 ,开发与运行环境都是win10,浏览器是64位chrome 59.0.3.由于淘宝的模拟登陆涉及到一些复杂的UA码算法以及滑块登陆验证,能力有限,为了图省事就使用浏览器手动登录淘宝然后python获取生成的cookie的方式来爬取登录后的

python-Python爬虫爬取网页源代码为空,求问原因&amp;amp;amp;解决方案(向)

问题描述 Python爬虫爬取网页源代码为空,求问原因&解决方案(向) 代码如下:import urllibimport urllib2import re url ='http://www.yingjiesheng.com/guangzhou-moreptjob-2.html'req = urllib2.Request(url)try: html = urllib2.urlopen(req).read() print htmlexcept urllib2.HTTPError e: print '