Python使用xslt提取網頁數據

圖片描述

1,引言

Python網絡爬蟲內容提取器一文咱們詳細講解了核心部件:可插拔的內容提取器類gsExtractor。本文記錄了肯定gsExtractor的技術路線過程當中所作的編程實驗。這是第一部分,實驗了用xslt方式一次性提取靜態網頁內容並轉換成xml格式。javascript

2,用lxml庫實現網頁內容提取

lxml是python的一個庫,能夠迅速、靈活地處理 XML。它支持 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),而且實現了常見的 ElementTree API。html

這2天測試了在python中經過xslt來提取網頁內容,記錄以下:java

2.1,抓取目標

假設要提取集搜客官網舊版論壇的帖子標題和回覆數,以下圖,要把整個列表提取出來,存成xml格式python

圖片描述

2.2,源代碼1:只抓當前頁,結果顯示在控制檯

Python的優點是用不多量代碼就能解決一個問題,請注意下面的代碼看起來很長,其實python函數調用沒有幾個,大篇幅被一個xslt腳本佔去了,在這段代碼中,只是一個好長的字符串而已,至於爲何選擇xslt,而不是離散的xpath或者讓人撓頭的正則表達式,請參看《Python即時網絡爬蟲項目啓動說明》,咱們指望經過這個架構,把程序員的時間節省下來一大半。git

能夠拷貝運行下面的代碼(在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="//*[@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="//*[@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,抓取結果

獲得的抓取結果以下圖:
圖片描述github

2.4,源代碼2:翻頁抓取,結果存入文件

咱們對2.2的代碼再作進一步修改,增長翻頁抓取和存結果文件功能,代碼以下:正則表達式

from urllib import request
from lxml import etree
import time

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="//*[@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="//*[@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 = 1
while (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配合的具體方法。segmentfault

4,接下來閱讀

本文介紹的方法一般用來抓取靜態網頁內容,也就是所謂的html文檔中的內容,目前不少網站內容是用javascript動態生成的,一開始html是沒有這些內容的,經過後加載方式添加進來,那麼就須要採用動態技術,請閱讀《Python爬蟲使用Selenium+PhantomJS抓取Ajax和動態HTML內容》

5,集搜客GooSeeker開源代碼下載源

1.GooSeeker開源Python網絡爬蟲GitHub源

6,文檔修改歷史

2016-05-26:V2.0,增補文字說明;把跟帖的代碼補充了進來2016-05-29:V2.1,增長最後一章源代碼下載源

相關文章
相關標籤/搜索