最近完成了一個文旅行業信息聚合的小應用,實現僅從一個入口了解全行業的信息動態,不用一個一個翻看各網站,節省了不少檢索時間。
一、基本思路
明確數據來源。基于前述目標,確定數據源為文化和旅游部管理部門官網,比如各省廳網站、各副省級城市網站,文化和旅游管理部門直屬單位網站,中國文化報電子版,中國旅游報電子版等,目前大約有60多個網站。
寫采集程序。日常使用 Win 系統+ Edge 瀏覽器,故采集程序使用 Python,配合 Selenium 4 來實現。獲取到的數據(標題、鏈接),存儲到 Sqlite3 數據庫。
寫展示網頁。將抓取到的數據進行展示,打開頁后,點擊某個標題,即可跳轉信息源網站,查看對應信息。
二、代碼框架
整個項目代碼框架如下
├
├─anhui_msg.py // 爬蟲1
├─get_bozhou.py // 爬蟲2
├─provinces_msg.py // 爬蟲3
├─province_level_cities.py // 爬蟲4
├─luyoubao_news.py // 爬蟲5
├─wenhuabao_news.py // 爬蟲6
├─newsspider.py // 爬蟲共用代碼
├─txt2db.py // 抓取信息轉存數據庫
├─auto_run.bat // 自動抓取、轉存、更新腳本
├─ahwlmsg.db // 保存所有數據的數據庫文
├─<DIR> html // 展示網頁代碼
├─<DIR> provinces // 保存各省文化和旅游廳網站信息
├─<DIR> province_level_cities // 保存副省級城市文化旅部網站信息
├─<DIR>?txt???????????????????????//?保存安徽省市文化和旅部網站信息
html 目錄下的文件如下:
├
├─<DIR>static????????????????????//?內含?CSS、JS、圖標
├─<DIR>templates // 網頁前端模板
├─run.bat // 本地自動運行網站腳本
├─ahwlmsg.db // 保存所有數據的數據庫文件
├─generate_html.py???????????????//?網頁后端
三、技術棧
采集程序: Python + Selenium4 + SQL
網頁前端: Html + CSS + JQuery
網頁后端 Python + Flask + SQL
四、代碼實現
(一)網頁信息獲取
信息采集代碼總體思路大體一致。均使用 Selenium 模擬瀏覽器打開相應網站,獲取鏈接后,全部保存為本地文件;然后進一步梳理存入數據庫。
以獲取副省級城市文化旅游網站信息為例。基本代碼如下:
def grasp_all_a(url, driver):assert(driver)driver.get(url)print("\033[1;31;40m looking {}... \033[0m".format(url))try:# 等待網頁打開15秒,直至可以定位到<a>標簽。WebDriverWait(driver, 15).until(EC.visibility_of_element_located((By.TAG_NAME,'a')))except:print("timeout")#?獲取網頁上所有的<a>標簽。a_tags = driver.find_elements(By.TAG_NAME, "a")#逐個分析<a>標簽,并分別處理。filename = get_filename(url).rstrip('/')with open("./province_level_cities/" + filename+".txt", 'w', encoding='utf-8') as f:for tag in a_tags:title = tag.get_attribute('title').replace('\n','').strip(' ')href = tag.get_attribute('href')if?title?and?href:if filename not in href:continueelif 'javascript' not in href:f.write(title + "\t" + href + "\n" )elif href:if 'javascript' in href:continueelse:f.write(tag.text.replace('\n','').strip(" ") + "\t" + href + "\n" )driver.quit()
實現邏輯分三步:
1. 準備工作。
2. 打開網頁后,獲取該網頁上所\<A>標簽。
3. 對每一個\<A>標簽的title和href屬性進行分析:沒有title和href則跳出;同時存在時,一看href是不是指向本網站,二看href中是不是包括JavaScript,如果鏈接指向本網站且鏈接中不包括JavaScript,就把A標簽的title、href屬性保存到文件里;只有href屬性且鏈接中不包括JavaScript時,做一點清理后,將href保存到文件中。
(二)網頁避坑設置
由于各種原因,并非所有網頁數據都能成功獲取,所以在打開網頁前需要做一些設置。通過反復調試,以下代碼可滿足多數情況下的需要。
def ready_to_grasp():path?=?r"d:\\webdriver\\msedgedriver.exe"if?os.path.exists(path):sys.path.append(path)else:print("Please?install?webdriver?first.\n")exit(-1)options = Options()options.add_argument('headless')options.add_argument('disable-gpu')options.add_argument('no-sandbox')options.add_argument('incognito')options.add_argument("disable-blink-features=AutomationControlled")options.binary_location?=?r"C:\\Program?Files?(x86)\\Microsoft\\Edge\\Application\\msedge.exe"driver?=?webdriver.Edge(options=options)driver.execute_cdp_cmd('Network.setUserAgentOverride',?\{"userAgent":?'Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?\AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/119.0.0.0?\Safari/537.36?Edg/119.0.0.0'})return?driver
以上代碼為三部分:一是準備工作;二是設置選項;三是調用執行。代碼本身可以說明。
(三)網頁展示
找個看著比較順眼的網站,保存到本地,去掉不需要的功能,確定前端樣式,形成網頁模板。
后端主要是響應網頁上的操作,查詢數據庫,并將查詢結果從后端向前端傳送等。
(最終網頁效果)
五、結語
這個周末項目式的“小雪球”,斷斷續續重寫了三遍。目前,程序每天在跑,每天在用,可瀏覽最近一周之內各省、副省級城市和安徽省各市文旅網站發布的信息資訊。
期間,也嘗試接入目前流行的大模型。比如,在鼠標移到網頁上某個標題時,自動連接大模型,在不跳轉頁面的情況下,對其內容進行摘要。