一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
写在前面
对于分布式爬虫学习来说,或者对于技术学习来说,没有捷径,两条路可以走,第一自己反复练习,孰能生巧;第二看别人分享的代码反复学习别人的写法,直到自己做到。
上篇博客相信你已经可以简单的将分布式爬虫运行起来,你可能会发现分布式爬虫是思想上的一个调整,从代码的写法上并没有过多的改变,但是要知道我们是使用scrapy-redis直接构建的分布式爬虫,相当于是站在了前辈的肩膀上去爬分布式那堵墙,不过作为了解分布式爬虫的第一步“构建”,这个里程碑我们已经实现,接下来我们要把这个里程碑砸的更夯实一些,方便后面的攀爬。
接下来我将用3篇左右的案例,不断的重复分布式爬虫写法,直到无招。
今天找个网站做参考, 人人都是产品经理
,声明下 不好意思,学习目的,爬来的数据会及时的删除滴
。
构建分布式爬虫
创建一个scrapy爬虫工程
scrapy.exe startproject woshipm
通过上述命令创建一个爬虫工程,注意如果你的scrapy.exe没有配置环境变量,请通过完整的路径定位到scrapy.exe然后在执行命令
创建一个基于 CrawlSpider
的爬虫文件
D:\python100\venv\Scripts\scrapy.exe genspider -t crawl pm xxx.com
通过上述命令创建爬虫文件的时候,一定要注意进入到爬虫工程中的spider文件夹内部,如果没有,需要拷贝一下生成的 pm.py
文件,粘贴到spider文件夹内部
上述两个步骤实施完毕,现在的目录结构如下
修改pm.py文件为分布式爬虫基础内容
最终的修改结果如下,注意注释部分内容
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy_redis.spiders import RedisCrawlSpider # 导入scrapy_redis
class PmSpider(RedisCrawlSpider): # 修改父类
name = 'pm'
# 注释以下两条内容
# allowed_domains = ['xxx.com']
# start_urls = ['http://xxx.com/']
rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
)
redis_key = 'pm_url' # 新增加一个redis_key 名称可以随意
def parse_item(self, response):
item = {}
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item
复制代码
修改setting.py文件增加redis部分
最终的修改结果如下
BOT_NAME = 'woshipm'
SPIDER_MODULES = ['woshipm.spiders']
NEWSPIDER_MODULE = 'woshipm.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# scrapy-redis相关配置,该部分具体说明,请参照上篇博客 https://dream.blog.csdn.net/article/details/107228400
# Scrapy-Redis相关配置
# 确保request存储到redis中
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER_PERSIST = True
# 设置redis为item pipeline
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
# 设置连接redis信息
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_ENCODING = 'utf-8'
DOWNLOAD_DELAY = 3
复制代码
启动redis并向其中lpush首次抓取地址
启动redis,进入到redis根目录,使用 redis-server.exe redis.windows.conf
即可启动 启动redis-cli ,在根目录下,使用 redis-cli -h 127.0.0.1 -p 6379
进行连接,由于我本机redis未设置密码,故直连即可。
通过lpush命令添加地址 127.0.0.1:6379> lpush pm_url http://www.woshipm.com/archive/page/1
。
以上步骤完成,一个基本的分布式爬虫已经编写完毕
测试爬虫是否正常运行
打开 pm.py
文件,修改网址匹配规则如下
rules = (
# 获取分页,注意修改完善,本篇就不对LinkExtractor做过多的解读,以后有机会基于scrapy写一些深入讲解的博客
# http://www.woshipm.com/archive/page/2
Rule(LinkExtractor(allow=r'page/\d+'), callback='parse_item', follow=True),
)
redis_key = 'pm_url'
def parse_item(self, response):
item = {}
item['titles'] = response.xpath('//h2[@class="post-title"]').get()
return item
复制代码
上述代码有个坑需要注意下,该问题其实是python基础知识问题
rules = (),该处rules是一个元组,请注意不要丢掉其中的逗号 ,
如果丢掉会出现如下错误信息 'Rule' object is not iterable
启动爬虫,具体启动方式很多,此处请进入到pm.py所在文件夹,然后通过下述命令启动
D:\python100\venv\Scripts\scrapy.exe runspider pm.py
如果无问题,你将看到如下画面
调整下数据,确定无问题
核心看一下 pm.py
中 xpath
是否正确
class PmSpider(RedisCrawlSpider):
name = 'pm'
# allowed_domains = ['xxx.com']
# start_urls = ['http://xxx.com/']
rules = (
# 获取分页
# http://www.woshipm.com/archive/page/2
Rule(LinkExtractor(allow=r'page/\d+'), callback='parse_item', follow=True),
)
redis_key = 'pm_url'
def parse_item(self, response):
links = response.xpath('//h2[@class="post-title"]/a')
for title in links:
item = WoshipmItem(
title=title.xpath('./text()').get(),
)
print(item)
yield item
复制代码
运行结果如下
写在后面
程序运行起来爬取速度很快,300多页数据不到1分钟就爬取完毕了,希望这篇博客能再次帮助你理解分布式爬虫