简单的爬虫

  • Post author:
  • Post category:其他


爬虫网站的步骤:

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()

输出结果:



版权声明:本文为weixin_45275526原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。