1. 项目背景
python 即时网络爬虫项目启动说明中我们讨论一个数字:程序员浪费在调测内容提取规则上的时间,从而我们发起了这个项目,把程序员从繁琐的调测规则中解放出来,投入到更高端的数据处理工作中。

2. 解决方案
为了解决这个问题,我们把影响通用性和工作效率的提取器隔离出来,描述了如下的数据处理流程图:
extactor.png

图中“可插拔提取器”必须很强的模块化,那么关键的接口有:
  • 标准化的输入:以标准的HTML DOM对象为输入
  • 标准化的内容提取:使用标准的xslt模板提取网页内容
  • 标准化的输出:以标准的XML格式输出从网页上提取到的内容
  • 明确的提取器插拔接口:提取器是一个明确定义的类,通过类方法与爬虫引擎模块交互

3. 提取器代码
可插拔提取器是即时网络爬虫项目的核心组件,定义成一个类: GsExtractor
       适用python3的源代码文件及其说明文档请从 github 下载

使用模式是这样的:
  • 实例化一个GsExtractor对象
  • 为这个对象设定xslt提取器,相当于把这个对象配置好(使用三类setXXX()方法)
  • 把html dom输入给它,就能获得xml输出(使用extract()方法)
下面是这个GsExtractor类的源代码(适用于Python3)
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # 模块名: gooseeker
  4. # 类名: GsExtractor
  5. # Version: 2.0
  6. # 适配Python版本: Python3
  7. # 说明: html内容提取器
  8. # 功能: 使用xslt作为模板,快速提取HTML DOM中的内容。
  9. # released by 集搜客(http://www.gooseeker.com) on May 18, 2016
  10. # github: https://github.com/FullerHua/jisou/core/gooseeker.py

  11. from urllib import request
  12. from urllib.parse import quote
  13. from lxml import etree
  14. import time

  15. class GsExtractor(object):
  16.     def _init_(self):
  17.         self.xslt = ""
  18.     # 从文件读取xslt
  19.     def setXsltFromFile(self , xsltFilePath):
  20.         file = open(xsltFilePath , 'r' , encoding='UTF-8')
  21.         try:
  22.             self.xslt = file.read()
  23.         finally:
  24.             file.close()
  25.     # 从字符串获得xslt
  26.     def setXsltFromMem(self , xsltStr):
  27.         self.xslt = xsltStr
  28.     # 通过GooSeeker API接口获得xslt
  29.     def setXsltFromAPI(self , APIKey , theme, middle=None, bname=None):
  30.         apiurl = "http://www.gooseeker.com/api/getextractor?key="+ APIKey +"&theme="+quote(theme)
  31.         if (middle):
  32.             apiurl = apiurl + "&middle="+quote(middle)
  33.         if (bname):
  34.             apiurl = apiurl + "&bname="+quote(bname)
  35.         apiconn = request.urlopen(apiurl)
  36.         self.xslt = apiconn.read()
  37.     # 返回当前xslt
  38.     def getXslt(self):
  39.         return self.xslt
  40.     # 提取方法,入参是一个HTML DOM对象,返回是提取结果
  41.     def extract(self , html):
  42.         xslt_root = etree.XML(self.xslt)
  43.         transform = etree.XSLT(xslt_root)
  44.         result_tree = transform(html)
  45.         return result_tree
复制代码


4. 用法示例
下面是一个示例程序,演示怎样使用GsExtractor类提取GooSeeker官网的bbs帖子列表。本示例有如下特征:
  • 提取器所用的xslt模板提前放在文件中:xslt_bbs.xml
  • 仅作为示例,实际使用场景中,xslt来源有多个,最主流的来源是GooSeeker平台上的api
  • 在控制台界面上打印出提取结果

