Java实现简易爬虫--抓取酷安网用户头像

时间:2022-01-16 20:40:48

转载自:http://blog.csdn.net/e_one/article/details/60876076

爬虫思路

以酷安网用户粉丝较多的用户的个人中心为进口,获取该用户的全部粉丝的个人中心链接,用户头像链接和用户名,并分别放入队列。开启两个线程获取信息,一个线程获取队列中的用户的信息并放入队列,另一个线程负责从头像链接队列中取出链接并下载用户头像。

爬虫分析

用浏览器打开一个用户的粉丝列表(http://coolapk.com/u/[用户id]/contacts)

 Java实现简易爬虫--抓取酷安网用户头像

并查看源码

 Java实现简易爬虫--抓取酷安网用户头像

我们可以看到粉丝列表以HTML的ul标签显示,并且其id为dataList,ul标签中的各个li标签即为每一个用户的信息啦~再进一步分析,li标签中的img标签为用户头像。h4标签的内容即为用户名,h4标签中的a标签的href属性为用户的个人中心链接。

通过观察我们还知道:用户的粉丝列表链接=个人中心链接+ "/contacts"

这样我们就可以开始爬取头像了

用到的库

Jsoup https://jsoup.org/download

HttpClient http://hc.apache.org/downloads.cgi

代码

Main.Java

 

[java] view plain copy print?Java实现简易爬虫--抓取酷安网用户头像Java实现简易爬虫--抓取酷安网用户头像
  1. package main;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.InputStream;  
  6. import org.apache.http.client.methods.CloseableHttpResponse;  
  7. import org.apache.http.client.methods.HttpGet;  
  8. import org.apache.http.impl.client.CloseableHttpClient;  
  9. import org.apache.http.impl.client.HttpClients;  
  10. import org.jsoup.Connection;  
  11. import org.jsoup.Jsoup;  
  12. import org.jsoup.nodes.Document;  
  13. import org.jsoup.nodes.Element;  
  14.   
  15. public class Main {  
  16.   
  17.     //浏览器UA  
  18.     private static String UA="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";  
  19.     //主机地址  
  20.     private static final String HOST="http://coolapk.com";  
  21.     //头像本地保存地址  
  22.     private static final String SAVE_PAYH="D:/coolapk/";  
  23.     //指示UserThread是否在运行  
  24.     private static boolean isRun=false;  
  25.     //用户中心界面队列  
  26.     private  static MyQueue<String> userUrlQueue=new MyQueue<>();  
  27.     //用户头像链接队列  
  28.     private static MyQueue<String> userHeadUrlQueue=new MyQueue<>();  
  29.     //用户名队列  
  30.     private static MyQueue<String> userNameQueue=new MyQueue<>();  
  31.     public static void main(String[] args) throws Exception {  
  32.         // TODO Auto-generated method stub  
  33.         userUrlQueue.put("http://coolapk.com/u/12202/contacts");  
  34.         java.io.File f=new java.io.File(SAVE_PAYH);  
  35.         //如果文件夹不存在,则创建  
  36.         if(!f.exists())  
  37.         {  
  38.             f.mkdirs();  
  39.         }  
  40.         start();  
  41.     }  
  42.   
  43.     /** 
  44.      * 开始 
  45.      */  
  46.     private static void start()  
  47.     {  
  48.         new UserThread().start();  
  49.         new HeadThread().start();  
  50.     }  
  51.       
  52.     /** 
  53.      * 获取相关的链接 
  54.      * @throws Exception 
  55.      */  
  56.     private static void getUserUrl() throws Exception {  
  57.         String url=userUrlQueue.poll();  
  58.         if(url!=null){  
  59.             isRun=true;  
  60.             Connection connection=Jsoup.connect(url);  
  61.             connection.userAgent(UA);  
  62.             Document document=connection.get();  
  63.               
  64.             Element ulElement=document.getElementById("dataList");  
  65.             org.jsoup.select.Elements liElements=ulElement.getElementsByTag("li");  
  66.             if (liElements==null) {  
  67.                 return;  
  68.             }  
  69.             for(Element li:liElements){  
  70.                 if(li==null)  
  71.                     continue;  
  72.                 //获取用户头像链接  
  73.                 String userHeadUrl=li.getElementsByTag("img").first().attr("src");  
  74.                 //获取一个用户的粉丝列表的url  
  75.                 String userUrl=HOST+li.getElementsByTag("h4").first()  
  76.                         .getElementsByTag("a").first()  
  77.                         .attr("href")+"/contacts";  
  78.                 //获取一个用户的用户名  
  79.                 String userName=li.getElementsByTag("h4").first()  
  80.                         .getElementsByTag("a").first().text();  
  81.                 //本地已保存就不再加入队列  
  82.                 if(!new File(SAVE_PAYH+userName+".jpg").exists()){  
  83.                     userUrlQueue.put(userUrl);  
  84.                     userHeadUrlQueue.put(userHeadUrl);  
  85.                     userNameQueue.put(userName);  
  86.                 }  
  87.             }  
  88.             //队列空了,isRun=false  
  89.             isRun=false;  
  90.         }  
  91.   
  92.     }  
  93.     /** 
  94.      * 获取图片并保存到本地 
  95.      * @param imgUrl 
  96.      * @param localPath 
  97.      * @throws Exception 
  98.      */  
  99.     private static void getImage(String imgUrl,String localPath) throws Exception {  
  100.         //System.out.println(imgUrl);  
  101.         CloseableHttpClient httpclient = HttpClients.createDefault();  
  102.         HttpGet httpget= new HttpGet(imgUrl);  
  103.         CloseableHttpResponse resp=httpclient.execute(httpget);  
  104.         InputStream inputStream=resp.getEntity().getContent();  
  105.         FileOutputStream fileOutputStream=new FileOutputStream(localPath);  
  106.         byte[] buf=new byte[1024];  
  107.         int len=0;  
  108.         while ((len=inputStream.read(buf))!=-1) {  
  109.             fileOutputStream.write(buf, 0, len);  
  110.             fileOutputStream.flush();  
  111.         }  
  112.         inputStream.close();  
  113.         fileOutputStream.close();  
  114.           
  115.     }  
  116.     /** 
  117.      * 获取链接线程 
  118.      * @author zyw 
  119.      * 
  120.      */  
  121.     public static class UserThread  extends Thread{  
  122.       
  123.         @Override  
  124.         public void run() {  
  125.             // TODO Auto-generated method stub  
  126.             //如果队列userUrlQueue不为空  
  127.             while (!userUrlQueue.isEmpty()) {  
  128.                 try {  
  129.                     getUserUrl();  
  130.                 } catch (Exception e) {  
  131.                     // TODO Auto-generated catch block  
  132.                     e.printStackTrace();  
  133.                 }  
  134.                   
  135.             }  
  136.         }  
  137.     }  
  138.     /** 
  139.      * 获取头像线程 
  140.      * @author zyw 
  141.      * 
  142.      */  
  143.     public static class HeadThread  extends Thread{  
  144.   
  145.         @Override  
  146.         public void run() {  
  147.             // TODO Auto-generated method stub  
  148.             //如果队列userHeadUrlQueue不为空,并且UserThread在工作  
  149.             while (!userHeadUrlQueue.isEmpty()||isRun) {  
  150.                 try {  
  151.                     String imgUrl=userHeadUrlQueue.poll();  
  152.                     String userName=userNameQueue.poll();  
  153.                     getImage(imgUrl, SAVE_PAYH+userName+".jpg");  
  154.                 } catch (Exception e) {  
  155.                     // TODO Auto-generated catch block  
  156.                     e.printStackTrace();  
  157.                 }  
  158.                   
  159.             }  
  160.         }  
  161.     }  
  162.       
  163. }  

MyQueue.java

[java] view plain copy print?Java实现简易爬虫--抓取酷安网用户头像Java实现简易爬虫--抓取酷安网用户头像
  1. package main;  
  2. import java.util.LinkedList;  
  3. import java.util.Queue;  
  4.   
  5. /** 
  6.  * 线程安全队列 
  7.  * @author zyw 
  8.  * 
  9.  * @param <T> 
  10.  */  
  11. public class MyQueue<T> {  
  12.      private LinkedList<T> userUrlQueue=new LinkedList<T>();  
  13.      private Object lock=new Object();  
  14.        
  15.      /** 
  16.       * 获取队列是否为空 
  17.       * @return 
  18.       */  
  19.      public boolean isEmpty() {  
  20.         return userUrlQueue.isEmpty();  
  21.     }  
  22.        
  23.      /** 
  24.       * 将一个元素插入队列尾 
  25.       * @param t 
  26.       */  
  27.      public void put(T t) {  
  28.          synchronized (lock) {  
  29.             userUrlQueue.addLast(t);  
  30.         }  
  31.     }  
  32.        
  33.      /** 
  34.       * 队列头取出一个元素 
  35.       * @return 
  36.       */  
  37.      public T  poll() {  
  38.          T t=null;  
  39.          synchronized (lock) {  
  40.              t=(T) userUrlQueue.removeFirst();  
  41.          }  
  42.         return t;  
  43.     }  
  44. }  

效果图

Java实现简易爬虫--抓取酷安网用户头像