爬蟲-oiwiki

我們將BASE_URL 設置為 "https://oi-wiki.org/"?后腳本就會自動開始抓取該url及其子頁面的所有內容,并將統一子頁面的放在一個文件夾中

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import os
import pdfkit
from urllib3.exceptions import InsecureRequestWarning# 禁用SSL警告
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)# 配置wkhtmltopdf路徑
config = pdfkit.configuration(wkhtmltopdf='/usr/local/bin/wkhtmltopdf')BASE_URL = "https://oi-wiki.org/"
DOMAIN = urlparse(BASE_URL).netlocheaders = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36","Accept-Language": "zh-CN,zh;q=0.9"
}visited = set()
queue = [BASE_URL]def is_valid_url(url):parsed = urlparse(url)return (parsed.netloc == DOMAIN andnot parsed.fragment andnot url.endswith(('.zip', '.pdf', '.jpg', '.png')))def extract_links(html, base_url):soup = BeautifulSoup(html, 'html.parser')links = []for a in soup.find_all('a', href=True):full_url = urljoin(base_url, a['href']).split('#')[0]if is_valid_url(full_url) and full_url not in visited:links.append(full_url)visited.add(full_url)return linksdef fetch_page(url):try:print(f"[*] 抓取中: {url}")res = requests.get(url, headers=headers, verify=False, timeout=30)res.encoding = 'utf-8'return res.textexcept Exception as e:print(f"[!] 抓取失敗: {url} - {str(e)}")return Nonedef clean_html(html, url):soup = BeautifulSoup(html, 'html.parser')# 移除所有頂部導航和側邊欄相關元素for tag in soup.select('.navbar, .page-toc, .sidebar, footer, .giscus, .page-footer, .page-actions'):tag.decompose()# 僅保留主內容區域main_content = soup.select_one('main article') or soup.select_one('article') or soup# 修正資源路徑for tag in main_content.find_all(['img', 'a']):for attr in ['href', 'src']:if tag.has_attr(attr):tag[attr] = urljoin(url, tag[attr])# 獲取有效標題(使用最后一個有效路徑段)title_parts = urlparse(url).path.strip('/').split('/')title = title_parts[-1].replace('-', ' ').title() if title_parts else "Document"return f"""<!DOCTYPE html><html><head><meta charset="utf-8"><title>{title}</title><style>body {{ font-family: 'Noto Sans CJK SC', Arial, sans-serif;line-height: 1.6;margin: 2em;}}/* 保持原有樣式 */</style></head><body><h1>{title}</h1>{main_content}</body></html>"""def save_as_pdf(html, url):parsed = urlparse(url)path_segments = [seg for seg in parsed.path.strip('/').split('/') if seg]if len(path_segments) > 1:dir_path = os.path.join('output', *path_segments[:-1])filename = f"{path_segments[-1]}.pdf"else:dir_path = 'output'filename = "index.pdf"os.makedirs(dir_path, exist_ok=True)full_path = os.path.join(dir_path, filename)try:pdfkit.from_string(html, full_path, configuration=config, options={'encoding': "UTF-8",'enable-local-file-access': None,'quiet': ''  # 隱藏控制臺輸出})print(f"[√] 已保存: {full_path}")except Exception as e:print(f"[!] PDF生成失敗: {full_path} - {str(e)}")def crawl():while queue:current_url = queue.pop(0)html = fetch_page(current_url)if not html:continuenew_links = extract_links(html, current_url)queue.extend(new_links)cleaned_html = clean_html(html, current_url)save_as_pdf(cleaned_html, current_url)if __name__ == "__main__":print("🚀 啟動爬蟲,目標站點:", BASE_URL)visited.add(BASE_URL)crawl()print("? 所有內容已保存至 output/ 目錄")

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903166.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903166.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903166.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

業務中臺與數據中臺:企業數字化轉型的核心引擎

前言&#xff1a;在當今數字化浪潮下&#xff0c;企業為了提升運營效率、加速創新步伐并更好地適應市場變化&#xff0c;業務中臺與數據中臺應運而生&#xff0c;成為企業架構中的關鍵組成部分。本文將深入探討業務中臺和數據中臺的簡介、發展史、技術流環節以及在實際生產中的…

