资讯专栏INFORMATION COLUMN

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

caohaoyu / 797人阅读

摘要:域名解析与地址域名解析是把域名指向网站空间,让人们通过注册的域名可以方便地访问到网站的一种服务地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替地址标识站点地址。

域名解析与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,可以看到,在页面上看到的绑定域名信息就是下图红框中的内容,所以只要能将Response的内容解析出来,获取到的内容就可以得到想要的域名列表。

上述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

@RestController
public 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 domainSpider(@PathVariable("ip") String ip) {
        long startTime = System.currentTimeMillis();
        List 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上,欢迎下载学习

Gitee

Github

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77574.html

相关文章

  • HTTP精简教程一:Web网络基础

    摘要:网络基础通常使用的网络包括互联网是在协议族的基础上运作的。协议族中的指的就是网际协议,协议名称中占据了一半位置,其重要性可见一斑。确保可靠性的协议位于传输层,提供可靠的字节流服务。 使用 HTTP 协议访问 Web Web浏览器根据地址栏中制定的 URL 从 Web 服务器获取文件资源(resource)等信息,从而显示出Web页面。 超文本传输协议(HTTP,HyperText Tr...

    KevinYan 评论0 收藏0
  • HTTP精简教程一:Web网络基础

    摘要:网络基础通常使用的网络包括互联网是在协议族的基础上运作的。协议族中的指的就是网际协议,协议名称中占据了一半位置,其重要性可见一斑。确保可靠性的协议位于传输层,提供可靠的字节流服务。 使用 HTTP 协议访问 Web Web浏览器根据地址栏中制定的 URL 从 Web 服务器获取文件资源(resource)等信息,从而显示出Web页面。 超文本传输协议(HTTP,HyperText Tr...

    刘玉平 评论0 收藏0
  • 从URL输入到页面展现到底发生什么?

    摘要:定义文档资源的名称二域名解析在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过地址。什么是域名解析协议提供通过域名查找地址,或逆向从地址反查域名的服务。 前言 打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?先给大家来张总体流程图,具体步骤请看下文分解!本文首发地址为GitHub博客,写文章不易,请多多支...

    elva 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<