分享一个检测某网页依赖第三方资源的 python 脚本

最近做了一项很恶心的工作——帮我们部门开外网白名单。

白名单提交上去之后要 IT 部审批,流程很麻烦,做不到快速迭代。汇总统计了几百个技术网站申请通过之后,发现很多网站不能正常展示,原来 IT 部门的白名单是基于域名做的,很多网站使用了 CDN 等第三方资源,这些地址都不在白名单里。

这个就比较头大了,几百个网站呢,干脆写个脚本批量统计一下,顺便以后同事想申请那个网站的时候也可以跑一下脚本,把依赖的地址一并申请了。

DepSpy.py:

#!/usr/bin/env python
# -*- coding: utf8 -*-

# 通过输入的网址获取其依赖的站点(html中引用到的)
# 依赖文件格式如下:
# *.microsoft.com
# *.outlook.com
# *.apple.com
# *.ibm.com

import urllib2
import urlparse
import socket
import sys
import re

def printHelp():
	print 'Approach 1: python DepSpy.py url dstfile'
	print '    * url starts with http:// or https://.'
	print '    * dstfile is the full name of output file,'
	print '      results output to stdin if dstfile is empty.'
	print '\r\nApproach 2: python DepSpy.py urlfile dstfile'
	print '    * urlfile is the full name of file listing input urls(splitted by \\n).'
	print '    * dstfile is the full name of output file,'
	print '      results output to stdin if dstfile is empty.'

# 根据命令行调用相应功能
def dispatch(args):
	try:
		if len(args) < 2:
			printHelp()
			return []
		elif len(args) == 2 and (['h', '/h', '-h', '?', '/?', '-?', 'help', '-help', '/help'].count(args[1]) != 0):
			printHelp()
		elif args[1].find(r'http://') == 0 or args[1].find(r'https://') == 0:
			# 命令行参数为一个网址
			return getDependHost(args[1])
		else:
			# 命令行参数为一个网址列表文件名
			urls = readURLList(args[1])
			ret = []

			for u in urls:
				print'---- Dealing with: ' + u + ' ----'
				lst = getDependHost(u)
				for it in lst:
					if ret.count(it) == 0:
						ret.append(it)
			return ret
	except Exception , e:
		print e

	return []

# 获取依赖站点
_pattern = re.compile(r'<(?:script|link).*(?:src|href)\s?=\s?"(https?://.+?)"')
_pwww = re.compile(r'^[a-z0-9-_]+\.')
def getDependHost(url):
	try:
		if url.find('http://') != 0:
			url = 'http://' + url

		def getHost(str):
			netloc = urlparse.urlparse(str).netloc
			
			if netloc.find('baidu.com') != -1:
				# 百度的网址要单独处理
				return netloc
			elif netloc.count('.') < 2:
				return '*.' + netloc
			else:
				netloc, dummy = re.subn(_pwww, '*.', netloc)

			return netloc

		resp = urllib2.urlopen(url)
		html = resp.read()
		deps = _pattern.findall(html)
		deps = map(getHost, deps)
		selfHost = getHost(url)
		ret = []
		
		for it in deps:
			if ret.count(it) == 0 and selfHost != it:
				ret.append(it)
		
		print ret
		return ret
	except Exception , e:
		print e
	
	return []

# 读取网址列表
def readURLList(path):
	fp = open(path, 'r')
	urls = []
	try:
		urls = fp.read().replace('\r', '').replace('*', 'www').split('\n')
	finally:
		fp.close()
	return urls

# 程序入口
if __name__ == '__main__':
	socket.setdefaulttimeout(60) # 全局超时设置
	lst = dispatch(sys.argv)

	if len(sys.argv) > 2:
		try:
			distFilename = sys.argv[2]
			fp = open(distFilename, 'w')
			
			for it in lst:
				fp.write(it + '\r\n')
		
			fp.close()
		except Exception , e:
			print 'Write File Error'
	else:
		try:
			for it in lst:
				print it
		except Exception , e:
			print ''

基本上我用 python 就是当跨平台命令行,代码写得很烂,见笑了。

另外,这个脚本只处理了网站主页,没有对子页面做爬虫处理,因为我觉得基本上一个网站各个页面使用的第三方资源应该是一样的。以及,所有的 ajax 请求都被忽略了,处理这个需要调用浏览器内核,太麻烦。






转载于:https://my.oschina.net/legendlee/blog/465955

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值