欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java爬蟲實(shí)現(xiàn)爬取京東上的手機(jī)搜索頁面 HttpCliient+Jsoup

 更新時(shí)間:2017年11月30日 09:42:41   作者:雜兵2號(hào)  
下面小編就為大家分享一篇Java爬蟲實(shí)現(xiàn)爬取京東上的手機(jī)搜索頁面 HttpCliient+Jsoup,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

1、需求及配置

需求:爬取京東手機(jī)搜索頁面的信息,記錄各手機(jī)的名稱,價(jià)格,評(píng)論數(shù)等,形成一個(gè)可用于實(shí)際分析的數(shù)據(jù)表格。

使用Maven項(xiàng)目,log4j記錄日志,日志僅導(dǎo)出到控制臺(tái)。

Maven依賴如下(pom.xml)

<dependencies>
 <dependency>
 <groupId>org.apache.httpcomponents</groupId>
 <artifactId>httpclient</artifactId>
 <version>4.5.3</version>
 </dependency>

 <dependency>
 <!-- jsoup HTML parser library @ https://jsoup.org/ -->
 <groupId>org.jsoup</groupId>
 <artifactId>jsoup</artifactId>
 <version>1.11.2</version>
 </dependency>

 <!-- https://mvnrepository.com/artifact/log4j/log4j -->
 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.17</version>
 </dependency>
 </dependencies>

log4j配置(log4j.properties),將INFO及以上等級(jí)信息輸出到控制臺(tái),不單獨(dú)設(shè)置輸出文檔。

log4j.rootLogger=INFO, Console 
 
#Console 
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

2、需求分析與代碼

2.1需求分析

第一步,建立客戶端與服務(wù)端的連接,并通過URL獲得網(wǎng)頁上的HTML內(nèi)容。

第二步,解析HTML內(nèi)容,獲取需要的元素。

第三步,將HTML內(nèi)容輸出到本地的文本文檔中,可直接通過其他數(shù)據(jù)分析軟件進(jìn)行分析。

根據(jù)以上分析,建立4個(gè)類,GetHTML(用于獲取網(wǎng)站HTML), ParseHTML(用于解析HTML), WriteTo(用于輸出文檔), Maincontrol(主控).下面分別對(duì)四個(gè)類進(jìn)行說明。為使代碼盡量簡潔,所有的異常均從方法上直接拋出,不catch。

2.2代碼

2.2.1GetHTML類

該類包含兩個(gè)方法:getH(String url), urlControl(String baseurl, int page),分別用于獲取網(wǎng)頁HTML及控制URL。由于此次爬取的網(wǎng)頁內(nèi)容只是京東上某一類商品的搜索結(jié)果,所以不需要對(duì)頁面上所有的URL進(jìn)行遍歷,只需要觀察翻頁時(shí)URL的變化,推出規(guī)律即可。只向外暴露urlControl方法,類中設(shè)置一個(gè)private的log屬性:private static Logger log = Logger.getLogger(getHTML.class); 用于記錄日志。

getH(String url),對(duì)單個(gè)URL的HTML內(nèi)容進(jìn)行獲取。

urlControl(String baseurl, int page),設(shè)置循環(huán),訪問多個(gè)頁面的數(shù)據(jù)。通過審查元素可以看到京東上搜索頁page的變化實(shí)際是奇數(shù)順序的變化。

再看一下點(diǎn)擊后網(wǎng)址的變化,可以發(fā)現(xiàn)實(shí)際變化的是page屬性的值。通過拼接的方式就可以很的容易的獲得下一個(gè)網(wǎng)頁的地址。

https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=3&s=47&click=0
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=5&s=111&click=0
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=7&s=162&click=0

整體代碼:

import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

