背景知识:
故事要从一个很小却很困扰我的实证研究问题说起。我所研究的课题是与知识产权和软件相关,博士论文中新写的一章需要一个数据支撑。需要知道从2006年IETF(互联网工程任务组,负责互联网标准开发和推动的组织)允许技术标准贡献者贡献软件代码并要求遵循BSD开源协议许可的知识产权政策实施以来到现在,有多少技术文本中包含BSD许可协议的软件代码。起初这个问题让我很纠结。老实讲,这个数字结果只会是我文章当中非常小的一部分,也就是一小段话。但是却需要遍历4000多个网页,我计算了工时,手动查询的话,每天工作两小时,做下来需要二十天工作量。但是如果缺少这个数据分析,我就不能够深度解析该标准制定组织的知识产权政策。于是我想到了,是否可以用编程语言python来完成这个任务呢。
任务设定:
IETF所有的技术标准公开存放在以下这个网页,2006年之后的文本编码是从4226到8445。
图片1:技术标准文件编码库
进入每一个编码的超链接后,点击plain text,就找到了我需要的目标文件,即编码所代表的每一个技术标准文本。如果该文本包含关键词 “CODE BEGINS” 和 “CODE ENDS”,则说明该文件包含了根据BSD协议许可的开源软件源代码。我的任务目标是,检测这4000多个文件中有多少个技术标准文件包含了这样的开源软件源代码。图片2:包含按照BSD协议许可的开源软件源代码的技术标准文本
第一步:抓取目标文件网页
点开任意编码所代表的技术标准文本链接,对比发现,该组织所有技术标准文件的网页链接都是 https://www.rfc-editor.org/rfc/rfcxxxx.txt 格式(xxxx为编码数字)于是我们可以采用一个for循环语句,让python自动抓取编号从4226到8445的文件。采用sum统计最后我们需要的总数,这里的初始值sum设为0。
这部分的代码如下:
sum = 0
for num in range (4226,8446):
#url 是所有需要检索的技术标准文本的链接
url='http://www.rfc-editor.org/rfc/rfc' + str(num) + '.txt'
小诀窍:注意用range函数表示连续整数列表时,计数到尾数结束,但不包括尾数。例如range (0,5)是[0,1,2,3,4],不包括5。所以此处应当是range(4226,8446)。链接前半部分是字符,而每一个编码是数字,二者不能直接相加。我们用str(num)把数字变成字符串,这样则可以直接联结。
第二步:关键词检索
需要找出包含关键词CODE BEGINS和CODE ENDS的目标文件。并sum累加。不含关键词的也分别显示,但不累加。
这里需要用urlopen函数打开链接读取内容。接着通过decode(),把数据从网页的二进制代码解析成待会可用来分析的字符串。
以上两步是实现本任务目标的主体部分。但是如果仅有上述语句的话,用python运行会出现错误。经研究发现,原来是因为4226到8445这些编码,有的编码并不存在对应的文件。于是我们需要增加try语句,让python知道在遇见该错误时,跳过该编码,直接进入下一次循环。
这部分的代码如下:
from urllib import request
try:
#urlopen函数打开链接读取内容
r = request.urlopen (url)
#如果遇见错误即不存在的编码显示错误编码
except IOError:
print ('error in' + str(num))
else:
#读取存在的编码文件
txt = r.read ().decode ()
#关键词
if ('CODE BEGINS' in txt) and ('CODE ENDS' in txt):
#存在关键词显示编码并累加
print (num)
sum = sum + 1
else:
#不存在关键词显示
print ('not found in' + str(num))
#显示总数
print ('in total'+ str(sum))
任务的完整代码:
sum = 0
for num in range (4226,8446):
url='http://www.rfc-editor.org/rfc/rfc' + str(num) + '.txt'
from urllib import request
try:
r = request.urlopen (url)
except IOError:
print ('error in' + str(num))
else:
txt = r.read ().decode ()
if ('CODE BEGINS' in txt) and ('CODE ENDS' in txt):
print (num)
sum = sum + 1
else:
print ('not found in' + str(num))
print ('in total'+ str(sum))
运行结果:
最后将累计的总数sum=69显示出来,任务完成!亲测用python 3运行半个小时,结果就出来了!这不到二十行的代码自动运行半个小时,就代替了我手动操作二十天的工作量。贴结果图加笑脸。决定认真学习编程,做不了机器人,懂他们的语言,至少能做他们的朋友!图片3:结果显示部分截图
基本知识:
延伸思考:
看了这个半个小时爬虫完成手动需要二十天工作量的数据分析你心动了么?在你的研究和工作中有没有需要分析页面关键词的任务呢?希望这短短的几行编码可以给你带来灵感。欢迎在评论区分享你的问题和想法。