百日筑基篇——爬取CSDN博客上的文章

百日筑基篇——爬取CSDN博客上的文章


前言

随着博客文章的不断增多,如何对自己的博客文章进行整理变得重要。本章就基于笔者自身的博客,来展示如何爬取博客上的文章url以及其它信息。最后保存为一个csv文件。

参考文章:
https://blog.csdn.net/seanyang_/article/details/126571472


一、爬虫代码

1.1. 设置请求头与url

在这里插入图片描述
在这里插入图片描述

import csv
from bs4 import BeautifulSoup
import requests

headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                         "(KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46"
           }  # 设置请求头,模拟用户

url = "https://blog.csdn.net/2301_78630677/article/list"  # 爬取的网址

1.2. 循环爬取每一页

因为文章是分页的,所以要循环爬取每一页,(比如我的博客是3页)

在这里插入图片描述

快速定位到页面的文章列表区

在这里插入图片描述

result_list = []
# 循环爬取每一页,虽然我的博客只有三页,但是可以设置多循环
for page_num in range(1, 100):
    response = requests.get(f'{url}/{page_num}', headers=headers)
    response.encoding = response.apparent_encoding  # 设置页面编码
    content = response.content  # 获取页面内容
    soup = BeautifulSoup(content, 'html.parser')  # 解析
    article_list = soup.find('div', class_='article-list')  # 获取到文章列表
    if article_list == None:
        break

1.3. 从每一页的文章列表中获取每个文章的信息

根据检查网页源代码,来具体分析,定点获取信息

在这里插入图片描述

    # 再从每一页的文章列表中通过循环获取具体的每篇文章的信息
    for article in article_list.find_all('div', class_='article-item-box csdn-tracking-statistics'):
        result = {}
        result['type'] = article.a.span.text  # 文章类型
        result['href'] = article.a["href"]  # 文章链接
        article_span = article.a.find_all('span')
        for span in article_span:
            span.clear()  # 清空span标签的内容
        result['name'] = article.a.get_text().strip()  # 文章标题
        result['date'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                 class_='date').text.strip()  # 文章发布日期
        result['read_num'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                     class_='read-num').text  # 阅读量
        result_list.append(result)  # 将每篇文章的信息添加到列表中
    print(result_list)

1.4. 导出csv文件

with open('csdn_paqu.csv', 'w', encoding='utf-8') as f:
    write = csv.DictWriter(f, fieldnames=['type', 'href', 'name', 'date', 'read_num'])  # 写入CSV文件
    write.writeheader()  # 写入列名
    write.writerows(result_list)  # 将包含字典的列表全部写入到CSV文件中

1.5. 整合代码

import csv
from bs4 import BeautifulSoup
import requests

headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                         "(KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46"
           }  # 设置请求头,模拟用户

url = "https://blog.csdn.net/2301_78630677/article/list"  # 爬取的网址

result_list = []
# 循环爬取每一页,虽然我的博客的文章列表只有三页,但是可以设置多循环,防止未爬取到
for page_num in range(1, 100):
    response = requests.get(f'{url}/{page_num}', headers=headers)
    response.encoding = response.apparent_encoding  # 设置页面编码
    content = response.content  # 获取页面内容
    soup = BeautifulSoup(content, 'html.parser')  # 解析
    article_list = soup.find('div', class_='article-list')  # 获取到文章列表
    if article_list == None:
        break

    # 再从每一页的文章列表中通过循环获取具体的每篇文章的信息
    for article in article_list.find_all('div', class_='article-item-box csdn-tracking-statistics'):
        result = {}
        result['type'] = article.a.span.text  # 文章类型
        result['href'] = article.a["href"]  # 文章链接
        article_span = article.a.find_all('span')
        for span in article_span:
            span.clear()  # 清空span标签的内容
        result['name'] = article.a.get_text().strip()  # 文章标题
        result['date'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                 class_='date').text.strip()  # 文章发布日期
        result['read_num'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                     class_='read-num').text  # 阅读量
        result_list.append(result)  # 将每篇文章的信息添加到列表中
    print(result_list)

with open('csdn_paqu.csv', 'w', encoding='utf-8') as f:
    write = csv.DictWriter(f, fieldnames=['type', 'href', 'name', 'date', 'read_num'])  # 写入CSV文件
    write.writeheader()  # 写入列名
    write.writerows(result_list)  # 将包含字典的列表全部写入到CSV文件中

二、使用pyqt生成小程序

使用qt设计师生成的ui文件,再转py文件。具体过程,请看:

python GUI编程——PyQt学习一

from PyQt6 import QtCore, QtGui, QtWidgets

