Skip to content

网页(请求)解析组件

请求解析组件通常需要使用者自己提供的(或者也可能是使用者唯一需要定义的组件), spydy只提供了一个DmozParser来获取dmoz网站的部分数据用以测试, 具体参考快速开始。不过spydy还是提供了部分组件来简化繁琐的网页解析工作, 比如:

XpathParser

基于使用者提供的xpath规则, 来解析网络请求对象的结果。只要使用者的自定义类继承了XpathParser, 那么只要在自定义类中写入值为xpath规则的类属性, XpathParser就会解析相应内容, 以DmozParser为例, 它是通过如下方式定义的:

class DmozParser(XpathParser):
    editors = "//div[@class='editors']/h3/text()[1]"
    categories = "//div[@class='categories']/h3/text()[1]"
    sites = "//div[@class='sites']/h3/text()[1]"
    languages = "//div[@class='languages']/h3/text()[1]"


后续, XpathParser就会把类的属性名作为输出结果(字典格式)的键, 类的属性值对应的xpath规则匹配出来的值作为输出结果的值。

CssParser

XpathParser, 当使用者的自定义类中继承了CssParser, 那么只要在自定义类中写入值为csss选择器规则的类属性, CssParser就会自动解析目标内容。

自定义parser

这里的自定义parser是指不继承上诉的XpathParser或者CssParser而完全由用户定义的解析组件。 有时候, 网页解析的逻辑会变的很复杂, 比如需要进行一些条件判断,类似当a出现的时候b的值是什么, 或者a的值是b和c的结合。虽然spydy的推荐的做法通常是, 继承spydy的XpathParser或者CssParser, 然后在filters这一步去进行更进一步的操作(spydy.filters.CommonFilter提供了非常便利的方法)。 比如前面提到的条件判断, 值的清洗之类。
但有时你可能想直接操作response对象(比如交互解析, 类似scrapy的shell功能, 则可以选择在自定义组件中打一个断点),或者你想返回的结果并不是字典,比如是字典的列表, 那么就需要来自己定义一个parser。

下面是一个用来演示的自定义parser:

from spydy.parsers import Parser
from requests_html import HTML

class Myparser(Parser): # 继承抽象积累Parser
    def __init__(self):  # any parameters you want to set
        pass

    def parse(self, response):  # must define
        html = HTML(html=response.text)

        content1 = html.xpath('') # define your parse logic here


        return {}  # 通常是字典, 也可以是字典列表, 但是后面的组件需要支持这种返回结果


上面的代码展示了编写自定义parser的一些要点:

  • 首先需要继承spydy的抽象基类Parser, 因为Parser定义了一个抽象方法parse, 所以继承自Parser 的自定义解析组件也要定义一个parse方法
  • response 其实就是上一个步骤的返回值, 通常是一个requests.Response对象(假设Myparser的上一步使用的是spydy的自带组件HttpRequestAsyncRequest的话), 所以可以调用response的text属性来获取页面html, 然后进行相应的解析
  • 最后返回结果, 一般是一个字典格式。当然也可以是字典列表, 但是后面的组件需要支持这种返回结果。详见存储组件
  • 定义__call__方法, 这个是非常重要的, 因为spydy是默认调用组件的__call__方法的, 所以一定要定义。
  • 定义__str__方法, 不是必须的, 但是为了更好地在日志中显示组件, 所以最好加上。

返回结果

Parser组件最后会返回一个字典(默认), 或者其他类型(比如字典的列表,某一些自定义场景下)。