起因
Gerrit,一种免费、开放源代码的代码审查软件,使用网页界面。利用网页浏览器,同一个团队的软件程序员,可以相互审阅彼此修改后的程序代码,决定是否能够提交,退回或者继续修改。它使用Git作为底层版本控制系统。
一句话概括,就是网页上查看你对git的修改信息,并且决定是否合入分支的一个中间审查工具。
起因是公司想要规范化工程师的提交信息,虽说不是我来弄,但是我想试试用之前学的爬虫来尝试抓取,并且可以初步的数据处理分析,然后可视化。正好一整套的流程走一遍。说干就干,打开网页,F12。
发现数据在表格里。抓呗!
但是发现抓出来的数据样子乱七八糟,最关键的是并没有这个table。所以就猜想,应该是动态加载的,转到network,xhr。
再刷新下页面,发现数据都在这个接口里嘛,这就简单了!
这里写图片描述
设计流程:获取数据,处理数据,可视化。
第一步:先获取数据,存到表格里。
一定要记得cookie啊,血的教训,我折腾了好久,得到的都是几个字符,后来才醒悟过来。
def requesst(url,limit_time):
continue_flag = 1
# while(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
'Cookie': 'GerritAccount=aRqdfpU4Oa1tMBZglP3GWlz.y1oY.8am'
}
data = requests.get(url, headers=headers).text
# content = data.text #你要的数据,JSON格式的
remove = re.compile('\)\]\}\'')
#去掉多余的几个垃圾字符
# data = data.replace(')]}\'',"")
data = re.sub(remove, "", data)
data_json = json.loads(data)
with open("gerrit.csv", "a",newline='') as csvfile:
writer = csv.writer(csvfile)
for one in data_json:
one["updated"] = time_format(one["updated"])
if (time_cmp(one["updated"], limit_time) < 0):
print("已经发现有超过时间的数据")
continue_flag = 0
break
else:
writer.writerow([one["project"], one["branch"], one["subject"], one["owner"]["name"], one["updated"]])
print(one["project"], one["branch"], one["subject"], one["owner"]["name"], one["updated"], one["_sortkey"])
return continue_flag, DOWNLOAD_URL + "&N=" + data_json[-1]["_sortkey"]
continue_flag是为了主程序里超过我限定的时间后就不再爬取下一页。
gerrit的默认url是下面这个url,然后下一页按钮的url是这个url加上这一页最后一项的_sortkey(形如0049b98c0000f3b8)。所以我要把下一页的url也return出来。
DOWNLOAD_URL = 'http://192.168.8.40:8080/changes/?q=status:merged&n=25&O=1'
# DOWNLOAD_URL = 'http://192.168.8.40:8080/changes/?q=status:merged&n=25&O=1&N=0049b98c0000f3b8'
嘿嘿,这个是最后的结果,中间编写过程就不放了,总之是不断丰富,不断简化的过程。
第二部分:处理数据。
#用正则表达式统计不符合规范的人员及其出现的个数 得到一个DataFrame
def subject_format_count():
nonstandard_count={}
#newline=' '可以防止两行之间出现空行
with open(r"gerrit.csv",newline='') as csvfile:
readCSV = csv.reader(csvfile, delimiter=',')
for row in readCSV:
matchObj = re.match(r"^TFS_\d+:" + row[3] + "_\D+\w+:.+", row[2])
if matchObj:
pass
else:
if row[3] in nonstandard_count:
nonstandard_count[row[3]] += 1
else:
nonstandard_count[row[3]] = 1
#去掉统进来的标签
nonstandard_count.pop('owner')
#按出现次数递减排序
sort_nonstandard_count = sorted(nonstandard_count.items(), key=lambda v: v[1], reverse=True)
#这地方的设置可以先查看sort_nonstandard_count 然后看看具体要的是哪个值 根据这里再写可视化
df = pandas.DataFrame(sort_nonstandard_count, index=[item[0] for item in sort_nonstandard_count])
return df
正则表达式可以度娘在线正则表达式测试找到最合适的正则。如果符合正则表达式则不处理,如果不符合,则将其存到nonstandard_count并且值+1。然后得到的nonstandard_count按照值排序,大的在前面。返回一个DataFrame,方便后续处理。
第三步:可视化
##可视化处理###############
def view_format_count(df):
# x为横坐标刻度
x = np.arange(len(df.index))
# 设置y轴的数值,取df的1列,0列为横坐标
y = np.array(df[1])
# 设置x横坐标显示为0列的名字
xticks1 = np.array(df[0])
# 设置横坐标格式 倾斜30°
plt.xticks(x, xticks1, size='small', rotation=30)
# 画出柱状图 appha为透明度
plt.bar(x, y, width=0.35, align='center', color='c', alpha=0.8)
# 在柱形图上方显示y值 zip(x,y)得到的是tuple列表 即各列顶点的坐标
# 然后再各列的顶点上方0.05设置一个文本 ha水平对齐left,right,center va垂直对齐 'center' , 'top' , 'bottom' ,'baseline'
for a, b in zip(x,y):
plt.text(a, b + 0.05, '%.0f' %b, ha='center', va='bottom', fontsize=11)
plt.show()
注释很详细了,就是画出df,然后在柱形图上加上这个值的text。
第四步 main
def main():
limit_time = input("请输入截止时间 格式:20171211000000\n")
url = DOWNLOAD_URL
continue_flag = 1
#写标题
with open("gerrit.csv", "w",newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["project", "branch", "subject", "owner", "updated"])
#循环爬下一页
while (continue_flag):
continue_flag, url = requesst(url,limit_time)
#处理数据并可视化
view_format_count(subject_format_count())
这个只是串起来了。关键的代码基本都贴出来了,其他的几个稍微处理数据的,没有贴出,可以访问我github查看。
github
这个直接爬是没用的哈,我是内网。
结果
额,我升级PyCharm前还好好的啊。升级完咋就这样了呢......我后面再琢磨琢磨。
总结一下
总的来说收获很大,自己实打实的从0开始做一个小的工具(都不算项目)。整个过程虽说小困难不断,但是基本都能找到问题所在,网上找到解决方法。其实没想象的难的,只要拆分成一部分一部分然后开始动手就好。虽说之前学得部分实在生疏,但做这个确实熟练了很多,就好像以前学习的时候,看着老师讲都懂,但是自己实际做题就懵了。多练就好!然后建议大家也在学习的过程中不断的找一些对自己能用上的小项目去做,会有成就感的!
网友评论