专栏地址 ʅ(‾◡◝)ʃ
前言
要写一个下载器,首先要实现一个接口函数,而这个函数可以对请求的数据进行处理也就是爬虫,其次才是写图形化界面
接口的实现
其实CSDN的浏览器页面的接口很复杂,是直接通过后台渲染成的 html, 但是手机端的app 就有单独的接口了
https://gw.csdn.net/cms-app/v1/blog_details/may_login/get_article_details_info_html?articleId=89147758&bloggerUserName=chouzhou9701&skin=night
这个 url 接口是我通过 charles 抓包获得的
下面是一个简单的下载的代码实现:
import requests
url = 'https://gw.csdn.net/cms-app/v1/blog_details/may_login/get_article_details_info_html?articleId=89147758&bloggerUserName=chouzhou9701&skin=night'
response = requests.get(url)
text = response.json()['data']['TextBody']
with open('blog.html','w') as f:
f.write(text)
这个没什么技术含量,就是通过接口简单的获取到返回的数据并把它写到 .html 一个文件里面
如果你细心的话,你就会发现这个 url 中有两个有用的参数(可变化的),articleId
和 bloggerUserName
也就是文章id 还有用户名
所以只要知道这两个参数,那么所有的文章就可以下载了,而你访问一个博客文章的 url 是就已经包含这两个参数了
比如
https://blog.csdn.net/chouzhou9701/article/details/89339625
可以看到 chouzhou9701 就是用户名,而 后面的 89339625 就是文章的 id
所以我们写一个函数,这个函数的作用有以下几点功能:
1.将从url 获取到用户名和文章的id
2.通过获提取到的这两个参数,重新构造接口
3.下载文章
代码实现
api
import requests
def download(url):
username,articleId = url.split('/')[-4],url.split('/')[-1]
url = 'https://gw.csdn.net/cms-app/v1/blog_details/may_login/get_article_details_info_html?articleId=%s&bloggerUserName=%s&skin=night' %(articleId,username)
response = requests.get(url)
text = response.json()['data']['TextBody']
with open('blog.html','w') as f:
f.write(text)
if __name__ == '__main__':
download('https://blog.csdn.net/chouzhou9701/article/details/89339625')
这个接口就写好了,试着运行这个文件,会在同级目录下生成一个blog.html文件,打开这个文件
会发现文章已经爬去完毕了,如果你不喜欢黑色主题你可以把接口的url中的skin=night
去掉
图像化界面实现
由于界面较为简单所以这里我不用qtdesigner了,直接写一个简单的界面
8
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
import sys
from api import download
class MyWin(QWidget):
"""docstring for Mywine"""
def __init__(self):
super(MyWin, self).__init__()
self.mythread = MyThread() # 实例化自己建立的任务线程类
self.mythread.signal.connect(self.callback) #设置任务线程发射信号触发的函数
self.pushButton = QPushButton('下载')
self.input_url = QLineEdit()
layout = QVBoxLayout(self) #实例化一个水平布局
layout.addWidget(self.input_url)
layout.addWidget(self.pushButton)
self.setLayout(layout)
self.pushButton.clicked.connect(self.download_blog)
def download_blog(self): # 这里test就是槽函数, 当点击按钮时执行 test 函数中的内容, 注意有一个参数为 self
self.mythread.data = self.input_url.text() # 这句就是给线程的实例化一个属性给其赋值,在线程里面就可以调用了
self.mythread.start() # 启动任务线程
def callback(self,i): # 这里的 i 就是任务线程传回的数据
QMessageBox.information(self,'提示信息',i)
class MyThread(QThread): # 建立一个任务线程类
signal = pyqtSignal(str) #设置触发信号传递的参数数据类型,这里是字符串
def __init__(self):
super(MyThread, self).__init__()
def run(self): # 在启动线程后任务从这个函数里面开始执行
url = self.data
print(self.data)
download(url)
self.signal.emit('下载完成')
if __name__ == '__main__':
app = QApplication(sys.argv)
mywin = MyWin() # 实例化一个窗口小部件
mywin.setWindowTitle('下载csdn博客') # 设置窗口标题
mywin.show() #显示窗口
sys.exit(app.exec())
这个是一个简单的图形化界面,你可以再次进行优化,比如判断输入的内容是否为空,或者把存储路径也加入个输入框可以当参数传递过去,不过这个现在已经能用了,虽然功能很少
作者:Hello_wshuo