这个模块在很多爬虫项目里应该还是挺实用的,不过我是用来批量查询whois和备案单位的,因为库里有大量的子域名,所以只需要对同顶级域名的其中一个域名获取信息即可,否则会造成数据库大量冗余信息,而且在后期更新的时候还会造成系统及网络不必要的压力。

找了这么个提取顶级域名的模块,当然也可以提取二级,三级。

这个模块本来时python2.7版本,我改了urlparse模块和其他的一些语法

代码量不大,就直接贴上来了

ExtractLevelDomain

github地址:https://github.com/rfyiamcool/ExtractLevelDomain.git

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from urllib.parse import urlparse
class ExtractLevelDomain():

 def __init__(self):
 self.topHostPostfix = [
 '.com','.la','.io',
 '.co', '.cn','.info',
 '.net', '.org','.me',
 '.mobi', '.us', '.biz',
 '.xxx', '.ca', '.co.jp',
 '.com.cn', '.net.cn', '.org.cn',
 '.mx','.tv', '.ws',
 '.ag', '.com.ag', '.net.ag',
 '.org.ag','.am','.asia',
 '.at', '.be', '.com.br',
 '.net.br',
 '.name',
 '.live',
 '.news',
 '.bz',
 '.tech',
 '.pub',
 '.wang',
 '.space',
 '.top',
 '.xin',
 '.social',
 '.date',
 '.site',
 '.red',
 '.studio',
 '.link',
 '.online',
 '.help',
 '.kr',
 '.club',
 '.com.bz',
 '.net.bz',
 '.cc',
 '.band',
 '.market',
 '.com.co',
 '.net.co',
 '.nom.co',
 '.lawyer',
 '.de',
 '.es',
 '.com.es',
 '.nom.es',
 '.org.es',
 '.eu',
 '.wiki',
 '.design',
 '.software',
 '.fm',
 '.fr',
 '.gs',
 '.in',
 '.co.in',
 '.firm.in',
 '.gen.in',
 '.ind.in',
 '.net.in',
 '.org.in',
 '.it',
 '.jobs',
 '.jp',
 '.ms',
 '.com.mx',
 '.nl','.nu','.co.nz','.net.nz',
 '.org.nz',
 '.se',
 '.tc',
 '.tk',
 '.tw',
 '.com.tw',
 '.idv.tw',
 '.org.tw',
 '.hk',
 '.co.uk',
 '.me.uk',
 '.org.uk',
 '.vg']

 self.extractPattern = r'[\.]('+'|'.join([h.replace('.',r'\.') for h in self.topHostPostfix])+')$'
 self.pattern = re.compile(self.extractPattern,re.IGNORECASE)
 self.level = "*"

 def parse_url(self,url):
 parts = urlparse(url)
 host = parts.netloc
 m = self.pattern.search(host)
 return m.group() if m else host

 def parse_url_level(self,url,level="*"):
 extractRule = self._parse_regex(level)
 parts = urlparse(url)
 host = parts.netloc
 pattern = re.compile(extractRule,re.IGNORECASE)
 m = pattern.search(host)
 self.level = level
 return m.group() if m else host

 def set_level(self,level):
 extractRule = self._parse_regex(level)
 self.extractPattern = extractRule
 self.pattern = re.compile(self.extractPattern,re.IGNORECASE)
 self.level = level

 def add_top_domain(self,top):
 if not top.startswith('.'):
 raise ValueError('top_domain must have . (.com|.com.cn|.net)')
 if top not in self.topHostPostfix:
 self.topHostPostfix.append(top)
 self._reset()
 return True
 else:
 return False

 def _reset(self):
 set_level(self.level)

 def _parse_regex(self,level):
 extractRule = r'(\w*\.?)%s('+'|'.join([h.replace('.',r'\.') for h in self.topHostPostfix])+')$'
 level = level if level == "*" else "{%s}"%level
 extractRule = extractRule%(level)
 return extractRule

if __name__ == "__main__":
 filter = ExtractLevelDomain()
 #默认等级
 print(filter.level)
 #默认直接输出域名,剔除url,
 print(filter.parse_url('http://www.vuln.cn/tag/linux%E5%B7%A5%E5%85%B7'))
 #可以在参数中定义几级域名,1代表顶级域名
 print(filter.parse_url_level('http://www.vuln.cn/tag/linux%E5%B7%A5%E5%85%B7',level=1))
 #也可以定义属性
 filter.set_level(1)
 print(filter.parse_url_level('http://www.vuln.cn/tag/linux%E5%B7%A5%E5%85%B7',level=1))
 print(filter.level)