最近在学习java的爬虫技术,学的是黑马的视频资源,由于是几年前的视频啦,京东页面有些许变化,在此记录我遇到的问题,使用的爬虫技术是httpClient和jsoup,项目搭建使用的springboot+ jpa。
首先给出主页的代码:
@Component public class ItemTask { @Autowired private HttpUtils httpUtils; @Autowired private ItemService itemService; public static final ObjectMapper MAPPER = new ObjectMapper(); //设置定时任务执行完成后,再间隔100秒执行一次 @Scheduled(fixedDelay = 1000 * 100) public void process() throws Exception { //分析页面发现访问的地址,页码page从1开始,下一页page加2 String url = "https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&suggest=1.his.0.0&wq=%E6%89%8B%E6%9C%BA&s=121&click=0&page="; //遍历执行,获取所有的数据 for (int i = 1; i < 10; i = i + 2) { //发起请求进行访问,获取页面数据,先访问第一页 String html = this.httpUtils.getHtml(url + i); //解析页面数据,保存数据到数据库中 this.parseHtml(html); } System.out.println("执行完成"); } //解析页面,并把数据保存到数据库中 private void parseHtml(String html) throws Exception { //使用jsoup解析页面 Document document = Jsoup.parse(html); //获取商品数据 Elements spus = document.select("div#J_goodsList > ul > li"); //遍历商品spu数据 for (Element spuEle : spus) { //获取商品spu String attr = spuEle.attr("data-spu"); long spu = Long.parseLong(attr.equals("")?"0":attr); // Long spu = Long.parseLong(spuEle.attr("data-spu")); //获取商品sku数据 Elements skus = spuEle.select("li.ps-item img"); for (Element skuEle : skus) { //获取商品sku Long sku = Long.parseLong(skuEle.attr("data-sku")); //判断商品是否被抓取过,可以根据sku判断 Item param = new Item(); param.setSku(sku); List<Item> list = this.itemService.findAll(param); //判断是否查询到结果 if (list.size() > 0) { //如果有结果,表示商品已下载,进行下一次遍历 continue; } //保存商品数据,声明商品对象 Item item = new Item(); //商品spu item.setSpu(spu); //商品sku item.setSku(sku); //商品url地址 item.setUrl("https://item.jd.com/" + sku + ".html"); //创建时间 item.setCreated(new Date()); //修改时间 item.setUpdated(item.getCreated()); //获取商品标题 String itemHtml = this.httpUtils.getHtml(item.getUrl()); String title = Jsoup.parse(itemHtml).select("div.sku-name").text(); item.setTitle(title); //获取商品价格 String priceUrl = "https://p.3.cn/prices/mgets?skuIds=J_"+sku; String priceJson = this.httpUtils.getHtml(priceUrl); //解析json数据获取商品价格 double price = MAPPER.readTree(priceJson).get(0).get("p").asDouble(); item.setPrice(price); //获取图片地址 String pic = "https:" + skuEle.attr("data-lazy-img").replace("/n9/","/n1/"); System.out.println(pic); //下载图片 String picName = this.httpUtils.getImage(pic); item.setPic(picName); //保存商品数据 this.itemService.save(item); } } } }
分享一下我学习中遇到的问题:
1.爬取数据为null,需要登录京东
看到这段代码应该就明白了吧,就是京东发现并非人为操作,需要登陆账号了。解决办法也很简单,只需要自己模拟浏览器登陆即可
在HttpUttils加上这段,两个方法中的HTTPGet对象都需要设置一下。
//设置请求头模拟浏览器 httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0");
2.java.lang.NumberFormatException: For input string: "",获取的spu为空串,加上一个前置空串判断即可
解决如下:
//获取商品spu String attr = spuEle.attr("data-spu"); //判断是否为空串 long spu = Long.parseLong(attr.equals("")?"0":attr);
以上两个bug是我学习遇到的,现已解决,爬取数据如下: