一直有一个需求,希望看到自己网站在百度的实时的排名
用过一些工具,要么反应迟钝,要么结果不准确或不实时
于是打算用jsoup写一个小爬虫来实时百度看网站排名

直接上代码


依赖只有jsoup
jar包下载地址:https://mvnrepository.com/artifact/org.jsoup/jsoup
或者引入
maven依赖

  1. <dependency>
  2. <groupId>org.jsoup</groupId>
  3. <artifactId>jsoup</artifactId>
  4. <version>1.11.3</version>
  5. </dependency>


代码

  1. package com.zzzmh.spider;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import org.jsoup.Jsoup;
  7. import org.jsoup.nodes.Document;
  8. import org.jsoup.nodes.Element;
  9. import org.jsoup.select.Elements;
  10. public class test {
  11.     /** 百度搜索基本url 后面可以接的参数有 pn rn ie 等 */
  12.     public final static String baseUrl = "https://www.baidu.com/s?ie=utf-8";
  13.     /** 连接超时时间 */
  14.     public static int timeout = 30 * 1000;
  15.     /** 连接重试次数 */
  16.     public static int times = 10;
  17.     /** UA */
  18.     public static String UserAgent[] = {
  19.             "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
  20.             "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
  21.             "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko",
  22.             "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",
  23.             "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32",
  24.             "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
  25.             "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 UBrowser/5.6.12150.8 Safari/537.36",
  26.             "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586",
  27.             "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32" };
  28.     /** 获取随机UA */
  29.     public static String getRandomUA() {
  30.         return UserAgent[(int) (Math.random() * (UserAgent.length))];
  31.     }
  32.     /** 在这里进行连接 如果失败会继续重试 */
  33.     public static Document getDocument(String url) {
  34.         Document doc = null;
  35.         for (int i = 0; i < times; i++) {
  36.             try {
  37.                 doc = Jsoup.connect(url).header("User-Agent", getRandomUA()).timeout(timeout).get();
  38.                 if (doc != null)
  39.                     break;
  40.             } catch (Exception e) {
  41.                 e.printStackTrace();
  42.             }
  43.         }
  44.         return doc;
  45.     }
  46.     /**
  47.      * 爬取百度指定关键字和页码的数据,只存id(排名号),title,url(百度会把url缩写) 亲测虽然
  48.      * 加了&rn=50可以明显增加效率,但结果和用户实际看到的有所出入,并不准确,故用默认rn,与用户实际看到保持一致
  49.      *
  50.      * @param keyword 关键字
  51.      * @param page 页码
  52.      */
  53.     public static List<Map<String, String>> spider(String keyword, int page) {
  54.         List<Map<String, String>> result = new ArrayList<>();
  55.         try {
  56.             Document document = getDocument(baseUrl + "&wd=" + keyword + "&pn=" + (page * 10));
  57.             Elements els = document.getElementsByClass("result");
  58.             for (Element el : els) {
  59.                 Map<String, String> map = new HashMap<>();
  60.                 try {
  61.                     map.put("id", el.attr("id"));
  62.                     map.put("title", el.getElementsByTag("a").get(0).text());
  63.                     map.put("url", el.getElementsByClass("f13").get(0).getElementsByTag("a").text());
  64.                     result.add(map);
  65.                 } catch (Exception e) {
  66.                 }
  67.             }
  68.         } catch (Exception e) {
  69.             e.printStackTrace();
  70.         }
  71.         return result;
  72.     }
  73.     /**
  74.      * 分析在指定关键字在百度的排名
  75.      *
  76.      * @param keyword 关键字
  77.      * @param url 要找的目标包含的url
  78.      * @param maxPage 最多找几页,防止死循环
  79.      * @return 找得到返回map 超过最大页码还找不到返回null
  80.      */
  81.     public static Map<String, String> BaiduRanking(String keyword, String url, int maxPage) {
  82.         System.out.println("开始查找百度中关键字为 \"" + keyword + "\" 且url包含 \""
  83.                 + url + "\" 的相关数据排名 最多查询 " + maxPage + "页");
  84.         for (int i = 0; i < maxPage; i++) {
  85.             // 输出当前页码和个数,不需要输出可以去掉
  86.             System.out.println("正在查询第" + i + "页中的第" + (i * 10 + 1) + " ~ " + ((i + 1) * 10) + "个");
  87.             List<Map<String, String>> list = spider(keyword, i);
  88.             for (Map<String, String> map : list) {
  89.                 if (map.get("url").contains(url)) {
  90.                     return map;
  91.                 }
  92.             }
  93.         }
  94.         return null;
  95.     }
  96.     public static void main(String[] args) {
  97.         /*
  98.          * 例如 找关键字 极简壁纸 主要的网址特征 bz.zzzmh.cn 最多找20页 (相当于找1~200个中有无匹配)
  99.          * 若有匹配返回 id title url
  100.          * 若无匹配返回 Null
  101.          */
  102.         System.out.println(BaiduRanking("极简插件", "zzzmh.cn", 20));
  103.     }
  104. }


