python多进程爬虫框架nspider

轻量级多进程爬虫框架nspider

楼主之前对爬虫颇有兴趣,为了学习爬虫和多进程+多线程编程,用了假期的时间写了一个爬虫框架,肯定是比不上那些专业的,就供大家玩玩和入门者一起交流和学习吧。

参考、借鉴了 Scrapy 架构, 以及 PSpider 架构。

github上有写了一点点的文档。

https://github.com/Nymphxyz/nspider

NymphSpider(NSpider) 是面向个人电脑的超轻量级资源爬取框架。nspider 基于requests库,采用多进程 + 多线程的设计。主要针对普通论坛、资源网站的图片、视频资源进行爬取。

nspider 基于 SQLite 进行数据和进度存储工作,在 nspider 设计框架和 SQLite 自有的鲁棒性上来看,你可以随时随地暂停,杀死nspider,nspider将会在下一次启动时自动恢复上一次的工作进度。

基础架构:

brief

安装 nspider 到你的 python 环境

pip install nspider

用法展示:

import nspider

# 用于url拼接
base_url = 'https://tieba.baidu.com'

# 自定义 parser 类, 用于解析页面
# 小提示: 你可以自定义无限个不同的 parser 针对不同的页面然后套娃。
# 当你不使用自带 save 和 resource 方法保存资源和数据的时候注意考虑多线程编程的安全性。
class PageContentParser(nspider.Parser):
    
    # parser为必须实现的方法, request 参数为 nspider 中的自定义 request 类, response 为 requests 库的标准返回对象。
    def parse(self, request, response):
        # 用于返回值
        is_failed = False
        # 解析页面逻辑,随意编写,这里使用了 nspider 自带的一些方法
        # get_text_from_res 可以把 response 转为纯文本
        text = nspider.common.get_text_from_res(response)
        # 这里用了 nspider 简单封装的 selector 类,可以使用 xpath 或者 beautiful soup。
        selector = nspider.Selector(text)
        # 试图找到帖子的具体内容
        content = selector.soup.find("div", attrs={"class": "p_postlist"})
        if content:
            # 试图找到帖子里所有的图片
            imgs = content.find_all("img", attrs={"class": "BDE_Image"})
            if imgs:
                for img in imgs:
                    # 过滤掉广告图片
                    if img.get("ad-dom-img"):
                        pass
                    else:
                        # 如果你不想自己写逻辑,也不是想下载资源,只是想保存一些数据,你可以选择使用自带 save 方法把数据存储到对应的 parser 数据库。
                        # 参数必须为可以 pickle 的对象。完成爬取后你可以自己写代码访问 parser 对应数据库 中的 “parser_data” 表取出数据。
                        self.save(img.get("src"))
                        # 如果你只是想使用自带的功能下载资源,那就调用 resource 方法,同样把资源记录到数据库中。这个数据和上面的 save 保存的表不一样。
                        self.resource(img.get("src"), save_dir="./test-download", dupe_filter=True)
            # 试图找到该帖子的下一页
            next_page = selector.xpath('//li[contains(@class, "l_pager")]/a[text()="下一页"]/@href')
            if next_page:
                # 找到了下一页,加入新的请求,并指定该请求使用的解析器。
                self.request(base_url + next_page[0], parser_class=PageContentParser)
        # 如果 content 为 空 说明解析失败,意味着response 返回的东西并不是我们所预计的东西,
        # 有可能触发了百度的反爬机制,返回了一个验证页面。
        else:
            # 告诉框架该次 解析 失败
            is_failed = True
            self.logger.info("URL: {} parser failed".format(request.url))
        # 返回一个任意对象,以及是否解析成功
        return None, is_failed

# 定义一个 spider 类
# 指定初始 url 和 对应的 parser
class WangBingbingSpider(nspider.Spider):
    start_url = ["https://tieba.baidu.com/p/7193897711"]
    start_parser = [PageContentParser]


if __name__ == "__main__":
    # 初始化 spider, 然后开始爬取。
    # 查看控制台输出,当然你发现控制台长时间未有新动态的时候,爬虫基本上就已经结束了,你可以直接关闭或杀死爬虫。
    wbb_spider = WangBingbingSpider()
    wbb_spider.start()
    
    # 下面两行为下载命令,你可以把上面的spider命令注释掉,然后用下面的命令来下载刚才你用 resource 方法添加的资源文件。
    # tps 表示限定每秒最大并发数, thread_num 指定下载线程的数量。
    # downloader = nspider.Downloader(tps=5, thread_num=5) 
    # 你需要指定下载的是哪个 parser 添加的资源文件
    # downloader.start(PageContentParser)

考虑到网络,解析速度等原因,nspider并没有对是否完成所有爬取做判断,因此当控制台长时间未出现新信息时,基本可以判断爬取已经结束,你需要手动关闭 spider

当添加 request dupe_filter 为 True 时(默认为True),你也可以尝试重新启动 nspdier 看看是否真的已经完成了所有请求。你应该只会看到 Refuse adding request 的信息。

现在你可以开始下载图片了。下载完毕后程序会自动退出。

如果中途退出,或者有些资源下载失败也不要紧,你可以多次运行该程序,默认配置会自动重新下载已经失败的,以及还没有下载的资源。

if __name__ == "__main__":
    # 初始化 spider, 然后开始爬取。
    # 查看控制台输出,当然你发现控制台长时间未有新动态的时候,爬虫基本上就已经结束了,你可以直接关闭或杀死爬虫。
    # wbb_spider = WangBingbingSpider()
    # wbb_spider.start()

    # 下面两行为下载命令,你可以把上面的spider命令注释掉,然后用下面的命令来下载刚才你用 resource 方法添加的资源文件。
    # tps 表示限定每秒最大并发数, thread_num 指定下载线程的数量。
    downloader = nspider.Downloader(tps=5, thread_num=5)
    # 你需要指定下载的是哪个 parser 添加的资源文件
    downloader.start(PageContentParser)

觉得有用的话,给个star吧,感谢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值