Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
,引言
在Python網絡爬蟲內容提取器一文我們詳細講解了核心部件:可插拔的內容提取器類gsExtractor。本文記錄了確定gsExtractor的技術路線過程中所做的編程實驗。這是第一部分,實驗了用xslt方式一次性提取靜態網頁內容并轉換成xml格式。
2,用lxml庫實現網頁內容提取
lxml是python的一個庫,可以迅速、靈活地處理 XML。它支持 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),并且實現了常見的 ElementTree API。
這2天測試了在python中通過xslt來提取網頁內容,記錄如下:
2.1,抓取目標
假設要提取集搜客官網舊版論壇的帖子標題和回復數,如下圖,要把整個列表提取出來,存成xml格式
2.2,源代碼1:只抓當前頁,結果顯示在控制臺
Python的優勢是用很少量代碼就能解決一個問題,請注意下面的代碼看起來很長,其實python函數調用沒有幾個,大篇幅被一個xslt腳本占去了,在這段代碼中,只是一個好長的字符串而已,至于為什么選擇xslt,而不是離散的xpath或者讓人撓頭的正則表達式,請參看《Python即時網絡爬蟲項目啟動說明》,我們期望通過這個架構,把程序員的時間節省下來一大半。
可以拷貝運行下面的代碼(在windows10, python3.2下測試通過):
from urllib import request from lxml import etree url="http://www.gooseeker.com/cn/forum/7"conn=request.urlopen(url) doc=etree.HTML(conn.read()) xslt_root=etree.XML("""\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template match="/"> <列表> <xsl:apply-templates select="http://*[@id='forum' and count(./table/tbody/tr[position()>=1 and count(.//*[@class='topic']/a/text())>0])>0]" mode="列表"/> </列表> </xsl:template> <xsl:template match="table/tbody/tr[position()>=1]" mode="list"> <item> <標題> <xsl:value-of select="*//*[@class='topic']/a/text()"/> <xsl:value-of select="*[@class='topic']/a/text()"/> <xsl:if test="@class='topic'"> <xsl:value-of select="a/text()"/> </xsl:if> </標題> <回復數> <xsl:value-of select="*//*[@class='replies']/text()"/> <xsl:value-of select="*[@class='replies']/text()"/> <xsl:if test="@class='replies'"> <xsl:value-of select="text()"/> </xsl:if> </回復數> </item> </xsl:template> <xsl:template match="http://*[@id='forum' and count(./table/tbody/tr[position()>=1 and count(.//*[@class='topic']/a/text())>0])>0]" mode="列表"> <item> <list> <xsl:apply-templates select="table/tbody/tr[position()>=1]" mode="list"/> </list> </item> </xsl:template> </xsl:stylesheet>""") transform=etree.XSLT(xslt_root) result_tree=transform(doc)print(result_tree)
2.3,抓取結果
得到的抓取結果如下圖:
2.4,源代碼2:翻頁抓取,結果存入文件
我們對2.2的代碼再做進一步修改,增加翻頁抓取和存結果文件功能,代碼如下:
from urllib import request from lxml import etree import timexslt_root=etree.XML("""\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template match="/"> <列表> <xsl:apply-templates select="http://*[@id='forum' and count(./table/tbody/tr[position()>=1 and count(.//*[@class='topic']/a/text())>0])>0]" mode="列表"/> </列表> </xsl:template> <xsl:template match="table/tbody/tr[position()>=1]" mode="list"> <item> <標題> <xsl:value-of select="*//*[@class='topic']/a/text()"/> <xsl:value-of select="*[@class='topic']/a/text()"/> <xsl:if test="@class='topic'"> <xsl:value-of select="a/text()"/> </xsl:if> </標題> <回復數> <xsl:value-of select="*//*[@class='replies']/text()"/> <xsl:value-of select="*[@class='replies']/text()"/> <xsl:if test="@class='replies'"> <xsl:value-of select="text()"/> </xsl:if> </回復數> </item> </xsl:template> <xsl:template match="http://*[@id='forum' and count(./table/tbody/tr[position()>=1 and count(.//*[@class='topic']/a/text())>0])>0]" mode="列表"> <item> <list> <xsl:apply-templates select="table/tbody/tr[position()>=1]" mode="list"/> </list> </item> </xsl:template> </xsl:stylesheet>""") baseurl="http://www.gooseeker.com/cn/forum/7"basefilebegin="jsk_bbs_"basefileend=".xml"count=1while (count < 12): url=baseurl + "?page=" + str(count) conn=request.urlopen(url) doc=etree.HTML(conn.read()) transform=etree.XSLT(xslt_root) result_tree=transform(doc) print(str(result_tree)) file_obj=open(basefilebegin+str(count)+basefileend,'w',encoding='UTF-8') file_obj.write(str(result_tree)) file_obj.close() count +=1 time.sleep(2)
我們增加了寫文件的代碼,還增加了一個循環,構造每個翻頁的網址,但是,如果翻頁過程中網址總是不變怎么辦?其實這就是動態網頁內容,下面會討論這個問題。
3,總結
這是開源Python通用爬蟲項目的驗證過程,在一個爬蟲框架里面,其它部分都容易做成通用的,就是網頁內容提取和轉換成結構化的操作難于通用,我們稱之為提取器。但是,借助GooSeeker可視化提取規則生成器MS謀數臺 ,提取器的生成過程將變得很便捷,而且可以標準化插入,從而實現通用爬蟲,在后續的文章中會專門講解MS謀數臺與Python配合的具體方法。
好了,以上就是小編給大家帶來的全部內容,轉發此文+關注 并私信小編“資料”即可免費領取2019最新python資料和零基礎入門教程,不定期分享干貨,歡迎初學和進階中的小伙伴!
過使用 XSLT,您可以把 XML 文檔轉換成 HTML 格式。
使用 XSLT 顯示 XML
XSLT 是首選的 XML 樣式表語言。
XSLT(eXtensible Stylesheet Language Transformations)遠比 CSS 更加完善。
XSLT 是在瀏覽器顯示 XML 文件之前,先把它轉換為 HTML:
使用 XSLT 顯示 XML
如果您想要學習有關 XSLT 的知識,請在我們的首頁查找 XSLT 教程。
在服務器上通過 XSLT 轉換 XML
在上面的實例中,當瀏覽器讀取 XML 文件時,XSLT 轉換是由瀏覽器完成的。
在使用 XSLT 來轉換 XML 時,不同的瀏覽器可能會產生不同結果。為了減少這種問題,可以在服務器上進行 XSLT 轉換。
1、"XML+XSLT"技術在J2EE技術平臺中的應用
Java語言及相關的應用技術的產生解決了跨平臺的軟件應用系統的開發,但沒有解決如何實現跨平臺的數據交換問題。在傳統的軟件應用系統中,為了能夠實現在不同的系統平臺之間交換數據、同時還要保證數據的完整性,是相對比較麻煩的一件事情。
基于此應用的目的和要求,誕生了XML(eXtensible Markup Language,可擴展標記語言)技術。應用XML語言可以實現軟件應用系統中的"內容"與"表現"相互分離,并且XML還是一種可擴展的標簽語言。
如下示例圖中的代碼為一個定義學生信息的XML格式文檔示例,讀者從此示例中可以了解到XML格式文檔只定義數據內容(或者應用系統處理的最終結果),而這些數據或者結果最終在什么終端設備顯示、以及以什么風格顯示都沒有定義。
基于XML語言及應用技術的XSLT(Extensible Stylesheet Language Transformations,擴展樣式表轉換語言)的主要作用是將XML由一種格式轉換為另一種格式(當然,也可以為其它格式,如HTML網頁,純文字等),而在J2EE Web應用系統的開發實現中,應用XSLT技術能夠實現將XML格式的源文檔通過轉換引擎并按照XSL(eXtensible Stylesheet Lanaguage,擴展樣式表語言)模板的格式最終轉換輸出目標HTML格式的文檔。
如下示例圖中的代碼為某個XSLT文檔文件的內容,其中包含有<xsl:stylesheet>、<xsl:template>等標簽,同時在<xsl:template></xsl:template>標簽內包含有一個完整的HTML文件所應該具有的標簽。這些標簽都起什么作用?源XML文檔最終在瀏覽器中的顯示結果如何?
由于XSLT文檔文件本身也是一個 XML格式的文檔,因此它也總是由如下的XML聲明語句起始:<?xml version="1.0" encoding="gb2312"?>
但由于本文章的篇幅有限,讀者如果需要詳細了解和學習XML、XSLT和XHTML等相關的語法、技術和應用等,可以參考作者的《J2EE Web核心技術——XHTML與XML應用開發》一書中相關章節內容。
讀者也許還會有許多的疑問,比如為什么要多此一舉?請讀者保持耐心,繼續往下閱讀。
2、XSL技術概述及在J2EE系統平臺中的應用
(1)XSL是什么
XSL就是可擴展樣式表語言(eXtensible Stylesheet Lanaguage),XSL是參考SGML(Standard Generalized Markup Language,標準通用標記語言)中的DSSSL(Document Style Semanticsand Specification Language,文檔樣式語義和規范語言,它主要是用來設置SGML的表現樣式)而設計的。
(2)為什么要提供XSL技術
盡管"CSS+Div"能夠為Web應用系統的頁面開發人員分離Web頁面中的結構和風格,從而實現分離Web頁面中的數據和表現。但如果其中的數據是采用XML格式表示,此時如果再繼續采用CSS層疊樣式表技術來為該XML格式文檔數據設置表現樣式,由于CSS層疊樣式表采用的是與XML完全不同的一套語法規則定義,無法使用相同的XML解析器進行處理和解析,這為軟件應用系統項目開發帶來了許多額外的負擔。
最初設計XSL的主要目的就是希望采用XML格式的語法規則提供一種為XML文檔設置表現樣式的新方法。而CSS的主要問題是由于沒有邏輯控制的能力——CSS不能重新排序文檔中的元素、也不能判斷和控制哪個元素被顯示、哪個不被顯示、當然也不能統計計算元素中的數據等功能要求。
因此CSS層疊樣式表技術一般只適合用于輸出固定內容的最終Web頁面文檔,但CSS層疊樣式表技術的主要優點是簡潔、消耗系統資源少;而XSLT雖然功能強大,但因為要重新索引XML結構樹,所以消耗系統內存量比較多。
在企業級的軟件應用系統開發中,一般常常將CSS和XSLT兩者相互結合使用。比如在Web服務器端用XSLT處理相關的文檔,而在客戶端則用CSS層疊樣式表技術來控制數據在瀏覽器端的最終顯示風格,這樣的設計方案能夠大大地減少響應時間。
3、XSL技術主要包括兩個組成部分
XSL技術主要包括兩個組成部分:XSLT(eXtensible Stylesheet Language Transformation)和XSL-FO(XSL Formatting Object)。
其中的XSLT主要是實現轉換XML格式的文檔,而XSL-FO主要是格式化XML文檔。其中XSL-FO的作用就類似CSS層疊樣式表技術在HTML頁面中的作用,但作者在本文中重點為讀者介紹XSLT相關的技術及應用。
因此,XSL從本質上可以看著為是一種可以將XML轉化成其它類型語言的語言、一種可以過濾和選擇XML數據的語言、一種能夠格式化XML數據的語言。
4、XSLT主要是面向轉換類型的應用
XSLT的主要作用是將XML文檔數據內容由一種格式轉換為另一種格式——比如,將XML格式的文檔轉換為HTML/XHTML(或者WML)等格式的文檔是目前XSLT應用最為廣泛的應用領域。
為什么要應用XSLT及相關的技術?因為XML格式的數據文檔能夠便于交換但不便于人類的閱讀和理解、特別是機器自動化地閱讀。因此如何能夠按照人類的要求顯示XML格式文檔中的數據?如何實現將同一個XML格式文檔中的數據在不同的顯示平臺中顯示輸出?
5、XSLT數據格式轉換的基本實現原理
數據格式轉換的重要思想是要把XML格式文檔視為一種樹形結構,轉換的過程其實就是從源XML格式文檔樹生成結果樹的過程。其中的XSL樣式單定義了源XML格式文檔樹和結果樹中對應部分的轉換規則,在每條規則中包含了一個模板,并對應著一種模式——模板定義了轉換的結果和轉換的基本規則,而模式則規定了需要進行轉換的元素或屬性對象。
6、XSLT數據格式轉換的實現過程
首先,將XML格式文檔轉換為DOM(Document Object Model,文檔對象模型)樹結構,這主要是利用XSLT來實現——XSLT處理器首先要做的是通過XML解析器(比如DOM或SAX)技術讀取XML格式文檔中的各個標簽和數據,并將XML樹狀結構重新整理和組合產生出一個臨時的樹狀結構,這個樹狀結構稱為XML文檔結果樹。
其次,再對轉換后的DOM樹進行格式化并轉換為其它的目標形式,這主要是利用XSL-FO來實現。XSL處理程序將這些數據轉換(也就是格式化過程)為另一種格式良好的XML文件(如:WML、HTML、VoiceXML等)。
目前在微軟IE瀏覽器中已經內嵌有實現這個轉換過程的XML處理器程序。歡迎讀者繼續閱讀作者的另一篇文章《軟件項目實訓及課程設計指導--應用XML+XSLT技術分離Web表示層數據和樣式示例》可以詳細學習和了解如何在軟件應用系統開發中應用XML+XSLT技術。
7、應用XSLT實現對XML格式文檔中的數據轉換和合并的應用示例
為了能夠讓讀者對"XML+XSLT"技術在企業級軟件應用系統開發中的應用有感性的認識,作者在下文中給出一個典型示例加以說明。
在下面示例中的XML格式文檔中的"學生信息"節點中有多個"班級"節點,可以通過XSLT中的<xsl:for-each>標簽把這些節點數據在一個表格單元格中顯示出來,從而產生出合并數據的應用效果。當然,也可以實現其它的應用效果,讀者可以自行實現。
(1)示例中所對應的XML格式文檔
該XML文檔文件名稱為student.xml,其中在<?xml-stylesheet?>標簽中通過href屬性指定對應的XSLT文件,該文件名稱為student.xsl。
<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="student.xsl" ?>
<軟件學院學生信息>
<學生信息 性別="男">
<姓名>張三</姓名>
<出生日期>1987/10/18</出生日期>
<專業>軟件工程</專業>
<班級 方向="J2EE軟件開發">軟件1班</班級>
<班級>9教東201</班級>
</學生信息>
<學生信息 性別="女">
<姓名>李四</姓名>
<出生日期>1988/2/18</出生日期>
<專業>軟件工程</專業>
<班級 方向="數字媒體方向">軟件2班</班級>
<班級>9教東202</班級>
</學生信息>
</軟件學院學生信息>
(2)示例中的XML文檔所對應的XSLT文檔(student.xsl) 文件
在student.xsl 文件中應用了XSL語言中的一些標簽,而XSLT文件中的標簽語法大致可分為如下的三種類型:
1)選擇模式,如<xsl:for-each>、<xsl:value-of>和 <xsl:apply-templates>等標簽,這些選擇模式的標簽語句將數據從XML文檔中提取出來,是一種簡單獲得數據的方法。在這些標簽中都有一個select屬性,選取XML文檔中特定的節點名的數據。
2)測試(識別)模式,如<xsl:if> 和<xsl:when>等標簽,類似于編程語言中的條件語句,主要是用于條件判斷和識別等用途。
3)匹配模式,如<xsl:template>標簽,它用于構建和定義一個模板。該標簽中的match 屬性主要是用于關聯 XML文檔中的標簽元素和轉換模板,但match 屬性的值是 XPath (XML Path Language,XML路徑語言)表達式(比如match="/" 則是定義整個XML格式文檔);位于<xsl:template> 標簽元素內部的內容則定義了寫到輸出結果的 HTML標簽代碼。
<?xml version="1.0" encoding="gb2312" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<head>
<title>XX交通大學軟件學院學生信息</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="軟件學院學生信息">
<h3>下面為XX交通大學軟件學院學生信息表</h3>
<table border="1">
<th>姓名</th>
<th>性別</th>
<th>出生日期</th>
<th>專業</th>
<th>班級</th>
<th>專業方向</th>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="學生信息">
<tr>
<td><xsl:value-of select="姓名"/></td>
<td><xsl:value-of select="@性別"/></td>
<td><xsl:value-of select="出生日期"/></td>
<td><xsl:value-of select="專業"/></td>
<td>
<xsl:for-each select="班級">
<xsl:value-of />
</xsl:for-each>
</td>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="班級">
<td><xsl:value-of select="@方向"/></td>
</xsl:template>
</xsl:stylesheet>
在student.xsl 文件中應用了<xsl:apply-templates> 標簽元素產生模板嵌套的應用效果,因為<xsl:apply-templates> 標簽元素可把一個模板應用于當前的標簽元素或者當前標簽元素的子節點中。
如果向 <xsl:apply-templates> 標簽元素添加一個 select 屬性,則此標簽元素就會僅僅處理與由其select 屬性所定義的XML標簽中屬性值相匹配的XML標簽元素,從而可以過濾XML標簽。
(3)本示例在Web瀏覽器中最終執行的結果
如何應用CSS+Div分離Web表示層數據處理邏輯和展現邏輯
如何應用策略設計模式分離JDBC數據庫連接中的外部環境信息
如何應用策略設計模式的思想設計通用的數據庫連接類
如何正確地創建和銷毀軟件應用系統中JDBC數據庫連接對象實例
如何應用觀察者設計模式重構系統中日志處理功能實現的程序代碼
*請認真填寫需求信息,我們會在24小時內與您取得聯系。