效果

1、网站标题: zzzmh’s blog 网站url: https://zzzmh.cn
参数:

  1. 关键字: "zzzmh" 目标包含url: "zzzmh.cn" 最多查询页数: "20"

运行结果:

  1. 开始查找百度中关键字为 "zzzmh" url包含 "zzzmh.cn" 的相关数据排名 最多查询 20
  2. 正在查询第0页中的第1 ~ 10
  3. 正在查询第1页中的第11 ~ 20
  4. {id=13, title=zzzmh's Blog - Design By zmh, url=https://zzzmh.cn/ 百度快照}



2、网站标题: 极简壁纸… 网站url: https://bz.zzzmh.cn
参数:

  1. 关键字: "极简壁纸" 目标包含url: "zzzmh.cn" 最多查询页数: "20"

运行结果:

  1. 开始查找百度中关键字为 "极简壁纸" url包含 "zzzmh.cn" 的相关数据排名 最多查询 20
  2. 正在查询第0页中的第1 ~ 10
  3. 正在查询第1页中的第11 ~ 20
  4. 正在查询第2页中的第21 ~ 30
  5. 正在查询第3页中的第31 ~ 40
  6. 正在查询第4页中的第41 ~ 50
  7. 正在查询第5页中的第51 ~ 60
  8. 正在查询第6页中的第61 ~ 70
  9. 正在查询第7页中的第71 ~ 80
  10. 正在查询第8页中的第81 ~ 90
  11. 正在查询第9页中的第91 ~ 100
  12. {id=93, title=极简壁纸_极致严选高清电脑桌面壁纸美图4k_最潮桌面壁纸网站, url=https://bz.zzzmh.cn/ 百度快照}



3、网站标题: 极简插件… 网站url: https://chrome.zzzmh.cn
参数:

  1. 关键字: "极简插件" 目标包含url: "zzzmh.cn" 最多查询页数: "20"

运行结果:

  1. 开始查找百度中关键字为 "极简插件" url包含 "zzzmh.cn" 的相关数据排名 最多查询 20
  2. 正在查询第0页中的第1 ~ 10
  3. 正在查询第1页中的第11 ~ 20
  4. 正在查询第2页中的第21 ~ 30
  5. 正在查询第3页中的第31 ~ 40
  6. 正在查询第4页中的第41 ~ 50
  7. 正在查询第5页中的第51 ~ 60
  8. 正在查询第6页中的第61 ~ 70
  9. 正在查询第7页中的第71 ~ 80
  10. 正在查询第8页中的第81 ~ 90
  11. 正在查询第9页中的第91 ~ 100
  12. 正在查询第10页中的第101 ~ 110
  13. 正在查询第11页中的第111 ~ 120
  14. 正在查询第12页中的第121 ~ 130
  15. 正在查询第13页中的第131 ~ 140
  16. 正在查询第14页中的第141 ~ 150
  17. 正在查询第15页中的第151 ~ 160
  18. 正在查询第16页中的第161 ~ 170
  19. 正在查询第17页中的第171 ~ 180
  20. 正在查询第18页中的第181 ~ 190
  21. 正在查询第19页中的第191 ~ 200
  22. null


补充:
1. 有结果返回map包含id、title、url。没有结果返回 Null
2. 百度搜索的url可以指定rn页码,最多一页50个,使用后有效减少了连接次数。但亲测下来设置过rn以后的结果与实际用户在百度搜索的结果排序和个数都有出入。故选择用默认rn来检测,效果最准确。


END