本文原地址
目錄
vue離線文檔下載地址
該文檔是vue2
版本離線中文文檔,由爬蟲程序在官網爬取,包括文檔、api、示例、風格指南等幾個部分
,下載地址是:vue2離線文檔
可運行源程序及說明
爲了程序的正常運行,需要按一下目錄建立文件夾和文件,這個層次目錄是根據源網站的目錄建立的,通過瀏覽器的開發者模式可以看到
主程序:vue_crawl.py
import requests
import re
import time
class VueCrawl:
headers = {
'Referer': 'https://vuejs.bootcss.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
# 網站根目錄
base_url = 'https://vuejs.bootcss.com'
# v2版本根索引目錄
index_url = 'https://vuejs.bootcss.com/v2/'
# 爬取目標
targets = ['style-guide', 'api', 'cookbook', 'examples', 'guide']
# 存放文檔的根目錄
base_dir = 'D:/code/python/vue_crawl/vue_files'
# 提取url的正則表達式
url_pattern = re.compile(r"<a\s+[^>]*href=\"([^#>\"]*)\"[^>]*>([^<]*)</a>")
# 提取css的正則表達式
css_pattern = re.compile(r"<link\s+[^>]*stylesheet[^>]*\s+href=\"([^#>\"]*)\"[^>]*>")
# 提取js的正則表達式
js_pattern = re.compile(r"<script\s+[^>]*src=\"([^>\"]*)\"[^>]*>\s*</script>")
# 提取img的正則表達式
img_pattern = re.compile(r"<img\s+[^>]*src=\"([^>\"]*)\"[^>]*>")
# 由於爬取到的靜態資源可能重複,所以用set存放
css_set = set()
js_set = set()
img_set = set()
# 抓取資源文件失敗時記錄錯誤信息
error_info = []
@staticmethod
def download(abspath, content):
"""存儲資源文件,參數content爲二進制形式"""
with open(abspath, 'wb')as f:
f.write(content)
def fix_pagesurl(self, content):
"""修正鏈接路徑爲相對路徑,否則爬下來的鏈接不會指向正確的位置"""
res_text = content.decode('utf-8', errors='ignore')
css_search_res = self.css_pattern.findall(res_text)
# css鏈接到base_dir目錄的css文件夾下
for item in css_search_res:
if not item.startswith(('http://', 'https://')):
self.css_set.add(item)
res_text = res_text.replace(item, "../.." + item)
js_search_res = self.js_pattern.findall(res_text)
# js鏈接到base_dir目錄的js文件夾下
for item in js_search_res:
if not item.startswith(('http://', 'https://')):
self.js_set.add(item)
res_text = res_text.replace(item, "../.." + item)
img_search_res = self.img_pattern.findall(res_text)
# 圖片鏈接到base_dir目錄的images文件夾下
for item in img_search_res:
if not item.startswith(('http://', 'https://')):
self.img_set.add(item)
res_text = res_text.replace(item, "../.." + item)
url_search_res = self.url_pattern.findall(res_text)
# 文檔鏈接到當前文件夾下
for item in url_search_res:
item_url = item[0]
if not item_url.startswith(('http://', 'https://')) and (
item_url.startswith("/v2/") and item_url.endswith('.html')):
res_text = res_text.replace(item_url, "./" + item_url.split('/')[-1])
return res_text.encode('utf-8')
def crawl_pages(self, target):
"""根據target [style-guide','api','cookbook','examples','guide']這幾個主要部分爬取"""
url_set = set()
init_r = requests.get(self.index_url + target, headers=self.headers)
init_text = init_r.content.decode('utf-8', errors='ignore')
url_search_res = self.url_pattern.findall(init_text)
for item in url_search_res:
item_url = item[0]
if not item_url.startswith(('http://', 'https://')) and (
item_url.startswith("/v2/" + target) and item_url.endswith('.html')):
url_set.add(item_url)
# 下載每個部分的首頁
VueCrawl.download(self.base_dir + '/v2/' + target + '/index.html', content=self.fix_pagesurl(init_r.content))
# 對首頁部分所有判定有效的鏈接進行下載
for item in url_set:
try:
filename = item.split('/')[-1]
res = requests.get(self.base_url + item, headers=self.headers)
print(str(res.status_code) + ":" + res.url)
res_content = res.content
VueCrawl.download(self.base_dir + '/v2/' + target + '/' + filename,
content=self.fix_pagesurl(res_content))
print('download file %s' % filename)
time.sleep(2)
except:
info = 'download file %s faild' % item
print(info)
self.error_info.append(info)
def download_staticfiles(self):
"""下載靜態資源文件"""
for item in self.js_set | self.img_set | self.css_set:
try:
res_content = requests.get(self.base_url + item, headers=self.headers).content
self.download(self.base_dir + item, res_content)
time.sleep(1)
except:
info = 'download file %s faild' % item
print(info)
self.error_info.append(info)
def main(self):
"""主體部分 首先爬文檔,之後下載靜態資源文件"""
for target in self.targets:
self.crawl_pages(target)
self.download_staticfiles()
if __name__ == '__main__':
init_r = VueCrawl().main()
抓取過程分析
主要抓取的東西有幾個大頁面,在程序中根據url
寫死就行了,如下圖:
# 要抓取的幾個大部分
targets = ['style-guide', 'api', 'cookbook', 'examples', 'guide']
每個大部分左側又有許多單獨頁面,需要一一抓取,如下圖:
主要鏈接需要用正則表達式提取出來,不提取包含#
的鏈接,不然會造成重複抓取,不抓取其他域名下的鏈接,這裏判斷的比較簡單,直接判斷是否以http,https
開頭:
# url_pattern = re.compile(r"<a\s+[^>]*href=\"([^#>\"]*)\"[^>]*>([^<]*)</a>")
url_set = set()
init_r = requests.get(self.index_url + target, headers=self.headers)
init_text = init_r.content.decode('utf-8', errors='ignore')
url_search_res = self.url_pattern.findall(init_text)
for item in url_search_res:
item_url = item[0]
if not item_url.startswith(('http://', 'https://')) and (item_url.startswith("/v2/" + target) and item_url.endswith('.html')):
url_set.add(item_url)
之後是對目標進行下載,這裏不再詳細說明,需要注意的是,在下載之前先要根據目錄改變各種資源的路徑層次結構