Python分布式爬虫顶级教程

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情

写在前面

题目中有个顶级,忽然觉得这篇博客要弄的高大上一些,要不都对不起标题呢?

上篇博客,我们已经将分布式需要配置的一些基本环境已经配置完毕,接下来就是实操环节了,这部分尽量将过程描述清晰,由于我操作的是 windows 操作系统,所以博客中相关步骤的截图都已 windows 为准。

对于分布式爬虫初学阶段,先从 scrapy 简单爬虫写起即可。

scrapy 爬取 CSDN 下载频道

为了测试方便,我找了一个规则比较简单的网址,CSDN 下载频道 https://download.csdn.net/ ,该网址对应的数据可以通过 https://download.csdn.net/home/get_more_latest_source?page=2 修改 URL 中参数 page 的值即可以不断获取数据,非常贴心。

创建爬虫

通过 scrapy 创建一个基本的爬虫,==关于如何创建,本文不再涉及,可翻阅之前文章即可==,注意,因为我电脑安装 scrapy 多个,并且本项目采用了虚拟环境,所以 scrapy 中添加了完整路径。

image.png

通过命令创建完毕,即可进入编码环节

在这里插入图片描述

修改 setting.py

修改setting.py如下,都是非常基础的修改,无需要特别说明的地方

ROBOTSTXT_OBEY = False # 不遵守robots.txt 的规则
DOWNLOAD_DELAY = 3 # 下载器在从同一网站下载连续页面之前应等待的时间(以秒为单位)
DOWNLOADER_MIDDLEWARES = {
   'csdn_down_file.middlewares.CsdnDownFileDownloaderMiddleware': 543,
}
ITEM_PIPELINES = {
   'csdn_down_file.pipelines.CsdnDownFilePipeline': 300,
}

复制代码

修改 middlewares.py

修改中间件middlewares.py,核心增加以下请求头,这里地方可以处理的趣味一些,很多网站用下面的思路可以骗过反爬程序,设置 UA 头的时候,可以设置为搜索引擎爬虫 UA,例如

扫描二维码关注公众号,回复: 13779556 查看本文章
  • 百度 Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)
  • 360 搜索 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0);
  • Google Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
  • 微软 bing,必应 Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
  • 腾讯搜搜 Sosospider+(+http://help.soso.com/webspider.htm)
  • 还有很多 >>> 具体自己去百度吧,这个骗反爬手段在某些网站有奇特的效果
import random
class UserAgentDownloadMiddleware(object):
    # user-agent随机请求头中间件
    USER_AGENTS = [
        "百度搜索爬虫相应的UA头即可"
    ]
    def process_request(self, request, spider):
        user_agent = random.choice(self.USER_AGENT)
        request.headers['User-Agent'] = user_agent

复制代码

修改 item.py

修改item.py,本篇博客为了降低编码量,我们只获取 3 个值即可

import scrapy
class CsdnDownFileItem(scrapy.Item):
    # define the fields for your item here like:
    file_id = scrapy.Field()
    title = scrapy.Field()
    source_url =scrapy.Field()
    pass
复制代码

修改 csdn_down.py

接下来就是核心的爬虫代码部分,按部就班编写即可,重点修改csdn_donw.py文件 在这里插入图片描述

import scrapy
from csdn_down_file.items import CsdnDownFileItem
import json


class CsdnDownSpider(scrapy.Spider):
    name = 'csdn_down'
    allowed_domains = ['download.csdn.net']
    start_urls = ['https://download.csdn.net/home/get_more_latest_source?page=1']

    def parse(self, response):
        rs =  json.loads(response.text)
        print(response.meta.get('page'))
        page = 2
        if response.meta.get('page') is not None:
            page = int(response.meta.get('page'))
            page += 1
        if rs.get('message') == 'ok':
            # 取出数据
            data = rs.get('data').get('list')
            # 存取数据
            for content in data:
                file_id = content.get('id')
                title = content.get('title')
                source_url = content.get('download_source_url')
                item = CsdnDownFileItem(
                    file_id=file_id,
                    title=title,
                    source_url=source_url
                )
                yield item

        next_url = f"https://download.csdn.net/home/get_more_latest_source?page={page}"
        yield scrapy.Request(url=next_url, callback = self.parse, meta = {'page': page})

复制代码

修改 pipelines.py

该部分代码修改比较简单,即将爬取下来的数据存储到一个 JSON 文件中,这个地方没有设置上限,所以爬虫不会自行停止,需要的话,增加一个上线页码即可,最终结果如下图。

from scrapy.exporters import JsonLinesItemExporter


class CsdnDownFilePipeline:
    def __init__(self):
        self.csdn = open('csdn.json', 'wb')

        self.csdn_exporter = JsonLinesItemExporter(
            self.csdn, ensure_ascii=False
        )

    def process_item(self, item, spider):
        self.csdn_exporter.export_item(item)
        return item

    def close_spider(self, item, spider):
        self.csdn.close()
复制代码

image.png

分布式爬虫

接下来要做的事情就是修改上述爬虫为分布式爬虫,确保你已经通过上一篇博客完整redisscrapy-redis的安装,请注意以下步骤

修改爬虫 csdn_down.py 文件

  1. 将爬虫的类从scrapy.Spider变成scrapy_redis.spiders.RedisSpider,或者是从scrapy.CrawlSpider变成scrapy_redis.spiders.RedisCrawlSpider,该部分修改如下图,注意类的继承关系
  2. 将爬虫中的start_urls删掉。增加一个redis_key="csdn:urls"。这个 redis_key 是为了以后在 redis 中控制爬虫启动的。爬虫的第一个 url,就是在 redis 中通过这个发送出去的。

    注意 csdn:urls 指的是 redis 数据库里面存储的名字

    在这里插入图片描述

修改 setting.py 文件

本部分核心就是配置 redis 加上开始 redis 存储

# ####################### redis配置文件 #######################

# 引入相关头文件
from scrapy_redis.scheduler import Scheduler
from scrapy_redis.pipelines import RedisPipeline

SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 确保所有爬虫共享相同的去重指纹,也可以自定义自己的去重规则
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 设置redis为item pipeline
ITEM_PIPELINES = {
  'scrapy_redis.pipelines.RedisPipeline': 300
}
# 在redis中保持scrapy-redis用到的队列,不会清理redis中的队列,从而可以实现暂停和恢复的功能。
SCHEDULER_PERSIST = True

REDIS_HOST = '127.0.0.1' # 主机名
REDIS_PORT = 6379 # 端口
REDIS_ENCODING = "utf-8"

复制代码

开始 redis

具体查阅上篇博客 ,开启之后,重新启动一个命令行,连接 redis,同时写入csdn:urls 命令行为: lpush csdn:urls https://download.csdn.net/home/get_more_latest_source?page=1 在这里插入图片描述

启动你的分布式爬虫

万事准备完毕,启动你的第一个基于 redis 的分布式爬虫吧。注意运行过程中 redis 服务器的控制台不要关闭哦~,最终在你的 redis 里面会形成如下数据

image.png 如果你有多台服务器,把爬虫程序依次布置好,即可实现基本的分布式爬虫

写在后面

本篇博客是从最基础的爬虫开始,注意将其改造成分布式爬虫,从理解程度上,把难度降到了最低,好了,下面的舞台是你的了,加油。

猜你喜欢

转载自juejin.im/post/7084612496778067975
今日推荐