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

 程序主代码(详情标注)

# -*- 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'

(.*?)

.*?
(.*?).*?(.*?)(.*?)', 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'
    ', 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'

 新建一个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'

|
|
') string = re.sub(pattern, '\n', string) return string

 

你可能感兴趣的:(python,sql)