Python html.parser庫學習小結

來源:互聯網
上載者:User

標籤:

分類路徑:/Datazen/DataMining/Crawler/ 前段時間,一朋友讓我做個小指令碼,抓一下某C2C商城上競爭者的銷售/價格資料,好讓他可以即時調整自己的營銷策略。自己之前也有過寫爬蟲抓某寶資料的經曆,實現的問題不大,於是就答應了。初步想法是利用pyhton中的urllib.request和re兩個lib(本文樣本用的是Pyhton 3.4 ,2.x的請自行切換),外加上其他的統計分析功能的話,最多兩個晚上(白天要工作)可以搞定。實際上做的過程中,遇到了兩個主要困難:(1)電商網站對於交易資料的保護很好。小爬蟲動不動就會被ban掉或者採用一些其他的保護措施使得其無法正常採集所需的資料,需要添加額外的代碼處理各種虐心的情況;(2)Regex實在是難寫,而且很複雜和很難維護。於是自己也思考有沒有其他的解決方案——本文就是對其中一解決方案的初步介紹。 一開始想到的當然是著名的第三方庫Beautifulsoup(作為一個廣東男人,我習慣把它稱為”靚湯“)。這個庫很強大,但正因為它強大,需要一點學習時間而我需要快點上手,於是只好日後再學(到時再寫一篇Beautifulsoup學習總結)。權衡以後,最後目光轉向了Python Standard Library中的html.parser。 html.parser是一個非常簡單和實用的庫,它的核心是HTMLParser類。從源碼來看,它內部封裝了一系列regular expression。工作的流程是:當你feed給它一個類似HTML格式的字串時,它會調用goahead方法向前迭代各個標籤,並調用對應的parse_xxxx方法提取start_tag, tag, attrs data comment和end_tag等等標籤資訊和資料,然後調用對應的方法對這些抽取出來的內容進行處理。整個HTMLParser的大致結構如所示:   可以發現,處理開始標籤(handle_starttag)、結束標籤(handle_endtag)和處理資料(handle_data)等處理函數在HTMLParser裡是沒有實現的(pass),這需要我們繼承HTMLParser這個類的並覆蓋這些方法。詳細可以參閱python文檔,這裡重點介紹幾個常用的方法: 
  1. feed(data):主要用於接受帶html標籤的str,當調用這個方法時並提供相應的data時,整個執行個體(instance)開始執行,結束執行close()。
  2. handle_starttag(tag, attrs): 這個方法接收Parse_starttag返回的tag和attrs,並進行處理,處理方式通常由使用者進行覆蓋,本身為空白。例如,串連的start tag是<a>,那麼對應的參數tag=’a’(小寫)。attrs是start tag <>中的屬性,以元組形式(name, value)返回(所有這些內容都是小寫)。例如,對於<A HREF="http://www.baidu.com“>,那麼內部調用形式為:handle_starttag(’a’,[(‘href’,’http://www.baidu.com)]).
  3. handle_endtag(tag):跟上述一樣,只是處理的是結束標籤,也就是以</開頭的標籤。
  4. handle_data(data):處理的是網頁的資料,也就是開始標籤和結束標籤之間的內容。例如:<script>...</script>的省略符號內容
  5. reset():將執行個體重設,包括作為參數輸入的資料進行清空。
 舉個例子吧。例如我們有以下一堆帶HTML標籤的資料,<h3 class="tb-main-title" data-title="【金冠現貨/全色/頂配版】Xiaomi/小米 小米note移動聯通4G手機">     【金冠現貨/全色/頂配版】Xiaomi/小米 小米note移動聯通4G手機
   </h3>
   <p class="tb-subtitle">
 【購機即送布丁套+高清貼膜+線控耳機+剪卡器+電影支架等等,套餐更多豪禮更優惠】    【購機即送布丁套+高清貼膜+線控耳機+剪卡器+電影支架等等,套餐更多豪禮更優惠】    【金冠信譽+順豐包郵+全國聯保---多重保障】
 </p>
   <div id="J_TEditItem" class="tb-editor-menu"></div> </div><h3 class="tb-main-title" data-title="【現貨增強/標準】MIUI/小米 紅米手機2紅米2移動聯通電信4G雙卡">
     【現貨增強/標準】MIUI/小米 紅米手機2紅米2移動聯通電信4G雙卡
   </h3>
   <p class="tb-subtitle">
 [紅米手機2代顏色版本較多,請親們閱讀購買說明按需選購---感謝光臨] 【金皇冠信譽小米手機集市銷量第一】【購買套餐送高清鋼化膜+線控通話耳機+ 剪卡器(含還原卡托)+ 防輻射貼+專用高清貼膜+ 擦機布+ 耳機繞線器+手機電影支架+ 一年延保服務+ 預設享受順豐包郵 !
 </p>
   <div id="J_TEditItem" class="tb-editor-menu"></div> </div>很明顯,這裡麵包含了兩台手機,我們的目標是提取兩個手機的名字出來。 由於當我們feed這個html到HTMLParser中後,他們所有的標籤都迭代,如果需要它只提取我們需要的資料時,我們需要設定當handle_starttag遇到那個標籤和屬性時,才調用handle_data並print出我們的結果,這個時候我們可以使用一個flg作為判定,代碼如下: 
#定義一個MyParser繼承自HTMLParserclass MyParser(HTMLParser):    re=[]#放置結果    flg=0#標誌,用以標記是否找到我們需要的標籤    def handle_starttag(self, tag, attrs):        if tag==‘h3‘:#目標標籤            for attr in attrs:                if attr[0]==‘class‘ and attr[1]==‘tb-main-title‘:#目標標籤具有的屬性                    self.flg=1#符合條件則將標誌設定為1                    break        else:            pass     def handle_data(self, data):        if self.flg==1:            self.re.append(data.strip())#如果標誌為我們需要的標誌,則將資料添加到列表中            self.flg=0#重設標誌,進行下次迭代        else:            passmy=MyParser()my.feed(html)
 運行結果如下,達到了我們的預期: 上面只是HTMLParser一個非常簡單的應用,但卻可以反應了HTMLParser這個類的一些特質。有了這些基本的認識後,我們就可以將相關功能進行擴充,從而形成一個標準的爬蟲了。下次,我們將利用相關的知識,構建一個基本的網路爬蟲,敬請期待哦。 --------------------------------------------------本文為作者原創文章,轉摘請註明出處:@Datazen

Python html.parser庫學習小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.