Python爬虫之BeautifulSoup+Requests爬取喜欢博主的全部博文(七)

原创不易,转载前请注明博主的链接地址:Blessy_Zhu https://blog.csdn.net/weixin_42555080
本次代码的环境:
运行平台: Windows
Python版本: Python3.x
IDE: PyCharm

一、 前言

当你比较喜欢一个博主的文章,而又想把它全部下载下来,这时候我们可以通过爬虫快速的爬取文章内容,如果需要还可以对文章进行Python的内容分析。而对于向我这样的Python初学者来说,这里面会遇到几个问题:
1)如何爬取一篇文章的内容
2)如何爬取分页的多篇文章的内容
3)如何将爬取的内容写入指定文件中
而这每一个问题中都有会涉及到很多小的问题。其实我们的代码也是按照这个思路来的,好了,那我么接下来我们开启学习之旅。
免责说明:这篇文章爬取的是https://blog.csdn.net/rlnLo2pNEfx9c/article/list/1(如图1所示)这个博主的文章,本次只是用来交流学习,如此博主有任何不满等问题,请联系我,我会立刻改换爬取的url。
 


在这里插入图片描述
图1

二、 代码编写与效果展示

首先呢,按照我们的惯例还是先给出代码和最终效果:

  1. 代码:
import requests
from bs4 import BeautifulSoup
import urllib.request
import time
import os
import urllib.error

class download(object):
    def __init__(self):
        self.chapter_name = []
        self.href_list = []
        self.head = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3493.3 Safari/537.36',
            'Accept': '*/*',
            'connection': 'keep-alive',
            'accept-encoding': 'zip, deflate, br',
            'accept-language': 'zh-CN,zh;q=0.9'
        }

    def get_url(self):
        for i in range(8):
            url = 'https://blog.csdn.net/rlnLo2pNEfx9c/article/list/%s' % (i + 1)
            strhtml = requests.get(url, params='html',headers=self.head)
            soup = BeautifulSoup(strhtml.text, 'lxml')

            data = soup.select('#mainBox > main > div.article-list > div > h4 > a')
            # print(data[0].get_text.remove[0])
            for item in data:
                result = {
                    'title': item.get_text().strip()[18:-1],
                    'URL': item.get('href'),
                    # 'URL' : re.findall('\d+',item.get('href'))
                }
                self.chapter_name.append(result.get('title'))
                self.href_list.append(result.get('URL'))

    def readSigleArticle(self,herf):
        if(herf=='https://blog.csdn.net/yoyo_liyy/article/details/82762601'):
            self.href_list.remove(herf)
        else:
            try:
                req = urllib.request.Request(herf)
                urllib.request.urlopen(req)
                singleURL = herf
                strhtml = requests.get(singleURL, params='html')
                soup = BeautifulSoup(strhtml.text, 'lxml')
                data = soup.find_all('div', class_='rich_media_content')
                self.article_content = data[0].text.replace('。', '。\n\n')
            except urllib.error.HTTPError:
                print(herf+ '=访问页面出错')
                time.sleep(2)
            except urllib.error.URLError:
                print(herf + '=访问页面出错')
                time.sleep(2)

    def write(self):
        folder_path = './CSDN'
        i = 0
        if os.path.exists(folder_path) == False:
            os.makedirs(folder_path)
        for herf in self.href_list:
            path = folder_path+'/{}'.format(i+1)
            txtPath = path + '/{}'.format(i + 1) + '.txt'
            if os.path.exists(path) == False:
                os.makedirs(path)
                open(txtPath, 'w')
            print(herf)
            with open(txtPath, 'a', encoding='utf-8') as f:
                f.write(self.article_content)

if __name__ == '__main__':
    dl=download()
    dl.get_url()
    for url in dl.href_list:
        dl.readSigleArticle(url)
        dl.write()
  1. 结果展示
    图2是是为每一篇文章都建立一个文件夹,图3是每个文件夹下都有一个扩展名为.txt的文件,图4是其中一篇.txt文件内容,图5是生成了一个名为“csdn”的文件夹存放所有的子文件夹和下载内容。
     

    在这里插入图片描述
    图2
    在这里插入图片描述
    图3
    在这里插入图片描述
    图4
    在这里插入图片描述
    图5

