爬虫实现:根据IP地址反查域名

域名解析与IP地址域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务;IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程,该过程由DNS服务器完成(来自百度百科)先来了解两个知识点1、一个域名同一时刻只能对应一个IP地址2、一个IP地址可以解析绑定多个域名,没有限制基于以上知识点,假如我们已知一个IP地址,我们怎么才能获取解析到该IP地址的所有域名信息呢?一种方式是国家工信部能开放查询接口以供查询(不知道会不会开放?);另外一种方式就是接下来我要分享的——爬虫实现:根据IP地址反查域名。实现原理实现原理其实很简单,现在已有网站提供了根据IP地址查询域名的功能,但是需要人为登录网站输入IP地址查询,我想要实现程序自动化查询,所以就想到了爬虫的方式,简单来说,就是模拟人的查询行为,将查询结果解析成我想要的域名列表。以site.ip138.com为例,打开F12,输入一个IP查询,观察控制台请求,看到下图中信息请求地址为:http://site.ip138.com/119.75….请求方式为:GET然后,分析Response,可以看到,在页面上看到的绑定域名信息就是下图红框中<span>的内容,所以只要能将Response的内容解析出来,获取到<span>的内容就可以得到想要的域名列表。上述Response是HTML页面,使用jsoup来解析HTML简直完美。jsoup是什么?jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。//解析成Document对象Document document = Jsoup.parse(result);if (document == null) { logger.error(“Jsoup parse get document null!”);}//根据ID属性“list”获取元素Element对象(有没有感觉很像jQuery?)Element listEle = document.getElementById(“list”);//根据class属性和属性值筛选元素Element集合,并通过eachText()遍历元素内容return listEle.getElementsByAttributeValue(“target”, “blank”).eachText();result的内容通过HttpClient模拟HTTP请求HttpGet httpGet = new HttpGet(url);httpGet.setHeader(“Accept”, “text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8”);httpGet.setHeader(“Accept-Encoding”, “gzip, deflate”);httpGet.setHeader(“Accept-Language”, “zh-CN,zh;q=0.9”);httpGet.setHeader(“Cache-Control”, “max-age=0”);httpGet.setHeader(“Connection”, “keep-alive”);httpGet.setHeader(“Cookie”, “Hm_lvt_d39191a0b09bb1eb023933edaa468cd5=1553090128; BAIDU_SSP_lcr=https://www.baidu.com/link?url=FS0ccst469D77DpdXpcGyJhf7OSTLTyk6VcMEHxT_9&wd=&eqid=fa0e26f70002e7dd000000065c924649; pgv_pvi=6200530944; pgv_si=s4712839168; Hm_lpvt_d39191a0b09bb1eb023933edaa468cd5=1553093270”);httpGet.setHeader(“DNT”, “1”);httpGet.setHeader(“Host”, host);httpGet.setHeader(“Upgrade-Insecure-Requests”, “1”);httpGet.setHeader(“User-Agent”, “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36”);String result = HttpUtils.doGet(httpGet);HTTP请求工具类public class HttpUtils { private static Logger logger = LoggerFactory.getLogger(HttpUtils.class); public static String doGet(HttpGet httpGet) { CloseableHttpClient httpClient = null; try { httpClient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(5000).setConnectionRequestTimeout(10000) .setSocketTimeout(5000).build(); httpGet.setConfig(requestConfig); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200 || httpResponse.getStatusLine().getStatusCode() == 302) { HttpEntity entity = httpResponse.getEntity(); return EntityUtils.toString(entity, “utf-8”); } else { logger.error(“Request StatusCode={}”, httpResponse.getStatusLine().getStatusCode()); } } catch (Exception e) { logger.error(“Request Exception={}:”, e); } finally { if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { logger.error(“关闭httpClient失败”, e); } } } return null; }}新增Controller@RestControllerpublic class DomainSpiderController { private static Logger logger = LoggerFactory.getLogger(DomainSpiderController.class); @Autowired private DomainSpiderService domainSpiderService; /** * @param ip 119.75.217.109 * @return */ @RequestMapping("/spider/{ip}") @ResponseBody public List<String> domainSpider(@PathVariable(“ip”) String ip) { long startTime = System.currentTimeMillis(); List<String> domains = domainSpiderService.domainSpiderOfIp138(ip); if(domains == null || domains.size() == 0) { domains = domainSpiderService.domainSpiderOfAizan(ip); } long endTime = System.currentTimeMillis(); logger.info(“完成爬虫任务总耗时:{}s”, (endTime - startTime) / 1000); return domains; }}启动Spring Boot应用,访问浏览器:http://localhost:8080/spider/119.75.217.109获得返回结果如下:怎么样?是不是很简单?优化改进:有时候仅仅通过一个网站查询的域名数据可能不太准确,甚至查询不到数据,我们也没法判断谁才是正确的,所以,可以通过爬取多个网站的结果结合起来使用,例如:dns.aizhan.com提出疑问:这些提供根据IP反查域名的网站,是怎么实现的呢?我咨询过其他人,他们的回答是这些网站收集了很多IP和域名的对应关系,真实情况是这样的吗?示例源码domain-spider代码已上传至码云和Github上,欢迎下载学习GiteeGithub ...

