欢迎访问的小伙伴! 希望在这里能帮到你。有问题请多多指教~ 点击联系站长

百度云电影资源分布式爬虫,二十倍效率提升——西西电影

Python 焦康阳 0评论

大家好,我是小焦。今天给大家带来的是西西电影网的分布式爬虫。一直想着练习一下分布式爬虫,百般思量下也是想到百度云电影资源。百度之下无意中发现这个西西电影网上面有着大量的电影资源。虽说普通的爬虫就能搞定我们的需求,但是我们要假象有着大量的资源去爬取,所以我们以分布式爬虫的思路来进行项目。

    分布式爬虫当然首选scrapy框架,省去大量的步骤。废话不多说,开始简单分析本次的项目吧。

准备工作

  • 目标网址:www.xidianying.com
  • 工具:python3、scrapy、scrapy-redis、redis、mongodb

    这里我们先不说分布式怎么实现,先说说如何编写此次的爬虫的思路。先来看看目标网站的结构。

经过网站的分析,我们发现目标网站结构也是非常的简单,静态网址。内容方面也是非常的规整,现在我们可以开始编写代码了。我们使用python的scrapy爬虫框架来爬取。项目中小焦编写了两个spider,但是在测试分布式时出现了问题,随后又重新整顿了下代码,成功实现分布式,所以我们按照重新编写的代码来说。(对scrapy不了解的朋友请先复习一下该框架再阅读此文章)

# 创建爬虫项目
scrapy startproject dianying
# 创建爬虫,名字为xixi
scrapy genspider xixi www.xidianying.com

下面代码小焦就不展开讲了,简单说下思路。此次代码我的目标是爬取前10页的资源,因为分布式爬虫的原因,我们先重构start_requests函数,项目会自动调取该函数生成的链接,再而调取parse函数。parse()函数则是对目标网页,所有电影资源二级页面链接的提取,并调用parse_onepage()函数对二级页面的内容进行提取。列出代码,大家一看就知道怎么回事了。

import scrapy
from dianying.items import DianyingItem

class XixiSpider(scrapy.Spider):
    name = 'xixi'
    allowed_domains = ['www.xidianying.com']
    # start_urls = ['http://www.xidianying.com/']
    # 这块构建url链接
    url = 'http://www.xidianying.com/list-56-{}.html'
    # 重构start-request函数,scrapy调用时是从这里读取链接
    def start_requests(self):
        for i in range(1,11):
            yield scrapy.Request(self.url.format(str(i)),callback=self.parse)

    def parse(self, response):
        print('开始爬取')
        # 分析网页,找出所有的链接
        lists = response.xpath("//tbody[starts-with(@id,'normalthread')]")
        for list in lists:
            b = '百度云'
            # 获取所有的标题和网址
            print('获取标题')
            lname = list.xpath("./tr/th/a[2]/text()").extract()
            # 返回的结果是list,我们转化为str格式
            names = ''.join(lname)
            print('标题为:',names)
            # 筛选出百度云关键字的链接,如果标题中含有百度云三个字,则提取herf
            if b in names:
                lurl = list.xpath("./tr/th/a[2]/@href").extract()
                # 同上进行结果是list,转换为str格式
                urls = ''.join(lurl)
                print("资源网址为:",urls)
                yield scrapy.Request(urls,callback=self.parse_onepage)

    # 这个函数为资源页面的百度云链接和提取码的分析
    def parse_onepage(self,response):
        item = DianyingItem()
        # 获取目标网页中的href,有可能包含多个href,且返回结果为list了,所以我们进行遍历
        print('获取页面中的所有链接')
        lists = response.xpath("//td[@class='t_f']//a/@href").extract()
        for list in lists:
            if 'baidu.com' in list:
                # 这块转换str是因为如果是多个a标签的话,list是lxml的unicode对象,所以先进行转换
                item['baiduurl'] = str(list)

        # 获取页面中的所有文本,找到提取码
        all = response.xpath("//td[@class='t_f']//text()").extract()
        for i in all:
            a = '提取'
            if a in i:
                item['tiquma'] = i

        # 获取该链接的标题
        name = response.xpath("//span[@id='thread_subject']/text()").extract_first()
        item['name'] = name
        yield item

分布式爬虫

上面我们已经理出了爬虫的具体代码,现在说说分布式爬虫。其实也是非常的简单,就是所有的爬虫共享同一个队列。将同一个项目分配给所有的机器共同执行,从而达到众人拾柴火焰高的功效。而scrapy框架中,我们只需将调度器用redis数据库来代替即可,所以这里就需要使用到scrapy_redis这个库。为了达到去重的目的,借助了redis集合的去重功能。这里我们也就不细说了,具体的请自行百度用法,而scrapy框架中实现分布式,只需加入一下代码即可。

# 分布式爬虫配置,在setting文件中加入一下代码
# 首先将调度器和去重类替换为scrapy_redis提供的类,下面两个为核心配置
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
​
# Redis连接设置,这里是本地数据库
REDIS_HOST = "192.168.31.214"
REDIS_PORT = 6379
​
# mongodb链接地址和db
MONGO_URI = '192.168.31.214'
MONGO_DATABASE = 'scrapy'

效果图

上面我们已经将整个目标网站的数据使用分布式进行爬取,并且保存到mongodb数据库中,对于pipelines文件数据操作这块也没有详细解说,这些大伙可自行下去了解,或者看小焦的代码即可。感谢阅读。

源码:https://github.com/zhanjiuyou/xidianying.git

喜欢 (5)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址