爬取糗事百科并保存在数据库中

本文介绍了一个爬虫项目,详细说明了如何创建爬虫类,实现初始化函数,以及获取和解析网页数据。重点在于解析过程中的下一页链接获取方法。此外,还提到了启动爬虫的函数,并提及辅助工具文件`tools`,内含两个工具类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 正则
import re
# 爬取网络数据
from urllib import request, parse
# 引入时间模块
import time
# 引入自己定义的工具类
# Tools用来清洗数据
# DBManger用来连接、关闭数据库并向数据库中插入数据
# 注:tools文件会在此博文下边给出
from tools import Tools, DBManger

声明爬虫类,定义初始化函数

class QSBKSpider(object):
    def __init__(self):
        self.url = 'https://www.qiushibaike.com/text/page/1'
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'}
        self.html = ''

获取网页的函数

    def get_html(self):
        # 声明变量记录获取网页的次数
        count = 1
        # 循环 在此循环里爬取网页,当获取网页失败且获取此数小于10时,继续爬取
        while 1:
            # 判断网页获取是否成功
            try:
                req = request.Request(self.url, headers=self.headers)
                response = request.urlopen(req)
                self.html = response.read().decode('utf-8')
            # 不成功的话先判断获取此网页的此数,如果大于10,则退出;如果小于10次,则继续爬取
            except Exception as e:
                count += 1
                if count>10:
                    print('当前页数据获取失败!')
                    break
                print('{},正在尝试第{}次连接'.format(e,count))
            # 成功爬取到网页则跳出循环
            else:
                break
            # 设置每爬取一次 间歇一分钟
            time.sleep(1)

解析数据 获取下一页链接

此处的难点与重点是获取下一页链接的方法

# 解析数据
    def parse_data(self):
        # 准备正则
        pattern = re.compile('<div.*?class="author.*?<h2>(.*?)</h2>.*?<div class="articleGender.*?>(.*?)</div>.*?<div '
                             'class="content.*?<span>(.*?)</span>.*?<i class="number.*?>(.*?)</i.*?<i.*?>(.*?)</i>',
                             re.S)
        res = re.findall(pattern, self.html)
        for info in res:
            msg = list(info)
            # 清洗数据
            msg[0] = Tools.strip_char(info[0])
            msg[2] = Tools.strip_char(info[2])
            # print('用户昵称:{}\n年龄:{}\n 内容:{}\n 好笑数:{}\n 评论数:{}'.format(msg[0],msg[1],msg[2],msg[3],msg[4]))
            # 将处理之后的数据填入数据库中  在此传递的参数可以是元组也可以是列表
            DBManger.insert_data(msg)

        # 正则直接找不到下一页链接,需要先找class="next"的位置
        # find()函数如果找到就返回字符串在网页中的位置,没有找到返回-1
        index = self.html.find('class="next"')
        # 如果找到class="next"
        if index != -1:
            # 截取它前一部分的字符串,这部分字符串将链接包括着
            s = self.html[index-100:index]
            # 再使用正则从截取的字符串中进行匹配
            next_pat = re.compile('href="(.*?)"')
            next_href = re.search(next_pat, s)
            page = next_href.group(1).split('/')[-2]
            print('正在爬取第{}页'.format(page))
            self.url = 'https://www.qiushibaike.com' + next_href.group(1)
            self.get_html()
            # 调用自身函数  解析数据
            self.parse_data()
        else:
            print('没有下一页...')

启动爬虫的函数

    def start(self):
        self.get_html()
        self.parse_data()
if __name__ == '__main__':
    # 先连接数据库
    DBManger.connect_db()
    # 爬虫
    qsbk = QSBKSpider()
    qsbk.start()
    # 关闭数据库
    DBManger.close_db()

附:文件tools,此文件包含两个工具类

# -*- coding:utf-8 -*-
import re
import sqlite3

class Tools(object):
    @classmethod
    def strip_char(cls,string):
        """
        :param string: 要进行处理的数据
        :return: 处理之后的数据
        """
        # 利用正则去除字符
        string = re.sub(re.compile('\n|\t| ', re.S), '', string)
        # 将换行标签替换为\n
        string = re.sub(re.compile('</br/>'),'\n',string)
        return string


# 数据库的管理类
class DBManger(object):
    # 声明类变量
    connect = None
    cursor = None

    # 连接数据库的操作
    @classmethod
    def connect_db(cls):
        cls.connect = sqlite3.connect('qsbk.db')
        cls.cursor = cls.connect.cursor()

    # 关闭数据库的操作
    @classmethod
    def close_db(cls):
        cls.cursor.close()
        cls.connect.close()

    # 向数据库中插入数据
    @classmethod
    def insert_data(cls,dz_tuple):
        sql = 'INSERT INTO qsbk(name,age,content,vote,comments)VALUES ("%s",%s,"%s",%s,%s)'%(dz_tuple[0],dz_tuple[1],dz_tuple[2],dz_tuple[3],dz_tuple[4])
        # 执行SQL语句
        cls.cursor.execute(sql)
        cls.connect.commit()


DBManger.connect_db()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值