[Python] 命令行模式阅读博客园的博文

通过Python脚本读取博客园分页数据,把标题、摘要和链接过滤出来,方便我们在命令行中阅读。

阅读本文可以熟悉一般爬虫的原理,以及指令交互界面的开发。

一、说明

  运行环境:win10/Python 3.5(Win10的玩家可以下载 Window Terminal Preview玩玩,确实不错!);

  主要模块:requests(发送http请求)、lxml.etree(格式化DOM树,xpath查找)、sys(获取命令行参数、重写标准输出等)、os(系统相关、如清屏操作);

  注意:由于时间仓促,没有详细测试,遇到问题麻烦这里反馈;所有英文指令不区分大小写;

  后续:后续还会增加查看详情,跳转浏览器等。

  本文地址:https://www.cnblogs.com/reader/p/11487398.html

二、交互页面

  1、1 开始

    

    直接运行脚本,即可出现如图操作界面。可以输入 1、2和Q进行操作。

  1、2 开始阅读

    

    如上图所示,输入 1 进入的开始阅读界面。可以在头部看到页码。这里操作相对多,N(next)下一页,B(Back)上一页,H(Home)首页,Q(Quit)退出,D {num}(Detail, 后面需要输入标题前面对应的数字进行读取摘要和链接等)。

    

  1、3 阅读摘要和链接 

   如图所示,每行分别对应 标题、链接和摘要。 

三、代码分析

  3、1 思路

    采集页面-->解析页面内容-->收集必要信息

    

  3.2 数据采集

    如下代码所示,根据页码进行数据采集。这里需要注意摘要的获取方式:

li.xpath(‘p‘)[0].xpath(‘string(.)‘)
 1     def download(self, page):
 2         """下载html页面内容"""
 3         self.set_target_url(page)
 4         response = requests.get(self.target_url, headers=self.headers)
 5         if response.status_code == 200:
 6             return response.content
 7         else:
 8             print("download fail")
 9             return ""
