爬虫网站的步骤:
1、找到要爬取的网址
2、分析网页内容,按F12控制后台,找到需要的数据在网页的哪个元素
(1)下载网页数据,使用requests模块(python3.7,pip install requests)
(2)解析HTML,使用BeautifulSoup模块(python3.7,pip install beautifulsoup4)
3、将获取的数据存储(sqllite数据库)
使用的数据库是sqlite3,python3.7
整体思路:
1、建立数据库连接函数并返回连接;
2、创建表
3、爬取数据,并插入表中
4、查询表中的数据
5、关闭数据库连接
难点:
a.判断表存不存在:create table if not exists
b.如何输出查询的数据:fetchall(),返回的是有多个 元组的 列表
c.判断插入的数据在表中是否存在,不存在才插入数据,
d.如何访问 列表中 元组的 元素:map(),itemgetter()
e.爬虫的间隔时间,如每5分钟爬取一次页面,time.sleep()
# 5分钟爬取一次漏洞网页,获取新的漏洞评分高于9的漏洞
# 下载网页使用requests模块
import requests
#解析HTML,得到目标数据使用BeautifulSoup模块
from bs4 import BeautifulSoup
# 时间模块time
import time
# 导入sqlite3模块
import sqlite3
from operator import itemgetter
def connect_db():
# 建立数据库连接,如果不存在将会创建该数据库
conn = sqlite3.connect('D:/vul.db')
# 事务隔离级别,默认是需要自己commit才能修改数据库,置为None自动每次修改都提交
conn.isolation_level = None
# 返回一个连接,可连接使用数据库
return conn
# 爬取数据(cvss_id,cvss_name,cvss_score,cvss的编号,名称,评分),并插入数据库的表中
def grab():
# 请求并下载网页
response = requests.get(r'网页地址')
# 将网页源码构造成一个beautifulSoup解析对象,html.parser网页解析器
high_risk_list = BeautifulSoup(response.text, "html.parser", from_encoding="utf-8")
# 获取a标签的对象a_node
tbody = high_risk_list.find('tbody')
# 将获取的到的数据通过游标插入到数据库中
cursor_grab = connect_db().cursor()
# 循环获取到所有a标签对象的文本(cvss的编号)和href
for a in tbody.find_all('a'):
# 获取a标签的文本.string,replace(" ", "").replace("\n", "")取消空格,换行
cvss_id = a.string.replace(" ", "").replace("\n", "")
# print('cvss_id:', cvss_id)
# 并请求所有a标签的链接,获取一个标签对象的属性get('xxx')
detail = '网页地址' + a.get('href')
# print(detail)
res = requests.get(detail)
# 将请求的新的页面(漏洞详情)构造成一个对象cvss_detail
cvss_detail = BeautifulSoup(res.text, "html.parser", from_encoding="utf-8")
cvss_name = cvss_detail.find('span', class_='header__title__text').text
# print('cvss_name:', cvss_name)
# 获取到漏洞的评分,
cvss_score = cvss_detail.find('div', class_='属性值').text.replace(" ", "").replace("\n", "")
# print('cvss_score:', cvss_score)
# 把cvss_id,cvss_name,cvss_score插入到数据库的表中,%字符串转换格式化
sql_insert = 'insert into cvss_table(cvss_id,cvss_name,cvss_score) values("%s","%s","%s")' % (cvss_id, cvss_name, cvss_score)
# 查询表中的id,如果没有就新增到表中,并告警
sql_selectID = 'select * from cvss_table'
cursor_grab.execute(sql_selectID)
#fetchall()从结果集中获取所有行(结果行)
fetchall = cursor_grab.fetchall()
# print('fetchall:', fetchall)
# cursor_grab.fetchall()返回的是有多个元组的 列表
# 访问列表中 元组的 元素,
# 使用运算符模块中的itemgetter()函数可以从给定的iterable(可迭代的)中获取每个项目,直到搜索到iterable的末尾为止
# 从fetchall列表中搜索索引的位置0,然后应用map函数将相同的函数一次又一次地应用与itemgetter函数结果的每个结果,最后将结果存储为列表
id_table = list(map(itemgetter(0), fetchall))
# 爬取评分大于9分的漏洞
if float(cvss_score) > 9:
# 如果查询到数据库中有漏洞信息则不插入,没有则插入并告警
if cvss_id not in id_table:
cursor_grab.execute(sql_insert)
print('发现新增高危漏洞:', cvss_name)
# 关闭游标
cursor_grab.close()
if __name__ == '__main__':
# 1新建表,,create table if not exists判断表存不存在,存在就不建立,不存在就建立
sql_create = 'create table if not exists cvss_table(cvss_id varchar(30) PRIMARY KEY, cvss_name varchar(30), cvss_score integer)'
cursor = connect_db().cursor()
cursor.execute(sql_create)
print("create table OK!")
# 2循环2次爬取数据
for i in range(2):
print('----第', i, '次爬取数据-----')
grab()
# 休眠5分钟后再继续爬取数据,单位为秒
# time.sleep(5*60)
time.sleep(2)
# 3查询插入表的数据
sql_select = 'select * from cvss_table'
cursor_sel = connect_db().cursor()
cursor.execute(sql_select)
print('----查询表的数据-----')
data = cursor.fetchall()
for d in data:
print(d)
# 4关闭数据库连接
cursor.close()
connect_db().close()
输出结果: