根据域名获取ip地址、端口、服务器类型和标题
这个是我在一家网络安全公司面试时的操作题,回来后经过多次修改后才得到一个比较完整的程序。
整个模块可以分成两个大部分。一个是数据库的操作,一个是信息的获取(类似爬虫?)
信息的获取分为四个小操作,ip的获取、端口的获取、服务器类型的获取和标题的获取。
IP的获取:
ip的获取代码:
def getIp(self,url):try:str_ip = str(socket.gethostbyname(url[7:])) #通过socket方式以域名获取IPself.print_msg(0, str_ip, "")self.ip = str_ipif str_ip:self.correct += 1except socket.error, e:print u"ip获取失败"
ip的获取其实比较简单,就是用socket模块的方法根据域名访问获取ip。要注意的是,这个域名是不包括”http://“,所以代码中用url[7:]
端口的获取其实更简单:
def getPort(self): #通过socket返回端口号try:str_port = str(socket.getservbyname('http', 'tcp'))self.print_msg(1, str_port, "")self.port = str_portif str_port:self.correct += 1except socket.error,e:print u"端口号获取失败"
用的也是socket模块的方法。
服务器类型的获取:
一开始我的想法是通过正则去匹配应答头,但是过了两天发现其实有更简单的方法,直接用urllib2模块的方法去访问,回传的数据中的header中直接找到"Server"这个键对应的键值就是服务器类型了。
def getServerType(self): #在header字典里寻找Server对应的键值self.server = str(self.header.get("Server"))self.print_msg(2,self.server, "")if self.server:self.correct +=1
最后就是标题的获取,这个其实算是最难的一个信息。标题没有像服务器类型一样存在header里面,而是在HTML文本里声明,其次在使用正则匹配时,我们首先要知道当前访问的页面的编码方式,这又需要去获取,最后不同的网页并不会固定title标签出现的位置,虽然大致位置一样。
所以我的想法是,先在回传数据的header里面找到‘content-type’(正常网页的编码方式都会在这里声明)。
然后获得这个字符串还不是编码方式,还要通过正则匹配匹配 charset:() 括号里面的才是真正的编码方式。
接着使用这个编码方式去对获取到的html文本解码,再编码成需要的类型(我的pycharm用utf-8)。
再就是对获取到的文体再正则匹配,这次匹配的是title标签里面的内容。
最后输出第一个匹配到的内容,输出的时候还要注意不同编码形式的字符串不能相连。
def getTitle(self): #通过正则匹配<title>标签内的字符data1 = self.header.get('content-type')pattern = re.compile(u"charset=(.*)")ress = pattern.findall(data1)if not ress: #如果在header列表找不到该网页的编码形式,则在response里匹配pattern = re.compile(r"charset=(.*)")ress = pattern.findall(self.response)if ress:temp = self.response.decode(ress[0],'ignore').encode("utf-8")xx = u"<title>(.*)</title>"pattern = re.compile(xx)results = pattern.findall(temp)if results:self.print_msg(3, "", results[0])self.title = results[0]if results[0]:self.correct += 1else:print u"找不到标题"
这四个内容都获取到了,就存到mysql数据库里面。
总的代码如下:
这是信息获取部分
# *_*coding:utf-8 *_*
import Queueimport gevent
import urllib2
import socket
import sys
import re
import threading
import DbSaveclass method1:def __init__(self,strurl):self.domain = ""self.ip = ""self.port = 0self.server = ""self.title = ""self.correct = 0self.problem_url = []self.queue = Queue.Queue()self.typeencode = sys.getfilesystemencoding()if strurl:for self.strurl in strurl:if self.check_domain(self.strurl):self.queue.put("http://"+self.strurl)else:print u"域名输入格式不正确"exit(0)else:print u"没有输入域名"exit(0)if not self.queue.empty():threads = [gevent.spawn(self.declare, i) for i in range(5)]try:gevent.joinall(threads)except KeyboardInterrupt, e:msg = '[WARNING] User aborted.'print self.problem_urldef declare(self,i):while not self.queue.empty():url = self.queue.get()try:self.domain = urlprint u"域名:"+urlself.urlget(url)self.getIp(url)self.getPort()self.getServerType()self.getTitle()print "-------------------------"DbSave.DbInsert(self.domain, self.ip,int(self.port), self.server, self.title)self.domain = ""self.ip = ""self.port = 0self.server = ""self.title = ""self.correct = 0except:print "数据库写入错误"if self.correct != 4:self.problem_url.append(url)self.correct = 0def urlget(self,url):try:res = urllib2.urlopen(url) #urllib2的get方法访问urlself.response = res.read() #获取正文self.header = res.headers #获取应答头except urllib2.URLError,e:print u"urllib2访问失败,退出.."exit(0)def getIp(self,url):try:str_ip = str(socket.gethostbyname(url[7:])) #通过socket方式以域名获取IPself.print_msg(0, str_ip, "")self.ip = str_ipif str_ip:self.correct += 1except socket.error, e:print u"ip获取失败"def getPort(self): #通过socket返回端口号try:str_port = str(socket.getservbyname('http', 'tcp'))self.print_msg(1, str_port, "")self.port = str_portif str_port:self.correct += 1except socket.error,e:print u"端口号获取失败"def getServerType(self): #在header字典里寻找Server对应的键值self.server = str(self.header.get("Server"))self.print_msg(2,self.server, "")if self.server:self.correct +=1def getTitle(self): #通过正则匹配<title>标签内的字符data1 = self.header.get('content-type')pattern = re.compile(u"charset=(.*)")ress = pattern.findall(data1)if not ress: #如果在header列表找不到该网页的编码形式,则在response里匹配pattern = re.compile(r"charset=(.*)")ress = pattern.findall(self.response)if ress:temp = self.response.decode(ress[0],'ignore').encode("utf-8")xx = u"<title>(.*)</title>"pattern = re.compile(xx)results = pattern.findall(temp)if results:self.print_msg(3, "", results[0])self.title = results[0]if results[0]:self.correct += 1else:print u"找不到标题"@staticmethoddef print_msg(signs, meg, title):switcher = {0: u"ip地址:",1: u"端口号:",2: u"服务器信息:",3: u"标题:",4: u"协程开启错误"}if meg:print switcher.get(signs)+megelse:print switcher.get(signs).encode("utf-8")+title@staticmethoddef check_domain(domain):pattern = re.compile(r'(?i)^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$')return pattern.match(domain)if __name__ == '__main__':L = ["www.51.com", "www.baidu.com", "www.1688.com", "www.taobao.com", "www.hao123.com","www.sohu.com", "www.youku.com", "www.taobao.com", "www.ifeng.com", "www.jd.com","www.4399.com", "www.126.com", "www.scnu.edu.cn", "www.163yun.com", "www.58.com","www.37.com", "www.tmall.com", "www.7k7k.com", "www.youxia.com", "sports.cctv.com","www.163.com", "v.qq.com", "www.bilibili.com", "www.hupu.com", "www.qidian.com","www.zol.com", "mail.qq.com", "www.51job.com", "www.liepin.com", "www.10086.cn","www.189.cn", "www.12306.com", "www.10010.com", "www.zol.com", "www.stockstar.com",]method1(L)
这是数据库部分:
# coding=utf-8
import MySQLdb
def Dbcreate():try:conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='pydatabase', port=3306,charset='utf8')cur = conn.cursor()urlmanager = """CREATE TABLE URLMESSAGE(DOMAIN CHAR(35) NOT NULL,IP CHAR(15),PORT INT,SERVER VARCHAR(20),TITLE TEXTCHARACTER SET utf8 COLLATE utf8_general_ci)"""cur.execute(urlmanager)cur.close()conn.close()except MySQLdb.Error, e:print "Mysql Error %d: %s" % (e.args[0], e.args[1])
def DbInsert(domain, ip, port, server, title):try:conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='pydatabase', port=3306,charset="utf8")cur = conn.cursor()cur.execute("INSERT INTO urlmessage(DOMAIN,IP,PORT,SERVER,TITLE) VALUES('%s','%s','%d','%s','%s')"%(domain,ip,port,server,title))cur.close()conn.commit()conn.close()except MySQLdb.Error, e:print "Mysql Error %d: %s" % (e.args[0], e.args[1])
尚未解决的问题:
1:在有些网页得到访问时间过长,会造成阻塞。
2:某些特殊的网页获取不到编码方式(只有www.qq.com出现这个问题)...
3:数据库的操作过于粗暴,正常来说不应该这么简单,导致一出现问题数据库就不工作了..
3:有些网页的标签无法获取。
解决方法:
1:应该使用多进程+协程的方法,我只是使用了协程(因为面试有道题目就是用协程,我只是想尝试一下..),通过多进程去设置访问超时时间。
2:这个问题尚未想到有什么解决的方案...因为只有这个域名出问题..
3:由于学数据库的时间太短,所以只会很简单的操作。这里我的想法是在信息获取和数据库操作之间加个中间层,设置一个缓存区,这样才可以一次打开数据库进行所有操作,而不是获取一个网页信息就操作一次。还有,数据库操作应该要很谨慎地处理数据,要有很好的异常处理机制(不是像我这样这么粗暴...),注意事务的提交和回滚。
4:这个问题的原因应该是正则匹配的不正确,因为不同网页HTML文本差的有点远...,暂时还没想到有什么方法..
还可以提升的部分:
在获取标题的部分,其实是把整个HTML都匹配一次,但其实我们只需要第一个获取到的title标签的内容.
输出内容时,不应该每获取到一个信息就调用一次print,可以统一输出。
好像在bs4的beautlfulsoup方法中有更好的对HTML文本的处理方法
根据域名获取ip地址、端口、服务器类型和标题相关推荐
- gethostbyname()函数:通过域名获取IP地址
客户端中直接使用 IP 地址会有很大的弊端,一旦 IP 地址变化(IP 地址会经常变动),客户端软件就会出现错误. 而使用域名会方便很多,注册后的域名只要每年续费就永远属于自己的,更换 IP 地址时修 ...
- 移远EC20 Ping指令,用域名获取IP 地址
移远EC20 Ping指令 AT+QPING=<contextID>,<host> <contextID> 整型.场景ID.范围:1~15. <host> ...
- python 解析域名_Python实现通过解析域名获取ip地址的方法分析
本文实例讲述了Python实现通过解析域名获取ip地址的方法.分享给大家供大家参考,具体如下: 从网上查找的一些资料,特此做个笔记 案例1: def getIP(domain): myaddr = s ...
- 路由器虚拟服务器打钩后不会生效,路由器自动获取IP地址,服务器无响应
满意答案 lpgsp077 2016.06.19 采纳率:45% 等级:8 已帮助:662人 如何配置路由器 现在安装宽带的人越来越多,但好多用户在路由器出现问题后如何重新配置路由器.今天我们祥 ...
- PHP根据域名获取IP地址的
gethostbyname (PHP 4, PHP 5, PHP 7) gethostbyname - 返回主机名对应的 IPv4地址. 说明 string gethostbyname ( strin ...
- C#之根据域名获取IP地址
IPHostEntry host = Dns.GetHostEntry("www.baidu.com");foreach(var va in host.AddressList){C ...
- 获取指定域名的IP地址
获取指定域名的IP地址 所需函数:gethostbyname 函数原型: struct hostent* gethostbyname(const char *name) 参数:const char * ...
- Python根据域名批量获取IP地址和经纬度(2021.12.1)
Python批量获取域名对应的IP地址和经纬度 1.DN.DNS.URL简介 1.1 域名 1.1.1 不同类型的域名 1.1.1.1 TLDs: Top-Level Domains 顶级域 1.1. ...
- 思科dhcp服务器动态获取ip地址
项目要求: 某公司共有网管中心.行政部.技术部.三个部门,分别处在一栋大楼中的两个楼层,为了保证公司内部主机始终能够连接Internet,采用双向冗余设计,分别使用路由器R1与路由器R2连接中国电信和 ...
最新文章
- 【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )
- 今年的校招,Java好拿offer吗?
- Linux 如何通过某一台服务器调用执行多台远程服务器上的脚本,结果显示在本地?...
- 中国产业数字化发展报告:数智创新,智驱未来
- 你们这些程序员,真得每天都在读代码吗?
- iOS UISegmentedControl
- 【C++入门】C++ List类
- PollingBlockTracker - encountered an error while attempting to update latest block:
- 开发版速达光耀-无公网IP服务器访问整体解决方案
- jsp包含html有乱码,jsp include包含html页面产生的乱码问题
- php怎么做一个音乐播放器,实现一个HTML5音乐播放器的实例
- StretchDIBits函数隐含的图像坐标系设置
- java软件测试技术栈
- 神州数码交换机的数据备份
- 跑得快,打不死!清华大学开发“小强”机器人,壮汉狂踩也挡不住前进步伐
- 太拼了!张朝阳的一张作息表刷爆朋友圈
- hdu 3625 Examining the Rooms
- 有个懂你的人,是温暖
- 怎么把计算机拉到桌面上,怎么把电脑游戏放到桌面
- 一个不错的java机器学习项目JSAT