JAVA爬取某东、某宝以及某宁商品详细数据(一)

  • 写在最前
  • 反爬策略问题解决
    • 请求头配置
      • 无代理模式
      • 代理模式
    • 某东
      • JDHTML解析
      • JD商品解析
    • 天猫
      • TMHTML解析
    • 苏宁
      • SNHTML解析

写在最前

     防止篇幅过长,对于如何爬取某东、某宝以及某宁的历史价格数据,会在下一篇博客中进行总结:https://blog.csdn.net/qq_40921561/article/details/110950930

反爬策略问题解决

    某东、某宝以及某宁电商网站平台,对于爬虫还算比较友好,唯一的问题就是有些数据是动态加载的,爬虫无法通过解析html页面获取数据。(比如某东的商品价格信息)

请求头配置

    这些请求头配置都是公共的配置,对于请求头,各大电商都没有做严格的反爬校验(某宝会校验user-agent,但是加上去也不影响)。
    另外,设置超时处理,一定要设置,不仅仅是为了防止后台一直在请求,收不到任何反馈信息,无法定位问题,还防止瞬时多次请求,IP被封。
对于user-agent随便打开一个网页,F12找到请求头信息中的user-agent。

    对于大批量数据的爬取,代理池的设置是必不可少的。代理池的作用就是,将请求的IP“伪装”成代理池中的IP进行请求,提高爬取上限。代理池可以用云代理或者本地代理池,对于个人或者小的需求项目,用本地代理池就可以。在这里推荐一下快刺代理(具体的问谷哥或者度娘,这里不做具体说明)
    以下便是对于url请求地址进行请求并返回html代码的工具接口

无代理模式