10
11     def parse(self, content):
12         """解析HTML内容"""
13         html = etree.HTML(content)
14         lists = html.xpath(‘//div[@id="post_list"]//div[@class="post_item_body"]‘)
15
16         del html
17         k = 1
18         print(‘+‘, ‘--‘ * 50, ‘+‘)
19         print(‘|‘, str("当前页码:"+str(self.page)).ljust(95), ‘|‘)
20         print(‘+‘, ‘--‘ * 50, ‘+‘)
21         for li in lists:
22             title = str(li.xpath(‘h3/a/text()‘)[0])
23             link = li.xpath(‘h3/a/@href‘)[0]
24             desc = li.xpath(‘p‘)[0].xpath(‘string(.)‘)
25
26             self.lists[k] = {
27                 ‘title‘: title,
28                 ‘desc‘: desc.strip(),
29                 ‘link‘: link
30             }
31
32             print(‘|‘, k, self.formatByWidth(title, 100-1-len(str(k))), ‘|‘)
33             k += 1
34         del lists
35         print(‘+‘, ‘--‘ * 50, ‘+‘)

    

四、源码

  注意:代码仅供学习,杜绝其他方式使用!请注明转发地址。

  1 # -*- coding:UTF-8 -*-
  2 import requests
  3 from lxml import etree
  4 import sys
  5 import io
  6 import os
  7
  8
  9 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding=‘gb18030‘)
 10
 11
 12 class CnBlogs:
 13     """"
 14         Auth:reader
 15         发表地址:https://www.cnblogs.com/reader/p/11487398.html
 16         作者地址:https://www.cnblogs.com/reader
 17     """
 18     def __init__(self):
 19         self.headers = {‘User-Agent‘:‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36‘}
 20
 21         self.target_domain = "https://www.cnblogs.com"
 22         self.page = 1
 23         self.lists = {}
 24
 25     def clearscreen(self):
 26         """根据系统,清屏操作"""
 27         # window下的清屏方式
 28         os.system("cls")
 29
 30     def set_target_url(self, page):
 31         if page == 1:
 32             self.target_url = self.target_domain
 33         else:
 34             self.target_url = ‘https://www.cnblogs.com/sitehome/p/‘+str(page)
 35
 36     def download(self, page):
 37         """下载html页面内容"""
 38         self.set_target_url(page)
 39         response = requests.get(self.target_url, headers=self.headers)
 40         if response.status_code == 200:
 41             return response.content
 42         else:
 43             print("download fail")
 44             return ""
 45
 46     def isascii(self, ch):
 47         return ch <= u‘\u007f‘
 48
 49     def formatByWidth(self, text, width):
 50         """格式化字符串长度"""
 51         count = 0
 52         for u in text:
 53             if not self.isascii(u):
 54                 count += 1
 55         return text + " " * (width - count - len(text))
 56
 57     def parse(self, content):
 58         """解析HTML内容"""
 59         html = etree.HTML(content)
 60         lists = html.xpath(‘//div[@id="post_list"]//div[@class="post_item_body"]‘)
 61
 62         del html
 63         k = 1
 64         print(‘+‘, ‘--‘ * 50, ‘+‘)
 65         print(‘|‘, str("当前页码:"+str(self.page)).ljust(95), ‘|‘)
 66         print(‘+‘, ‘--‘ * 50, ‘+‘)
 67         for li in lists:
 68             title = str(li.xpath(‘h3/a/text()‘)[0])
 69             link = li.xpath(‘h3/a/@href‘)[0]
 70             desc = li.xpath(‘p‘)[0].xpath(‘string(.)‘)
 71
 72             self.lists[k] = {
 73                 ‘title‘: title,
 74                 ‘desc‘: desc.strip(),
 75                 ‘link‘: link
 76             }
 77
 78             print(‘|‘, k, self.formatByWidth(title, 100-1-len(str(k))), ‘|‘)
 79             k += 1
 80         del lists
 81         print(‘+‘, ‘--‘ * 50, ‘+‘)
 82
 83     def descopt(self, k):
 84         """读取详情"""
 85         k = int(k)
 86         if k not in self.lists.keys():
 87             return
 88         self.clearscreen()
 89         print(‘+‘, ‘--‘ * 50, ‘+‘)
 90         print(‘|‘, self.formatByWidth(self.lists[k][‘title‘], 100), ‘|‘)
 91         print(‘+‘, ‘--‘ * 50, ‘+‘)
 92         print(‘|‘, self.formatByWidth(self.lists[k][‘link‘], 100), ‘|‘)
 93         print(‘+‘, ‘--‘ * 50, ‘+‘)
 94
 95         print(‘|‘, self.formatByWidth(self.lists[k][‘desc‘], 100), ‘|‘)
 96
 97         print(‘+‘, ‘--‘ * 50, ‘+‘)
 98         input("输入任意键返回...\r\n")
 99
100     def readopt(self):
101         """开始阅读操作"""
102         while True:
103             self.clearscreen()
104             print("\r\n")
105             html = self.download(page=self.page)
106             self.parse(html)
107
108             print("[N]:下一页,[B]:上一页,[H]:首页,[D {num}]:简述, [Q]:返回")
109
110             cmd = input("请输入操作编号[N、B、H、D、Q]:")
111
112             if cmd == ‘Q‘ or cmd == ‘q‘:    # 返回
113                 break
114             elif cmd == ‘N‘ or cmd == ‘n‘:  # 下一页
115                 self.page += 1
116             elif cmd == ‘B‘ or cmd == ‘b‘:  # 上一页
117                 self.page -= 1
118                 if self.page <= 0:
119                     self.page = 1
120             elif cmd == ‘H‘ or cmd == ‘h‘:  # 首页
121                 self.page = 1
122             else:
123                 cmd = cmd.split(‘ ‘)
124
125                 if len(cmd) != 2:
126                     continue
127                 # 读取简述
128                 if cmd[0] == ‘D‘ or cmd[0] == ‘d‘:
129                     self.descopt(cmd[1])
130
131     def aboutopt(self):
132         self.clearscreen()
133         print("博客园地址: https://www.cnblogs.com/reader\r\n")
134         input("输入任意键返回...\r\n")
135
136     def start(self):
137         self.clearscreen()
138         while True:
139             print(‘+‘, ‘--‘*50, ‘+‘)
140             print(‘|‘, "欢迎使用博客园阅读器(reader 开发)".center(88), ‘|‘)
141             print(‘+‘, ‘--‘ * 50, ‘+‘)
142             print(‘|‘, "[1]:开始阅读".center(95), ‘|‘)
143             print(‘|‘, "[2]:关于作者".center(95), ‘|‘)
144             print(‘|‘, "[Q]:退出软件".center(95), ‘|‘)
145             print(‘+‘, ‘--‘ * 50, ‘+‘)
146
147             cmd = input("请输入操作编号[1、2、Q]:")
148             if cmd == ‘1‘:
149                 self.readopt()
150             elif cmd == ‘2‘:
151                 self.aboutopt()
152             elif cmd == ‘Q‘ or cmd == ‘q‘:
153                 break
154
155             os.system("cls")
156
157         print("已退出,欢迎使用!")
158
159
160 if __name__ == "__main__":
161     obj = CnBlogs()
162     obj.start()

原文地址:https://www.cnblogs.com/reader/p/11487398.html

时间: 2024-11-07 17:00:22

[Python] 命令行模式阅读博客园的博文的相关文章

python数据挖掘领域工具包 - wentingtu - 博客园

python数据挖掘领域工具包 - wentingtu - 博客园 python数据挖掘领域工具包 原文:http://qxde01.blog.163.com/blog/static/67335744201368101922991/ Python在科学计算领域,有两个重要的扩展模块:Numpy和Scipy.其中Numpy是一个用python实现的科学计算包.包括: 一个强大的N维数组对象Array: 比较成熟的(广播)函数库: 用于整合C/C++和Fortran代码的工具包: 实用的线性代数.傅

Python爬虫入门教程:博客园首页推荐博客排行的秘密

1. 前言 虽然博客园注册已经有五年多了,但是最近才正式开始在这里写博客.(进了博客园才知道这里面个个都是人才,说话又好听,超喜欢这里...)但是由于写的内容都是软件测试相关,热度一直不是很高.看到首页的推荐博客排行时,心里痒痒的,想想看看这些大佬究竟是写了什么文章这么受欢迎,可以被推荐.所以用Python抓取了这100位推荐博客,简单分析了每个博客的文章分类,阅读排行榜,评论排行榜及推荐排行榜,最后统计汇总并生成词云.正好这也算是一篇非常好的Python爬虫入门教程了. 2. 环境准备 2.1

使用python xmlrpc 发送内容到博客园

xmlrpc 参考上一篇文章 博客园 http://rpc.cnblogs.com/metaweblog/WeyneChen 从连接可以看到支持的metaweblog API 代码 import xmlrpc.client as xmlrpclib import codecs serviceUrl,appkey = 'http://rpc.cnblogs.com/metaweblog/WeyneChen','weynechen' blogid = '177230' cid = '782172'

Python爬虫入门教程 54-100 博客园等博客网站自动评论器

爬虫背景 爬虫最核心的问题就是解决重复操作,当一件事情可以重复的进行的时候,就可以用爬虫来解决这个问题,今天要实现的一个基本需求是完成"博客园" 博客的自动评论,其实原理是非常简单的,提炼一下需求 基本需求 登录博客园<不实现,登录单独编写博客> 调用评论接口 返回请求结果 确定流程之后,基本就是找突破口的环节了 实际的去评论一下,然后不管你用什么抓包工具都可以,只要抓取到你想要的数据,即可 评论API如下 Request URL: https://www.cnblogs.

nodejs爬取博客园的博文

其实写这篇文章,我是很忐忑的,因为爬取的内容就是博客园的,万一哪个顽皮的小伙伴拿去干坏事,我岂不成共犯了? 好了,进入主题. 首先,爬虫需要用到的模块有: express ejs superagent (nodejs里一个非常方便的客户端请求代理模块) cheerio (nodejs版的jQuery) 前台布局使用bootstrap 分页插件使用 twbsPagination.js 完整的爬虫代码,在我的github中可以下载.主要的逻辑代码在 router.js 中. 1. 爬取某个栏目第1页

博客园屏蔽博文页面广告的方法

在“设置”页面中的“页面定制css”中加入以下css代码即可 #site_nav_under,.c_ad_block{ display:none; } 为了博客园这个还算有节操的网站能够运营下去,还是保留广告吧.博客园的广告不是很影响阅读体验.

python——关于简单爬取博客园班级成员发的博文的题目、发布人、阅读、评论,再存到csv文件中

因为老师要以班里每个人发的博客质量作为最后总成绩的评定的一部分,就要把班上所有同学发的博客都统计起来,可以用来评定的因素有:阅读.评论.推荐等,但因为今天只是做一个简单的爬取,推荐这个元素在班级博客中需要点开每一篇博文才能看到获取,就不爬取了,只爬取阅读和推荐,加上每篇博文的发布人和标题. 我先会放上代码,再逐条解释其含义及作用. 代码如下(其中爬取的网页是以我自己的班级为例): 1 from bs4 import BeautifulSoup 2 import pandas as pd 3 im

博客园代码高亮插件(类似csdn的代码插入)

博客园内置支持SyntaxHighlighter代码着色,使用此内置着色特性需要将博客的默认编辑器改为TinyMCE(“管理”-“选项”中设置).如果使用CuteEditor,CuteEditor会自动去除代码中的空格,造成代码格式破坏. 如果您使用Windows Live Writer写博客(配置步骤),通过Windows Live Writer代码着色插件,可以方便进行SyntaxHighlighter代码着色. 我们推荐的代码着色插件是:Windows Live Writer Source

博客园写作避坑指南【持续更新】

以下是花了一晚上调格式之后的血泪经验,如果之后有新的发现会持续更新-- 关于英文单词自动断行 如果你和我一样需要写英文博文,你会发现遇到行尾的英文单词全部被拦腰截断,看上去怪怪的. 这是因为博客园默认模板CSS将mainContent设置为word-break:break-all,即强制断行. 好在博客园开放了页面定制CSS代码,我们可以很方便地加入自己的设置来覆盖掉默认设置,只需要在"设置 -> 页面定制CSS代码"中加入以下代码: #mainContent { word-br