因为工作需要,需要爬取一个静态网站,于是就写了下面的代码,发出来给有需要的朋友用。
import requests
import re
import os
class FindFiles:
# 最终形成的文件列表
fileSet = set()
pathSet = set()
# 网站域名
site = ""
# 启动程序
def start(self):
print("启动程序...")
self.site = input("请输入网站域名:\n")
name = input("请输入首页文件名:\n")
# 得到文件
self.getFile("",name)
# 获得文档内容并编码
def getFile(self,path,name):
print("获取文件 -> " + name)
# 文件地址
if path == "":
# 网页地址
pageSrc = self.site + "/" + name
fileSrc = "./" + name
else:
# 网页地址
pageSrc = self.site + "/" + path + "/" + name
fileSrc = "./" + path + "/" + name
# 整理文件路径
self.execFilePath(path)
# 整理文件名称
fileName = self.execFileName(name)
# 如果文件集合中没有 就下载并保存 (避免重复遍历)
if fileSrc not in self.fileSet:
if not os.path.isfile(fileSrc):
# 从互联网上拉取文件
file = requests.get(pageSrc)
if str.lower(fileName[1]) != "jpeg" and str.lower(fileName[1]) != "jpg" and str.lower(fileName[1]) != "png" and str.lower(fileName[1]) != "gif" and str.lower(fileName[1]) != "js" :
# 从文件中获取路径
code = file.text.encode('iso-8859-1').decode('gbk')
# 在目标路径创建相应的文件
f=open(fileSrc,'wb')
#将下载到的图片数据写入文件
f.write(file.content)
f.close()
else:
if str.lower(fileName[1]) != "jpeg" and str.lower(fileName[1]) != "jpg" and str.lower(fileName[1]) != "png" and str.lower(fileName[1]) != "gif" and str.lower(fileName[1]) != "js" :
# 从本地读取文件并设置编码
code = ""
f = open(fileSrc,'r')
for l in f.readlines():
code += l
f.close()
self.fileSet.add(fileSrc)
print("Saved file is : " + fileSrc)
# 如果是页面文件就要进行处理
if str.lower(fileName[1]) == "asp" or str.lower(fileName[1]) == "php" or str.lower(fileName[1]) == "html" or str.lower(fileName[1]) == "htm":
self.execHTML(code)
elif str.lower(fileName[1]) == "css":
# 从CSS中获取路径
self.execCss(code)
# 从文档里寻找路径
def execHTML(self,code):
print("整理HTML...")
# 代码不规范,会经常用单引号
htmlStr = str.replace(code,"'",'"')
# 利用正则表达式获取文件路径
parttern = re.compile(r'"([^"]+)\.(jpg|css|js|jpeg|png|gif|asp|php|html|htm)"', re.I|re.M)
srcList = parttern.findall(htmlStr)
# 遍历路径信息
for src in srcList:
# 整理路径和文件名
pathList = str.split(src[0],"/")
pathStr = "/".join(pathList[:-1])
nameStr = pathList[-1]+"."+src[1]
# 重新遍历文件(进入递归)
print("Page callback to GetFile : " + pathStr + "/" + nameStr)
self.getFile(pathStr,nameStr)
# 从CSS文件里寻找文件
def execCss(self,code):
print("整理CSS...")
# 利用正则表达式获取文件路径
parttern = re.compile(r'url\((.+)\.(jpg|jpeg|gif|png)\)', re.I|re.M)
srcList = parttern.findall(code)
print("CSS Inside file:")
print(srcList)
# 遍历路径信息
for src in srcList:
# 整理路径和文件名
pathList = str.split(src[0],"/")
pathStr = "/".join(pathList[:-1])
nameStr = pathList[-1]+"."+src[1]
# 重新遍历文件(进入递归)
print("CSS callback to GetFile : " + pathStr + "/" + nameStr)
self.getFile(pathStr,nameStr)
# 处理文件目录
def execFilePath(self, pathStr):
print("整理路径...")
if (pathStr != ""):
paths = "."
pathList = str.split(pathStr,"/")
# 遍历目录
for path in pathList:
paths += "/" + path
# 检查是否存在该目录
if paths not in self.pathSet:
# 检查目录是否已经创建
if not os.path.isdir(paths):
os.mkdir(paths)
self.pathSet.add(paths)
print("Created path is : " + paths)
else:
pathList = []
# 将分组的路径信息返回
return pathList
# 处理文件名称
def execFileName(self, nameStr):
print("整理文件名...")
nameList = str.split(nameStr,".")
nameFront = ""
for name in nameList[:-1]:
nameFront += name
# 返回文件扩展名之前的字符 和文件扩展名
return [nameFront,nameList[-1]]
if __name__ == '__main__':
findFiles = FindFiles()
findFiles.start()
只是做了简单的文件类型判定,程序其实可以写的更优质一点,懒得优化了,这么小的东西,已经够用了。