python开源爬虫框架scrapy源码解析(一)

    前年实习的时候因为一个偶然的机会开始接触爬虫,因为我是做JAVA开发的,当然优先JAVA开源的爬虫框架,对比Heritrix、Nutch等爬虫框架后选择Heritrix,经过近一个月的折腾最后完成任务.因为一些个人的原因离开实习公司后来校招进入现在的坑,刚好有机会接触Python, 知道有一个目前用的比较多的爬虫框架Scrapy,正好有点兴趣就玩了下,顺便就当是学习python.

    前面说了很多废话接下来开始本文的主题,由于第一次写这种文章以及个人资历尚浅, 文中难免会有错误还请见谅,请大家指出~ 谢谢.

ScrapyPython开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试

Scrapy的安装可以参考官方文档。官网地址:http://www.scrapy.org/

Scrapy的源码可以在github下载.。源码地址:https://github.com/scrapy/scrapy


本系列文章按照scrapy使用步骤对源码进行介绍,主要分为下面几个方面:

             1、 安装Scrapy

             2、 新建一个Scrapy工程。

             3、 运行Scrapy工程。

   scrapy提供两种安装方式,第一种是采用linux命令安装如apt-get,另外也可以下载源码然后通过运行 python install set.py来进行安装.

 下面是对安装文件set.py的介绍,set.py中必须了解的是console_scripts,scrapy的命令行就是通过console_scripts配置的模板实现的.

with open(join(dirname(__file__), 'scrapy/VERSION'), 'rb') as f:
    version = f.read().decode('ascii').strip()    #获取scrapy版本信息
 
setup(
    ……………………………………………………………….
    packages=find_packages(exclude=('tests', 'tests.*')), #发现scrapy模块包
    include_package_data=True,
    zip_safe=False,
    entry_points={
        'console_scripts': ['scrapy =  scrapy.cmdline:execute']
                            #命令执行模块  scrapy.cmdline
    },
    ………………………………………………………
    install_requires=[     #安装需要的依赖模块
        'Twisted>=10.0.0',
        'w3lib>=1.8.0',
        'queuelib',
         ………………………………………………………………….
        'service_identity',
    ],
)

set.py中可以了解到scrapy的命令行模式都是通过调用cmdline.pyexecute方法实现的例如,执行scrapy crawl examples实际是调用scrapy.commands包中crawl.pyrun方法.下面的是cmdline.py代码片段.

def execute(argv=None, settings=None):
    if argv is None:
        argv = sys.argv
 
    # --- backwards compatibility for scrapy.conf.settings singleton ---
    if settings is None and 'scrapy.conf' in sys.modules:
        from scrapy import conf
        if hasattr(conf, 'settings'):
            settings = conf.settings
    # ------------------------------------------------------------------
 
    if settings is None:
        settings = get_project_settings()   #获取settings配置    
    check_deprecated_settings(settings)   #检查配置是否合法
 
    # --- backwards compatibility for scrapy.conf.settings singleton ---
    import warnings
    from scrapy.exceptions import ScrapyDeprecationWarning
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", ScrapyDeprecationWarning)
        from scrapy import conf
        conf.settings = settings
    # ------------------------------------------------------------------
 
    inproject = inside_project()    #返回bool值
    cmds = _get_commands_dict(settings, inproject)  #获取scrapy 命令模板,如startproject crawl 等
    cmdname = _pop_command_name(argv)  #获取当前执行的命令
    parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(), \
        conflict_handler='resolve')   #命令选项
    if not cmdname:
        _print_commands(settings, inproject)
        sys.exit(0)
    elif cmdname not in cmds:
        _print_unknown_command(settings, cmdname, inproject)
        sys.exit(2)
 
    cmd = cmds[cmdname]  #取出当前命令class
    parser.usage = "scrapy %s %s" % (cmdname, cmd.syntax())
    parser.description = cmd.long_desc()
    settings.setdict(cmd.default_settings, priority='command') #设置默认配置
    cmd.settings = settings
    cmd.add_options(parser)
    opts, args = parser.parse_args(args=argv[1:])
    _run_print_help(parser, cmd.process_options, args, opts)
 
    cmd.crawler_process = CrawlerProcess(settings)  #获取爬虫流程控制class
    _run_print_help(parser, _run_command, cmd, args, opts)  #调用_run_command方法
    sys.exit(cmd.exitcode)

def _run_command(cmd, args, opts):
    if opts.profile:    
        _run_command_profiled(cmd, args, opts)   #存在命令行选项调用该方法
    else:
        cmd.run(args, opts)  #调用ScrapyCommand子类的run方法

 


你可能感兴趣的:(python,爬虫,scrapy)