爬虫进阶:框架功能完善-多爬虫实现之多个解析函数实现

未匹配的标注

爬虫实现多个解析函数

响应对象的解析方法封装

为response对象封装xpath、正则、json、等方法和属性,以支持对数据的解析和提取

# scrapy_plus/http/response.py
import re
import json

from lxml import etree


class Response(object):
    '''框架内置Response对象'''
    def __init__(self, url, status_code, headers, body):
        self.url = url    # 响应url
        self.status_code = status_code    # 响应状态码
        self.headers = headers    # 响应头
        self.body = body    # 响应体

    def xpath(self, rule):
        '''提供xpath方法'''
        html = etree.HTML(self.body)
        return html.xpath(rule)

    @property
    def json(self):
        '''提供json解析
        如果content是json字符串,是才有效
        '''
        return json.loads(self.body)

    def re_findall(self, rule, data=None):
        '''封装正则的findall方法'''
        if data is None:
            data = self.body
        return re.findall(rule, data)

实现多个解析函数

由于现在不同的请求对应不同的解析函数,因此需要为请求对象指明它的解析函数,因此为请求对象增加一个属性

# scrapy_plus/http/request.py
class Request(object):
    '''框架内置请求对象,设置请求信息'''

    def __init__(self, url, method='GET', headers=None, params=None, data=None, parse='parse'):
        self.url = url    # 请求地址
        self.method = method    # 请求方法
        self.headers = headers    # 请求头
        self.params = params    # 请求参数
        self.data = data    # 请求体
        self.parse = parse    # 指明它的解析函数, 默认是parse方法
        self.meta = None
# scrapy_plus/http/response.py
class Response:
    '''完成对响应对象的封装'''

    def __init__(self, url, body, headers, status_code, meta={}):
        '''
        初始化resposne对象
        :param url: 响应的url地址
        :param body: 响应体
        :param headers:  响应头
        :param status_code: 状态码
        '''
        self.url = url
        self.headers = headers
        self.status_code = status_code
        self.body = body
        self.meta = meta

在引擎中需要动态的判断和获取对应的解析函数

# scrapy_plus/core/engine.py
class Engine(object):

    ......

    def _execute_request_response_item(self):
        '''根据请求、发起请求获取响应、解析响应、处理响应结果'''

        ......

       #request对象经过下载器中间件的process_request进行处理
        request = self.downloader_mid.process_request(request)

        #4. 调用下载器的get_response方法,获取响应
        response = self.downloader.get_response(request)

        response.meta = request.meta

        #response对象经过下载器中间件的process_response进行处理
        response = self.downloader_mid.process_response(response)
        #response对象经过下爬虫中间件的process_response进行处理
        response = self.spider_mid.process_response(response)

        #parse方法
        parse = getattr(self.spider,request.parse)

        #5. 调用爬虫的parse方法,处理响应
        for result in parse(response):
            #6.判断结果的类型,如果是request,重新调用调度器的add_request方法
            if isinstance(result,Request):
                #在解析函数得到request对象之后,使用process_request进行处理
                result = self.spider_mid.process_request(result)
                self.scheduler.add_request(result)
                self.total_request_nums += 1
            #7如果不是,调用pipeline的process_item方法处理结果
            else:
                self.pipeline.process_item(result)

        self.total_response_nums += 1

        ......

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~