领导给布置了一个任务,将公司的Wiki中的资料全部爬取下来。
接到任务后,先去网上找了一下方法,发现有confluence-dumper-master这个插件,于是将这个插件下载下来。
运行起来发现在转化的过程中总是出现字符字节类错误,每次出现错误就使用deepseek进行改错优化,最终的结果是:将插件错误改正,然后新增了前端代码转换为pdf文件的功能。所以优化好后的插件是有三个功能:将前端页面爬取下来;将页面中的插件下载下来;将前端代码转换为pdf文件的格式。
在运行的过程中又发现运行起来太慢,一个空间爬取就需要一个半小时,而且如果前端页面中如果有超链接的话pdf的转换会出错所以又再次对其进行优化,新增多线程加异步,超链接内容下载等功能。
至此,圆满完成任务,撒花!!!
def init_session():
"""初始化全局会话"""
session = requests.Session()
session.mount('http://', HTTPAdapter(pool_connections=settings.HTTP_POOL_SIZE,
pool_maxsize=settings.HTTP_POOL_SIZE))
return session
GLOBAL_SESSION = init_session() # 替换所有 requests.get 为 GLOBAL_SESSION.get
def async_downloader(url, path):
"""带连接复用的异步下载"""
with GLOBAL_SESSION.get(url, stream=True) as r:
r.raise_for_status()
with open(path, 'wb') as f:
for chunk in r.iter_content(chunk_size=2**20): # 1MB/chunk
f.write(chunk)
return path
def http_get(url, stream=False):
"""带错误处理的HTTP GET请求"""
try:
response = requests.get(
url,
auth=settings.HTTP_AUTHENTICATION,
headers=settings.HTTP_CUSTOM_HEADERS,
verify=settings.VERIFY_PEER_CERTIFICATE,
proxies=settings.HTTP_PROXIES,
stream=stream
)
response.raise_for_status()
return response
except Exception as e:
raise ConfluenceException(f"请求失败: {str(e)}")
额,领导又提了个需求,要按目录格式爬取。。。
再次进行优化:
def process_space_full(space_key):
"""全量空间处理(需要补充)"""
try:
safe_space = utils.sanitize_filename(space_key)
space_folder = os.path.join(settings.EXPORT_FOLDER, safe_space)
os.makedirs(space_folder, exist_ok=True)
# 获取所有页面(带重试机制)
pages = {}
retry_count = 0
while retry_count < 3 and not pages:
try:
pages = utils.get_all_pages(space_key)
except Exception as e:
print(f"{Fore.YELLOW}⚠ 获取页面列表失败,正在重试({retry_count + 1}/3)...{Style.RESET_ALL}")
time.sleep(2 ** retry_count)
retry_count += 1
# 全量模式处理逻辑
with ThreadPoolExecutor(max_workers=settings.MAX_THREADS) as executor:
futures = []
for page_id in pages:
# 全量模式下每个页面独立目录
page_folder = os.path.join(space_folder, f"page_{page_id}")
futures.append(executor.submit(
process_page_hierarchy,
page_id,
page_folder
))
for future in tqdm(as_completed(futures), total=len(futures), desc="🚀 全量处理进度"):
try:
future.result()
except Exception as e:
print(f"{Fore.RED}✗ 页面处理失败: {str(e)}{Style.RESET_ALL}")
GlobalStats.errors += 1
return True
except Exception as e:
print(f"\n{Fore.RED}✗ 空间处理失败: {space_key} - {str(e)}{Style.RESET_ALL}")
GlobalStats.errors += 1
return False
over over