这一篇教程,我们一起采用一种更复杂,但是更具有扩展性、更易维护的方式来实现新闻采集的功能。
在上一篇教程中,已经提到我们会分别对NNTP服务器的新闻内容以及网页中的新闻内容进行获取,并且以不同的格式输出。
新闻的来源有两种:
- NNTP服务器(web.aioe.org)的新闻组(comp.lang.python)
- 36Kr网站上的新闻快讯(http://36kr.com/newsflashes)
大家可以通过上一篇教程的代码,以及访问上方36Kr的网页地址了解来源的不同形式。
最终输出的目标格式也有两种:
- Print显示输出
- HTML文件
目标格式下方图片所示。
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
Print显示输出:
HTML文件:
通过上方两张图片,大家能够看出,我们是从两个新闻源获取到新闻内容并混合到一起,采用不同的格式输出这些新闻内容。
为了清晰的实现这个功能,我们先进行一下结构的划分:
- 新闻来源类型(NNTP来源类和Web来源类)
- 新闻内容(新闻类)
- 报告类型(普通显示输出类和HTML文件输出类)
- 处理过程(代理类)
- 主程序
根据不同类的功能,我们能够看到有明确的分层。
- 不同的新闻来源构成后端
- 不同的输出类型构成前端
- 处理过程代理类是中间层
最终,通过主程序将这些具有不同功能的类结合到一起,共同实现目标功能。
1、添加需要使用的模块
在实现这个功能的过程中,我们需要用到很多模块。
示例代码:
'''
想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
'''
from datetime import date, timedelta
from nntplib import NNTP
from email import message_from_string
from urllib.request import urlopen
import re, textwrap
上面这些模块,在之后的使用中,大家能够看到它们的用途,这里不再一一介绍。
2、定义类和主程序
根据上面结构的划分,我们编写的代码中,需要完成以下类和主程序的编写。
示例代码:
class NewsItem: # 新闻内容类
pass
class NNTPSource: # NNTP新闻源类
pass
class SimpleWebSource: # 网页新闻源类
pass
class PlainDestination: # 普通输出目标类
pass
class HTMLDestination: # HTML文件目标类
pass
class NewsAgent: # 新闻代理类
pass
def runDefaultSetup(): # 主程序
pass
3、定义处理每行新闻内容宽度的方法
我们在普通输出目标时,新闻内容的每一行都应该有固定的宽度。
所以,我们可以先定义一个处理内容宽度的方法。
示例代码:
def wrap(string, width=50): # 定义处理字符串宽度的方法
return '\n'.join(textwrap.wrap(string, width)) + '\n' # 返回处理之后的结果
4、各个类的实现
(1)新闻内容类
首先,需要定义一条新闻包含的内容:标题和新闻主体。
另外,在普通输出目标时,标题和主体之间要使用横线“—–”进行分隔,横线的数量取决于字符的数量。
但是,中文和英文字符宽度不一样,在显示时,一个英文字符占一个字节宽度,而一个中文字符占两个字节宽度。
所以,在这个类中,我们还需要定义一个字符的字节数量,默认一个字符的字节数量为1。
示例代码:
class NewsItem: # 新闻内容类
def __init__(self, title, body, byteNumber=1):
self.title = title # 新闻标题
self.body = body # 新闻主体
self.byteNumber = byteNumber # 每个字符的字节数量
(2)NNTP新闻源类
这个类,我们需要实现从NNTP服务器的新闻组获取新闻源并将每一条新闻生成的方法。
因为获取到的新闻数量比较多,在这里,我限制了获取数量为前10条新闻。
具体实现过程,大家通过代码中的注释进行理解。
示例代码:
class NNTPSource: # NNTP新闻源类
def __init__(self, server_name, group, window):
self.server_name = server_name # 服务器地址
self.group = group # 新闻组名称
self.window = window # 时间窗口
def getItems(self): # 新闻生成器
yesterday = date.today() - timedelta(days=self.window) # 计算新闻获取的起始时间
server = NNTP(self.server_name) # 创建服务器连接对象
ids = server.newnews(self.group, yesterday)[1] # 获取新闻id列表
count = 0 # 创建计数变量
for id in ids: # 循环获取新闻id
count += 1 # 计数递增
if count
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?