论如何优雅的复制一个网站的所有页面
推荐关注
说在前面
处理并保存单个页面
网站复制之需要保存的内容
在开始动手写代码之前,我们需要确定一下要保存下来的内容,以便后期编写脚本来处理。
暂且分为这么两个部分:
网页源码(单个页面的html源码)
css、js与图片文件(静态文件)
css、js与图片文件的下载地址都是从网页源码中获取得到的,如图:
网站复制之链接的提取
有了一个页面的链接,就可以通过这个链接获取HTML源码进而获取各类文件的相对地址。相较于路径处理,这里的方式就简单直接很多。用beautifulsoup直接获取标签,再获取链接即可。过程如图:
通过构造一个ExtractLinks()函数来获取一个网页内所有同类标签的同种参数。可以节省一些重复的语句,方面获取到css、js、img、a标签的url地址。
这里的过滤的内容如下:
去重复
丢弃无效url地址如:#、javascript伪协议等
那获取了链接之后就需要对路径进行处理了。
网站复制之路径的处理
在网页源码当中,相对地址的形式有很多种情况。
需要正常应对的相对地址形式有多少种呢?用图片文件作为一个例子,简单总结了一些如下:
页面地址 | 源码中地址 | 下载地址 | |
---|---|---|---|
1 | https://example.com/c/d/a.html | None | None |
2 | https://example.com/c/d/a.html | # | None |
3 | https://example.com/c/d/a.html | test/a.jpg | https://example.com/c/d/test/a.jpg |
4 | https://example.com/c/d/a.html | ./test/a.jpg | https://example.com/c/d/test/a.jpg |
5 | https://example.com/c/d/a.html | ../a.jpg | https://example.com/c/a.jpg |
6 | https://example.com/c/d/a.html | //example.com/a.jpg | https://example.com/a.jpg |
7 | https://example.com/c/d/a.html | https://example.com/a.jpg | https://example.com/a.jpg |
8 | https://example.com/c/d/a.html | /test?id=1 | https://example.com/test?id=1 |
9 | https://example.com/c/d/a.html | /./a.jpg | https://example.com/a.jpg |
10 | https://example.com/c/d/a.html | data:image/png;base64,... | data:image/png;base64,... |
页面地址:用于获取源码中的文件地址,并根据url的层级关系确定图片保存的路径。 图片地址:根据页面地址与图片地址确定图片的下载地址
页面地址 图片地址 图片的下载地址 替换的图片地址 保存的路径 图片地址的类型(方便DEBUG)
Md5Encrypt(): 是用作对站外文件的下载链接进行MD5加密,防止重复下载 GetUrlPart(): 用于获取url中不同部分的值,方便对url的处理 ProcessResourcePath(): 处理页面地址和图片地址的相对关系
网站复制之单个页面的处理与保存
文件地址替换
链接地址替换
以.html结尾的 => 直接以原文件名保存 以.php等不适.html结尾的 => 在原来的文件名后添加.html后缀保存 没有文件名的 => 保存为index.html
保存文件的总结
获取网站的所有页面
获取网站的所有页面的链接
通过这个方式把网站所有的url获取到,然后批量进行单个页面的保存即可。
加快获取链接与保存文件的速度
为了加快获取网站所有页面的链接和保存每个页面的文件,我们需要使用多线程和协程来加快执行效率。
我使用的是自己写的一个简单的协程框架:
协程初体验之简单的利用框架
这个框架的流程如下图所示:
框架写的比较简陋,修改一下是可以直接用到复制网站脚本里面的。具体内容可以进文章里面细看。
通过协程,可以显著加快获取网站所有页面与保存单个页面的速度。
总结
Github项目
文章中各个部分的代码实现都在一个python脚本当中,github仓库地址如下:
SiteCopy: https://github.com/Threezh1/SiteCopy
使用命令:
复制单个页面:
python sitecopy.py -u "https://threezh1.com"
复制整个网站(-t设置线程):
python sitecopy.py -u "https://threezh1.com" -e -t 30
声明:
对互联网任何网站的复制需在取得授权后方可进行,若使用者因此做出危害网络安全的行为后果自负,与作者无关,特此声明。
存在的问题
目录替换时在有些情况下会进行多次替换导致页面无法正常显示
网站或图床有防爬措施时无法正常保存
网络问题导致脚本无法正常执行
非常希望能够和师傅们共同交流对这些问题的解决方式,我的邮箱:makefoxm@qq.com
复制网站测试
复制自己的博客:https://threezh1.com 花费时间:2分钟48秒
运行截图:
目录截图:
页面截图:
本文转自先知社区,原作者Threezh1(侵删)