百日筑基篇——爬取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文件。具体过程,请看:
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 进阶篇