之前用爬虫爬了三个源,共爬取了30w左右的博客,爬虫项目:itmap_spiders。
接着对这些文本进行分析,要求是找出每篇文章的关键词。我对TF*IDF算法有一些了解,就选择了它。项目:itmap_data_analysis。
业务架构
由于数据量有点大,所以使用消息队列进行拆分,拆分标准是按照步骤来。具体的步骤如下图所示。
技术栈:
使用pika
来与RabbitMQ
连接。
使用click
来编写命令行命令。
使用mongodb
来储存结果。
遇到的问题
logging
使用click
时发现一直没有打印日志,解决方法是设置日志级别:
logging.basicConfig(level=logging.INFO)
click
跟随另一位同伙的代码,第一次使用click,真是好用啊!
需要能够多次输入collection时,需要增加参数multiple
,这样在命令行使用时,可以多次添加--collection collection_name
或-c collection_name
。
@click.command()
@click.option('--collection', '-c', type=click.Choice(collections), multiple=True, help='mongo中的collection名')
def func(collection):
for c in collection:
pass
pymongo
速度
计算TF的步骤,由于消费者执行速度实在太慢(rabbit的admin界面对应的queue的state大部分情况下是idle
状态),所以稍微优化了下。
目前主要是通过使用bulk-write来提速。另外,对于计算TF步骤而言,设计的时候是一次只对一篇文章进行计算,但是发现这样做太耗费与mongodb
的连接了,所以改成了一次对100篇文章进行计算。
与消费者的龟速成鲜明对比的是,生产者往队列里塞得极快!至于计算TF后面俩步骤是什么情况,还得等我先跑完TF再看。。。
auth
terminal中输入mongo
use admin
db.auth(‘username’,’password’)
备份
terminal中输入
mongodump -u username -p password --authenticationDatabase=admin -d data -o /data/db
-u 是username -p是password,不填会报authentication的错, --authenticationDatabase需要指明auth在哪个db中
-d 是要备份的db,不指明就是所有
-o 是dump文件保存的地方,不指明就是当前目录
还可以使用-h 来指明是哪个mongod,比如127.0.0.1:27017,端口可不填
恢复
terminal中输入
mongorestore -h localhost:27017 -d data . -u root -p Song123654 --authenticationDatabase=admin
各个参数同上,那个点表示是当前目录
*nix命令
*nix 使用scp传输文件
scp ubuntu@111.112.113.114:~/datadir/data/article-juejin.bson article-juejin.bson
前面和ssh登录一样,因为scp也是使用ssh,后面同cp命令
修改文件的用户组
chgrp [-R] group_name file_name
修改文件所有者
chown [-R] owner_name file_name
-R表示递归,会将目录下的所有文件同时做修改
也可以这么用:
chown group_name:owner_name file_name
docker-compose命令
docker-compose up -d service_name
docker-compose build/start/stop/restart service_name
docker-compose scale service_name=2
docker-compose logs -f service_name
defaultdict
想要将defaultdict的默认值也设置为defaultdict:
defaultdict(lambda: defaultdict(int))
若直接写,会报错,是因为defaultdict(int)
并不是可调用对象:
In [2]: defaultdict(defaultdict(int))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-535a33200cb5> in <module>()
----> 1 defaultdict(defaultdict(int))
TypeError: first argument must be callable or None