这个是我在一家网络安全公司面试时的操作题,回来后经过多次修改后才得到一个比较完整的程序。

整个模块可以分成两个大部分。一个是数据库的操作,一个是信息的获取(类似爬虫?)

信息的获取分为四个小操作,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地址、端口、服务器类型和标题相关推荐

  1. gethostbyname()函数:通过域名获取IP地址

    客户端中直接使用 IP 地址会有很大的弊端,一旦 IP 地址变化(IP 地址会经常变动),客户端软件就会出现错误. 而使用域名会方便很多,注册后的域名只要每年续费就永远属于自己的,更换 IP 地址时修 ...

  2. 移远EC20 Ping指令,用域名获取IP 地址

    移远EC20 Ping指令 AT+QPING=<contextID>,<host> <contextID> 整型.场景ID.范围:1~15. <host> ...

  3. python 解析域名_Python实现通过解析域名获取ip地址的方法分析

    本文实例讲述了Python实现通过解析域名获取ip地址的方法.分享给大家供大家参考,具体如下: 从网上查找的一些资料,特此做个笔记 案例1: def getIP(domain): myaddr = s ...

  4. 路由器虚拟服务器打钩后不会生效,路由器自动获取IP地址,服务器无响应

    满意答案 lpgsp077 2016.06.19 采纳率:45%    等级:8 已帮助:662人 如何配置路由器 现在安装宽带的人越来越多,但好多用户在路由器出现问题后如何重新配置路由器.今天我们祥 ...

  5. PHP根据域名获取IP地址的

    gethostbyname (PHP 4, PHP 5, PHP 7) gethostbyname - 返回主机名对应的 IPv4地址. 说明 string gethostbyname ( strin ...

  6. C#之根据域名获取IP地址

    IPHostEntry host = Dns.GetHostEntry("www.baidu.com");foreach(var va in host.AddressList){C ...

  7. 获取指定域名的IP地址

    获取指定域名的IP地址 所需函数:gethostbyname 函数原型: struct hostent* gethostbyname(const char *name) 参数:const char * ...

  8. 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. ...

  9. 思科dhcp服务器动态获取ip地址

    项目要求: 某公司共有网管中心.行政部.技术部.三个部门,分别处在一栋大楼中的两个楼层,为了保证公司内部主机始终能够连接Internet,采用双向冗余设计,分别使用路由器R1与路由器R2连接中国电信和 ...

最新文章

  1. 【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )
  2. 今年的校招,Java好拿offer吗?
  3. Linux 如何通过某一台服务器调用执行多台远程服务器上的脚本,结果显示在本地?...
  4. 中国产业数字化发展报告:数智创新,智驱未来
  5. 你们这些程序员,真得每天都在读代码吗?
  6. iOS UISegmentedControl
  7. 【C++入门】C++ List类
  8. PollingBlockTracker - encountered an error while attempting to update latest block:
  9. 开发版速达光耀-无公网IP服务器访问整体解决方案
  10. jsp包含html有乱码,jsp include包含html页面产生的乱码问题
  11. php怎么做一个音乐播放器,实现一个HTML5音乐播放器的实例
  12. StretchDIBits函数隐含的图像坐标系设置
  13. java软件测试技术栈
  14. 神州数码交换机的数据备份
  15. 跑得快,打不死!清华大学开发“小强”机器人,壮汉狂踩也挡不住前进步伐
  16. 太拼了!张朝阳的一张作息表刷爆朋友圈
  17. hdu 3625 Examining the Rooms
  18. 有个懂你的人,是温暖
  19. 怎么把计算机拉到桌面上,怎么把电脑游戏放到桌面
  20. 一个不错的java机器学习项目JSAT

热门文章

  1. 可以设计一个电子三缝干涉实验
  2. 要嫁就嫁程序员:那些你不理解的真实的他们。
  3. 2021-7-7HTML5前端基础
  4. SOA面向服务架构:通信逻辑与SOME/IP消息格式
  5. 22.1.30总结反思
  6. 前端页面性能优化指标
  7. 【docker】啊嗷嗷暗暗啊
  8. 10堆沙子那堆沙子溶解会变色问题(二进制标记和排序标记)
  9. 中国矿业大学算法概论作业一 D、沙子的质量
  10. python爬虫学习——HTTP抓包工具Fiddler