在進行網頁抓取的時候,分析定位html節點是獲取抓取信息的關鍵,目前我用的是lxml模塊(用來分析XML文檔結構的,當然也能分析html結構), 利用其lxml.html的xpath對html進行分析,獲取抓取信息。
首先,我們需要安裝一個支持xpath的python庫。目前在libxml2的網站上被推薦的python binding是lxml,也有beautifulsoup,不嫌麻煩的話還可以自己用正則表達式去構建,本文以lxml為例講解。
假設有如下的HTML文檔:
<html> <body> <form> <div id='leftmenu'> <h3>text</h3> <ul id='china'><!-- first location --> <li>...</li> <li>...</li> ...... </ul> <ul id='england'><!-- second location--> <li>...</li> <li>...</li> ...... </ul> </div> </form> </body></html>
直接使用lxml處理:
import codecs from lxml import etree f=codecs.open("ceshi.html","r","utf-8") content=f.read() f.close() tree=etree.HTML(content)etree提供了HTML這個解析函數,現在我們可以直接對HTML使用xpath了,是不是有點小激動,現在就嘗試下吧。
在使用xpath之前我們先來看看作為對照的jQuery和RE。
在jQuery里要處理這種東西就很簡單,特別是假如那個ul節點有id的話(比如是<ul id='china'>):
$("#china").each(function(){...});具體到此處是:
代碼如下:$("#leftmenu").children("h3:contains('text')").next("ul").each(function(){...});
找到id為leftmenu的節點,在其下找到一個內容包含為”text”的h3節點,再取其接下來的一個ul節點。
在python里要是用RE來處理就略麻煩一些:
block_pattern=re.compile(u"<h3>檔案</h3>(.*?)<h3>", re.I | re.S)m=block_pattern.findall(content)item_pattern=re.compile(u"<li>(.*?)</li>", re.I | re.S)items=item_pattern.findall(m[0])for i in items: print i
那么用xpath要怎么做呢?其實跟jQuery是差不多的:
nodes=tree.xpath("/descendant::ul[@id='china']")當然,現在沒有id的話也就只能用類似于jQuery的方法了。完整的xpath應該是這樣寫的(注意,原文件中的TAG有大小寫的情況,但是在XPATH里只能用小寫):
代碼如下:nodes=tree.xpath(u"/html/body/form/div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")
更簡單的方法就是像jQuery那樣直接根據id定位:
nodes=tree.xpath(u"http://div[@id='leftmenu']/h3[text()='text']/following-sibling::ul[1]")
這兩種方法返回的結果中,nodes[0]就是那個“text”的h3節點后面緊跟的第一個ul節點,這樣就可以列出后面所有的ul節點內容了。
新聞熱點
疑難解答