public class getHTML {
 //建立日志
 private static Logger log = Logger.getLogger(getHTML.class);
 private static String getH(String url) throws ClientProtocolException, IOException {
 //控制臺(tái)輸出日志,這樣每條訪問的URL都可以在控制臺(tái)上看到訪問情況
 log.info("正在解析" + url);
 
 /* 
  * 以下內(nèi)容為HttpClient建立連接的一般用法
  * 使用HttpClient建立客戶端
  * 使用get方法訪問指定URL
  * 獲得應(yīng)答
  * */
 
 CloseableHttpClient client = HttpClients.createDefault();
 HttpGet get = new HttpGet(url);
 CloseableHttpResponse response = client.execute(get);
 
 /*
  * 以下內(nèi)容為將HTML內(nèi)容轉(zhuǎn)化為String
  * 獲得應(yīng)答體
  * 將應(yīng)答體轉(zhuǎn)為String格式,此處使用了EntityUtils中的toString方法,編碼格式設(shè)置為"utf-8"
  * 完成后關(guān)閉客戶端與應(yīng)答
  * */
 HttpEntity entity = response.getEntity();
 String content;
 if (entity != null) {
  content = EntityUtils.toString(entity, "utf-8");
  client.close();
  response.close();
  return content;
 } else
  return null;
 }
 public static void urlControl(String baseurl, int page) throws ClientProtocolException, IOException {
 //設(shè)置當(dāng)前頁count
 int count = 1;
 //如果當(dāng)前頁小于想要爬取的頁數(shù)則執(zhí)行
 while (count < page) {
  //實(shí)際訪問的URL為不變的URL值拼接上URL變化的值
  String u = baseurl + (2 * count - 1) + "&click=0";
  //此處調(diào)用ParseHTML類中的方法對(duì)URL中的HTML頁面進(jìn)行處理,后面詳細(xì)介紹該類
  String content = ParseHTML.parse(getH(u)).toString();
  //此處調(diào)用WriteTo類中的方法對(duì)解析出來的內(nèi)容寫入到本地,后面詳細(xì)介紹該類
  WriteTo.writeto(content);
  count++;
 }
 }
}

2.2.2ParseHTML類

該步驟需要通過審查元素對(duì)需要爬取內(nèi)容的標(biāo)簽進(jìn)行確定,再通過Jsoup中的CSS選擇器進(jìn)行獲取。

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ParseHTML {
 
 public static StringBuilder parse(String content)
 {
 //使用Jsoup中的parse方法對(duì)已經(jīng)轉(zhuǎn)換為String的HTML內(nèi)容進(jìn)行分析,返回值為Document類
 Document doc = Jsoup.parse(content);
 //使用選擇器select對(duì)需要找的元素進(jìn)行抓取,例如第一個(gè)select中選擇的是ul標(biāo)簽中class屬性等于gl-warp clearfix的內(nèi)容
 Elements ele = doc.select("ul[class = gl-warp clearfix]").select("li[class=gl-item]");
 //設(shè)置一個(gè)容器,用于裝各個(gè)屬性
 StringBuilder sb = new StringBuilder();
 //通過上一個(gè)選擇器可以獲得整個(gè)頁面中所有符合要求的元素,也即各款手機(jī),下面則需要對(duì)每款手機(jī)進(jìn)行遍歷,獲取其屬性
 for (Element e : ele) {
  //此處對(duì)各個(gè)屬性的獲取參考了網(wǎng)上一篇爬取京東上內(nèi)容的文章,應(yīng)該有其他不同的寫法
  String id = e.attr("data-pid");
  String mingzi = e.select("div[class = p-name p-name-type-2]").select("a").select("em").text();
  String jiage = e.select("div[class=p-price]").select("strong").select("i").text();
  String pinglun = e.select("div[class=p-commit]").select("strong").select("a").text();
  //向容器中添加屬性
  sb.append(id+"\t");
  sb.append(mingzi+"\t");
  sb.append(jiage+"\t");
  sb.append(pinglun+"\t");
  sb.append("\r\n");
 }
 return sb;
 }
}

2.2.3WriteTo類

此類中的方法將解析完成的內(nèi)容寫入到一個(gè)本地文件中。只是簡單的IO。

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class WriteTo {
 // 設(shè)置文件存放的位置
 private static File f = new File("C:\\jingdong.txt");
 public static void writeto(String content) throws IOException {
 //使用續(xù)寫的方式,以免覆蓋前面寫入的內(nèi)容
 BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
 bw.append(content);
 bw.flush();
 bw.close();
 }
}

2.2.4MainControl類

主控程序,寫入基地址與想要獲取的頁面數(shù)。調(diào)用getHTML類中的urlControl方法對(duì)頁面進(jìn)行抓取。

import java.io.IOException;
import org.apache.http.client.ClientProtocolException;

public class MainControl {
 public static void main(String[] args) throws ClientProtocolException, IOException {
 // TODO Auto-generated method stub
 String baseurl = "https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc="
  + "utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=";
 int page = 5;//設(shè)置爬取頁數(shù)
 getHTML.urlControl(baseurl, page);
 }
}

3、爬取結(jié)果

