美文网首页
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