三、 代码讲解

接下来一一讲解一下代码,这次的代码其实是对前几篇文章代码的一个综合应用,最主要用到的还是BeautifulSoup和Requests库,还有一些time库、os库等这些我们以前也讲过了。当然如果一下子接受不了这么多代码,屡不清逻辑的话,也可以先参考我的这几篇文章:Python学习之使用Beautiful Soup解析网页(简析)Python爬虫基础之requests+BeautifulSoup+Image 爬取图片并存到本地(四)Python爬虫基础之Requests和XPath实例(二)这些内容相对来说更加容易理解。

好了咱们接下来分模块讲解代码。

1)初始化变量模块

def __init__(self):
    self.chapter_name = []
    self.href_list = []
    self.head = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3493.3 Safari/537.36',
        'Accept': '*/*',
        'connection': 'keep-alive',
        'accept-encoding': 'zip, deflate, br',
        'accept-language': 'zh-CN,zh;q=0.9'
    }

这里面的变量都是全局变量,在这里面我定义了chapter_name、href_list这两个列表用来分别存放文章姓名和文章地址链接,当然还有我们的headers这个的作用我在Python爬虫基础之requests+BeautifulSoup+Image 爬取图片并存到本地(四)这篇文章里讲过,忘记的小伙伴可以去看一下。有人会问你这个传递的“self”是啥子东西吗?这个我把它理解问一个桥梁,通过self.XX在一个函数中就可以给其他函数传递内容,当然也可以把它理解为一个java学的public,即定义了一个共有属性。

2) 获取全部文章的url模块

def get_url(self):
    for i in range(8):
        url = 'https://blog.csdn.net/rlnLo2pNEfx9c/article/list/%s' % (i + 1)
        strhtml = requests.get(url, params='html',headers=self.head)
        soup = BeautifulSoup(strhtml.text, 'lxml')

        data = soup.select('#mainBox > main > div.article-list > div > h4 > a')
         for item in data:
            result = {
                'title': item.get_text().strip()[18:-1],
                'URL': item.get('href'),
              }
            self.chapter_name.append(result.get('title'))
            self.href_list.append(result.get('URL'))

这篇文章里面的内容大部分我再这篇文章Python学习之使用Beautiful Soup解析网页(简析)已经涉及到了,忘记的小伙伴可以去踩踩哦!
挑一些没有以前涉及到内容讲解一下:(1)首先呢,解释一下,我的range(Num)中的Num为什么是8,这是因为看博主的全部文章只用了8个分页,这个数字实际是分页的计数。(2)url = ‘https://blog.csdn.net/rlnLo2pNEfx9c/article/list/%s’ % (i + 1)这个里面我们用到了字符格式化,这个内容可以参考这两篇文章:https://www.cnblogs.com/fat39/p/7159881.html和https://www.cnblogs.com/czqq/p/6108557.html,同时也需要解释一下为什么要这么写,通过打开不同分页,

https://blog.csdn.net/rlnLo2pNEfx9c/article/list/1
https://blog.csdn.net/rlnLo2pNEfx9c/article/list/2
https://blog.csdn.net/rlnLo2pNEfx9c/article/list/3

我们可以看到他们的url的不同就是在最后一个数字,所以我们可以通过控制最后一个数字,通过拼接字符串实现改变url,进而实现读取不同分页博文的url的功能。(3)最后两句还是通过self这个桥梁将数据公有化。

3)单篇文章内容下载

def readSigleArticle(self,herf):
    if(herf=='https://blog.csdn.net/yoyo_liyy/article/details/82762601'):
        self.href_list.remove(herf)
    else:
        try:
            req = urllib.request.Request(herf)
            urllib.request.urlopen(req)
            singleURL = herf
            strhtml = requests.get(singleURL, params='html')
            soup = BeautifulSoup(strhtml.text, 'lxml')
            data = soup.find_all('div', class_='rich_media_content')
            self.article_content = data[0].text.replace('。', '。\n\n')
        except urllib.error.HTTPError:
            print(herf+ '=访问页面出错')
            time.sleep(2)
        except urllib.error.URLError:
            print(herf + '=访问页面出错')
            time.sleep(2)

