网络攻防技术——子域名收集
-
作业题目
本次实验主要考察大家的编程能力及子域名的信息收集方法,在文件夹"Lab1_code"提供了使用 Bing 搜索引擎的域名收集功能。请对该代码进行扩展,使其可支持百度搜索引擎的域名收集功能。
需要实现如下功能:
a) 支持百度搜索引擎的域名提取,其中从百度搜索引擎提取的域名需为真实域名,而非百度的域名跳转链接;
b) 可扩充其他功能,比如域名所在的标题等信息。
-
实验步骤及结果
-
绕过反爬:
百度服务器会通过对请求头分析判断是否为爬虫程序,因此伪造请求头,注意connection字段设置为close,否则会在爬取过程中超过最大可建立连接数,此外还要加入user-agent,accept,referer,cookie字段,可以从自己的浏览器获取
过快的访问速度会被百度服务器判定为爬虫,于是我们设置每爬取一个域名,程序sleep一秒钟
-
确定爬取URL
在百度的搜索URL中,通过GET方法传入参数名为pn的一个参数,其参数值可以确定是百度搜索结果显示的第几页(10表示第二页,20表示第三页,以此类推),通过for循环建立URL列表,这里设置为爬取10页
-
获取百度跳转链接
访问上面生成的URL,通过分析发现,百度搜索结果显示的域名链接并不是qq.com的真实域名,而是百度为每一个域名都生成了百度自己的跳转链接,并在<h3>标签下的href属性值,我们需要先通过bs4解析器获得百度的跳转链接
-
获取域名地址
拿到了百度的跳转链接,去遍历访问并拿到URL,在去掉重复值后获得真实的域名URL
这里需要注意拿到的href值可能不是有效URL,可以通过正则表达式筛选,判定正则为 '^https?://.+'
-
获取域名标题信息
通过分析发现,域名的标题信息位于HTML源码的<head>标签下的<title>标签中,于是通过bs4的html解析工具获取<title>标签内容,作为域名标签信息
有些网站因为停止维护或网络问题无法访问,为了不让程序停止运行,使用抛出异常机制进行处理
-
实验结果展示
运行爬虫程序,结果展示如下:(部分)
分析结果发现,百度会对同一个网站申请到不同的域名,如:www.baidu.com、m6.baidu.com、mc.baidu.com等,均指向baidu搜索首页的网站。
完整代码如下:
1 # 本次实验内容主要为:收集qq.com域名下的子域名, 2 # 收集方法为使用baidu搜索引擎,采用爬手段,爬取搜索到的域名 3 # bing搜索引擎搜索子域名的语法为:site:[域名] 4 import requests #用于请求网页 5 from bs4 import BeautifulSoup #用于处理获取的到的网页源码数据 6 from urllib.parse import urlparse #用于处理url 7 import urllib 8 import urllib.error 9 import re 10 import time 11 12 #定义一个采用baidu搜索的方法 13 def baidu_search(): 14 Subdomain = [] #定义一个空列表用于存储收集到的子域名 15 #定义请求头,绕过反爬机制 16 headers = { 17 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.50', 18 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 19 'referer':'https://www.baidu.com/s?ie=UTF-8&wd=domain%3Abaidu.com', 20 'cookie':'BAIDUID=64FED9E2DC1BAD938B534B963CAF6FFB:FG=1', 21 'Connection':'close' 22 } 23 #定义请求ul 24 # url = "https://www.baidu.com/s?ie=UTF-8&wd=domain%3Aqq.com" 25 for j in range(0,10): 26 j = str(j) 27 url="https://www.baidu.com/s?wd=site%3Abaidu.com&pn=" + j + "0&oq=site%3Aqq.com&ie=utf-8&usm=1&fenlei=256&rsv_idx=1&rsv_pq=bbc06deb00041eb5&rsv_t=f933Fpnhk7srFA2e9TGPLm%2FQ74u9bCUsmfPFuoRtaO2zoSFNU%2FMjOERrLTA" 28 resp = requests.get(url,headers=headers) #访问url,获取网页源码 29 DATA = str(resp.content,'utf-8') 30 # print(DATA) 31 32 soup = BeautifulSoup(resp.content,'html.parser') #创建一个BeautifulSoup对象,第一个参数是网页源码,第二个参数是Beautiful Soup 使用的 HTML 解析器, 33 job_bt = soup.find_all('h3') #find_all()查找源码中所有<h2>标签的内容 34 for i in job_bt: 35 link0 = i.a.get('href') #循环获取‘href’的内容 36 pattern = re.compile(r'^https?://.+') 37 if(re.match(pattern, link0)): 38 print("<<<<<<<<<<<------>>>>>>>>>>>") 39 print(link0) 40 # link=urllib.request.urlopen(link0).geturl() 41 l = urllib.request.urlopen(link0) 42 try: 43 link = l.geturl() 44 #urlparse是一个解析url的工具,scheme获取url的协议名,netloc获取url的网络位置 45 domain = str(urlparse(link).scheme + "://" + urlparse(link).netloc) 46 if domain in Subdomain: #如果解析后的domain存在于Subdomain中则跳过,否则将domain存入子域名表中 47 pass 48 else: 49 Subdomain.append(domain) 50 print(domain) 51 52 #接下来打印title 53 requests.packages.urllib3.disable_warnings() 54 source = requests.get(domain,headers=headers,verify=False) #访问url,获取网页源码 55 # print(resp.content) 56 soup = BeautifulSoup(source.content,'html.parser') 57 if(soup.find('head')): 58 title0 = soup.find('head') 59 if(title0.title): 60 title= title0.title.getText() #getText函数获取标签文本 61 if(title): 62 print(title) 63 else: 64 print("没有标签") 65 else: 66 print("需要js加载") 67 except urllib.error.HTTPError as e: 68 if e.code == 500: 69 # 如果HTTP状态码为500,跳过该异常并继续执行其他代码 70 pass 71 else: 72 # 处理其他HTTP错误 73 print('HTTPError:', e.code) 74 pass 75 except urllib.error.URLError as e: 76 # 处理URL错误 77 print('URLError:', e.reason) 78 pass 79 except Exception as e: 80 # 处理其他异常 81 print('Error:', str(e)) 82 pass 83 time.sleep(1) 84 print("-------------------------------------------------------已爬取页数:" + str(j)) 85 baidu_search()
-
本文来自博客园,作者:Leo1017,转载请注明原文链接:https://www.cnblogs.com/leo1017/p/17933240.html