zoukankan      html  css  js  c++  java
  • 分布式爬虫

    分布式爬虫

    scrapy_redis使用

    dupefilter去重:

    request_fingerpint() 请求指纹

    使用haslib.sha1 对 request.method, request.url, request.headers, request.body 进行加密

    40个字符的16进制字符串, 缺点太占内存

    优化 :

    将scrapy_redis中默认去重的dupefilter改为:

    使用BloomFilter 去重, 内存小 ,比较快

    1.在项目中使用以下设置:

    #启用redis中的存储请求队列调度。
    SCHEDULER =  scrapy_redis.scheduler.Scheduler

    #确保所有蜘蛛通过redis共享相同的重复过滤器。
    DUPEFILTER_CLASS =  scrapy_redis.dupefilter.RFPDupeFilter

    #将请求的数据存储在redis中进行后期处理。
    ITEM_PIPELINES = {
        ' scrapy_redis.pipelines.RedisPipeline '300
    }

    指定连接Redis时使用的主机和端口(可选)。
    REDIS_HOST = 'localhost'
    REDIS_PORT = 6379

    具体用法参考链接 : https://github.com/rmax/scrapy-redis

    2.使用

    import scrapy
    from scrapy_redis.spiders import RedisSpider  # 使用RedisSpider

    from reading_network.items import ReadingNetworkItem

    # 在basc模板的spider基础上作修改:
    class GuoxueSpider(RedisSpider):  # 改为继承RedisSpider
       name = 'guoxue'
       redis_key = 'start_urls'  # 设置存放开始爬取地址的key key为start_urls, value为起始url

    注意: 运行命令与之前不同, 命令:

    cd spiders目录

    scrapy runspider guoxue.py(爬虫文件)

     

    3.数据持久化,存入mysql

    import pymysql
    from redis import Redis
    import json

    # 从redis中取出数据,然后储存到mysql
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='450502',
                          charset='utf8', database='spider1')
    cursor = conn.cursor()
    redis_conn = Redis()


    def insert_mysql():
       while 1:
           # 从redis中取数据
           # print(redis_conn.brpop('guoxue:items', timeout=60))   # 取不到时会有60s的延时,超时后报错, (b'guoxue:items', b'{'name' : 'xxx'}')
           try:
               _, data = redis_conn.brpop('guoxue:items', timeout=60)
           except:
               cursor.close()
               conn.close()
               break

           # 转化为python对象
           data = json.loads(data, encoding='utf-8')
           keys = ', '.join(data.keys())
           values = ', '.join(['%s'] * len(data))  # '%s, %s, %s'
           sql = f'insert into guoxue({keys}) values({values})'
           try:
               cursor.execute(sql, tuple(data.values()))  # 传一个元组 替换 其中%s
               conn.commit()
           except Exception as e:
               print(e)
               conn.rollback()


    if __name__ == '__main__':
       insert_mysql()

     

    使用分布式

    1.修改配置

    • window下需修改redis配置文件redis.windows.conf, 重启redis

      bind 127.0.0.1 改为 0.0.0.0

      protected-mode no # 关闭保护模式

      requirepass 123456 # 其他服务器远程访问需要带上密码

      • linux下redis修改配置文件redis.windows.conf, 重启redis

        bind 0.0.0.0

        requirepass 123456

        其他服务器连接本机redis: redis-cli -h 本机ip

        访问需输入密码: auth 123456

    • settings中需将共享redis数据库的服务器地址改为:

    REDIS_URL = 'redis://:123456@本机ip:6379'  # 不是本地ip127.0.0.1

    2.使用

    和上面基本一样,只是使用crawlspider; 继承类改为 RedisCrawlSpider

    import scrapy
    from scrapy_redis.spiders import RedisCrawlSpider  # 使用RedisCrawlSpider

    from reading_network.items import ReadingNetworkItem

    # 在crawl模板的spider基础上作修改:
    class GuoxueSpider(RedisCrawlSpider):  # 改为继承RedisCrawlSpider
       name = 'guoxue'
       redis_key = 'start_urls'  # 设置存放开始爬取地址的key key为start_urls, value为起始url

     

  • 相关阅读:
    android activity状态的保存
    java android 序列号serializable和parcelable
    java 中的 自定义viewUtils框架
    CSS隐藏元素的几种妙法
    WCF、WebAPI、WCFREST、WebService之间的区别
    前端大全
    最全前端资源汇集
    Unicode和汉字编码小知识
    关于写保护
    js实现密码加密
  • 原文地址:https://www.cnblogs.com/Deaseyy/p/11266778.html
Copyright © 2011-2022 走看看