其中(1)

if(herf==‘https://blog.csdn.net/yoyo_liyy/article/details/82762601’):
self.href_list.remove(herf)

之所以写这部分内容,是因为爬取完“获取全部文章的url模块“后看到里面竟然出现了一篇完全不相干的内容,在页面上也没找到,所以当读到它的时候就去除该链接。(2)为了避免出现打不开的页面,特意写了一个异常处理块,这里面涉及到的内容可以看一下这篇文章https://blog.csdn.net/sinat_41104353/article/details/79296541
(3)其中self.article_content = data[0].text.replace(’。’, ‘。\n\n’)
再说这个代码之前我们可以看一下图6这个内容,我们发现这些文本信息都是一个完整的句子,并以句号结尾,其实我们获得的data数据是一个完整的列表对象(该对象里面有全部的HTML内容),我们通过data[0].text取到该HTML中的文本信息(但是此时的内容是一个没有换行的列表信息),然后通过replace(‘。’,’。\n\n’)去替换就可以实现获得整篇文章的文本,并且是一句一换行,比较美观。
 


在这里插入图片描述
图6

4) 写模块

def write(self):
    folder_path = './CSDN'
    i = 0
    if os.path.exists(folder_path) == False:
        os.makedirs(folder_path)
    for herf in self.href_list:
        path = folder_path+'/{}'.format(i+1)
        txtPath = path + '/{}'.format(i + 1) + '.txt'
        if os.path.exists(path) == False:
            os.makedirs(path)
            open(txtPath, 'w')
        print(herf)
        with open(txtPath, 'a', encoding='utf-8') as f:
            f.write(self.article_content)

(1)这个内容大部分已经涉及到了,忘记的小伙伴可以去看一下我的这篇文章哦!Python爬虫基础之requests+BeautifulSoup+Image 爬取图片并存到本地(四)(2)其中代码里面涉及到的读写操作可以参考这篇博文,讲解比较详细:https://www.cnblogs.com/snowbook/p/5764549.html
(3)其中

path = folder_path+’/{}’.format(i+1)
txtPath = path + ‘/{}’.format(i + 1) + ‘.txt’

这部分内容涉及到了字符串格式化:

> 符串类型格式化采用format()方法,基本使用格式是:
 <模板字符串>.format(<逗号分隔的参数>)
调用format()方法后会返回一个新的字符串,参数从0 开始编号。
">>> {}:计算机{}的CPU 占用率为{}%。".format("2016-12-31","PYTHON",10)
 >>> Out[10]: '2016-12-31:计算机PYTHON的CPU 占用率为10%。'

format()方法中<模板字符串>的槽除了包括参数序号,还可以包括格式控制信息。此时,槽的内部样式如下:
{<参数序号>: <格式控制标记>}
其中,<格式控制标记>用来控制参数显示时的格式,包括:<填充><对齐><宽度>,<.精度><类型>6 个字段,这些字段都是可选的,可以组合使用。

以上内容参考博文https://blog.csdn.net/i_chaoren/article/details/77922939

5)主函数模块

if __name__ == '__main__':
    dl=download()
    dl.get_url()
    for url in dl.href_list:
        dl.readSigleArticle(url)
        dl.write()

通过实例化download类,进而通过调用类中的方法,从而实现对全部的博文下载的效果。

四 总结

总而言之,我们这次是通过定义一个download类在类中有多个函数分别实现: def init(self)初始化变量、def get_url(self)获得全部的url、def readSigleArticle(self,herf)读取单篇文章的内容、def write(self)在本地写下文章的内容,通过在主函数if name == 'main’中实例化类,调用类中的方法,实现喜欢博主的全部博文的目的。本篇内容综合应用了前面学到的内容,算是一个阶段的成果。但是本文只是实现了爬取文章中的文字的效果,对于博文中的图片、数表等还没有实现爬虫提取的效果,通过进一步对Python的学习,日后会继续完善 爬虫数据清洗数据可视化 的效果。同时也希望大佬们批评指正,因为是新手难免会有说的不恰当甚至错误的内容,还请大佬们不要手下留情。

  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值