本文记录一下最近在做的事情,会把思考过程和解决问题的方案写出来。当然,由于本人技术有限,所以可能并不是最好的方案,还请大家见谅!(黑猫白猫只要抓到老鼠,不就是好喵?~)
前言:
事情是这样的,有一些文章,我要根据文章内容做分类,具体怎么分我会单独开一篇文章来讲这件事情,这篇文章的重点不是分类,而是分类前的准备!
1、已有的东西:手头上有一些文章的url(这里就不说是什么平台了,避嫌)存在数据库中,和这些文章的分类(可以理解为已经有一部分分类的结果了,相对是比较准确的)
2、想要的东西:我是根据文章内容做分类,所以肯定要有每篇文章的内容,这就是我没有的
3、综上:这就是我写这篇文章的原因,我需要每篇文章的内容,包括两部分。第一部分是已经有分类的文章内容,第二部分是新的没有分类的文章内容,然后通过已有的分类,来为新的文章分类。
4、最后一点:提前说一下,本人不是专业的python攻城狮,我可能就是一个打杂的,所以没有用上一些高大上的python框架,还请大家见谅!
正文:
因此我要做的事情分为以下几步:
1、从数据库中取url信息。
2、通过url获得页面上我所需要的正文部分(html解析)。
3、将拿到的数据插回数据库中
第一步:python查询postgresql
我想这是最简单的一个步骤了,只要找下python连接postgresql(以下统称,pg)的库,然后调用下api就好了。
因此我使用到了:psycopg2这个库
相关网站:https://www.yiibai.com/postgresql/postgresql_python.html
这里稍微说下,其实查询就分两种,是一次性全部查出来还是分批查(第一种是查完再查,第二张多线程同时查)
1、如果是一次性全部查出来,该注意的就是数据量的大小了吧,因为我的数据量在100W以内,所以我采用一次性全部查出
2、如果是分批查,就要考虑是前者还是后者。如果是前者,每次查出来的就必须是之前没查出来过的(否则会重复数据),如果多线程同时查,那就得将数据做个排序,然后通过limit分片区拿不同页的数据(这个跟分页的功能是一样的,确保每一页也就是每个线程拿到的数据都不一样)
3、代码:
conn_1 = psycopg2.connect(database="数据库名", user="用户名", password="秘密",
host="数据库ip",
port="数据库端口")
cur1 = conn_1.cursor()
#通过sql中join的方式查出未爬到的数据
sql1 = "SELECT 想要查的字段 " \
"from 全量数据表 a " \
"left join 已经爬到的数据表 b " \
"on a.关联键1=b.关联键1 and a.关联键2=b.关联键2 WHERE b.关联键1 is null"
cur1.execute(sql1)
#一次性拉取所有数据
rows = cur1.fetchall()
print('拉取到数据')
#可以判断下执行的时间
start=time.time()
#########################################
##--这里是拿到数据去请求网页获得数据的代码--##
#########################################
end = time.time()
print("time: " + str(end - start))
conn_1.close()
或者如果你不想要一次性全部查出来,可以分页,sql如下:
#第一页
SELECT 想要查的字段 FROM (SELECT 想要查的字段
from 全量数据表 a
left join 已经爬到的数据表 b
on a.关联键1=b.关联键1 and a.关联键2=b.关联键2 WHERE b.关联键1 is null) c
order by 某个字段 limit 1000 offset 0
#第二页
SELECT 想要查的字段 FROM (SELECT 想要查的字段
from 全量数据表 a
left join 已经爬到的数据表 b
on a.关联键1=b.关联键1 and a.关联键2=b.关联键2 WHERE b.关联键1 is null) c
order by 某个字段 limit 1000 offset 1000
#第三页
SELECT 想要查的字段 FROM (SELECT 想要查的字段
from 全量数据表 a
left join 已经爬到的数据表 b
on a.关联键1=b.关联键1 and a.关联键2=b.关联键2 WHERE b.关联键1 is null) c
order by 某个字段 limit 1000 offset 2000
#...以此类推,多线程(或者多进程,多进程就是运行多个py文件),每个线程(或者进程)运行一个分页