安装模块
- pip install scrapy scrapy-redis -i https://pypi.doubanio.com/simple
-
创建分布式爬虫环境
- 链接:https://pan.baidu.com/s/16aXPHtePiarEIFATwcILbw 提取码:hhhh
-
- 复制example_project文件,可自行更改名称
-
- 保留自己需要用的爬虫文件(这里留mycrawler_redis.py)
-
项目目录结构如下
主机和从机
- 主机(master) 启动redis-server
-
- 从机(salve)保证可以成功连接上主机的redis(从机不需要启动redis,只需要保证可以成功连接)
-
第一个分布式爬虫(从机)
- #在mycrawler_redis.py
-
-
- from scrapy.spiders import Rule
- from scrapy.linkextractors import LinkExtractor
- from scrapy_redis.spiders import RedisCrawlSpider
-
- class MyCrawler(RedisCrawlSpider):
-
- # 爬虫名
- name = 'mycrawler_redis'
- # redis_key: 类似start_url,但是只是redis的一个key
- # 监听redis中的key
- redis_key = 'mycrawler:start_urls'
- # 允许的域名
- allowed_domains = ['baike.baidu.com']
-
- rules = [
- Rule(LinkExtractor(allow=('item/.*?',)),callback='parse_page',follow=True),
- ] #定义规则
-
- def parse_page(self, response):
- # 标题
- title = response.xpath('//dd[@class="lemmaWgt-lemmaTitle-title"]/h1/text()').get()
- print(title)
-
- # item
- item = BaikeItem()
- item['title'] = title
- yield item
-
-
-
-
-
-
- #items.py中
- from scrapy.item import Item, Field
- class BaikeItem(Item):
- title = Field()
-
-
-
-
- #pipelines.py管道中
- class ExamplePipeline(object):
- def process_item(self, item, spider):
- return item
-
-
-
-
-
- #settings.py中
-
- SPIDER_MODULES = ['example.spiders']
- NEWSPIDER_MODULE = 'example.spiders'
-
- USER_AGENT = 'scrapy-redis (+https://github.com/rolando/scrapy-redis)'
-
-
- # dupefilter: 去重
- DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
- # 使用scrapy_redis的调度器
- SCHEDULER = "scrapy_redis.scheduler.Scheduler"
- # 是否允许暂停
- SCHEDULER_PERSIST = True
-
-
- #SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderPriorityQueue"
- #SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderQueue"
- #SCHEDULER_QUEUE_CLASS = "scrapy_redis.queue.SpiderStack"
-
- ITEM_PIPELINES = {
- 'example.pipelines.ExamplePipeline': 300,
-
- # 使用redis管道:自动存入redis,默认存入本机的redis
- 'scrapy_redis.pipelines.RedisPipeline': 400,
- }
-
- LOG_LEVEL = 'DEBUG'
-
- DOWNLOAD_DELAY = 1
-
- #配置远程连接redis
- #方法1
- REDIS_URL = "redis://:密码@IP地址:端口"
-
- #方法2
- # REDIS_HOST = 'IP地址'
- # REDIS_PORT = 6379
- #REDIS_PARAMS = {
- # 'password': '123456',
- # }
-
执行分布式爬虫(从机)
- cd 到爬虫文件路径
- scrapy runspider mycrawler_redis.py --监听主机redis
-
Redis添加URL(主机)
- lpush mycrawler:start_urls https://baike.baidu.com
- 注意:需要和爬虫文件中 redis_key 相对应 ,url对应需要爬取的网址即可
-
- (添加成功后,从机开始爬取,因为写的代码是深度爬取,所以爬虫会一直运行)
-
爬虫运行后Redis中
- 在Redis中自动产生下面3个key
- 1) "mybaike:requests"
- 要爬取的url请求队列
-
- 2) "mybaike:items"
- 会自动存储到redis中的数据(在爬虫文件中yield的那个item)
-
- 3) "mybaike:dupefilter"
- 过滤器: 过滤重复的request
-
存入Mysql
- 在mysql中创建一个表 id(int ,自增) 和 title(varchar)字段
-
- 在主项目中新建py文件夹Redis_to_MySQL.py
-
-
- import redis
- import pymysql
- import time
- import json
-
- # 连接redis
- r = redis.Redis()
-
- # 连接MySQL
- db = pymysql.connect(
- host='localhost', port=3306,
- user='root', password='root',
- database='spider88', charset='utf8'
- )
- cursor = db.cursor()
-
- while True:
- # 1. 从redis中取数据
- # blpop: 会等待mybaike:items有数据才会执行,否则会暂停一直等待
- keys, values = r.blpop('mycrawler_redis:item')
- # print(keys, values)
- item = json.loads(values.decode())
-
- # 2.存入MySQL数据库
- sql = 'insert into baike(title1) values("%s")' % item['title']
- cursor.execute(sql)
- db.commit()
-
- print(f'--- {item["title"]} 存入MySQL成功 ---')
-
- time.sleep(0.1)
-
-
-
- #这个文件需要单独执行
-