java爬蟲練習|爬取京東上的手機商品數據


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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM