91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用python實現精準搜索并提取網頁核心內容

發布時間:2021-11-01 11:43:32 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇文章主要講解了“怎么用python實現精準搜索并提取網頁核心內容”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用python實現精準搜索并提取網頁核心內容”吧!

    生成PDF

    開始想了一個取巧的方法,就是利用工具(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()))
    • response 是頁面的一個響應,其中包含了頁面的所有內容,可以通過 xpath 提取想要的部分

    • "body//div" 的意思是提取所以 body 標簽下的 div 子標簽,注意:// 操作是遞歸的

    • 遍歷所有提取到的標簽,計算其中包含的 div 數量,和 p 數量

    • p 數量 和 div 數量的差值作為這個元素的權值,意思是如果這個元素里包含了大量的 p 時,就認為這里是文章主體

    • 通過比較權值,選擇出權值最大的元素,這便是文章主體

    • 得到文章主體之后,提取這個元素的內容,相當于 jQuery[5] 的 outerHtml

    簡單明了,測試了幾個頁面確實挺好。

    不過大量提取時發現,很多頁面提取不到數據。仔細查看發現,有兩種情況。

    • 有的文章內容被放在了 <article> 標簽里了,所以沒有獲取到

    • 有的文章每個 <p> 外面都包裹了一個 <div>,所以 p 的數量 和 div 的抵消了

    再調整了一下策略,不再區分 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 數量比較大的節點,注意 if 判斷條件中 換成了 >= 號,作用時篩選出同樣具有 p 數量的結點

    • 經過篩選之后,按照 div 數量排序,然后選取 div 數量最少的

    經過這樣修改之后,確實在一定程度上彌補了前面的問題,但是引入了一個更麻煩的問題。

    就是找到的文章主體不穩定,特別容易受到其他部分有些 p 的影響。

    選擇最優

    既然直接計算不太合適,需要重新設計一個算法。

    我發現,文字集中的地方是往往是文章主體,而前面的方法中,沒有考慮到這一點,只是機械地找出了最大的 p

    還有一點,網頁結構是個顆 DOM 樹[6]

    怎么用python實現精準搜索并提取網頁核心內容

    那么越靠近 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)
    • 定義了一個 find 函數,這是為了方便做遞歸,第一次調用的參數是 body 標簽,和前面一樣

    • 進入方法里,只找出該節點的直接孩子們,然后遍歷這些孩子

    • 判斷如果孩子是 p 節點,提取出其中的所有文字,包括子節點的,然后將文字的長度作為權值

    • 提取文字的地方比較繞,先取出直接的文本,和間接文本,合成 list,對每部分文本做了去除前后空字符,最后合并為一個字符串,得到了所包含的文本

    • 如果孩子節點不是 p,就遞歸調用 find 方法,而 find 方法返回的是 指定節點所包含的文本長度

    • 在獲取子節點的長度時,做了縮減處理,用以體現距離越遠,權值越低的規則

    • 最終通過 引用傳遞的 sel 參數,記錄權值最高的節點

    通過這樣改造之后,效果特別好。

    為什么呢?其實利用了密度原理,就是說越靠近中心的地方,密度越高,遠離中心的地方密度成倍的降低,這樣就能篩選出密度中心了。

    50% 的坡度比率是如何得到的呢?

    其實是通過實驗確定的,剛開始時我設置為 90%,但結果時 body 節點總是最優的,因為 body 里包含了所有的文字內容。

    反復實驗后,確定 50% 是比較好的值,如果在你的應用中不合適,可以做調整。

    感謝各位的閱讀,以上就是“怎么用python實現精準搜索并提取網頁核心內容”的內容了,經過本文的學習后,相信大家對怎么用python實現精準搜索并提取網頁核心內容這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    本溪市| 柯坪县| 自贡市| 常州市| 苍梧县| 噶尔县| 九龙坡区| 龙川县| 铜鼓县| 绥中县| 宝清县| 宣城市| 谢通门县| 和龙市| 松溪县| 道真| 鹤峰县| 井研县| 墨竹工卡县| 安义县| 桃园市| 峨眉山市| 二连浩特市| 丰县| 文水县| 新巴尔虎右旗| 临朐县| 成安县| 融水| 上林县| 鹤壁市| 章丘市| 奎屯市| 揭东县| 辽中县| 北碚区| 泰兴市| 普兰县| 灌云县| 井冈山市| 龙里县|