本文目录导读:

- 使用 wget(最简单)
- 使用 Python + requests + BeautifulSoup
- 使用 selenium(处理JavaScript动态加载)
- 使用专业工具 - HTTrack
- 完整的批量下载脚本
- 使用建议
- 注意事项
要自动下载网页中的所有资源,可以使用多种方法,我推荐几种实用方案:
使用 wget(最简单)
# 下载整个网站(递归) wget -r -np -k https://example.com # 常用参数说明 wget \ -r \ # 递归下载 -np \ # 不追溯上级目录 -k \ # 转换链接为本地可用 -p \ # 下载页面所需的所有资源 -nc \ # 避免重复下载 -e robots=off \ # 忽略robots.txt -U "Mozilla/5.0" \ # 设置User-Agent -P ./download_dir \ # 指定下载目录 https://example.com
使用 Python + requests + BeautifulSoup
import requests
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin, urlparse
import re
def download_all_resources(url, output_dir="downloaded_site"):
# 创建目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 下载页面
response = requests.get(url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
soup = BeautifulSoup(response.text, 'html.parser')
# 保存HTML
with open(f"{output_dir}/index.html", "w", encoding="utf-8") as f:
f.write(response.text)
# 提取并下载各种资源
resource_tags = {
'img': 'src',
'link': 'href', # CSS, favicon
'script': 'src',
'source': 'src', # video, audio
'video': 'src',
'audio': 'src',
'iframe': 'src',
'object': 'data',
'embed': 'src'
}
downloaded = set()
for tag_name, attr in resource_tags.items():
for tag in soup.find_all(tag_name):
src = tag.get(attr)
if src and not src.startswith('data:'):
# 处理相对路径
full_url = urljoin(url, src)
if full_url not in downloaded:
try:
# 下载资源
file_response = requests.get(full_url, timeout=10)
# 生成保存路径
parsed = urlparse(full_url)
file_path = parsed.path.lstrip('/')
if not file_path:
file_path = f"resource_{len(downloaded)}"
full_path = os.path.join(output_dir, file_path)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
# 保存文件
with open(full_path, 'wb') as f:
f.write(file_response.content)
downloaded.add(full_url)
print(f"下载成功: {file_path}")
except Exception as e:
print(f"下载失败 {full_url}: {str(e)}")
# 使用示例
download_all_resources("https://example.com")
使用 selenium(处理JavaScript动态加载)
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests
import os
from urllib.parse import urljoin, urlparse
def download_dynamic_page(url, output_dir="downloaded_dynamic"):
# 设置无头浏览器
chrome_options = Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(options=chrome_options)
# 加载页面
driver.get(url)
# 等待JavaScript执行
driver.implicitly_wait(5)
# 获取所有资源
resources = driver.execute_script("""
var resources = [];
var elements = document.querySelectorAll('img, link[rel="stylesheet"], script[src], source, video, audio');
elements.forEach(function(elem) {
var src = elem.src || elem.href;
if (src) resources.push(src);
});
return resources;
""")
# 下载资源(同上)
# ...
driver.quit()
使用专业工具 - HTTrack
# 安装 # macOS: brew install httrack # Ubuntu: apt-get install httrack # 下载网站 httrack https://example.com -O ./mysite -%v # 或使用图形界面 httrack
完整的批量下载脚本
#!/usr/bin/env python3
import argparse
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin, urlparse
import re
class WebResourceDownloader:
def __init__(self, max_concurrent=10):
self.semaphore = asyncio.Semaphore(max_concurrent)
self.downloaded = set()
async def download_resource(self, session, url, output_dir):
async with self.semaphore:
if url in self.downloaded:
return
self.downloaded.add(url)
try:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=30)) as response:
if response.status == 200:
# 生成保存路径
parsed = urlparse(url)
file_path = parsed.path.lstrip('/')
if not file_path or file_path.endswith('/'):
file_path = f"index_{len(self.downloaded)}"
# 保存文件
full_path = os.path.join(output_dir, file_path)
os.makedirs(os.path.dirname(full_path), exist_ok=True)
content = await response.read()
with open(full_path, 'wb') as f:
f.write(content)
return file_path, content
except Exception as e:
print(f"下载失败 {url}: {e}")
return None, None
async def download_page(self, url, output_dir, depth=0, max_depth=3):
if depth > max_depth:
return
async with aiohttp.ClientSession() as session:
# 下载页面
file_path, content = await self.download_resource(session, url, output_dir)
if not content:
return
# 解析HTML
soup = BeautifulSoup(content, 'html.parser')
# 提取链接
links = set()
for tag in ['img', 'script', 'link', 'source', 'video', 'audio']:
for element in soup.find_all(tag):
src = element.get('src') or element.get('href')
if src:
full_url = urljoin(url, src)
links.add(full_url)
# 并发下载
tasks = []
for link in links:
if link not in self.downloaded:
tasks.append(self.download_resource(session, link, output_dir))
results = await asyncio.gather(*tasks)
# 递归下载子页面(可选)
for a_tag in soup.find_all('a', href=True):
href = a_tag['href']
if href.startswith('http') or href.startswith('/'):
full_url = urljoin(url, href)
if urlparse(full_url).netloc == urlparse(url).netloc: # 同域名
tasks.append(self.download_page(full_url, output_dir, depth+1, max_depth))
def main():
parser = argparse.ArgumentParser(description='下载网页所有资源')
parser.add_argument('url', help='目标URL')
parser.add_argument('-o', '--output', default='downloaded', help='输出目录')
parser.add_argument('-c', '--concurrent', type=int, default=10, help='并发数')
parser.add_argument('-d', '--depth', type=int, default=2, help='递归深度')
args = parser.parse_args()
downloader = WebResourceDownloader(args.concurrent)
asyncio.run(downloader.download_page(args.url, args.output, max_depth=args.depth))
if __name__ == '__main__':
main()
使用建议
- 简单场景:使用
wget命令 - 需要解析:使用 Python + BeautifulSoup
- 动态网站:使用 Selenium
- 完整镜像:使用 HTTrack
- 高效下载:使用异步脚本
注意事项
- 尊重网站的 robots.txt 和使用条款
- 注意不要对服务器造成过大压力(限制并发数)
- 有些资源可能需要处理反爬虫机制
- 动态加载的内容需要更复杂的处理
选择哪种方法取决于你的具体需求和网页的复杂度。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播