美文网首页
Python爬虫项目 -- 爬取豆瓣读书新书速递并按出版日期排名

Python爬虫项目 -- 爬取豆瓣读书新书速递并按出版日期排名

作者: liaojiawei | 来源:发表于2020-04-21 08:58 被阅读0次

    目的:爬取豆瓣读书/新书速递这一页下所有的书名、作者、出版社和出版日期,并依据出版的先后时间对书名进行排序

    思路分析:首先分析原网页,以某一本书为类,把要爬取内容的父级标签取出来;然后依次对子级标签(书名、作者等)进行正则匹配;得到书名、作者等目标元素存储在dict中,通过循环得到页面所有的目标元素,交给list存储;最后对list进行排序操作

    要用到的库

    import pysnooper
    import requests
    import re
    
    • pysnooper是一种代码检查工具,可以通过python的pip安装
    pip install pysnooper
    
    • re是Python内置模块, 提供了 Perl 风格的正则表达式模式
    目标信息 源代码分析 输出结果

    完整代码:

    @pysnooper.snoop(output='./log/debug.log')
    class Spider():
        # 爬取目录地址
        url = 'https://book.douban.com/latest?icn=index-latestbook-all'
    
        # 打开浏览器, 直接复制请求报头
        user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36 Edg/81.0.416.53'
        headers = {
            'User-Agent': user_agent
        }
    
        # 要用到的各种正则表达式作为类属性, 后面会用到
        root_pattern = '<div class="detail-frame">([\s\S]*?)</div>'
        bn_pattern = '<a[\s\S]*?>([\s\S]*?)</a>'
        ed_pattern = '<p class="color-gray">([\s\S]*?)</p>'
        da_pattern = '<p class="color-gray">[\s\S]*?(\d{4}-\d{1,2}-?\d?)[\s\S]*?</p>'
    
        '''
        @description:爬取网页原始数据
        @param {type} 这里说一下,所有类的方法都要传入self参数 {object}
        @return: 异常或是原始html页面
        '''
        def __fetch_content(self):
            try:
                r = requests.get(self.url, headers=self.headers)
                r.raise_for_status()  # 请求状态码。 当然这里是多余的,只是记一下,可以通过不同的状态码,抛出不同的异常提示
                r.encoding = r.apparent_encoding
                return r.text
            except Exception as e:
                return e
    
        '''
        @description: 对请求的网页进行分析处理,这里需要用到上面定义的正则表达式
        @param {type} 原始页面数据
        @return: 目标信息列表list
        '''    
        def __analysis(self, html):
    
            # root_html为目标元素的父级标签,一本书的所有目标信息都在这个地方
            root_html = re.findall(self.root_pattern, html)
            authors = []
    
            # 4. 循环得到页面所有书籍的信息
            for i in root_html:
                book_name = re.findall(self.bn_pattern, i) # 1. 得到书名
                editor_name = re.findall(self.ed_pattern, i) # 2. 得到作者/出版信息
                date = re.findall(self.da_pattern, i) # 3. 从出版信息中分解出出版日期
    
                # 将一本书的目标信息存储在dict中
                author = {'book_name': book_name,'editor_name': editor_name,'date': date}
    
                # 依次将每本书的信息添加到author列表中
                authors.append(author)
    
            # 返回书籍信息列表
            return authors
    
        '''
        @description: 对__analysis返回的信息进一步处理,因为此时得到的数据有很多空白字符(包括换行符),这个方法的目的是把不需要的字符处理成完全干净的字符
        @param {type} 经过分析得到的信息列表
        @return: 干净的目标信息列表list
        '''    
        def __refine(self, authors):
    
            # lambda匿名函数对authors进行深度处理
            l = lambda authors: return {
                'book_name': author['book_name'][0],
                'editor_name': author['editor_name'][0].strip(),
                'date': author['date'][0]
            }
    
            # map()函数把authors列表中每一个dict通过匿名函数处理
            return map(l, authors)
    
        '''
        @description: 返回排序后的信息列表
        @param {type} 信息列表
        @return: 信息列表
        '''    
        def __sort(self, authors):
            return sorted(authors, key=lambda authors: authors['date'])
    
        # 定义排序规则 -- 以出版日期进行排序 图三
        def __sort_seed(self, authors):
            return authors['date']
    
        # 整理输出列表0
        def __show(self, authors):
            for i in range(0, len(authors)):
                print('出版时间排名第' + str(i + 1) + ':' +
                      authors[i]['book_name'] + ' ----- ' + authors[i]['editor_name'])
    
        # 除了go方法之外,其他所有的方法都是类的私有方法,不允许外部直接访问,一切数据处理的入口都是go()函数
        def go(self):
            html = self.__fetch_content()
            Message_info = self.__analysis(html)
            Message_info = list(self.__refine(Message_info))
            Message_info = self.__sort(Message_info)
            Message_info = self.__show(Message_info)
            print(Message_info)
    
    
    spider = Spider()
    spider.go()
    

    参考文档:

    吟: python之r.raise_for_status() : https: // blog.csdn.net / kangyan_ / article / details / 78506243

    python调试利器pysnooper : https: // blog.csdn.net / luanpeng825485697 / article / details / 102954985)

    pysnooper github地址 : https: // github.com / cool - RR / pysnooper

    相关文章

      网友评论

          本文标题:Python爬虫项目 -- 爬取豆瓣读书新书速递并按出版日期排名

          本文链接:https://www.haomeiwen.com/subject/xkbjihtx.html