WordPress 有定時任務機制,WP Super Cache 插件就是通過這個定時任務來進行預緩存,在我使用的過程中預緩存一次最多生成十幾個頁面,並且在下一次定時任務運行的時候才會繼續生成,效率是非常的慢,如果一直掛著 WP Super Cache 預緩存頁面可以一直自動生成,但是效率還是太慢了,於是我寫了一個簡單的 python 腳本並且可以把 WP Super Cache 不能預緩存的分類頁面也能緩存上。
代碼:#
首先我們的伺服器需要 python3 環境,並且我們的 WordPress 安裝好了 WP Super Cache 插件,把下面的代碼編輯成 page.py,用於緩存分類的分頁。
import os
import requests
import time
from concurrent.futures import ThreadPoolExecutor
from itertools import islice
# 定義鏈接和對應的數量
links = {
"https://k7blog.com": 60,
"https://k7blog.com/a8": 10,
}
# 生成鏈接
all_links = []
for link, count in links.items():
for i in range(1, count + 1):
page_link = f"{link}/page/{i}" if i > 1 else link
all_links.append(page_link)
# 將鏈接分組以便後續並發訪問
def chunk(it, size):
it = iter(it)
return iter(lambda: tuple(islice(it, size)), ())
# 訪問鏈接的函數
def visit_url(url):
try:
response = requests.get(url)
print(f"Visited: {url}, Status Code: {response.status_code}")
except Exception as e:
print(f"Failed to visit: {url}, Error: {e}")
# 設置並發數和延遲
concurrency = 10 # 並發數
delay = 1 # 延遲時間(秒)
# 創建線程池並並發訪問鏈接
with ThreadPoolExecutor(max_workers=concurrency) as executor:
for chunked_links in chunk(all_links, concurrency):
futures = [executor.submit(visit_url, url) for url in chunked_links]
time.sleep(delay)
# 將鏈接寫入到page.txt文件中
with open("page.txt", "w") as f:
for link in all_links:
f.write(link + "\n")
把代碼中的鏈接替換成你的分類頁就可以了,每一行的分類頁後面數字就是你的分頁數量。
比如我的分類有 10 頁,那麼我可以設置 15 頁,後續文章多了分頁多了不會緩存不上。
在把下面的代碼添加到 url.py:
import requests
import xml.etree.ElementTree as ET
import threading
import time
# 設置並發數和請求間隔
CONCURRENT_REQUESTS = 10
REQUEST_INTERVAL = 1 # seconds
def fetch_sitemap(url):
"""
獲取網站地圖內容
"""
response = requests.get(url)
if response.status_code == 200:
return response.content
else:
print(f"Failed to fetch sitemap from {url}")
return None
def extract_sitemap_urls(sitemap_content):
"""
從網站地圖內容中提取子地圖鏈接
"""
urls = []
if sitemap_content:
try:
root = ET.fromstring(sitemap_content)
for loc in root.findall(".//{http://www.sitemaps.org/schemas/sitemap/0.9}loc"):
urls.append(loc.text)
except ET.ParseError as e:
print("Error parsing sitemap XML:", e)
return urls
def fetch_urls_from_sitemap(url):
"""
從網站地圖中提取網頁鏈接
"""
sitemap_content = fetch_sitemap(url)
if sitemap_content:
return extract_sitemap_urls(sitemap_content)
else:
return []
def fetch_url(url):
"""
發送請求到網站鏈接
"""
try:
response = requests.get(url)
# 在這裡處理你想要的響應內容
print("Fetched:", url)
except requests.RequestException as e:
print("Error fetching", url, ":", e)
def main():
sitemap_url = "https://k7blog.com/wp-sitemap.xml" # 替換為你的网站地圖鏈接
sitemap_urls = fetch_urls_from_sitemap(sitemap_url)
all_urls = []
# 從所有子地圖中提取網頁鏈接
for url in sitemap_urls:
all_urls.extend(fetch_urls_from_sitemap(url))
# 寫入到url.txt文件
with open('url.txt', 'w') as f:
for url in all_urls:
f.write(url + '\n')
print("Urls extracted and written to url.txt file.")
# 並發請求的線程函數
def fetch_urls(urls):
while urls:
url = urls.pop(0)
fetch_url(url)
time.sleep(REQUEST_INTERVAL)
# 以CONCURRENT_REQUESTS個線程並發發送請求
threads = []
for _ in range(CONCURRENT_REQUESTS):
thread = threading.Thread(target=fetch_urls, args=(all_urls,))
thread.start()
threads.append(thread)
# 等待所有線程完成
for thread in threads:
thread.join()
if __name__ == "__main__":
main()
把地圖地址替換成你的地圖地址,會自動抓取網站的全部鏈接進行預緩存。
如果我們在寶塔添加定時任務選擇 shell 腳本:
python3 /你的目錄/page.py
python3 /你的目錄/url.py
可能會出現一個報錯:
Traceback (most recent call last):
File "/a8dog.py", line 2, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
這是因為寶塔的定時任務是使用寶塔的 python 環境,沒有安裝 requests 模塊,我們只需要隨便添加一個 shell 定時任務腳本:
pip3 install requests
執行一下,然後再重新添加定時任務就可以了。
注意:#
如果你的域名有 cdn 或者防火牆,頻繁的預緩存可能會出現被攔截的情況,請把 IP 加入白名單並且把修改 host 文件,把域名指向源 IP 或者 127.0.0.1,這樣就不會消耗 cdn 流量。