下面是源代码,都可从 github 下载
  1. #-*_coding:utf8-*-
  2. # 使用GsExtractor类的示例程序
  3. # 访问集搜客论坛,以xslt为模板提取论坛内容
  4. # xslt保存在xslt_bbs.xml中
  5. from urllib import request
  6. from lxml import etree
  7. from gooseeker import GsExtractor

  8. # 访问并读取网页内容
  9. url = "http://www.gooseeker.com/cn/forum/7"
  10. conn = request.urlopen(url)
  11. doc = etree.HTML(conn.read())

  12. bbsExtra = GsExtractor()    # 生成xsltExtractor对象
  13. bbsExtra.setXsltFromFile("xslt_bbs.xml")    # 调用set方法设置xslt内容
  14. result = bbsExtra.extract(doc)    # 调用extract方法提取所需内容

  15. print(str(result))
复制代码
xslt_bbs.zip (662 Bytes, 下载次数: 360)
举报 使用道具
| 回复

共 27 个关于本帖的回复 最后回复于 2018-4-26 22:54

Fuller 管理员 发表于 2016-5-19 19:06:50 | 显示全部楼层
一个问题:
1,这个etree生成的transform对象,就能用html文本文档做输入又能用DOM对象做数据?

两个建议:
1,open(xsltFilePath,'r',encoding='UTF-8')  逗号之后加上空格,便于阅读
2,给出一个用法程序,方便大家理解
举报 使用道具
Fuller 管理员 发表于 2016-5-19 20:52:35 | 显示全部楼层
另外,setXslt(self,xsltFilePath)只是其中一种抓取规则源——磁盘文件。建议在命名上给其它源预留好。比如,
1,从内存中来的抓取规则
2,直接从GooSeeker会员中心来的抓取规则
等等
举报 使用道具
shenzhenwan10 金牌会员 发表于 2016-5-19 22:37:57 | 显示全部楼层
setXslt目前规划了3个:1.从文件来 2.从内存对象来 3.从API来
我修改一下类定义
举报 使用道具
shenzhenwan10 金牌会员 发表于 2016-5-19 22:40:44 | 显示全部楼层
Fuller 发表于 2016-5-19 19:06
一个问题:
1,这个etree生成的transform对象,就能用html文本文档做输入又能用DOM对象做数据?

应该是HTML DOM
我会给出用法程序
举报 使用道具
shenzhenwan10 金牌会员 发表于 2016-5-20 12:04:28 | 显示全部楼层
完善了类的定义,贴出了一个测试过的示例程序
举报 使用道具
shenzhenwan10 金牌会员 发表于 2016-5-26 17:36:11 | 显示全部楼层
更新了提取器类gsExtractor的定义,实现了从GooSeeker API获取xslt的方法
举报 使用道具
Fuller 管理员 发表于 2016-5-26 18:18:50 | 显示全部楼层
shenzhenwan10 发表于 2016-5-26 17:36
更新了提取器类gsExtractor的定义,实现了从GooSeeker API获取xslt的方法

从api获取抓取规则的话,现在这个实现,不知道python用的是同步方式还是异步方式?
举报 使用道具
Fuller 管理员 发表于 2016-5-29 16:12:30 | 显示全部楼层
extract()方法输出的是xml字符串还是xml DOM?这个没有说清楚。加上Python这种没有类型的编程语言,容易懵圈
举报 使用道具
Fuller 管理员 发表于 2016-5-29 16:25:38 | 显示全部楼层
简书上有篇介绍Scrapy的文章《Scrapy爬虫学习记录》,先运行
  1. scrapy startproject xxxx
复制代码
生成一个爬虫,就把程序架子搭起来了,然后自己用python代码补充进去,比如parse部分和pipeline的处理部分等等。这个思想挺好的。我们是否也能融入这个框架,或者做一个类似框架?
举报 使用道具
您需要登录后才可以回帖 登录 | 立即注册

精彩推荐

  • Gephi社会网络分析-马蜂窝游记文本分词并同
  • Gephi社会网络分析-基于马蜂窝游记文本以词
  • 知乎话题文本根据词语间距筛选后生成共词矩
  • 马蜂窝游记文本分词后以词语间距为筛选条件
  • 学习使用apriori算法挖掘关联关系

热门用户

GMT+8, 2024-3-29 18:32