0%

分布式 爬虫 Scrapy项目 scrapyd

分布式 爬虫 Scrapy项目 scrapyd

1、配置redis服务器允许远程连接

配置参考地址:https://www.cnblogs.com/masonblog/p/12726914.html

2. 配置setting 文件

1
2
3
4
5
6
7
8
9
10

""" scrapy-redis配置 """
# 调度器类
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 指纹去重类
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 是否在关闭时候保留原来的调度器和去重记录,True=保留,False=清空
SCHEDULER_PERSIST = True
# Redis服务器地址
REDIS_URL = "redis://127.0.0.1:6379/1" # Redis默认有16库,/1的意思是使用序号为2的库,默认是0号库(这个可以任意)

开启爬虫

项目 说明

  • 豆瓣电影top250 使用scrapyredis 分布式爬虫 进行, 爬取,

  • 爬取 标题,图片

  1. 在节点1,2开启 (此时爬虫并未开始,而是等待Redis中 top250:start_urls http://xxxxx

    1607311850953

    因为 douban 爬虫 继承Redisspider 我们没有传入 start_urls

    原因: 这个项目 实现的是分布式,也就意味着在其他节点 (服务器) 上,也是相同的,会出现爬取重复的 start_urls中的url ,这是没有必要的

    1607322864382

  2. 我们需在 redis客户端 输入 push指令开启 爬虫 才是 真正开始(注意一定要选择setting.py 文件中的配置的数据库)

    1
    2
    3

    $redis > select 2
    $redis > lpush top250:start_urls https://movie.douban.com/top250?start=0&filter=
  3. 此时 我们需要 把数据 合在一起,方案是 存入redis 中,

    通过中间件 会将信息Item 存储在Redis中

    1607324372718

  4. 我们从redis 中取出数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    import base64
    import csv
    import json
    import os

    import redis


    def main():
    # 指定Redis数据库信息
    redis_cli = redis.StrictRedis(host='127.0.0.1', port=6379, db=5)

    # 判断是否存在download文件夹,如果没有则创建
    download_path = os.getcwd() + '/download/' # 当前文件夹下的download文件夹
    if not os.path.exists(download_path): # 判断文件夹或文件
    os.makedirs(download_path)

    while True:
    # FIFO模式为 blpop,LIFO模式为 brpop,获取键值
    source, data = redis_cli.blpop(["top250:items"])

    item = json.loads(data.decode()) # data.decode()目的,因为从Redis中提取到的数据时byte类型,所以转换为字符串类型

    msg_type = item.get("type")
    if msg_type == "info":
    # # 信息
    # {
    # "type": "info",
    # "img_src": img_src,
    # "title": title,
    # "rating_num": rating_num,
    # "people_num": people_num
    # }
    # 如果是信息,就保存到csv文件
    with open(download_path + '豆瓣电影TOP250.csv', 'a') as f:
    # 创建一个csv的DictWriter对象,这样才能够将写入csv格式数据到这个文件
    f_csv = csv.DictWriter(f, ['title', 'img_src', 'rating_num', 'people_num'])
    # 写入多行行(当做数据)
    item.pop("type") # 删除type 这个key-value
    f_csv.writerows([item])
    print("保存信息到CSV....ok")

    elif msg_type == "img":
    # 存储图片
    with open(download_path + item.get("img_name"), "wb") as f:
    img_data = base64.b64decode(item.get("img_bytes"))
    f.write(img_data)
    print("保存图片ok....")


    if __name__ == '__main__':
    main()

  5. 注意: 其中redis 不允许存入二进制数据

    ​ 而 我们爬取到的图片 却是二进制数据,

    ​ 我们通过base64 转换 存入redis数据库中,

    ​ Python base64与图片之间的转换https://blog.csdn.net/qq_34449006/article/details/84312550

------ 本文结束------

欢迎关注我的其它发布渠道