项目来源:
https://github.com/aosabook/500lines
中文翻译:
https://github.com/HT524/500LineorLess_CN
不过这个中文项目并没有翻译完。
英文原版:
http://www.aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html
500lines项目是由一些牛人用500行以内的代码编写的项目,对于python学习是很有益处的,个人觉得crawler(网络爬虫)相对来说,更有用一点。同时该项目涉及到Coroutine(协程)、asyncio(异步IO)、aiohttp(基于asyncio
实现的HTTP框架)相对来说有点难度的知识,再加上该项目作者之一是Guido van Rossum(python之父)。所以该项目是非常值得学习的。
拿到一个项目代码以后,一般是先运行,看看什么效果?
首先,安装aiohttp包:
pip install aiohttp
由于本人采用的是win7+Anaconda3,默认aiohttp会安装在:Anaconda3\Lib\site-packages目录下:
查看readme.txt文件后,我们在控制台运行程序:
python crawl.py -q xkcd.com
然而什么也没看到,什么文件也没下载下来。所以我们还是老实的研究下代码,看看是怎么回事吧。通过上面的命令我们知道,程序入口在crawl.py里面。为了测试方便,单独建了一个文件testlogging.py,代码如下:
# -*- coding: utf-8 -*-
import argparse
ARGS = argparse.ArgumentParser(description="Web crawler")
ARGS.add_argument('--iocp', action='store_true', dest='iocp',default=False, help='Use IOCP event loop (Windows only)')
ARGS.add_argument('--select', action='store_true', dest='select',default=False, help='Use Select event loop instead of default')
ARGS.add_argument('roots', nargs='*',default=[], help='Root URL (may be repeated)')
ARGS.add_argument('--max_redirect', action='store', type=int, metavar='N',default=10, help='Limit redirection chains (for 301, 302 etc.)')
ARGS.add_argument('--max_tries', action='store', type=int, metavar='N',default=4, help='Limit retries on network errors')
ARGS.add_argument('--max_tasks', action='store', type=int, metavar='N',default=100, help='Limit concurrent connections')
ARGS.add_argument('--exclude', action='store', metavar='REGEX',help='Exclude matching URLs')
ARGS.add_argument('--strict', action='store_true',default=True, help='Strict host matching (default)')
ARGS.add_argument('--lenient', action='store_false',dest='strict',default=False, help='Lenient host matching')
ARGS.add_argument('-v', '--verbose', action='count', dest='level',default=2, help='Verbose logging (repeat for more verbose)')
ARGS.add_argument('-q', '--quiet', action='store_const', const=0, dest='level',default=2, help='Only log errors')
args = ARGS.parse_args()
print('''
args.roots=%s,
args.iocp=%s,
args.select=%s,
args.max_redirect=%s,
args.max_tries=%s,
args.max_tasks=%s,
args.exclude=%s,
args.strict=%s,
args.level=%s''' % (args.roots,args.iocp,args.select,args.max_redirect,args.max_tries,args.max_tasks,args.exclude,args.strict,args.level))
argparse包有点复杂,作用是从解析控制台的各种参数,从而对程序进行相应的控制。但是规则相当的多,所以这篇文件的重点,就是解释argparse的用法与上面参数具体的意义。
argparse用法参考文章:
https://docs.python.org/3/library/argparse.html
我们单独建一个文件,运行下上面的代码:
python testlogging.py --help
注意,参数(-h,--help)属于系统自动增加的。
- help
参数的帮助信息,描述每个参数的作用。
- metavar
帮助信息中显示的参数名称。
ARGS.add_argument('--max_redirect', action='store', type=int, metavar='N',default=10, help='Limit redirection chains (for 301, 302 etc.)')
ARGS.add_argument('--max_tries', action='store', type=int, metavar='N',default=4, help='Limit retries on network errors')
ARGS.add_argument('--max_tasks', action='store', type=int, metavar='N',default=100, help='Limit concurrent connections')
ARGS.add_argument('--exclude', action='store', metavar='REGEX',help='Exclude matching URLs')
上面的代码对应下面的输出:
--max_redirect N Limit redirection chains (for 301, 302 etc.)
--max_tries N Limit retries on network errors
--max_tasks N Limit concurrent connections
--exclude REGEX Exclude matching URLs
所以这个metavar就相当于一个占位符,起一个提示的作用,如果要改变max_tasks的值,只需在命令行加上 “--max_tasks 101”即可。
- dest
参数别名。
ARGS.add_argument('--strict', action='store_true',default=True, help='Strict host matching (default)')
ARGS.add_argument('--lenient', action='store_false', dest='strict',default=False, help='Lenient host matching')
第一行"--strict"的值默认可以通过args.strict访问,但是“--lenient”也把自己的名字取为"strict",也就是说通过"--lenient"命令可以把args.trict变成False。
注意,有了dest后,不能再通过args.lenient来访问--lenient参数的值了。
positional arguments(定位参数)
ARGS.add_argument('roots', nargs='*',default=[], help='Root URL (may be repeated)')
上面这种没加"-"的参数,叫定位参数。
- nargs
参数的数量。可以是具体的数字;?首先从命令行中获取,没有则从default中获取;* 号,表示 0 或多个参数;或者是 + 号表示 1 或多个参数。
roots参数用法如下:
python testlogging.py www.baidu.com
此时args.roots的值为['www.baidu.com']。
- action
命令行参数的操作,操作的形式有以下几种:- store:仅仅存储参数的值(默认为None)
ARGS.add_argument('--exclude', action='store', metavar='REGEX',help='Exclude matching URLs')
用法如下:
python testlogging.py --exclude 555 www.baidu.com
此时args.exclude为555,如果把555去掉,则为www.baidu.com,也就是说store存储的值会是exclude后面的第一个参数。
- store_const:存储const关键字指定的值
ARGS.add_argument('--iocp', action='store_true', dest='iocp',default=False, help='Use IOCP event loop (Windows only)')
ARGS.add_argument('--select', action='store_true', dest='select',default=False, help='Use Select event loop instead of default')
ARGS.add_argument('-q', '--quiet', action='store_const', const=0, dest='level',default=2, help='Only log errors')
第一行中,store_true意思是如果参数中出现--iocp参数,则args.iocp的值为True,否则为默认值False。第二行类似。第三行则指定了const的值为0,即出现该命令时,args.level的值为0。
- count
统计参数出现的次数。
ARGS.add_argument('-v', '--verbose', action='count', dest='level',default=2, help='Verbose logging (repeat for more verbose)')
-v与--verbose是一个意思,一个是简称,一个是全称。上面代码的意思是统计参数v出现的次数,用法如下:
python testlogging.py -v
此时args.level的值为3,因为default为2,再加上-v出现的1次,一共3次。如果上面的参数改为-vvv,args.level就是5。
我们运行下最开始的命令:
python crawl.py -q xkcd.com
由于两个参数的名字相同,实际上我们只有9个参数,它们的值分别如下:
本篇文章至此结束,主要探讨了关于argparse模板关于参数的各种设定,以及代表什么意思。这些参数将对后面的程序流程控制有着致关重要的作用。