# 命令行工具 命令行工具为**feapder**内置支持的,可方便快速的创建项目、爬虫、item、以及调试请求等,使用方法如下: ## 1.查看支持的命令行 打开命令行窗口,输入feapder >feapder feapder 1.1.3 Usage: feapder [options] [args] Available commands: create create project、feapder、item and so on shell debug response Use "feapder -h" to see more info about a command 可见feapder支持`create`及`shell`两种命令 ## 2. feapder create 使用feapder create 可快速创建项目、爬虫、item等,具体支持的命令可输入`feapder create -h` 查看使用帮助 > feapder create -h usage: feapder [-h] [-p] [-s [...]] [-i [...]] [-t] [-init] [-j] [-sj] [--host] [--port] [--username] [--password] [--db] 生成器 optional arguments: -h, --help show this help message and exit -p , --project 创建项目 如 feapder create -p -s [ ...], --spider [ ...] 创建爬虫 如 feapder create -s spider_type=1 AirSpider; spider_type=2 Spider; spider_type=3 BatchSpider; -i [ ...], --item [ ...] 创建item 如 feapder create -i test 则生成test表对应的item。 支持like语法模糊匹配所要生产的表。 若想生成支持字典方式赋值的item,则create -item test 1 -t , --table 根据json创建表 如 feapder create -t -init 创建__init__.py 如 feapder create -init -j, --json 创建json -sj, --sort_json 创建有序json --setting 创建全局配置文件 feapder create -setting --host mysql 连接地址 --port mysql 端口 --username mysql 用户名 --password mysql 密码 --db mysql 数据库名 具体使用方法如下: ### 1. 创建爬虫项目 命令 feapder create -p 示例: feapder create -p first-project 生成如下: ![-w354](http://markdown-media.oss-cn-beijing.aliyuncs.com/2021/02/08/16127822246620.jpg) * items: 文件夹存放与数据库表映射的item * spiders: 文件夹存放爬虫脚本 * main.py: 运行入口 * setting.py: 爬虫配置文件 若项目比较简单,不需要这个层次结构管理,也可不创建项目,直接创建爬虫 ### 2. 创建爬虫 爬虫分为3种,分别为 轻量级爬虫(AirSpider)、分布式爬虫(Spider)以及 批次爬虫(BatchSpider) 命令 feapder create -s * AirSpider 对应的 spider_type 值为 1 * Spider 对应的 spider_type 值为 2 * BatchSpider 对应的 spider_type 值为 3 * 默认 spider_type 值为 1 AirSpider爬虫示例: feapder create -s first_spider 1 生成first_spider.py, 内容如下: import feapder class FirstSpider(feapder.AirSpider): def start_requests(self): yield feapder.Request("https://www.baidu.com") def parse(self, request, response): print(response) if __name__ == "__main__": FirstSpider().start() 若为项目结构,建议先进入到spiders目录下,再创建爬虫 ### 3. 创建 item item为与数据库表的映射,与数据入库的逻辑相关。 在使用此命令前,需在数据库中创建好表,且setting.py中配置好数据库连接地址 命令 feapder create -i 示例 1. 建表 CREATE TABLE `spider_data` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 2. 配置setting.py, 连接方式换成自己数据库的 ![-w799](http://markdown-media.oss-cn-beijing.aliyuncs.com/2021/02/08/16127839359771.jpg) 3. 进入items目录,执行命令 feapder create -i spider_data 生成如下: ``` from feapder import Item class SpiderDataItem(Item): """ This class was generated by feapder. command: feapder create -i spider_data. """ def __init__(self, *args, **kwargs): # self.id = None self.title = None ``` 若字段有默认值或者自增,则默认注释掉,可按需打开 若不配置setting.py, 可在命令行中指定数据库连接信息 feapder create -i spider_data --host localhost --db feapder --username feapder --password feapder123 也可在环境变量中配置数据库连接信息, 以mac电脑为例 > vim ~/.bash_profile export MYSQL_IP='xxx' export MYSQL_PORT='xxx' export MYSQL_DB='xxx' export MYSQL_USER_NAME='xxx' export MYSQL_USER_PASS='xxx' > source ~/.bash_profile 这样,以后所有的项目setting.py中均可不配置mysql连接信息 **若item字段过多,不想逐一赋值,可通过如下方式创建** feapder create -i spider_data 1 生成: ``` from feapder import Item class SpiderDataItem(Item): """ This class was generated by feapder. command: feapder create -i spider_data 1. """ def __init__(self, *args, **kwargs): # self.id = kwargs.get('id') self.title = kwargs.get('title') ``` 这样当我们请求回来的json数据时,可直接赋值,如 ``` response_data = {"title":" 测试"} # 模拟请求回来的数据 item = SpiderDataItem(**response_data) ``` ### 4. 创建json 或 有序json 此命令和快速将 `xxx:xxx` 这种字符串格式转为json格式,常用于将网页或者抓包工具抓取出来的header、cookie转为json 用法示例: 1. 输入命令,回车 > feapder create -j 请输入需要转换的内容: (xxx:xxx格式,支持多行) 1. copy 请求头,粘贴到提示下方 ![](http://markdown-media.oss-cn-beijing.aliyuncs.com/2021/02/08/16127849396722.jpg) 1. 输出如下: ![-w1394](http://markdown-media.oss-cn-beijing.aliyuncs.com/2021/02/08/16127850065269.jpg) **sort_json** 与json命令类似,只不过该命令生成的json是按照key排序的有序字典, 命令为 feapder create -sj ### 5. 根据json创建表 有时,我们需要解析的字段特别多,手动建表太麻烦,此命令可根据json内容的key创建表,根据value推断字段类型 运行前,请参考**创建item**过程,将数据库配置好 命令: feapder create -t 用的示例: > feapder create -t test 请输入表数据 json格式 如 {"name":"张三"} 等待输入: {"name":"张三"} 请设置注释 回车跳过 name : varchar(255) -> comment: 是否添加batch_date 字段 (y/n):n 请设置唯一索引, 多个逗号间隔 等待输入: id CREATE TABLE `feapder`.`test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id 自动递增', `name` varchar(255) COMMENT '', `gtime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '抓取时间', PRIMARY KEY (`id`), UNIQUE `idx` USING BTREE (`id`) comment '' ) COMMENT=''; test 创建成功 创建过程会提示添加字段注释、唯一索引等。batch_date用于记录采集批次的,不用可输入n。看到创建成功后,我们去数据库里就可以看到表了 ### 6. 创建init 该命令用于创建\__init__.py的,并自动会引入当前目录下的所有py文件到\__all__中 示例如下: feapder create -init 观察生成的\__init__.py文件,已自动包含当前目录下的py文件 ![-w880](http://markdown-media.oss-cn-beijing.aliyuncs.com/2021/02/08/16127859798201.jpg) ## 3. feapder shell 下载调试器,可方便测试抽取规则是否正确,输入`feapder shell -h`查看使用帮助 > feapder shell -h 下载调试器 usage: feapder shell [options] [args] optional arguments: -u, --url 抓取指定url -c, --curl 抓取curl格式的请求 由提示可以看出,支持url及curl两种方式 1. 以url为例,请求百度: 请求 > feapder shell -u https://www.baidu.com MainThread|2020-06-21 23:21:37,208|request.py|get_response|line:283|DEBUG| -------------- None.parser request for ---------------- url = https://www.baidu.com method = GET body = {'proxies': None, 'timeout': 22, 'stream': True, 'verify': False, 'headers': {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36'}} Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) Type 'copyright', 'credits' or 'license' for more information IPython 7.14.0 -- An enhanced Interactive Python. Type '?' for help. now you can use response In [1]: 测试抽取title的xpath是否正确 In [1]: response.xpath('//title/text()').extract_first() Out[1]: '百度一下,你就知道' 可以看出,我们可以直接使用response, response支持xpath表达式 若想查看都支持哪些函数,可输入`response.` 然后敲两次`tab键`,如下: ![-w1738](http://markdown-media.oss-cn-beijing.aliyuncs.com/2020/06/21/15927532396490.jpg) 1. 以curl为例,请求百度(通常用来测试post接口比较方便) 1. 打开浏览器检查工具,复制需要测试的接口为curl格式 ![-w569](http://markdown-media.oss-cn-beijing.aliyuncs.com/2020/06/21/15927533333272.jpg) 1. 测试 输入`feapder shell --`, 粘贴刚刚复制的curl > feapder shell --curl 'https://www.baidu.com/' \ -H 'Connection: keep-alive' \ -H 'Pragma: no-cache' \ -H 'Cache-Control: no-cache' \ -H 'Upgrade-Insecure-Requests: 1' \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36' \ -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \ -H 'Sec-Fetch-Site: none' \ -H 'Sec-Fetch-Mode: navigate' \ -H 'Sec-Fetch-User: ?1' \ -H 'Sec-Fetch-Dest: document' \ -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' \ -H 'Cookie: PSTM=1589621705; BAIDUID=BC3B63E7833EB3D77970A2CF9AE7F4A2:FG=1; BIDUPSID=016405978E2364A4AFD0227A36DA60DE; BD_UPN=123253; BDUSS=nl2a3EzNGp-aGdham5xanhVYjZLbXNWTENBRWl0VTJuLTVEUGJOa2VodjhGTzVlRVFBQUFBJCQAAAAAAAAAAAEAAACCgXjpQm9yaXMwNjIxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPyHxl78h8ZeW; delPer=0; BD_CK_SAM=1; BD_HOME=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=1; ZD_ENTRY=google; H_PS_PSSID=1442_31672_21102_32046_31321_30823_32107_26350; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm' \ --compressed MainThread|2020-06-21 23:29:48,773|request.py|get_response|line:283|DEBUG| -------------- None.parser request for ---------------- url = https://www.baidu.com/ method = POST body = {'data': {}, 'headers': {'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Sec-Fetch-Site': 'none', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Sec-Fetch-Dest': 'document', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Cookie': 'PSTM=1589621705; BAIDUID=BC3B63E7833EB3D77970A2CF9AE7F4A2:FG=1; BIDUPSID=016405978E2364A4AFD0227A36DA60DE; BD_UPN=123253; BDUSS=nl2a3EzNGp-aGdham5xanhVYjZLbXNWTENBRWl0VTJuLTVEUGJOa2VodjhGTzVlRVFBQUFBJCQAAAAAAAAAAAEAAACCgXjpQm9yaXMwNjIxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPyHxl78h8ZeW; delPer=0; BD_CK_SAM=1; BD_HOME=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=1; ZD_ENTRY=google; H_PS_PSSID=1442_31672_21102_32046_31321_30823_32107_26350; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm'}, 'proxies': None, 'timeout': 22, 'stream': True, 'verify': False} Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) Type 'copyright', 'credits' or 'license' for more information IPython 7.14.0 -- An enhanced Interactive Python. Type '?' for help. now you can use response In [1]: