Ⅰ.Re:Scrapy自定义模板

创建默认模板

# Scrapy 版本 2.6.2 

# 创建项目
# scrapy startproject [配置参数(可选)] <项目名称(字母开头,只运行数字字母下划线)> [项目输出路径(可选)]
scrapy startproject scarpy_demo "d:\爬虫 - 项目"

# 创建爬虫
cd d:\爬虫 - 项目
# scrapy genspider [配置参数(可选)] <爬虫名称> <抓取目标的域名或URL>
scrapy genspider spider_demo toscrape.com

命令行参数

# 参考帮助
scrapy startproject -h
scrapy genspider -h 

全局命令

# startproject
scrapy startproject <project_name> [project_dir]

# genspider 
# -t 参数添加的模板为框架自带的模板(..\site-packages\scrapy\templates\spiders),用 scrapy genspider -l 命令查看
scrapy genspider [-t template] <name> <domain or URL>

# settings
# 查看爬虫设置的值,scrapy settings --get DOWNLOAD_DELAY
scrapy settings [options]

# runspider
# 可以运行脱离项目的爬虫
scrapy runspider <spider_file.py>

# shell
# scrapy shell http://quotes.toscrape.com/
scrapy shell [url]

## 可以保存网页本地调试
scrapy shell './Quotes to Scrape.html'
## --spider 指定爬虫
scrapy shell http://quotes.toscrape.com/ --spider=spider_demo
## -c code 评估代码,打印并退出
scrapy shell http://quotes.toscrape.com/ -c '(view(response) , resp
onse.status, response.url)'
## --no-redirect 不要重定向;--nolog 不要运行日志
scrapy shell --no-redirect --nolog http://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F -c '(response.status, response.url)'

# fetch
# --spider=SPIDER 指定爬虫;--headers 打印响应头;--no-redirect 不要重定向
# scrapy fetch --nolog http://httpbin.org/get
scrapy fetch <url>

# view
# 浏览器显示页面,scrapy view http://quotes.toscrape.com/
scrapy view <url>

# version
# 输出 Python、Twisted 和平台信息,这对于错误报告很有用,scrapy version -v
scrapy version [-v]

# bench
# 一个简单的基准测试套件
scrapy bench

项目命令

# crawl
# scrapy crawl spider_demo
scrapy crawl <spider>

# check
scrapy check [-l] <spider>

# list
scrapy list

# edit
scrapy edit <spider>

# parse
scrapy parse <url> [options]

创建自定义模板

# 假设有一套自己做的模板,目录名叫 ‘templates’

# 创建项目
scrapy startproject -s TEMPLATES_DIR=templates scarpy_demo

# 创建爬虫
cd scarpy_demo
scrapy genspider -s TEMPLATES_DIR="../templates" spider_demo toscrape.com

源码解析

  • startproject.py

    • 渲染文件明细

      TEMPLATES_TO_RENDER = (
          ('scrapy.cfg',),
          ('${project_name}', 'settings.py.tmpl'),
          ('${project_name}', 'items.py.tmpl'),
          ('${project_name}', 'pipelines.py.tmpl'),
          ('${project_name}', 'middlewares.py.tmpl'),
      )
    • class Command(ScrapyCommand)

      """
      Command 类中 run 函数 主要是对参数的校验、模板文件拷贝及渲染
      自定义模板的核心在于 templates_dir 这个类变量
      """
        def run(self, args, opts):
              if len(args) not in (1, 2):
                  raise UsageError()
      
              project_name = args[0]
              project_dir = args[0]
      
              if len(args) == 2:
                  project_dir = args[1]
      
              if exists(join(project_dir, 'scrapy.cfg')):
                  self.exitcode = 1
                  print(f'Error: scrapy.cfg already exists in {abspath(project_dir)}')
                  return
      
              if not self._is_valid_name(project_name):
                  self.exitcode = 1
                  return
      
              self._copytree(self.templates_dir, abspath(project_dir))
              move(join(project_dir, 'module'), join(project_dir, project_name))
              for paths in TEMPLATES_TO_RENDER:
                  path = join(*paths)
                  tplfile = join(project_dir, string.Template(path).substitute(project_name=project_name))
                  render_templatefile(tplfile, project_name=project_name, ProjectName=string_camelcase(project_name))
              print(f"New Scrapy project '{project_name}', using template directory "
                    f"'{self.templates_dir}', created in:")
              print(f"    {abspath(project_dir)}\n")
              print("You can start your first spider with:")
              print(f"    cd {project_dir}")
              print("    scrapy genspider example example.com")
      
      '''
      类属性 templates_dir 中如果没有传 TEMPLATES_DIR 这个参数的话就会按默认的逻辑处理
      所以自定义模板需要多设置一个settings参数。
      -s TEMPLATES_DIR=templates
      templates 为模板文件夹
      '''
        @property
          def templates_dir(self):
              return join(
                  self.settings['TEMPLATES_DIR'] or join(scrapy.__path__[0], 'templates'),
                  'project'
              )        
  • genspider.py

    '''
    genspider 命令和 startproject 大同小异
    
    sanitize_module_name 对爬虫名称的处理
    extract_domain 对域名参数传url地址的处理,有个https的已知问题,无伤大雅
    '''
    def sanitize_module_name(module_name):
        """Sanitize the given module name, by replacing dashes and points
        with underscores and prefixing it with a letter if it doesn't start
        with one
        """
        module_name = module_name.replace('-', '_').replace('.', '_')
        if module_name[0] not in string.ascii_letters:
            module_name = "a" + module_name
        return module_name
    
    def extract_domain(url):
        """Extract domain name from URL string"""
        o = urlparse(url)
        if o.scheme == '' and o.netloc == '':
            o = urlparse("//" + url.lstrip("/"))
        return o.netloc
  • 自带 templates 模板结构

    templates
        ├─project
        │  │  scrapy.cfg
        │  │
        │  └─module
        │      │  items.py.tmpl
        │      │  middlewares.py.tmpl
        │      │  pipelines.py.tmpl
        │      │  settings.py.tmpl
        │      │  __init__.py
        │      │
        │      └─spiders
        │            __init__.py
        │
        └─spiders
                basic.tmpl

使用 scrapy-template-plus 及其 builder 生成项目

项目地址:https://github.com/yuanqimanong/scrapy-template-plus

使用方法

  1. 先安装 requirements.txt 环境
  2. 再运行 builder-run.py 按操作提示
  3. 用 IDE 加载项目,并设置对应的根目录

实现原理

生成项目:继承 startproject.Command ,加载settings,重写TEMPLATES_TO_RENDERrun方法

生成爬虫:继承 genspider.Command,重写 run方法


Ⅰ.Re:Scrapy自定义模板
https://元气码农少女酱.我爱你/40dd86514b92/
作者
元气码农少女酱
发布于
2023年5月2日
许可协议