
作者:李曉飛
來源:Python 技術
爬蟲程序想必大家都很熟悉了,隨便寫一個就可以獲取網頁上的信息,甚至可以通過請求自動生成 Python 腳本[1]。
最近我遇到一個爬蟲項目,需要爬取網上的文章。感覺沒有什么特別的,但問題是沒有限定爬取范圍,意味著沒有明確的頁面的結構。
對于一個頁面來說,除了核心文章內容外,還有頭部,尾部,左右列表欄等等。有的頁面框架用 div 布局,有的用 table,即使都用 div,不太的網站風格和布局也不同。
但問題必須解決,我想,既然搜索引擎抓取到各種網頁的核心內容,我們也應該可以搞定,拎起 Python, 說干就干!
如何解決呢?
開始想了一個取巧的方法,就是利用工具(wkhtmltopdf[2])將目標網頁生成 PDF 文件。
好處是不必關心頁面的具體形式,就像給頁面拍了一張照片,文章結構是完整的。
雖然 PDF 是可以源碼級檢索,但是,生成 PDF 有諸多缺點:
耗費計算資源多、效率低、出錯率高,體積太大。
幾萬條數據已經兩百多G,如果數據量上來光存儲就是很大的問題。
不生成PDF,有簡單辦法就是通過 xpath[3] 提取頁面上的所有文字。
但是內容將失去結構,可讀性差。更要命的是,網頁上有很多無關內容,比如側邊欄,廣告,相關鏈接等,也會被提取下來,影響內容的精確性。
為了保證有一定的結構,還要識別到核心內容,就只能識別并提取文章部分的結構了。像搜索引擎學習,就是想辦法識別頁面的核心內容。
我們知道,通常情況下,頁面上的核心內容(如文章部分)文字比較集中,可以從這個地方著手分析。
于是編寫了一段代碼,我是用 Scrapy[4] 作為爬蟲框架的,這里只截取了其中提取文章部分的代碼 :
divs = response.xpath("body//div")
sel = None
maxvalue = 0 for d in divs:
ds = len(d.xpath(".//div"))
ps = len(d.xpath(".//p")) value = ps - ds if value > maxvalue:
sel = { "node": d, "value": value }
maxvalue = value print("".join(sel['node'].getall()))
簡單明了,測試了幾個頁面確實挺好。
不過大量提取時發現,很多頁面提取不到數據。仔細查看發現,有兩種情況。
再調整了一下策略,不再區分 div,查看所有的元素。
另外優先選擇更多的 p,在其基礎上再看更少的 div。調整后的代碼如下:
divs = response.xpath("body//*")
sels = []
maxvalue = 0 for d in divs:
ds = len(d.xpath(".//div"))
ps = len(d.xpath(".//p")) if ps >= maxvalue:
sel = { "node": d, "ps": ps, "ds": ds
}
maxvalue = ps
sels.append(sel)
sels.sort(lambda x: x.ds)
sel = sels[0] print("".join(sel['node'].getall()))
經過這樣修改之后,確實在一定程度上彌補了前面的問題,但是引入了一個更麻煩的問題。
就是找到的文章主體不穩定,特別容易受到其他部分有些 p 的影響。
既然直接計算不太合適,需要重新設計一個算法。
我發現,文字集中的地方是往往是文章主體,而前面的方法中,沒有考慮到這一點,只是機械地找出了最大的 p。
還有一點,網頁結構是個顆 DOM 樹[6]
那么越靠近 p 標簽的地方應該越可能是文章主體,也就是說,計算是越靠近 p 的節點權值應該越大,而遠離 p 的結點及時擁有很多 p 但是權值也應該小一點。
經過試錯,最終代碼如下:
def find(node, sel): value = 0 for n in node.xpath("*"): if n.xpath("local-name()").get() == "p":
t = "".join([s.strip() for s in (n.xpath('text()').getall() + n.xpath("*/text()").getall())]) value += len(t) else: value += find(n, a)*0.5 if value > sel["value"]:
sel["node"] = node
sel["value"] = value return value sel = { 'value': 0, 'node': None
}
find(response.xpath("body"), sel)
通過這樣改造之后,效果特別好。
為什么呢?其實利用了密度原理,就是說越靠近中心的地方,密度越高,遠離中心的地方密度成倍的降低,這樣就能篩選出密度中心了。
50% 的坡度比率是如何得到的呢?
其實是通過實驗確定的,剛開始時我設置為 90%,但結果時 body 節點總是最優的,因為 body 里包含了所有的文字內容。
反復實驗后,確定 50% 是比較好的值,如果在你的應用中不合適,可以做調整。
描述了我如何選取文章主體的方法后,后沒有發現其實很是很簡單的方法。而這次解決問題的經歷,讓我感受到了數學的魅力。
一直以來我認為只要了解常規處理問題的方式就足以應對日常編程了,可以當遇到不確定性問題,沒有辦法抽取出簡單模型的問題時,常規思維顯然不行。
所以平時我們應該多看一些數學性強的,解決不確定性問題的方法,以便提高我們的編程適應能力,擴展我們的技能范圍。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25