class Ui_CSDN_paqu(object):
    def setupUi(self, CSDN_paqu):
        CSDN_paqu.setObjectName("CSDN_paqu")
        CSDN_paqu.resize(551, 378)
        CSDN_paqu.setStyleSheet("*{\n"
"    font-size:15px;\n"
"}")
        self.pushButton_paqu = QtWidgets.QPushButton(parent=CSDN_paqu)
        self.pushButton_paqu.setGeometry(QtCore.QRect(210, 180, 121, 71))
        self.pushButton_paqu.setObjectName("pushButton_paqu")
        self.widget = QtWidgets.QWidget(parent=CSDN_paqu)
        self.widget.setGeometry(QtCore.QRect(11, 11, 501, 23))
        self.widget.setObjectName("widget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_url = QtWidgets.QLabel(parent=self.widget)
        self.label_url.setObjectName("label_url")
        self.horizontalLayout_2.addWidget(self.label_url)
        self.lineEdit_url = QtWidgets.QLineEdit(parent=self.widget)
        self.lineEdit_url.setObjectName("lineEdit_url")
        self.horizontalLayout_2.addWidget(self.lineEdit_url)
        self.widget1 = QtWidgets.QWidget(parent=CSDN_paqu)
        self.widget1.setGeometry(QtCore.QRect(10, 90, 501, 23))
        self.widget1.setObjectName("widget1")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget1)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_path = QtWidgets.QLabel(parent=self.widget1)
        self.label_path.setObjectName("label_path")
        self.horizontalLayout.addWidget(self.label_path)
        self.horizontalLayout_3.addLayout(self.horizontalLayout)
        self.lineEdit_path = QtWidgets.QLineEdit(parent=self.widget1)
        self.lineEdit_path.setObjectName("lineEdit_path")
        self.horizontalLayout_3.addWidget(self.lineEdit_path)

        self.retranslateUi(CSDN_paqu)
        QtCore.QMetaObject.connectSlotsByName(CSDN_paqu)

    def retranslateUi(self, CSDN_paqu):
        _translate = QtCore.QCoreApplication.translate
        CSDN_paqu.setWindowTitle(_translate("CSDN_paqu", "CSDN_paqu"))
        self.pushButton_paqu.setText(_translate("CSDN_paqu", "开始爬取"))
        self.label_url.setText(_translate("CSDN_paqu", "填写CSDN博客的URL"))
        self.label_path.setText(_translate("CSDN_paqu", "爬取后的文件路径"))

主要程序:

import sys
from PyQt6.QtWidgets import (
    QApplication, QDialog, QMessageBox
)
from csdn_paqu import Ui_CSDN_paqu
import csv
from bs4 import BeautifulSoup
import requests


class my_csdn_paqu(Ui_CSDN_paqu, QDialog):
    def __init__(self):
        super(my_csdn_paqu, self).__init__()
        self.setupUi(self)
        self.pushButton_paqu.clicked.connect(self.paqu)
        self.show()

    def paqu(self):
        url = self.lineEdit_url.text()
        path = self.lineEdit_path.text()
        if not url or not path:
            QMessageBox.warning(self, '警告', '请输入url和保存路径')
        else:
            headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                                     "(KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46"
                       }  # 设置请求头,模拟用户

            # url = "https://blog.csdn.net/2301_78630677/article/list"  # 爬取的网址

            result_list = []
            # 循环爬取每一页,虽然我的博客只有三页,但是可以设置多循环
            for page_num in range(1, 100):
                response = requests.get(f'{url}/{page_num}', headers=headers)
                response.encoding = response.apparent_encoding  # 设置页面编码
                content = response.content  # 获取页面内容
                soup = BeautifulSoup(content, 'html.parser')  # 解析
                article_list = soup.find('div', class_='article-list')  # 获取到文章列表
                if article_list == None:
                    break

                # 再从每一页的文章列表中通过循环获取具体的每篇文章的信息
                for article in article_list.find_all('div', class_='article-item-box csdn-tracking-statistics'):
                    result = {}
                    result['type'] = article.a.span.text  # 文章类型
                    result['href'] = article.a["href"]  # 文章链接
                    article_span = article.a.find_all('span')
                    for span in article_span:
                        span.clear()  # 清空span标签的内容
                    result['name'] = article.a.get_text().strip()  # 文章标题
                    result['date'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                             class_='date').text.strip()  # 文章发布日期
                    result['read_num'] = article.find('div', class_='info-box d-flex align-content-center').find('span',
                                                                                                                 class_='read-num').text  # 阅读量
                    result_list.append(result)  # 将每篇文章的信息添加到列表中
                print(result_list)
            try:
                with open(path, 'w', encoding='utf-8') as f:
                    write = csv.DictWriter(f, fieldnames=['type', 'href', 'name', 'date', 'read_num'])  # 写入CSV文件
                    write.writeheader()  # 写入列名
                    write.writerows(result_list)  # 将包含字典的列表全部写入到CSV文件中
                    f.flush()  # 确保数据被写入文件中
                #print(path)
                QMessageBox.information(self, '提示', '爬取成功')
            except:
                QMessageBox.warning(self, '警告', '保存失败')
              


if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_csdn_paqu = my_csdn_paqu()
    sys.exit(app.exec())

爬取成功

在这里插入图片描述

在这里插入图片描述


总结

本章简单整理了一下如何从CSDN博客上爬取文章,并制作了一个简单的爬取小程序。这是一个比较简单的程序,还可以使其功能更加丰富,比如可以直接上传一个存储多个url的文件,来遍历url,而不是一个一个url地去爬取。当然因为主要是对自己的CSDN博客文章的信息爬取,这样也足够了。

无言独上西楼,月如钩…

–2023-11-2 进阶篇

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星石传说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值