zoukankan      html  css  js  c++  java
  • python

    ## scrapy 依赖 twisted
      - twisted 是一个基于事件循环的 异步非阻塞 框架/模块

    ##  项目的创建 

    1. 创建 project
        scrapy  startproject  项目名称
       
        项目名称(项目结构)
            - spiders    # 爬虫文件
                - q.py
                - w.py
            - items.py         # 持久化
            - pipelines         # 持久化
            - middlewares.py   # 中间件
            - settings.py    # 配置文件(爬虫)
        scrapy.cfg    # 配置文件(部署)
    
    2. 创建爬虫
        cd 项目名称
       
        scrapy genspider  q  q.com
        scrapy genspider  w  w.com
    
    3. 启动爬虫
        scrapy crawl  q --nolog   # 不查看日志
        scrapy crawl  w              # 默认查看日志

    ## pipeline 做持久化

        - pipeline 是所有爬虫公用的,如果想要给某个爬虫制定需要使用 spider 参数进行判断处理:
          if spider.name == 'xxx'

    1. 自定义的爬虫文件中 将每次获取到的数据 传给 ScrapyDeom1Item 类方法
    for item in item_list:
        href = item.xpath('.//a/@href').extract_first()
        txt = item.xpath('.//a/text()').extract_first()
        yield ScrapyDeom1Item(text=txt, href=href)
    
    2. items 中 ScrapyDeom1Item 类方法 将需要存储的数据接收到。
    class ScrapyDeom1Item(scrapy.Item):
        href = scrapy.Field()
        text = scrapy.Field()
    
    3. settings 中定义做持久化的类( ScrapyDeom1Pipeline ) 和 定义一个文件路径
    ITEM_PIPELINES = {
       'scrapy_deom1.pipelines.ScrapyDeom1Pipeline': 300,
           # 文件路径                       # 优先级( 1-1000 )
    }
    PATH = 'new.log'
    
    4. 到 pipelines.py 文件中 找到 ScrapyDeom1Pipeline 类并做持久化
    from scrapy.exceptions import DropItem
    class ScrapyDeom1Pipeline(object):
    
        def __init__(self, path):  # 初始化定义文件操作 和 文件要保存的路径
            self.f = None
            self.path = path
    
        @classmethod
        def from_crawler(cls, crawler):
            """
            初始化的时候,用来创建 pipeline 对象
            :param crawler:
            :return:
            """
            # 去settings 寻找要保存的文件路径
            path = crawler.settings.get('PATH')
            return cls(path)
    
        def open_spider(self, spider):
            """
            爬虫刚启动时调用 - 此处用来做打开文件操作
            :param spider:
            :return:
            """
            self.f = open(self.path, 'a+')
    
        def process_item(self, item, spider):
            """
            爬虫执行中调用 - 此处用来做将数据写入文件 操作
            :param item:
            :param spider:
            :return:
            """
            self.f.write(item['href']+'
    ')
            # raise DropItem()   # 抛出异常,使后续的 pipeline 的 process_item 方法不执行
            return item    # 这个 item 是要返回给下个类的
    
        def close_spider(self, spider):
            """
            爬虫执行完毕后调用 - 此处用来做关闭文件操作
            :param spider: 
            :return: 
            """
            self.f.close()

    ## 去重

    1. 创建一个 dupefilters.py 文件(用于做去重操作):
    from scrapy.dupefilters import BaseDupeFilter
    from scrapy.utils.request import request_fingerprint
    
    
    class MyDupeFilter(BaseDupeFilter):
    
        def __init__(self):
            self.visited_fd = set()
    
        @classmethod
        def from_settings(cls, settings):
            return cls()
    
        def request_seen(self, request):
            """
            判断当前请求的URL是否存在 - 用于去重
                - 如果存在则  pass
                - 如不存在则  添加
            :param request:
            :return:
            """
            # 将当前 URL 加密成一定位数的字符
            print(request)
            fd = request_fingerprint(request=request)
            if fd in self.visited_fd:
                return True
            self.visited_fd.add(fd)
    
        def open(self):  # can return deferred
            """
            执行前的一些操作
            :return:
            """
            print('爬虫开始')
    
        def close(self, reason):  # can return a deferred
            """
            执行结束后的一些操作
            :param reason:
            :return:
            """
            print('爬虫结束')
    
        def log(self, request, spider):  # log that a request has been filtered
            """
            访问的每一个  URL  的日志信息
            :param request:
            :param spider:
            :return:
            """
            pass
    
    
    2. settings 中注册这个类
    DUPEFILTER_CLASS = 'scrapy_demo1.dupefilters.MyDupeFilter'
    
    3. 可以设置是否使用当前定义的去重方法
    # True 表示不使用 
    # False 表示使用 (默认为False)
    yield Request(url=page, callback=self.parse, dont_filter=True)

    ##  限制深度查询

    配置文件中(settings):
    DEPTH_LIMIT = 3  # 查询深度设置为三层

    ##  Cookie

    # 解析 cookie
    cookie_jar = CookieJar()
    cookie_jar.extract_cookies(response, response.request)

    # 去对象中将cookie解析到字典
    for k, v in cookie_jar._cookies.items():
    for i, j in v.items():
    for m, n in j.items():
    self.cookie_dict[m] = n.value

    # 获取 cookie

    cookies=self.cookie_dict,
     
  • 相关阅读:
    WebService及WCF获取客户端IP,端口
    单链表创建,删除节点,获取元素(与线性表比较)
    c语言描述简单的线性表,获取元素,删除元素,
    解决wamp mysql数据库出现乱码的问题。
    c语言将2进制数转化为10进制数(栈的初始化,进栈,出栈)
    c++描述将一个2进制数转化成10进制数(用到初始化栈,进栈,入栈)
    css各兼容应该注意的问题
    C++需要注意的地方和小算法
    php最简单的文件处理。
    C++ 一目了然虚基类!
  • 原文地址:https://www.cnblogs.com/chaoqi/p/10545034.html
Copyright © 2011-2022 走看看