django admin 去掉新增 刪除

在Django Admin中&#xff0c;你可以通過自定義Admin類來自定義哪些按鈕顯示&#xff0c;哪些不顯示。如果你想隱藏“新增”和“刪除”按鈕&#xff0c;可以通過重寫change_list_template或使用ModelAdmin的has_add_permission和has_delete_permission屬性來實現。 方法1&…

基于云原生架構的后端微服務治理實戰指南

一、引言&#xff1a;為什么在云原生時代更需要微服務治理&#xff1f; 在單體應用時代&#xff0c;開發和部署雖然簡單&#xff0c;但隨著系統規模的擴大&#xff0c;單體架構的維護成本急劇上升&#xff0c;部署頻率受限&#xff0c;模塊之間相互影響&#xff0c;最終導致系…

MIT6.S081 - Lab10 mmap(文件內存映射)

本篇是 MIT6.S081 2020 操作系統課程 Lab10 的實驗筆記&#xff0c;目標只有一個&#xff1a;實現文件映射到內存的功能&#xff0c;也就是 mmap。 作為一名 Android 開發者&#xff0c;我可太熟悉 mmap 這個詞兒了。Android 的 跨進程通信 Binder 驅動、圖形內存分配和管理、…

基于BenchmarkSQL的OceanBase數據庫tpcc性能測試

基于BenchmarkSQL的OceanBase數據庫tpcc性能測試 安裝BenchmarkSQL及其依賴安裝軟件依賴編譯BenchmarkSQLBenchmarkSQL props文件配置數據庫和測試表配置BenchmarkSQL壓測裝載測試數據TPC-C壓測(固定事務數量)TPC-C壓測(固定時長)生成測試報告重復測試流程梳理安裝Benchmar…

WinForm真入門(17)——NumericUpDown控件詳解

一、基本概念? NumericUpDown 是 Windows 窗體中用于數值輸入的控件&#xff0c;由文本框和上下調節按鈕組成。用戶可通過以下方式調整數值&#xff1a; 點擊調節按鈕增減數值鍵盤直接輸入使用方向鍵調整 適用于需要限制數值范圍或精確控制的場景&#xff08;如年齡、參數配…

汽車自動駕駛介紹

0 Preface/Foreword 1 介紹 1.1 FSD FSD: Full Self-Driving&#xff0c;完全自動駕駛 &#xff08;Tesla&#xff09; 1.2 自動駕駛級別 L0 - L2&#xff1a;輔助駕駛L3&#xff1a;有條件自動駕駛L4/5 &#xff1a;高度/完全自動駕駛

AiCube 試用 - ADC 水位監測系統

AiCube 試用 - ADC 水位監測系統 水位檢測在水資源管理、城市防洪、農業灌溉、家用電器和工業生產等多領域發揮積極建設作用。利用水位傳感器&#xff0c;可以實現水資源的智能管理&#xff0c;提高生產效率。 本文介紹了擎天柱開發板利用 AiCube 工具快速創建 I/O 電壓讀取&…

秒殺壓測計劃 + Kafka 分區設計參考

文章目錄 前言&#x1f680; 秒殺壓測計劃&#xff08;TPS預估 測試流程&#xff09;1. 目標設定2. 壓測工具推薦3. 壓測命令示例&#xff08;ab版&#xff09;4. 測試關注指標 &#x1f4e6; Kafka Topic 分區設計參考表1. 單 Topic 設計2. 分區路由規則設計&#xff08;Part…

memcpy 使用指南 (C語言)

memcpy 是 C 語言標準庫中的一個重要函數&#xff0c;用于在內存區域之間復制數據。它是 <string.h> 頭文件中定義的高效內存操作函數之一。 函數原型 void *memcpy(void *dest, const void *src, size_t n); 參數說明 dest: 目標內存地址&#xff0c;數據將被復制到這…

跨境電商貨物體積與泡重計算器:高效便捷的物流計算工具

