用python正则表达式爬取糗事百科并储存在sql中

本文介绍了一个糗事百科爬虫项目的实现过程,包括如何利用Python进行网页抓取、正则表达式数据提取、SQLite数据库存储等关键技术点。

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

 程序主代码(详情标注)

# -*- coding: utf-8 -*-
__author__ = '木之易'
__date__ = '2018/8/7 11:20'
from urllib import request
import re
import sqlite3
from tools import StrTools

"""
QsbkSpider

url 地址
html 网页源代码
headers 请求头
conn  数据库连接
cursor 数据库游标

connect_sql() 连接数据库
close_sql() 关闭数据库
create_table() 创建数据表
get_html() 获取网页源代码
parse_html() 解析网页源代码,提取数据
save_data() 保存数据
get_next_link() 获取下一页链接
run()启动程序

"""

class QsbkSpider(object):

    def __init__(self):
        # 1.准备请求的url地址
        self.url = 'https://www.qiushibaike.com/hot/'
        self.html = ''
        # 如果不加请求头,默认情况下User-Agent是Python开头的
        # 会导致对方服务器发现你是一段爬虫程序,拒绝返回数据
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0'
        }
        self.conn = None
        self.cursor = None
        self.create_table()

    def connect_sql(self):
        """连接数据库,获取游标"""
        self.conn = sqlite3.connect('sqbk.db')
        self.cursor = self.conn.cursor()

    def close_sql(self):
        """关闭数据库"""
        # 提交操作
        self.conn.commit()
        # 关闭游标
        self.cursor.close()
        # 关闭数据库
        self.conn.close()

    def create_table(self):
        # 1.链接数据库
        self.connect_sql()
        # 2.准备sql语句
        sql = 'CREATE TABLE IF NOT EXISTS qsbk(id INTEGER PRIMARY KEY, author CHAR, age INTEGER ,content TEXT, smile_num INTEGER ,comments INTEGER)'
        # 3.执行sql
        self.cursor.execute(sql)
        # 4.关闭
        self.close_sql()

    def get_html(self):
        """构建请求,发送请求,接收响应数据"""
        # 构建请求对象
        req = request.Request(url=self.url, headers=self.headers)
        # 发请求,获取源代码
        response = request.urlopen(req)
        # 将返回的数据读取并转换为字符串,赋值给对象的html属性
        self.html = response.read().decode('utf-8')

    def parse_html(self):
        """准备正则,提取网页数据"""
        # 准备正则
        pattern = re.compile(r'<h2>(.*?)</h2>.*?<div class="articleGender.*?>(.*?)</div.*?<div class="content".*?<span>(.*?)</span>.*?<i class="number">(.*?)</i.*?<i class="number">(.*?)</i>', re.S)
        # 使用findall()函数  查找所有用户
        results = re.findall(pattern, self.html)

        for r in results:

            # 处理字符串
            author = StrTools.process_str(r[0])
            age = r[1]
            content = StrTools.process_str(r[2])
            smile_num = r[3]
            comments = r[4]
            self.save_data(author, age, content, smile_num, comments)

    def save_data(self, *args):
        """保存数据"""
        # 1.连接数据库
        self.connect_sql()
        # 2.准备sql语句
        sql = "INSERT INTO qsbk(author,age,content,smile_num,comments)VALUES('%s',%s,'%s',%s,%s)" % args
        # 3.执行sql
        self.cursor.execute(sql)
        # 4.关闭
        self.close_sql()

    def get_next_link(self):
        """
        获取下一页链接"
        :return: True 表示找到下一页,可以继续执行循环 False表示没有找到下一页,可以结束循环
        """""
        # 1.找到ul标签部分的html代码
        pattern = re.compile(r'<ul class="pagination".*?</ul>', re.S)
        # search() 1.正则表达式  2.要进行查找的字符串
        res = re.search(pattern, self.html)
        # 若找到
        if res:
            # group() 获取分组信息
            # 获取ul包裹的标签代码
            ul_html = res.group()
            # 再次使用正则从ul包裹的标签代码中提取所有页的链接
            links = re.findall(re.compile(r'<li.*?<a href="(.*?)"', re.S), ul_html)
            # 判断链接地址是否包含page字符,若包含则有下一页,若不包含则无下一页
            if 'page' in links[-1]:
                # 拼接下一页完整地址
                self.url = 'https://www.qiushibaike.com' + links[-1]
                return True
            else:

                return False
        else:

            return False

    def run(self):
        # 爬取页数初始值为零,每爬完一页,页数加1
        count = 0
        while True:
            self.get_html()
            count += 1
            print('正在爬取第%s页数据,请稍后.....' % count)
            self.parse_html()
            print('第%s页数据爬取完成,已入库!' % count)
            is_next = self.get_next_link()
            if not is_next:
                print('数据爬取完毕,已存入数据库中!')
                break

if __name__ == '__main__':

    qsbk = QsbkSpider()
    qsbk.run()

 新建一个tools文件,内写入工具类,用来清理正则表达式中无法在写正则时过滤的字符

 

# -*- coding: utf-8 -*-
__author__ = '木之易'
__date__ = '2018/8/7 11:20'

import re


class StrTools(object):
    """
    建立一个工具类
    """
    @staticmethod
    # 静态函数,可用类直接调用函数,不必再创建对象
    def process_str(string):
        """
        处理字符串中的特殊字符
        :param string: 要进行处理的字符串
        :return: 处理之后的字符串
        """
        string = string.strip('\n')
        # 准备替换br的正则
        pattern = re.compile(r'<br/><br/>|<br/>|<br>')
        string = re.sub(pattern, '\n', string)

        return string

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值