#教您使用java爬蟲gecco抓取JD所有商品信息(一) ##gecco爬蟲 若是對gecco尚未了解能夠參看一下gecco的github首頁。gecco爬蟲十分的簡單易用,JD所有商品信息的抓取9個類就能搞定。 ##JD網站的分析 要抓取JD網站的所有商品信息,咱們要先分析一下網站,京東網站能夠大致分爲三級,首頁上經過分類跳轉到商品列表頁,商品列表頁對每一個商品有詳情頁。那麼咱們經過找到全部分類就能逐個分類抓取商品信息。 ##入口地址 http://www.jd.com/allSort.aspx,這個地址是JD所有商品的分類列表,咱們以該頁面做爲開始頁面,抓取JD的所有商品信息 ###新建開始頁面的HtmlBean類AllSortcss
@Gecco(matchUrl="http://www.jd.com/allSort.aspx", pipelines={"consolePipeline", "allSortPipeline"}) public class AllSort implements HtmlBean { private static final long serialVersionUID = 665662335318691818L; @Request private HttpRequest request; //手機 @HtmlField(cssPath=".category-items > div:nth-child(1) > div:nth-child(2) > div.mc > div.items > dl") private List<Category> mobile; //家用電器 @HtmlField(cssPath=".category-items > div:nth-child(1) > div:nth-child(3) > div.mc > div.items > dl") private List<Category> domestic; public List<Category> getMobile() { return mobile; } public void setMobile(List<Category> mobile) { this.mobile = mobile; } public List<Category> getDomestic() { return domestic; } public void setDomestic(List<Category> domestic) { this.domestic = domestic; } public HttpRequest getRequest() { return request; } public void setRequest(HttpRequest request) { this.request = request; } }
能夠看到,這裏以抓取手機和家用電器兩個大類的商品信息爲例,能夠看到每一個大類都包含若干個子分類,用List<Category>表示。gecco支持Bean的嵌套,能夠很好的表達html頁面結構。Category表示子分類信息內容,HrefBean是共用的連接Bean。html
public class Category implements HtmlBean { private static final long serialVersionUID = 3018760488621382659L; @Text @HtmlField(cssPath="dt a") private String parentName; @HtmlField(cssPath="dd a") private List<HrefBean> categorys; public String getParentName() { return parentName; } public void setParentName(String parentName) { this.parentName = parentName; } public List<HrefBean> getCategorys() { return categorys; } public void setCategorys(List<HrefBean> categorys) { this.categorys = categorys; } }
##獲取頁面元素cssPath的小技巧 上面兩個類難點就在cssPath的獲取上,這裏介紹一些cssPath獲取的小技巧。用Chrome瀏覽器打開須要抓取的網頁,按F12進入發者模式。選擇你要獲取的元素,如圖:java
在瀏覽器右側選中該元素,鼠標右鍵選擇Copy--Copy selector,便可得到該元素的cssPathjquery
body > div:nth-child(5) > div.main-classify > div.list > div.category-items.clearfix > div:nth-child(1) > div:nth-child(2) > div.mc > div.items
若是你對jquery的selector有了解,另外咱們只但願得到dl元素,所以便可簡化爲:git
.category-items > div:nth-child(1) > div:nth-child(2) > div.mc > div.items > dl
##編寫AllSort的業務處理類 完成對AllSort的注入後,咱們須要對AllSort進行業務處理,這裏咱們不作分類信息持久化等處理,只對分類連接進行提取,進一步抓取商品列表信息。看代碼:github
@PipelineName("allSortPipeline") public class AllSortPipeline implements Pipeline<AllSort> { @Override public void process(AllSort allSort) { List<Category> categorys = allSort.getMobile(); for(Category category : categorys) { List<HrefBean> hrefs = category.getCategorys(); for(HrefBean href : hrefs) { String url = href.getUrl()+"&delivery=1&page=1&JL=4_10_0&go=0"; HttpRequest currRequest = allSort.getRequest(); SchedulerContext.into(currRequest.subRequest(url)); } } } }
@PipelinName定義該pipeline的名稱,在AllSort的@Gecco註解裏進行關聯,這樣,gecco在抓取完並注入Bean後就會逐個調用@Gecco定義的pipeline了。爲每一個子連接增長"&delivery=1&page=1&JL=4_10_0&go=0"的目的是隻抓取京東自營而且有貨的商品。SchedulerContext.into()方法是將待抓取的連接放入隊列中等待進一步抓取。瀏覽器