初学:简单爬取糗事百科段子

糗事百科属于静态文章

爬取静态网站关键点:写正则表达式

引包:

                          sqlite3数据库包: import sqlite3 
                                正则表达式:  import re
   负责打开浏览url内的html 文本: from urllib.request import Request, urlopen
   随机生成代理ip(浏览器请求头): from fake_useragent import UserAgent

建类:
        1.工具类
            对提取的元组中的数据,进行整理,删除无效的字符的类(\n.
)
            思路:先用正则表达式对爬取出的数据进行二次爬取,将要整理的字符串用sub方法进行替换,最后将结果重新封装成一个元组。
            origin_tuple_data:爬取出的一次数据。
                         data: 爬取出的二次数据
       sub(参数1,参数2,参数3): 替换规则,替换结果,替换元组
       =================================================================================             
            class DataTool(object):
                pattern_n = re.compile(r'\n', re.S)
                pattern_br = re.compile(r'
', re.S)

                def process_tuple_data(self,origin_tuple_data):
                    nick_name = re.sub(self.pattern_n, '', origin_tuple_data[0])
                    content = re.sub(self.pattern_n, '', origin_tuple_data[2])
                    content = re.sub(self.pattern_br, '', content)
                    data = (nick_name, origin_tuple_data[1], content, origin_tuple_data[3], origin_tuple_data[4])
                    return data
       ==================================================================================
        2.数据库工具类
            操作数据库:

                        1.创建数据库的连接对象,创建游标,这两个对象一般连接一次即可;
                        2.数据的增删改查;
                        3.关闭数据库、关闭游标对象,一般都是在数据保存完毕之后关闭即可。
       ==================================================================================
            class DBTool(object):
                connect = None
                cursor = None
    
                @classmethod
                def create_db_cursor(cls):
                    cls.connect = sqlite3.connect('qsbk.db')             数据库连接
                    cls.cursor = cls.connect.cursor()                         创建游标

                @classmethod
                def insert_db_cursor(cls, tuple_data):                     传入元组,用insert插入语句将元组中的数据加入表中(qs为表名,表需要自己在数据库中建立)         
                    sql_str = 'INSERT INTO qs (nick_name, level, content, vote_number, comment_number) VALUES("%s","%s","%s","%s","%s")' % (tuple_data[0],tuple_data[1],tuple_data[2],tuple_data[3],tuple_data[4])    
                    cls.cursor.execute(sql_str)                            执行sql语言
                    cls.connect.commit()                                     提交到数据库                         

                @classmethod
                def close_db_cursor(cls):                                  
                    cls.cursor.close()                                       关闭游标
                    cls.connect.close()                                    关闭连接
       ===================================================================================
       3.爬虫类:对象属性
       ===================================================================================
            class QSBKSpider(object):
                def __init__(self):
                    self.base_url = 'https://www.qiushibaike.com/hot/page/'    页面路径
                  # self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}                                       浏览器请求头
                    self.tool = DataTool()                                               实例化工具类DataTool的对象
                    self.ua = UserAgent()                                              实例化ua对象

                def get_list_html(self,page_num):                               如果有多页,获取每一个列表页的html网络源代码
                    page_url = self.base_url + str(page_num)               构造每一页的url地址  
                    headers = {'User-Agent': self.ua.random   }             random属性:从ie、firefox、chrome等浏览器的ua中,随机获取一个ua即user-agent
                    request = Request(page_url, headers=headers)
                    try:
                        response = urlopen(request)                         实现对目标url的访问
                    except Exception as e:
                        print('请求失败:地址{},原因{}'.format(page_url, e))
                        return None
                    else:
                        return response.read().decode()

                def parse_list_html(self, html):                             解析上一个函数请求的html源代码
                    if html:
                        # 使用正则表达式开始解析网页源代码
                        # 写正则注意事项:
                        # 1.尽量找到要匹配的零散数据所在的标签,而且这个标签必须和这些零散的数据一样能够循环。因为findall在循环匹配数据的时候,是按照整个正则表达式规则循环匹配的。
                        # 2.在参考网页中"审查元素"来设置正则匹配规则的时候,一定要确认是否和"网页源代码"中的标签顺序、属性顺序等保持一致,如果不一致的话,必须参考“网页源代码”来设置正则匹配规则。因为“审查元素”中的html代码是经过JS渲染之后的源代码。

                        pattern = re.compile(r'

.*?

(.*?)

.*?
(.*?)
.*?
(.*?).*?
.*?(.*?).*?(.*?)',re.S)
                        results_list = re.findall(pattern, html)
                        for data in results_list:
                            new_data = self.tool.process_tuple_data(data)    用工具类对爬取出的数据进行二次处理
                            DBTool.insert_db_cursor(new_data)                存入数据库
                            print(new_data)

                    else:
                        print('html源代码为None')


            if __name__ == '__main__':
                DBTool.create_db_cursor()                              创建数据库对象、游标对象
                obj = QSBKSpider()                                         创建类对象
                for x in range(1,10):                                         循环爬取多页数据,当然这个爬取的总页码也是可以通过爬取首页的页面得到
                    html = obj.get_list_html(x)                             range()取1到10之间的整数,能取到1,无法取到10
                    obj.parse_list_html(html)
                    DBTool.close_db_cursor()                            关闭数据库、游标对象


            fake_user_agent: pip install fake-useragent 这个第三方库,它维护了各种主流浏览器的UA标识,并且会定期的更新这个库,淘汰一些过期的UA。
 

数据库表:数据库保存在和.py文件同一文件夹下

初学:简单爬取糗事百科段子_第1张图片

运行结果:

初学:简单爬取糗事百科段子_第2张图片

数据库中保存信息:

初学:简单爬取糗事百科段子_第3张图片

 

你可能感兴趣的:(python,学习,爬虫,python)