自己封装一个爬虫框架
1. 简介
2. 使用
3. 不足
4. 总结
1.简介
先看一下项目整体的目录结构:
1.1 run.py: 启动文件,文件的具体参数请仔细看注释内容
1.2 spider.py:具体的爬虫文件,里面主要有三个方法
- List item
1) save_data(data, mode=‘db’):保存目标数据,data是2)中返回的data, mode=’db’ 是保存的模式,这里默认保存为MySQL或sqlite, 当要保存为 csv文件时,mode=’csv’, 要保存为mongodb 时, mode=’mongodb’
2) extract_target(html, dict_arg): 解析目标数据,实际调用时,html为3)中返回的html源码,dict_arg为 config.py 文件 配置的lxml xpath方法的解析参数
3) craw_html(url, way=’’): url: 爬取地址, way: 使用爬取html源码的方式是requests, 或selenium, 这里默认使用requests, 当way 不为空是则使用selenium方式,这里selenium 用的是chrome 浏览器的无头模式,当你需要用到这种方式爬取源码时,还需要下载和你的chrome浏览器匹配的chrome浏览器驱动器。
1.3 config.py: 配置的lxml xpath方法的解析参数
parser_arg = {
‘title’: ‘//div[@class=“w”]/div[@class=“bt”]/a//text()’,
‘img’: ‘//div[@class=“w”]/div[@class=“pic”]/a/img/@src’,
}
1.4 craw_thread.py: 多线程爬取(使用的queue进行线程间通信,queue是线程安全的), 原理如下图:
默认各使用3个线程(3个爬取html源码的线程即producer,3个解析获取目标数据的线程即middle, 3个存储目标数据线程即concumer)来处理,producer, middle, concumer 的实现使用的是spider.py文件中对应的craw_html(), extract_target(), save_data()方法
1.5 model.py:主要使用sqlalchemy 来生成保存模式为mysql, 或sqlite的数据表。如果保存为sqlite, 会在当前目录生产一个model.db 的数据库文件,该文件保存的即为目标数据,可以用navicat, sqlitebrowser等工具打开,如果保存为mysql, 请把# engine = create_engine(‘mysql://root:[email protected]/xzj?charset=utf8’, pool_size=100) # 保存至mysql
该行注释放开,填写你本地mysql数据库的用户名和密码,并把上一行保存为sqllite的代码注释
1.6 save_config.py:
该文件主要处理保存为mysql, sqlite, csv, mongodb等保存模式的实 现,使用该框架一般不需要修改该文件
2.使用
- List item
1)修改run.py 文件的main()函数的相关参数,具体参数值请看注释内容,修改目标url
2)修改config.py 中的参数,该参数是一个字典, 字典的键会与保存的目标字段值一致(当保存为mysql, 或sqlite 时数据断要根据此处的参数名进行相应修改,3)会详细说明),字典的值需要符合lxml xpath() 解析语法。 爬虫所要用到的解析规则可以统一放在此处配置,只需在调用spider.py 文件的extract_target() 时传入相对应的参数即可。
- 修改save_config.py 文件:
(1)当保存为sqllite或mysql时,请仔细阅读下图代码的注释
(2)当保存为csv, 数据库文件名是target.csv, 如果该文件名已存在,会往该文件追加数据, 如果想重新存放所有数据,请把已存在的target.csv 文件重命名或删除。
(3)当保存的模式是 mongodb时,默认的数据库名是Target, 数据表名是target, 注意你本机的mongodb 是否存在重名的数据库。
4) 修改model.py 文件:
该文件主要处理生成的数据表字段,通过sqlalchemy 生成数据表
3. 不足
- List item
1) 参数封装的不够彻底:run.py 的main函数的参数和爬取的url 可以直接放到命令行中传入,如scrapy一样通过命令启动项目时传入一些必要的参数。启动项目时需要修改的地方过于分散,如果能集中到一处,同时修改会更好
2) 当启用多线程爬取时,数据已经爬取完成时项目不会自动停止,需要手动停止。原来是通过判断queue_detail_url, queue_html, queue_data 队列中的数据是否为空来决定是否退出循环爬取,但考虑到爬取html, 解析html, 保存目标数据三部分所用到的时间是不一样的,用时短的部分会让其中某个队列先为空,造成程序提前退出,所以这里用的是一个while True 的死循环。为了让项目能自动停止,我现在能想到的解决方法是通过判断queue_detail_url 队列为空时,让producer 通过多线程的notify() 通知处于wait() 状态的middle然后producer部分跳出死循环。middle 接到通知后,又notify() 处于wait() 状态的consumer然后跳出死循。consumer接到notify() 后直接跳出死循环。
4. 总结
关于我自己封装的爬虫框架已经全部介绍完毕了,如果你有什么不了解或对不足之处有更好的解决方案可以给我发邮件,我的邮箱:[email protected],
所有的代码的github地址:https://github.com/JackXie1010/spider_frame