1,引言javascript
在Python网络爬虫内容提取器一文咱们详细讲解了核心部件:可插拔的内容提取器类gsExtractor。本文记录了肯定gsExtractor的技术路线过程当中所作的编程实验。这是第一部分,实验了用xslt方式一次性提取静态网页内容并转换成xml格式。html
2,用lxml库实现网页内容提取java
lxml是python的一个库,能够迅速、灵活地处理 XML。它支持 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),而且实现了常见的 ElementTree API。python
这2天测试了在python中经过xslt来提取网页内容,记录以下:git
2.1,抓取目标程序员
假设要提取集搜客官网旧版论坛的帖子标题和回复数,以下图,要把整个列表提取出来,存成xml格式 github
2.2,源代码1:只抓当前页,结果显示在控制台正则表达式
Python的优点是用不多量代码就能解决一个问题,请注意下面的代码看起来很长,其实python函数调用没有几个,大篇幅被一个xslt脚本占去了,在这段代码中,只是一个好长的字符串而已,至于为何选择xslt,而不是离散的xpath或者让人挠头的正则表达式,请参看《Python即时网络爬虫项目启动说明》,咱们指望经过这个架构,把程序员的时间节省下来一大半。编程
能够拷贝运行下面的代码(在windows10, python3.2下测试经过):windows
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,抓取结果
获得的抓取结果以下图:
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配合的具体方法。
4,接下来阅读
本文介绍的方法一般用来抓取静态网页内容,也就是所谓的html文档中的内容,目前不少网站内容是用javascript动态生成的,一开始html是没有这些内容的,经过后加载方式添加进来,那么就须要采用动态技术,请阅读《Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容》。
5,集搜客GooSeeker开源代码下载源
6,文档修改历史