一份爬虫文件的分析

一份爬虫文件的分析

最近实验室学长布置下来了任务,是有关将各种CVE的信息整合后形成一张攻击图的。下面的代码是最开始的步骤,目的是通过python爬虫将CVE的四个目标信息从两个网站上爬取下来,并存入mongodb数据库。

源代码

# Script to web scrape vulnerability information into mongodb

from bs4 import BeautifulSoup
from pymongo import MongoClient
from urllib.request import Request, urlopen
import csv
import sys
import re

client = MongoClient('mongodb://localhost:27017/')
db = client.project #project是一个自定义的数据库。
vulns = db.vulnerabilities #vulnerabilities是db中的一个数据表
vulns.drop()  #删除数据表中的集合【删除之前,重新爬取最新的数据】

mapping1 = { 'High': 2, 'Low': 1, 'None': 0 } #数据结构——字典
mapping2 = { 'Admin': 2, 'User': 1, 'None': 0 }

filename=sys.argv[1]  #在命令行中输入的第二个文件,第一个文件就是这个py文件本身
print("Current file:\t", sys.argv[1])

try:
    with open(filename) as csv_file:  #with语句打开文件不用手动关闭文件,提高了代码的优雅性
        csv_reader = csv.reader(csv_file) #调用csv库中的reader方法得到一个遍历csv文件各行的读取器对象
        for row in csv_reader: #利用for循环把csv文件每行的内容读取下来[每行返回的是一个列表]
            CVE = row[0]  #行列表的第一个,因为每行只有一个文件,所以返回的值就是那个CSV的名称
            print(CVE)
            url = "https://www.cvedetails.com/cve/" + CVE
            req = Request(url, headers={ 'User-Agent': 'Mozilla/5.0' })
            html_doc = urlopen(req).read()
            soup = BeautifulSoup(html_doc, 'lxml')  #BeautifulSoup使得按照标签、id、class来寻找内容成为可能
            table = soup.find("table", { 'id': 'cvssscorestable', 'class': 'details' })
            field_row = table.findAll("tr")[6]
            field_value = field_row.find("span").string
            gained_access = mapping2[field_value]

            url = "https://nvd.nist.gov/vuln/detail/" + CVE
            html_doc = urlopen(url).read()
            soup = BeautifulSoup(html_doc, 'lxml')

            required_priv_string = re.findall("vuln-cvssv3-pr\&\#39\;\&gt\;\s(.*?)\s\&lt.*",html_doc.decode()) #re是正则模块,引号内的内容就是正则语句,注意html_doc.decode()的内容和soup的内容略有不同
            if len(required_priv_string) != 0:
                field_value = required_priv_string[0]
            else:
                field_value = 'None'

            required_priv = mapping1[field_value]

            attack_vectors = re.findall("vuln-cvssv2-av\&\#39\;\&gt\;(.*?)\&lt.*",html_doc.decode())
            attack_vector = attack_vectors[0]

            # Add entry
            document = {}
            document['cveName'] = CVE
            document['gained_access'] = gained_access
            document['required_priv'] = required_priv
            document['access_vector'] = attack_vector

            #print(document)
            vulns.insert_one(document)

    print("Successfully imported CVE details")

except IOError:
    print("File {} does not exist".format(filename))
    exit()

pymongo模块

这个python模块是用来连接本地的mongodb的。

from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client.project 
vulns = db.vulnerabilities
vulns.drop()  

我们初始化一个MongoClient之后就可以用.来选择数据库、数据库再.一下就是数据表。数据表的各种操作也是通过. ;非常直观与易用。这里要注意的是,我们使用client.database来选择一个数据库的时候,如果这个数据库不存在,我们这样调用后这个database不会立刻被创建,只有这个数据库中有表了,并且往表中插入集合后,这个数据库才会被创建。

sys模块

sys.argv属性会以列表方式返回我们在python3命令后输入的文件名称。其中sys.argv[0]自然就是我们运行的python文件名。

➜  ~ cat test.py         
import sys
print(sys.argv)%                                                                 
➜  ~ python3 test.py fuck
['test.py', 'fuck']

python with语句

with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等。

我们可以利用with语句来打开一个文件,这样我们就不用手动来关闭文件,提高了代码的优雅度。

with open(filename) as f: 
    dosomething

同时我们可以用as来给这个文件句柄取一个好听的别名。

csv库

之前只是听说过CSV这个词,今天更加深入地了解了一下。

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须像二进制数字)那样被解读的数据。

这个爬虫文件用到了这样一个csv文件。

在这里插入图片描述

我们在之后的程序中会爬取这些CVE的信息,那python是如何处理CSV文件的呢?

这里利用到了csv这个库。

csv_reader = csv.reader(csv_file) #调用csv库中的reader方法得到一个遍历csv文件各行的读取器对象
    for row in csv_reader: #利用for循环把csv文件每行的内容读取下来[每行返回的是一个列表]
        CVE = row[0]  #行列表的第一个,因为每行只有一个文件,所以返回的值就是那个CSV的名称
        print(CVE)

urllib.request库中Request和urlopen

from urllib.request import Request, urlopen

url = "https://www.cvedetails.com/cve/CVE-2021-31760"
req = Request(url, headers={ 'User-Agent': 'Mozilla/5.0' })
html_doc = urlopen(req).read()

我们来看一看html_doc会返回怎么样的内容。

在这里插入图片描述

经过vscode的格式化之后,我们发现它和普通的html文件差不多,但是有着许多\r\n\t等换行符。

我们可以通过输出html_doc.decode()来消除掉这些换行符,代码和结果如下

from urllib.request import Request, urlopen

url = "https://www.cvedetails.com/cve/CVE-2021-31760"
req = Request(url, headers={ 'User-Agent': 'Mozilla/5.0' })
html_doc = urlopen(req).read()
with open('3.html', "w") as f:
  f.write(str(html_doc.decode()))

在这里插入图片描述

bs4库中的BeautifulSoup

我们看到利用urllib.request里面的Request和urlopen已经爬到了网页的源代码。那我们为什么还需要BeautifulSoup这个工具呢?原因在于我们用它可以方便得利用标签、id、class来进行信息的检索。

soup = BeautifulSoup(html_doc, 'lxml') #选择lxml解析器
table = soup.find("table", { 'id': 'cvssscorestable', 'class': 'details' })#找到id为cvs...;class为details的table标签
field_row = table.findAll("tr")[6] #在这个标签中找到第七个tr标签
field_value = field_row.find("span").string	#得到这个tr标签中的span标签的值

re正则库

 required_priv_string = re.findall("vuln-cvssv3-pr\&\#39\;\&gt\;\s(.*?)\s\&lt.*",html_doc.decode())

利用re可以实现正则匹配。

在这里插入图片描述

format格式函数

print("File {} does not exist".format(filename))

实现了类似C中%s的操作。python中用{}来代替。

~ cat test.py
print('{} yyds!'.format('wuuconix'))%~ python3 test.py
wuuconix yyds!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值