python使用xslt提取网页数据的方法


Posted in Python onFebruary 23, 2018

1、引言

在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格式

 python使用xslt提取网页数据的方法

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="//*[@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)

源代码请通过本文结尾的GitHub源下载。

2.3、抓取结果

得到的抓取结果如下图:

 python使用xslt提取网页数据的方法

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开源代码下载源

1.GooSeeker开源Python网络爬虫GitHub源

6、文档修改历史

2016-05-26:V2.0,增补文字说明;把跟帖的代码补充了进来

2016-05-29:V2.1,增加最后一章源代码下载源

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的文件和目录操作实现代码
Mar 13 Python
用Python制作简单的钢琴程序的教程
Apr 01 Python
json跨域调用python的方法详解
Jan 11 Python
python实现csv格式文件转为asc格式文件的方法
Mar 23 Python
python matlibplot绘制多条曲线图
Feb 19 Python
基于python指定包的安装路径方法
Oct 27 Python
在pycharm中python切换解释器失败的解决方法
Oct 29 Python
Python常见数字运算操作实例小结
Mar 22 Python
使用python制作一个解压缩软件
Nov 13 Python
pytorch实现mnist分类的示例讲解
Jan 10 Python
Python中tkinter的用户登录管理的实现
Apr 22 Python
对Keras自带Loss Function的深入研究
May 25 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
Feb 23 #Python
python爬虫获取多页天涯帖子
Feb 23 #Python
Python即时网络爬虫项目启动说明详解
Feb 23 #Python
Python爬豆瓣电影实例
Feb 23 #Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
Feb 23 #Python
Python各类图像库的图片读写方式总结(推荐)
Feb 23 #Python
python自动发邮件库yagmail的示例代码
Feb 23 #Python
You might like
乐信RP2100的电路分析和打磨
2021/03/02 无线电
phpMyadmin 用户权限中英对照
2010/04/02 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
PHP实现电商订单自动确认收货redis队列
2017/05/17 PHP
php实现构建排除当前元素的乘积数组方法
2018/10/06 PHP
PHP如何开启Opcache功能提升程序处理效率
2020/04/27 PHP
JavaScript语句可以不以;结尾的烦恼
2007/03/08 Javascript
javascript中的几个运算符
2007/06/29 Javascript
基于jquery的图片懒加载js
2010/06/30 Javascript
javascript闭包传参和事件的循环绑定示例探讨
2014/04/17 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
2014/09/04 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
javascript事件冒泡和事件捕获详解
2015/05/26 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
Node.js实现文件上传
2016/07/05 Javascript
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
2017/11/20 Javascript
JavaScript如何借用构造函数继承
2019/11/06 Javascript
[38:30]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场2
2014/05/24 DOTA
[01:01:36]Optic vs paiN 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
[46:23]完美世界DOTA2联赛PWL S2 FTD vs Magma 第一场 11.20
2020/11/23 DOTA
Python标准库urllib2的一些使用细节总结
2015/03/16 Python
详解Python中的join()函数的用法
2015/04/07 Python
python友情链接检查方法
2015/07/08 Python
Python win32com 操作Exce的l简单方法(必看)
2017/05/25 Python
python for循环输入一个矩阵的实例
2018/11/14 Python
详解python实现小波变换的一个简单例子
2019/07/18 Python
django+tornado实现实时查看远程日志的方法
2019/08/12 Python
Pycharm打开已有项目配置python环境的方法
2020/07/03 Python
加拿大时尚少女服装品牌:Garage
2016/10/10 全球购物
美国网上眼镜供应商:LEOTONY(眼镜、RX太阳镜和太阳镜)
2017/10/31 全球购物
Unix里面如何在后台运行程序
2016/10/14 面试题
超市业务员岗位职责
2013/12/05 职场文书
综合测评自我评价
2015/03/06 职场文书
公司行政管理制度范本
2015/08/05 职场文书