跨境電商貨物體積與泡重計算器&#xff1a;高效便捷的物流計算工具 工具簡介 貨物體積與泡重計算器是一款免費的在線工具&#xff0c;專門為物流從業者、跨境電商賣家和需要計算貨物運輸體積重量的用戶設計。這款工具可以幫助您快速計算貨物的體積和對應的空運、快遞泡重&…

如何避免爬蟲因Cookie過期導致登錄失效

1. Cookie的作用及其過期機制 1.1 什么是Cookie&#xff1f; Cookie是服務器發送到用戶瀏覽器并保存在本地的一小段數據&#xff0c;用于維持用戶會話狀態。爬蟲在模擬登錄后&#xff0c;通常需要攜帶Cookie訪問后續頁面。 1.2 Cookie為什么會過期&#xff1f; 會話Cookie&…

matlab simulink中理想變壓激磁電流容易有直流偏置的原因分析。

simulink把線性變壓器模塊拉出來&#xff0c;設置沒有繞線電阻的變壓器&#xff0c;激磁電感和Rm都有&#xff0c;然后給一個50%占空比的方波&#xff0c;幅值正負10V&#xff0c;線路中設置一個電阻&#xff0c;模擬導線阻抗。通過示波器觀察激磁電流&#xff0c;發現電阻越小…

電力系統失步解列與振蕩解析

一、基本概念解析 1. 失步&#xff08;Out-of-Step&#xff09; 在電力系統中&#xff0c;失步是指并列運行的同步發電機因功率失衡導致轉子間相對角度超過穩定極限&#xff0c;無法維持同步運行的狀態。具體表現為&#xff1a; 當系統發生短路、負荷突變或故障切除等擾動時&…

ctfhub-RCE

關于管道操作符 windows&#xff1a; 1. “|”&#xff1a;直接執行后面的語句。 2. “||”&#xff1a;如果前面的語句執行失敗&#xff0c;則執行后面的語句&#xff0c;前面的語句只能為假才行。 3. “&”&#xff1a;兩條命令都執行&#xff0c;如果前面的語句為假則直…

Missashe考研日記-day28

Missashe考研日記-day28 1 專業課408 學習時間&#xff1a;2h學習內容&#xff1a; 今天先是預習了OS關于虛擬內存管理的內容&#xff0c;然后聽了一部分視頻課&#xff0c;明天接著學。知識點回顧&#xff1a; 1.傳統存儲管理方式特征&#xff1a;一次性、駐留性。2.局部性原…

01 appium環境搭建

環境搭建 Java JDKNode.jsAndroidStudio(提供sdk)appiumappium Inspector 相關安裝包下載 鏈接&#xff1a;https://pan.xunlei.com/s/VOOf3sCttAdHvlMkc7QygsoJA1# 提取碼&#xff1a;x4s5 AndroidStudio下載安裝sdk AndroidStudio下載 安裝運行&#xff0c;配置代理及測…

指針(4)

1.回調函數 回調函數就是通過函數指針調用的函數。 將函數的指針&#xff08;地址&#xff09;作為一個參數傳遞給另一個函數&#xff0c;當這個指針被調用其所指向的函數時&#xff0c;被調用的函數就是回調函數。回調函數不是由該函數的實現方直接調用&#xff0c;而是在特…

Raptor碼的解碼成功率matlab實現

下面是使用matlab實現關于Raptor 碼解碼成功率的仿真代碼&#xff0c;并繪制成功率隨編碼符號數量變化的圖形示例。代碼中包含了 Raptor 碼的預編碼&#xff08;使用稀疏矩陣乘法模擬&#xff09;、LT 編碼、解碼過程&#xff0c;以及解碼成功率的計算和繪圖。 具體代碼如下&am…

域名系統DNS

DNS介紹 DNS是一個域名系統&#xff0c;在互聯網環境中為域名和IP地址相互映射的一個分布式數據庫 &#xff0c; 能夠使用戶更方便的訪問互聯網&#xff0c;而不用去記住能夠被機器直接讀取的IP數串。類似于生活中的114服務&#xff0c;可以通過人名找到電話號碼&#xff0c;也…