【SexyLady爬虫框架】开动小手做一个爬虫框架

项目场景:

本人对于技术的热爱犹如对性感美女一般痴迷,所以自己便开发了一款性感爬虫框架

1:【我是小白】想当初自己写爬虫的时候总是要写很多重复的开头,就和数学公式一样,要先写一个”解:“啊西~😒,那麽现在你只需要编写set_spider和parser两个模板就可以快速的完成一个爬虫框架。

2:【我是大白】TA很简单,对特定的爬虫目标直接分类,单页单目标、单页多目标、多页单目标、多页多目标,通用爬虫、聚焦爬虫......,大兄弟,这莫多个类型,你还要判断还要决策,多幸苦啊😫。在SexyLady中,封装了很多Tools,你直接调用就可以,你想要的,我都做了。

吹了这莫多,不如讲讲我在开发的过程中遇到的问题,各位看官,请勿拍桌,看好了。


想的太多,不知从何改起

我最开始想的是用户传来一个爬取链接和方法(post,get),那摩爬虫就可以直接传来一个解析器,直接开始对数据进行解析,让你专心处理分析数据而不是研究请求爬虫这一块,最开始其实完成了这一块,如下代码:

class SexyRequest:

    def __init__(self):
        self.SPIDER_NAME = None
        self.URLS = None
        self.METHOD = 'get'
        self.HEADERS = None
        self.RESPONSE = None
        self.client = None

    def __init_response(self, url, mode='text', **kwargs):
        """
            with httpx.Client(event_hooks={'response': [raise_on_4xx_5xx]}) as client:
                self.RESPONSE = client.request(self.METHOD, url, headers=self.HEADERS, **kwargs)
                self.RESPONSE.encoding = self.RESPONSE.apparent_encoding
            return getattr(self.RESPONSE, mode)
        """
        self.client = httpx.Client(event_hooks={'response': [raise_on_4xx_5xx]})
        self.RESPONSE = self.client.request(self.METHOD, url, headers=self.HEADERS, **kwargs)
        self.RESPONSE.encoding = self.RESPONSE.apparent_encoding
        return getattr(self.RESPONSE, mode)

    def _init_parser(self):
        for url in self.start_request():
            parser = etree.HTML(self.__init_response(url))
            yield parser.xpath

    def start_request(self):
        yield from self.URLS

    def private_response(self, mode, **kwargs):
        for url in self.start_request():
            yield self.__init_response(url, mode=mode, **kwargs)

用户编写spider.py文件继承 SexyRequest,接着调用 private_response 就可以得到 response,那摩调用 _init_parser, 则直接拿到爬取任务链接的解析器,是不是很方便呢?但是最后想把这里改好来,改的好看点(强迫症),在改的过程总想了很多新的功能和特性,所以导致半天不知道改哪里或者怎么改(哭唧唧),最后改的是这样子的:

ML = logger


def make_logfile(file_name, rotation="1 week", retention="10 days"):
    """
    简单的初始化log的文件
    使用帮助: https://pythondict.com/life-intelligent/tools/loguru/
    """
    return ML.add("%s_.log" % file_name, rotation=rotation, retention=retention)


def raise_on_4xx_5xx(response):
    """
    您还可以使用这些挂钩来安装响应处理代码,例如此示例,它创建一个始终在 4xx 和 5xx 响应时引发的客户端实例。引发一个 httpx.HTTPStatusError
    """
    try:
        response.raise_for_status()
    except HTTPStatusError as e:
        ML.warning('MyError: %s & status_code== %d' % (e, response.status_code))


class SexyRequest:

    def __init__(self):
        self.SPIDER_NAME = None
        self.URLS = None
        self.METHOD = 'get'
        self.HEADERS = None
        self.RESPONSE = None
        self.client = None

    def __init_response(self, url, mode='text', **kwargs):
        """
            with httpx.Client(event_hooks={'response': [raise_on_4xx_5xx]}) as client:
                self.RESPONSE = client.request(self.METHOD, url, headers=self.HEADERS, **kwargs)
                self.RESPONSE.encoding = self.RESPONSE.apparent_encoding
            return getattr(self.RESPONSE, mode)
        """
        self.client = httpx.Client(event_hooks={'response': [raise_on_4xx_5xx]})
        self.RESPONSE = self.client.request(self.METHOD, url, headers=self.HEADERS, **kwargs)
        self.RESPONSE.encoding = self.RESPONSE.apparent_encoding
        return getattr(self.RESPONSE, mode)

    def _init_parser(self):
        for url in self.start_request():
            parser = etree.HTML(self.__init_response(url))
            yield parser.xpath

    def start_request(self):
        yield from self.URLS

    def private_response(self, mode, **kwargs):
        for url in self.start_request():
            yield self.__init_response(url, mode=mode, **kwargs)


class SexyParser:

    def __init__(self):
        self.xpath = None

    def exec_xpath(self, response):
        parser = etree.HTML(response)
        return parser.xpath

    def inn(self, source, xpath: classmethod = None, _raise=False):
        """
        用例编写:
            parser = SexyParser()
            result['hot_search'] = parser.inn('//*[@class="title-content-title"]/text()', self.xpath, _raise=True)

        :param source: xpath 语句
        :param xpath: method
        :param _raise: 异常开关
        :return:
        """
        if _raise and not xpath(source):
            raise ValueError('执行xpath(%s)为空' % source)
        elif not _raise and not xpath(source):
            ML.warning('xpath语句可能有问题: < source: %s > = None ' % source)
        else:
            return xpath(source)


class MiniWeChatBot:
    """
    用例编写:
        token = (corpid, corpsecret, agentid)
        app = MiniWeChatBot(TOKEN)
        app.wcs_text("is test message...")
        ...
    """

    def __init__(self, token):
        """
        你可以声明一个变量,该变量为:tuple,元组中包含corpid, corpsecret, agentid
        """
        self.app = Sender(*token)

    def wcs_text(self, message):
        """
        :param message: Text content sent
        """
        self.app.send_text(message)

    def wcs_image(self, path):
        """
        :param path: Sent picture address
        """
        self.app.send_image(path)

    def wcs_file(self, path):
        """
        :param path: File address sent
        """
        self.app.send_file(path)

大家只要看request和response,在这上面我可谓是花了大心思,可能是技术比较烂的原因或者想的太多太杂乱了,没有详细的流程图和开发文档才导致自己开发速度很慢。


原因分析:

1、想的太多

2、做的太少

3、没有流程图,走一步看一部

4、没有框架流程图


解决方案:

每次改动我都会事前添加一个任务点,例如今天需要完成什么功能接口等,同时呢,流程图也在添加制作当中,还不是很明确,而且现在新版的完全就是逻辑重写了,有兴趣的可以来我的git查看项目,一起经交流群探讨技术哦

项目地址:神经蛙/SexySpider (gitee.com)https://gitee.com/lone_time_no_see_CJ/SpiderAPI

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值