爬取20頁。

3.1控制臺(tái)輸出

3.2文檔輸出

可以直接使用Excel打開,分隔符為制表符。列分別為商品編號(hào),名稱,價(jià)格與評(píng)論數(shù)。

4、小結(jié)

此次爬取使用了HttpClient與Jsoup,可以看到對(duì)于簡單的需求,這些工具還是非常高效的。實(shí)際上也可以把所有類寫到一個(gè)類當(dāng)中,寫多個(gè)類的方式思路比較清晰。

以上這篇Java爬蟲實(shí)現(xiàn)爬取京東上的手機(jī)搜索頁面 HttpCliient+Jsoup就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot集成slf4j+log4j2的示例代碼

    SpringBoot集成slf4j+log4j2的示例代碼

    這篇文章主要介紹了SpringBoot集成slf4j+log4j2的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 一文徹底理清SpringBoot CURD處理邏輯、順序

    一文徹底理清SpringBoot CURD處理邏輯、順序

    這篇文章主要給大家介紹了關(guān)于如何一文徹底理清SpringBoot CURD處理邏輯、順序的相關(guān)資料,CURD是一個(gè)數(shù)據(jù)庫技術(shù)中的縮寫詞,一般的項(xiàng)目開發(fā)的各種參數(shù)的基本功能都是CURD,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • 跳表的由來及Java實(shí)現(xiàn)詳解

    跳表的由來及Java實(shí)現(xiàn)詳解

    跳表(Skip List)是一種基于鏈表的數(shù)據(jù)結(jié)構(gòu),它可以支持快速的查找、插入、刪除操作,本文主要來和大家講講跳表的由來與實(shí)現(xiàn),感興趣的小伙伴可以了解一下
    2023-06-06
  • SpringBoot圖文并茂講解Lombok庫的安裝與使用

    SpringBoot圖文并茂講解Lombok庫的安裝與使用

    Lombok想要解決了的是在我們實(shí)體Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不會(huì)用到,但是某些時(shí)候仍然需要復(fù)寫,以期方便使用的方法;在使用Lombok之后,將由其來自動(dòng)幫你實(shí)現(xiàn)代碼生成
    2022-06-06
  • vue數(shù)據(jù)響應(yīng)式原理重寫函數(shù)實(shí)現(xiàn)數(shù)組響應(yīng)式監(jiān)聽

    vue數(shù)據(jù)響應(yīng)式原理重寫函數(shù)實(shí)現(xiàn)數(shù)組響應(yīng)式監(jiān)聽

    Vue的通過數(shù)據(jù)劫持的方式實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,即使用Object.defineProperty()來實(shí)現(xiàn)對(duì)屬性的劫持,但是Object.defineProperty()中的setter是無法直接實(shí)現(xiàn)數(shù)組中值的改變的劫持行為的,需要的朋友可以參考下
    2023-05-05
  • Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法

    Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法

    這篇文章主要介紹了Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能掌握理解這種方法,需要的朋友可以參考下
    2017-09-09
  • jsoup?框架的使用小結(jié)

    jsoup?框架的使用小結(jié)

    jsoup 是一款基于Java的HTML解析器,它提供了一套非常省力的API,不但能直接解析某個(gè)URL地址、HTML文本內(nèi)容,而且還能通過類似于 DOM、CSS 或者jQuery的方法來操作數(shù)據(jù),所以jsoup也可以被當(dāng)做爬蟲工具使用,這篇文章主要介紹了jsoup使用,需要的朋友可以參考下
    2023-04-04
  • JAVA設(shè)計(jì)模式之解釋器模式詳解

    JAVA設(shè)計(jì)模式之解釋器模式詳解

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之解釋器模式詳解,解釋器模式是類的行為模式,給定一個(gè)語言之后,解釋器模式可以定義出其文法的一種表示,并同時(shí)提供一個(gè)解釋器,需要的朋友可以參考下
    2015-04-04
  • 老生常談foreach(增強(qiáng)for循環(huán))和for的區(qū)別

    老生常談foreach(增強(qiáng)for循環(huán))和for的區(qū)別

    下面小編就為大家?guī)硪黄仙U刦oreach(增強(qiáng)for循環(huán))和for的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • java 方法泛型入?yún)和String的重載關(guān)系詳解

    java 方法泛型入?yún)和String的重載關(guān)系詳解

    這篇文章主要介紹了java 方法泛型入?yún)和String的重載關(guān)系詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論