April 13, 2019 · 1 min · jiezi

Jsoup爬虫获取自己网站在百度搜索中的实时排名

一直有一个需求,希望看到自己网站在百度的实时的排名用过一些工具,要么反应迟钝,要么结果不准确或不实时于是打算用jsoup写一个小爬虫来实时百度看网站排名直接上代码依赖只有jsoupjar包下载地址:https://mvnrepository.com/artifact/org.jsoup/jsoup或者引入maven依赖<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version></dependency>代码package com.zzzmh.spider;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;public class test { /** 百度搜索基本url 后面可以接的参数有 pn rn ie 等 / public final static String baseUrl = “https://www.baidu.com/s?ie=utf-8"; /* 连接超时时间 / public static int timeout = 30 * 1000; /* 连接重试次数 / public static int times = 10; /* UA / public static String UserAgent[] = { “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”, “Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50”, “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”, “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)”, “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”, “Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko”, “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”, “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”, “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” }; /* 获取随机UA / public static String getRandomUA() { return UserAgent[(int) (Math.random() * (UserAgent.length))]; } /* 在这里进行连接 如果失败会继续重试 / public static Document getDocument(String url) { Document doc = null; for (int i = 0; i < times; i++) { try { doc = Jsoup.connect(url).header(“User-Agent”, getRandomUA()).timeout(timeout).get(); if (doc != null) break; } catch (Exception e) { e.printStackTrace(); } } return doc; } /* * 爬取百度指定关键字和页码的数据,只存id(排名号),title,url(百度会把url缩写) 亲测虽然 * 加了&rn=50可以明显增加效率,但结果和用户实际看到的有所出入,并不准确,故用默认rn,与用户实际看到保持一致 * * @param keyword 关键字 * @param page 页码 / public static List<Map<String, String>> spider(String keyword, int page) { List<Map<String, String>> result = new ArrayList<>(); try { Document document = getDocument(baseUrl + “&wd=” + keyword + “&pn=” + (page * 10)); Elements els = document.getElementsByClass(“result”); for (Element el : els) { Map<String, String> map = new HashMap<>(); try { map.put(“id”, el.attr(“id”)); map.put(“title”, el.getElementsByTag(“a”).get(0).text()); map.put(“url”, el.getElementsByClass(“f13”).get(0).getElementsByTag(“a”).text()); result.add(map); } catch (Exception e) { } } } catch (Exception e) { e.printStackTrace(); } return result; } /* * 分析在指定关键字在百度的排名 * * @param keyword 关键字 * @param url 要找的目标包含的url * @param maxPage 最多找几页,防止死循环 * @return 找得到返回map 超过最大页码还找不到返回null / public static Map<String, String> BaiduRanking(String keyword, String url, int maxPage) { System.out.println(“开始查找百度中关键字为 "” + keyword + “" 且url包含 "” + url + “" 的相关数据排名 最多查询 " + maxPage + “页”); for (int i = 0; i < maxPage; i++) { // 输出当前页码和个数,不需要输出可以去掉 System.out.println(“正在查询第” + i + “页中的第” + (i * 10 + 1) + " ~ " + ((i + 1) * 10) + “个”); List<Map<String, String>> list = spider(keyword, i); for (Map<String, String> map : list) { if (map.get(“url”).contains(url)) { return map; } } } return null; } public static void main(String[] args) { / * 例如 找关键字 极简壁纸 主要的网址特征 bz.zzzmh.cn 最多找20页 (相当于找1~200个中有无匹配) * 若有匹配返回 id title url * 若无匹配返回 Null */ System.out.println(BaiduRanking(“极简壁纸”, “zzzmh.cn”, 20)); }}效果1、网站标题: zzzmh’s blog 网站url: https://zzzmh.cn参数:关键字: “zzzmh” 目标包含url: “zzzmh.cn” 最多查询页数: “20"运行结果:开始查找百度中关键字为 “zzzmh” 且url包含 “zzzmh.cn” 的相关数据排名 最多查询 20页正在查询第0页中的第1 ~ 10个正在查询第1页中的第11 ~ 20个{id=13, title=zzzmh’s Blog - Design By zmh, url=https://zzzmh.cn/ 百度快照}2、网站标题: 极简壁纸… 网站url: https://bz.zzzmh.cn参数:关键字: “极简壁纸” 目标包含url: “zzzmh.cn” 最多查询页数: “20"运行结果:开始查找百度中关键字为 “极简壁纸” 且url包含 “zzzmh.cn” 的相关数据排名 最多查询 20页正在查询第0页中的第1 ~ 10个正在查询第1页中的第11 ~ 20个正在查询第2页中的第21 ~ 30个正在查询第3页中的第31 ~ 40个正在查询第4页中的第41 ~ 50个正在查询第5页中的第51 ~ 60个正在查询第6页中的第61 ~ 70个正在查询第7页中的第71 ~ 80个正在查询第8页中的第81 ~ 90个正在查询第9页中的第91 ~ 100个{id=93, title=极简壁纸_极致严选高清电脑桌面壁纸美图4k_最潮桌面壁纸网站, url=https://bz.zzzmh.cn/ 百度快照}3、网站标题: 极简插件… 网站url: https://chrome.zzzmh.cn参数:关键字: “极简插件” 目标包含url: “zzzmh.cn” 最多查询页数: “20"运行结果:开始查找百度中关键字为 “极简插件” 且url包含 “zzzmh.cn” 的相关数据排名 最多查询 20页正在查询第0页中的第1 ~ 10个正在查询第1页中的第11 ~ 20个正在查询第2页中的第21 ~ 30个正在查询第3页中的第31 ~ 40个正在查询第4页中的第41 ~ 50个正在查询第5页中的第51 ~ 60个正在查询第6页中的第61 ~ 70个正在查询第7页中的第71 ~ 80个正在查询第8页中的第81 ~ 90个正在查询第9页中的第91 ~ 100个正在查询第10页中的第101 ~ 110个正在查询第11页中的第111 ~ 120个正在查询第12页中的第121 ~ 130个正在查询第13页中的第131 ~ 140个正在查询第14页中的第141 ~ 150个正在查询第15页中的第151 ~ 160个正在查询第16页中的第161 ~ 170个正在查询第17页中的第171 ~ 180个正在查询第18页中的第181 ~ 190个正在查询第19页中的第191 ~ 200个null补充:有结果返回map包含id、title、url。没有结果返回 Null百度搜索的url可以指定rn页码,最多一页50个,使用后有效减少了连接次数。但亲测下来设置过rn以后的结果与实际用户在百度搜索的结果排序和个数都有出入。故选择用默认rn来检测,效果最准确。本篇博客也发表在了我的个人主页,欢迎查看,地址https://zzzmh.cn/single?id=58END ...

January 22, 2019 · 3 min · jiezi