/*** @Description: 获取页面的htmlgetHtml* @param url 地址* @param headerMap 头部信息*/public static String getHtml(String url, Map<String, Object> headerMap){String entity = null;CloseableHttpClient httpClient = HttpClients.createDefault();//设置超时处理RequestConfig config = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();HttpGet httpGet = new HttpGet(url);httpGet.setConfig(config);//设置头部信息if (null != headerMap.get("accept")){httpGet.setHeader("Accept", headerMap.get("accept").toString());}if (null != headerMap.get("encoding")){httpGet.setHeader("Accept-Encoding", headerMap.get("encoding").toString());}if (null != headerMap.get("language")){httpGet.setHeader("Accept-Language", headerMap.get("language").toString());}if (null != headerMap.get("host")){httpGet.setHeader("Host", headerMap.get("host").toString());}if (null != headerMap.get("referer")){httpGet.setHeader("Referer", headerMap.get("referer").toString());}//固定项httpGet.setHeader("Connection", "keep-alive");httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36");try {//客户端执行httpGet方法,返回响应CloseableHttpResponse httpResponse = httpClient.execute(httpGet);//得到服务响应状态码if (httpResponse.getStatusLine().getStatusCode() == 200) {entity = EntityUtils.toString(httpResponse.getEntity(), "utf-8");}httpResponse.close();httpClient.close();} catch (IOException e) {e.printStackTrace();}return entity;}

代理模式

 private static Logger logger = Logger.getLogger(HttpClientUtils.class);/*** @Description: 代理 获取页面的htmlgetHtml* @param url 地址* @param ip * @param port* @param headerMap 头部信息*/public static String getHtml(String url, String ip, String port, Map<String, Object> headerMap){String entity = null;CloseableHttpClient httpClient = HttpClients.createDefault();logger.info(">>>>>>>>>此时线程: " + Thread.currentThread().getName() + " 爬取所使用的代理为: "+ ip + ":" + port);HttpHost proxy = new HttpHost(ip, Integer.parseInt(port));RequestConfig config = RequestConfig.custom().setProxy(proxy).setConnectTimeout(3000).setSocketTimeout(3000).build();HttpGet httpGet = new HttpGet(url);httpGet.setConfig(config);//设置头部信息if (null != headerMap.get("accept")){httpGet.setHeader("Accept", headerMap.get("accept").toString());}if (null != headerMap.get("encoding")){httpGet.setHeader("Accept-Encoding", headerMap.get("encoding").toString());}if (null != headerMap.get("language")){httpGet.setHeader("Accept-Language", headerMap.get("language").toString());}if (null != headerMap.get("host")){httpGet.setHeader("Host", headerMap.get("host").toString());}//固定项httpGet.setHeader("Connection", "keep-alive");httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36");try {//客户端执行httpGet方法,返回响应CloseableHttpResponse httpResponse = httpClient.execute(httpGet);//得到服务响应状态码if (httpResponse.getStatusLine().getStatusCode() == 200) {entity = EntityUtils.toString(httpResponse.getEntity(), "utf-8");}httpResponse.close();httpClient.close();} catch (IOException e) {entity = null;}return entity;}

    对于获取价格(最高价、最低价)以及历史数据,会在下一篇博客中详细说明。https://blog.csdn.net/qq_40921561/article/details/110950930

某东

    各个VO类不做详细赘述,这里的示例都是无代理的爬取。(实际跑的时候最好加代理池)。另外,为了加快爬取速度,这里建议改成多线程。(方便做介绍,在页面解析处,我会用多线程的方式对爬取的每页数据的所有商品进行解析)

JDHTML解析

/*** @Description: JDItemDetail 爬取京东商品信息* @param name 要查询的商品名字* @return*/private List<ItemDetailsVO> JDItemDetail(String name){List<ItemDetailsVO> itemDetailsVOs = new LinkedList<ItemDetailsVO>();//分页查找商品数据 取前10页for (int i = 1; i <= 10 ; i++) {//京东分页 page 为 1 3 5  .....//         对应第一页 第二页....String url="https://search.jd.com/Search?keyword=" + name + "&enc=utf-8&page="+(2*i-1);String html = "";try{html = HttpClientUtils.doGet(url);parseJDIndex(itemDetailsVOs, html);} catch (IOException e){throw ExceptionFactory.iOStremException();}}return itemDetailsVOs;}

JD商品解析

    对于刚学习java的同学,这里的CountDownLatch不可少,具体:开了多线程之后,如果不对每个线程做限制,每个线程跑完接口并不会停止,最后获取不到数据。

/*** @Description: parseJDIndex   解析京东页面* @param html* @throws IOException* @throws InterruptedException*/@SuppressWarnings("null")private  static void parseJDIndex(List<ItemDetailsVO> itemDetailsVOs, String html) throws IOException{CountDownLatch jdThreadSignal = new CountDownLatch(3);Document document = Jsoup.parse(html);//商品列表Elements elements = document.select("#J_goodsList>ul>li");if(elements!=null||elements.size()!=0){//这里为了体现快速测试只取每页的前三个元素//取全部元素可以改成//for (Element element : elements) {for (int i=0;i<3;i++) {//获得每个li的pid   dataa-pid//狗东改了,就很气  data-skuElement element = elements.get(i);new Thread( new Runnable() {@Overridepublic void run() {try{String pid = element.attr("data-sku");ItemDetailsVO itemDetailsVO = parsePid(pid);itemDetailsVOs.add(itemDetailsVO);} catch (IOException e){throw ExceptionFactory.iOStremException();}jdThreadSignal.countDown();}}).start();}}try{jdThreadSignal.await();} catch (InterruptedException e){throw ExceptionFactory.threadCountException();}}
/*** @Description: parseIndex   获得某个页面的详细数据* @param pid* @return */private static ItemDetailsVO parsePid(String pid) throws IOException {//拼接url 进入商品详情页String productUrl="https://item.jd.com/"+pid+".html";String productHtml = HttpClientUtils.doGet(productUrl);Document document = Jsoup.parse(productHtml);ItemDetailsVO itemDetailsVO = new ItemDetailsVO();itemDetailsVO.setImgLogo("../img/jdLogo.png");//获得商品标题if(document.select("div.sku-name").size()>0){itemDetailsVO.setTitle(document.select("div.sku-name").get(0).text());}//获得商品品牌itemDetailsVO.setBrand(document.select("#parameter-brand li").attr("title"));//获得商品名称itemDetailsVO.setItemName(document.select("[class=parameter2 p-parameter-list] li:first-child").attr("title"));//获取商品店铺itemDetailsVO.setStoreName(document.select("div.name a").attr("title"));//获得店铺类别itemDetailsVO.setStoreType(document.select("[class=name goodshop EDropdown] em").text());//获取图片itemDetailsVO.setImgUrl(document.select("#spec-img").attr("data-origin"));//获得商品链接String itemUrl = "https://item.jd.com/" + pid + ".html";itemDetailsVO.setItemUrl(itemUrl);//评论炸了  狗东  记得修复  不许刷水军itemDetailsVO.setCommentNum("1000+");itemDetailsVO.setSales("100+");//获取商品价格parsePrice(itemDetailsVO, itemUrl);itemDetailsVO.setPid(pid);return itemDetailsVO;}

天猫

页面请求同上,只是网址不同而已,具体解析如下:

String name="";
"https://list.tmall.com/search_product.htm?q=" + name;

TMHTML解析

 /*** @Description: parseTMIndex   解析天猫页面* @param html*/private  static void parseTMIndex(List<ItemDetailsVO> itemDetailsVOs, String html) {CountDownLatch tmThreadSignal = new CountDownLatch(3);Document document = Jsoup.parse(html);Elements ulList = document.select("div[class='view grid-nosku']");Elements liList = ulList.select("div[class='product']");//这里为了体现快速测试只取每页的前三个元素//取全部元素可以改成//for (Element element : liList ) {for (int i=0;i<3;i++) {Element item = liList.get(i);new Thread(new Runnable(){@Overridepublic void run(){ItemDetailsVO itemDetailsVO = new ItemDetailsVO();itemDetailsVO.setImgLogo("../img/tmLogo.png");// 商品IDString id = item.select("div[class='product']").select("p[class='productStatus']").select("span[class='ww-light ww-small m_wangwang J_WangWang']").attr("data-item");itemDetailsVO.setPid(id);// 商品名称String name = item.select("p[class='productTitle']").select("a").attr("title");itemDetailsVO.setTitle(name);name = name.substring(name.indexOf("】")+1).split(" ")[0];//商品名字和商品品牌if (name.contains("/")) {name = name.substring(0, name.indexOf("/"));}else {//对过长的名字和品牌进行截取if (name.length()>6){char c = 0;if (name.charAt(0)>255){for (int j = 0; j < name.length(); j++){if (name.charAt(j)<=255){c = name.charAt(j);break;}}}else {for (int j = 0; j < name.length(); j++){if (name.charAt(j)>255){c = name.charAt(j);break;}}}if (c!=0)name = name.substring(0,name.indexOf(c));}  }itemDetailsVO.setBrand(name);itemDetailsVO.setItemName(name);// 商品价格itemDetailsVO.setPrice(item.select("p[class='productPrice']").select("em").attr("title"));// 商品网址itemDetailsVO.setItemUrl("https://detail.tmall.com/item.htm?id="+id);Elements spanList = item.select("p[class='productStatus']").select("span");// 商品销量itemDetailsVO.setSales(spanList.get(0).select("em").text());// 商品评价数itemDetailsVO.setCommentNum(spanList.get(1).select("a").text());// 商品店铺itemDetailsVO.setStoreName(spanList.get(2).attr("data-nick"));// 商品图片网址itemDetailsVO.setImgUrl(item.select("div[class='productImg-wrap']").select("a").select("img").attr("src"));try{parsePrice(itemDetailsVO, "https://detail.tmall.com/item.htm?id="+id);} catch (ParseException e){throw ExceptionFactory.parseException();} catch (IOException e){throw ExceptionFactory.iOStremException();}itemDetailsVOs.add(itemDetailsVO);tmThreadSignal.countDown();}}).start(); }try{tmThreadSignal.await();} catch (InterruptedException e){throw ExceptionFactory.threadCountException();}}

苏宁

苏宁请求网址如下:

String url = "https://search.suning.com/"+name+"/";

SNHTML解析

/*** @Description: parseSNIndex   解析苏宁页面* @param html*/private  static void parseSNIndex(List<ItemDetailsVO> itemDetailsVOs, String html) {CountDownLatch snThreadSignal = new CountDownLatch(3);Document document = Jsoup.parse(html);Elements liElements = document.select("div[class='product-list  clearfix']").select("ul").select("li");for (int i=0;i<3;i++) {Element element = liElements.get(i);new Thread(new Runnable(){@Overridepublic void run(){ItemDetailsVO itemDetailsVO = new ItemDetailsVO();itemDetailsVO.setImgLogo("../img/snLogo.png");Element elementMain = element.select("div.item-bg").select("div.product-box").select("div.res-img").select("div.img-block").get(0);Element elementPrice = element.select("div.item-bg").select("div.product-box").select("div.res-info").select("div.price-box").select("span").get(0);Element elementTitle = element.select("div.item-bg").select("div.product-box").select("div.res-info").select("div.title-selling-point").select("a").get(0);Element elementCommonts = element.select("div.item-bg").select("div.product-box").select("div.res-info").select("[class=evaluate-old clearfix]").select("div.info-evaluate").select("a").get(0);//商品piditemDetailsVO.setPid(elementPrice.attr("datasku").split("\\|")[0]);//商品标题String title = "";if (elementTitle.text().contains("【")){if (elementTitle.text().startsWith("【")){title = elementTitle.text().substring(elementTitle.text().indexOf("】")+1);}else {title = elementTitle.text().substring(0,elementTitle.text().indexOf("【"));}}else {title = elementTitle.text();}itemDetailsVO.setTitle(title);//评论数itemDetailsVO.setCommentNum(elementCommonts.select("i").text());//销量itemDetailsVO.setSales(itemDetailsVO.getCommentNum());//商品名字和品牌String brand = "";String itemName = "";if (itemDetailsVO.getTitle().startsWith("(")){brand = itemDetailsVO.getTitle().substring(0, itemDetailsVO.getTitle().indexOf("("));itemName = itemDetailsVO.getTitle().substring(itemDetailsVO.getTitle().indexOf(")")+1, itemDetailsVO.getTitle().indexOf(" ")==-1?itemDetailsVO.getTitle().length():itemDetailsVO.getTitle().indexOf(" "));}else {brand = itemDetailsVO.getTitle().split(" ")[0];itemName = itemDetailsVO.getTitle().split(" ")[0];}itemDetailsVO.setBrand(brand);itemDetailsVO.setItemName(itemName);//店铺名字itemDetailsVO.setStoreName(element.select("div.item-bg").select("div.product-box").select("div.res-info").select("div.store-stock").select("a").text());//图片地址itemDetailsVO.setImgUrl(elementMain.select("img").attr("src"));//商品链接itemDetailsVO.setItemUrl("https:"+elementMain.select("a").attr("href"));try{parsePrice(itemDetailsVO, itemDetailsVO.getItemUrl());} catch (ParseException e){throw ExceptionFactory.parseException();} catch (IOException e){throw ExceptionFactory.iOStremException();}itemDetailsVOs.add(itemDetailsVO);snThreadSignal.countDown();}}).start();}try{snThreadSignal.await();} catch (InterruptedException e){throw ExceptionFactory.threadCountException();}}

JAVA爬取淘宝、京东、天猫以及苏宁商品详细数据(一)相关推荐

  1. Python爬虫爬取淘宝、天猫某商品页面相关信息实例

    一.爬取天猫店铺的相关信息 URL="https://detail.tmall.com/item.htm?spm=a230r.1.14.8.4a1a115fb1rHn5&id=617 ...

  2. python爬取淘宝全部『螺蛳粉』数据,看看你真的了解螺蛳粉吗?

    01.前言 上一篇文章(爬取淘宝热卖商品并可视化分析,看看大家都喜欢买什么!)爬取分析了淘宝的热卖商品,从分析来看『螺蛳粉』的销量巨高.因此这篇文章将爬取淘宝全部『螺蛳粉』商品数据,通过可视化分析淘宝 ...

  3. python爬取淘宝天猫评论(通过cookie)

    今天分享的是使用python语言然后通过cookie来爬取淘宝天猫评论的方法. 1.首先我们打开一个产品页,地址:几素usb小风扇,按下F12,然后下拉到产品评论可以看到如下图 2.点击这个scrip ...

  4. 江湖小白之一起学Python (五)爬取淘宝商品信息

    趁热需打铁,随着这几天的鸡血澎湃,我们来实现一下爬取淘宝商品信息,我记得几年前曾用python写了下抓取淘宝天猫,京东,拍拍的爬虫,专门采集商品信息,图片,评论及评论图片,我还用pyqt开发了个客户端 ...

  5. 爬虫案例 --- Python 爬取淘宝数据存到数据库

    可以做爬虫的语言有很多,如 PHP.Java.C/C++.Python等等... 1)PHP语言 虽然是世界上最好的语言,但是他天生不是干这个的,而且对多线程.异步支持不够好,并发处理能力很弱.爬虫是 ...

  6. Python requests爬取淘宝商品信息

    作者:achen 联系方式:wh909077093 这里记一下大概的思路以及实现方法,有基础的小伙伴看了基本就能实现了,如果有业务需要可以联系我哈哈哈哈哈哈 本文代码参考猪哥66的思路 项目内容 指定 ...

  7. 利用Python爬虫爬取淘宝商品做数据挖掘分析实战篇,超详细教程

    项目内容 本案例选择>> 商品类目:沙发: 数量:共100页  4400个商品: 筛选条件:天猫.销量从高到低.价格500元以上. 项目目的 1. 对商品标题进行文本分析 词云可视化 2. ...

  8. python爬取淘宝商品做数据挖掘

    作业要求:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3159 项目内容: 本项目选择 淘宝商品类目:零食 数量:一共100页,44 ...

  9. 使用Appium爬取淘宝App数据

    0x01.介绍说明 1.简介 Appium是一个自动化测试开源工具.通过WebDriver协议驱动IOS.Android.Windows Phone平台上的原生应用.混合应用和web应用. 2.App ...

最新文章

  1. 《预训练周刊》第33期:艾伦AI研究所等 | 预训练语言模型的高效分层域适应
  2. 80个Python经典资料(教程+源码+工具)汇总——下载目录
  3. 第十五届全国大学生智能车竞赛线下比赛成绩和奖项
  4. 解散了地图接口讨论群
  5. PHP-RSA加密跨域通讯实战
  6. expect java_expect命令
  7. keytool基本使用
  8. win10开启虚拟化服务器,win10怎么开启vt技术-win10开启vt虚拟化技术的方法 - 河东软件园...
  9. 转:超越一切的熵增定律
  10. Java选择题(十)
  11. 解决PotPlayer播放视频没有声音
  12. EZ-USB FX2 LP CY7C68013A 开发指南(1)--基本概念
  13. Macbook M1 软件不兼容的解决办法
  14. 逻辑仿真工具VCS的使用-Makefile
  15. Notepad++--常用的配置
  16. python中集合运算_Python—集合的操作、文件的操作
  17. tooltip的api【getPopupContainer】
  18. 进行卡方检验前为什么要加权个案
  19. SAP FI 系列 (023) - 使用工作清单维护汇率
  20. 推荐个将其他文档转为pdf的软件:Nitro PDF Creator

热门文章

  1. 英国留学生本科生毕业论文应该多长?
  2. 堆栈上的舞蹈之释放重引用(UAF) 漏洞原理实验分析
  3. 祖安服务器位置,光明日报:不能坐视粗鄙的祖安文化侵蚀校园
  4. c语言密码加密程序6,c语言加密程序.docx
  5. 记一次服务器宕机处理过程
  6. ASP核酸检测报告查询系统源码
  7. mysql 每日数据备份方案_mysql数据库备份方案
  8. 【艾特淘】影响店铺权重有哪些因素?
  9. 华为G520联通版解锁,ROOT,RECOVERY、卡刷及删除定制软件教程
  10. Vim 同时插入多行,删除多行