抓取淘宝天猫的商品的促销价格

十度 Java 2016年09月28日 收藏

通过商品的url获取促销价,天猫淘宝的促销价并不是直接生成的,而是通过js间接生成的。所以通过jsoup等工具无法抓取。

首先是尝试使用htmlUnit,因为其可以,模拟浏览器运行js、css。经试验,htmlunit确实可以运行js,尝试抓取我自己的网站,可成功获取ajax、js生成的内容。但在抓取淘宝网站时出现异常,htmlunit对网站内容的格式有一定的要求,于是只能想其他办法(以后再尝试此方法)。

接着使用httpwatch分析淘宝的请求,发现其中一个请求返回的值中有促销价的信息。

这个请求有2个关键点,关键1:参数itemid(就是商品的id)。关键2:是请求header的Referer。

具体代码如下:

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.UnsupportedEncodingException;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. import org.apache.http.HttpResponse;
  9. import org.apache.http.client.ClientProtocolException;
  10. import org.apache.http.client.HttpClient;
  11. import org.apache.http.client.methods.HttpGet;
  12. import org.apache.http.client.methods.HttpPost;
  13. import org.apache.http.impl.client.DefaultHttpClient;
  14.  
  15.  
  16. public class Test4Taobao {
  17.  
  18. public static void main(String[] args) throws ClientProtocolException, IOException {
  19. HttpClient httpclient = new DefaultHttpClient();
  20. String url="http://detail.tmall.com/item.htm?spm=a230r.1.14.44.RoTYht&id=43508885384&ns=1&abbucket=20";
  21. String id=getStrByPrePost(url, "id=", "&");//根据url获取商品的id
  22. if(id!=null){
  23. //组装出获取商品信息的url
  24. String detailUrl="http://mdskip.taobao.com/core/initItemDetail.htm?itemId="+id+"×tamp=1429065419751&tgTag=false&cartEnable=true&addressLevel=2&progressiveSupport=false&isUseInventoryCenter=false&household=false¬AllowOriginPrice=false&isRegionLevel=false&sellerUserTag=303632416&sellerUserTag2=18020085046181888&tmallBuySupport=true&isAreaSell=false&queryMemberRight=true&isIFC=false&sellerUserTag3=70368779862144&sellerUserTag4=8800522208643&service3C=true&tryBeforeBuy=false&isSecKill=false&isForbidBuyItem=false&sellerPreview=false&itemTags=843,1163,1478,1483,1547,1611,1803,1867,2049,2059,2443,2507,2635,3787,3974,4166,4555,4811,5323,21762,21826,25282,28802,29122,34178,56130,56194&isApparel=false&offlineShop=false&showShopProm=false&callback=setMdskip";
  25. HttpGet get = new HttpGet(detailUrl);
  26. get.addHeader("Referer", url);//Referer必须要设置
  27. HttpResponse response = httpclient.execute(get);
  28. String content = getContent(response);
  29. content=getStrByPrePost(content, "setMdskip(", ")");
  30. //返回的内容是json格式,可以通过gson等来解析,为了方便,此处直接截取。
  31. System.out.println("商品信息:"+content);
  32. String promotionPrice = getStrByPrePost(content, "promotionList", null);
  33. promotionPrice = getStrByPrePost(promotionPrice, "\"price\":", ",");
  34. System.out.println("商品价格:"+promotionPrice);
  35. }
  36. }
  37. /**
  38. * 获取返回内容的string
  39. * @param response
  40. * @return
  41. * @throws IllegalStateException
  42. * @throws IOException
  43. */
  44. private static String getContent(HttpResponse response) throws IllegalStateException, IOException {
  45. java.io.InputStream is = response.getEntity().getContent();
  46. BufferedReader br = new BufferedReader(new InputStreamReader(is, "GBK"));//response.getEntity().getContentEncoding().getName()
  47. String line = "";
  48. String temp= null;
  49. while ((temp = br.readLine()) != null) {
  50. line+=temp;
  51. }
  52. return line;
  53. }
  54.  
  55. /**
  56. * 根据前后的文本截取指定的内容。
  57. * @param str
  58. * @param pre
  59. * @param post
  60. * @return
  61. */
  62. public static String getStrByPrePost(String str,String pre,String post){
  63. if(str!=null){
  64. if(pre!=null){
  65. int s = str.indexOf(pre);
  66. if(s>-1){
  67. str = str.substring(s+pre.length(), str.length());
  68. }else{
  69. return null;
  70. }
  71. }
  72. if(post!=null){
  73. int e = str.indexOf(post);
  74. if(e>-1){
  75. str = str.substring(0,e);
  76. }else{
  77. return null;
  78. }
  79. }
  80. }
  81. return str;
  82. }
  83. }
第一篇博客

to be continued