最近在學習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是我學習遇到的,現已解決,爬取數據如下: