一起养成写作习惯!这是我参与「掘金日新计划 · 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 中添加了完整路径。
通过命令创建完毕,即可进入编码环节
修改 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,例如
- 百度
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()
复制代码
分布式爬虫
接下来要做的事情就是修改上述爬虫为分布式爬虫,确保你已经通过上一篇博客完整redis
与scrapy-redis
的安装,请注意以下步骤
修改爬虫 csdn_down.py 文件
- 将爬虫的类从
scrapy.Spider
变成scrapy_redis.spiders.RedisSpider
,或者是从scrapy.CrawlSpider
变成scrapy_redis.spiders.RedisCrawlSpider
,该部分修改如下图,注意类的继承关系 - 将爬虫中的
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 里面会形成如下数据
如果你有多台服务器,把爬虫程序依次布置好,即可实现基本的分布式爬虫
写在后面
本篇博客是从最基础的爬虫开始,注意将其改造成分布式爬虫,从理解程度上,把难度降到了最低,好了,下面的舞台是你的了,加油。