# mirror-sites

## 介绍
模拟浏览器访问来镜像站点或下载资源

## 使用说明

1.  全局安装：`npm install -g mirror-sites`
2.  全局命令使用： `mirror-sites`
3.  增加适当的[参数](#参数说明)，就会将站点的所有网络资源下载下来

## 参数说明

### -u(必须): 站点 url
要镜像的站点 url ，一般是该站点的首页，例如 https://vuejs.org/

### -remote(推荐): 下载第三方站点资源
站点引用的 CDN 等第三方站点的资源是否要一并下载

例如 `<script src="https://cdn.usefathom.com/script.js" />` 会下载到 `/cdn.usefathom.com/script.js`，页面代码也会被改写成 `<script src="/cdn.usefathom.com/script.js" />`，更多改写规则请查看 [-source](#source-网页源码)

### -p(推荐): 用自己的 Chrome
默认会在首次使用 mirror-sites 时，自动下载 chromium 浏览器来进行镜像操作

不想下载浏览器而是想使用自己的 Chrome 浏览器进行镜像操作时，可以通过命令打开你的浏览器 (浏览器地址请根据你的系统和安装目录来填写)

`"C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe" --remote-debugging-port=9222`

按照上面示例打开浏览器，此参数就是远程调试端口号9222

对于需要登录的页面，你可以在浏览器上手动登录后重新镜像一次

### -new(请看): 卡住时使用
使用 [-p](#p推荐-用自己的-chrome) 时，会优先在你的浏览器中找到已经打开了站点的页签中操作，若程序卡在 `Configuring mirroring operations...`，则不明原因无法操作你的页签。使用 `-new` 则新打开一个页签来进行操作

### -load(请看): 中断后继续下载
镜像过程中可能会出现意外中断或卡死的情况，中断后下次又会从头开始镜像，已经下载过的资源又会下载一遍

使用 `-load` 可以让网页从上次中断的地方继续

无论是否使用 `-load`，存档都会生成在 [输出目录](#o-输出目录)/mirror-sites-record.json

存档文件格式如下
- failed: 下载失败的文件，可以手动重试下载
- download: 下载成功的文件
- links: 站点爬取到的链接，后面的数字代表不同的状态
  - 0: 还没镜像
  - 1: 镜像成功
  - 2: 镜像失败，可能链接是个接口，最终会重定向
  - 3: [忽略的地址](#m-限制-url)，爬取到了地址，但是不进行镜像
  - -1: 第三方站点，不会进行镜像

### -m: 限制 url
需要在网站内镜像的 url 的正则表达式，与该表达式的路径部分不匹配的 url 将被忽略。这对于过滤包含语言信息的 url（如/en/index.html）非常有用，以避免重复采集不同语言的同一页面。例如如果您只想采集英语，请输入"-m \\/en.*" 则只会采集 /en 开头的 url

### -o: 输出目录
默认为命令行执行时的目录 + 站点域名

### -t: 下载资源类型
要下载的资源类型，不填默认就镜像整个网站，下载的资源会按照**下载地址**创建文件夹存，例如
```
/css/index.css
/js/index.js
/images
  /icons
    /icon.svg
  /logo
    /logo.png
```

所有支持的类型如下

- xhr: 包含 xhr 和 fetch ，一般为接口返回的 json 数据
- document: html 页面
- stylesheet: css 文件
- script: js 文件
- image: 图片
- media: 音频/视频
- font: 字体

多个类型用 '|' 分割，例如你只想下载图片，音频/视频，可以填写 `image|media`

此时下载的资源会按照**类型**创建文件夹存放，例如
```
/image
  /a.jpg
  /b.png
  /c.gif
/media
  /audio
    /a.mp3
    /b.wav
  /video
    /a.mp4
    /b.mov
```

### -source: 网页源码
下载的 html 保持源码，不将 url 全地址替换成相对地址。对于使用了 vue.js 等框架，源码里包含自定义组件的情况比较有用

#### 不使用 -source 的好处
会将链接的全路径修改为相对路径

假设镜像的网站有如下代码
```
<script src="https://cdn.usefathom.com/script.js" />
<a href="https://vuejs.org/api/application.html#createapp" />
```
会被转换成
```
<script src="/cdn.usefathom.com/script.js" />
<a href="/api/application.html#createapp" />
```

- a 标签

原本 a 标签点击后会跳回到源站点，这通常需要你镜像完网站后，手动将所有的 a 标签链接改为相对路径，如果源网站本来就用的相对路径则不需要修改

- 资源

资源也会使用源站点的资源，如果源站点改了 url 或 url 对应的内容，你的站点将无法使用或出现错误

所以一般需要配合 [-remote](#remote推荐-下载第三方站点资源) 使用，将第三方站点的资源也下载到本地(/cdn.usefathom.com/script.js)

#### 使用 -source 的好处
如果网站使用原生 js 方式开发，代码如下
```
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<div id="app">
  <h1>-source</h1>
  <my-component />
</div>

<script>
  const { createApp, ref } = Vue
  const MyComponent = {
	  data() {
	    return {
        count: 0,
      }
	  },
	  template: `<div @click="count++">count is {{ count }}</div>`,
	}

  const app = createApp({})
  app.component('my-component', MyComponent);
  app.mount('#app')
</script>
```

可以看到源码包含 `<my-component />` 这样的自定义组件

不使用 -source 时，替换了资源 `/unpkg.com/vue@3/dist/vue.global.js` 重新保存出来的网页代码，将是渲染之后的页面

此时，`<my-component />` 就会变成 `<div>count is 0</div>` 并且失去点击事件，这显然镜像的结果将会非常糟糕

使用 `-source` 保持下载源码将会非常有用

手动替换 url 的部分，还是手动替换自定义组件的部分，需要你自行权衡

如果有更好的能兼容两个的方案可以提 Issue 给作者

