#!/sur/bin/nve python
# coding: utf-8
import os
import re
def get_article_info(blog):
''' re.findall方法提取各项信息,返回各项信息格式化字符串元组 '''
title = '\n\n标题:' + ''.join(re.findall(r'var articleTitle = "([\u2003 \S]+)"', blog))
url = '\n地址:' + ''.join(re.findall(r'本文链接:<a href="([\S]+)"', blog)).strip()
articleDesc = '\n摘要:' + ''.join(re.findall(r'var articleDesc = "([\u2003 \S]+)"', blog))[:98]
the_end = re.findall(r'\w', articleDesc[-1]) # 获取句末单词字符。
n = len(articleDesc)
if the_end and n > 98: # 句末无标点且摘要字符数大于设定值,加省略号。
articleDesc += '……'
elif the_end and n < 98: # 句末无标点且摘要字符数小于设定值,加句号。
articleDesc += '。'
nike = ''.join(re.findall(r'var nickName = "([\u2003 \S]+)"', blog))
first = ''.join([''.join(i) for i in re.findall(r'>(于) ([\S\s]+) (\w*发布)</span>', blog)])
late = ''.join([''.join(i) for i in re.findall(r'<span class="time">(\w+) ([\S\s]+) (修改)</span>', blog)])
if first and late: # 拼接博文发布、编辑时间信息。
edit = f"\n{nike}{first},{late}。"
elif first and not late:
edit = f"\n{nike}{first}。"
else:
edit = ''
read = '\n阅读:' + ''.join(re.findall(r'<span class="read-count">(\d+)</span>', blog))
active = re.findall(r'(\d*)\s*</span>\s+</a>\s+<div class="tool-hover-tip"><span class="text space">(\w+)', blog)
active = '\n' + '\n'.join([f"{y}:{x}" if x else f"{y}:0" for x,y in active]) # 列表解析式格式化博文的点赞、踩、收藏、打赏、评论信息。
return title, articleDesc, url, '\n作者:' + nike, edit, read, active # 返回提取的信息数据元组。
def html_error(blog):
''' 获取博文页面源码错误提示 '''
if not blog: # 获取博文页面源码为空。
tip = f"{'':>13}请核查Url拼写是否正确!"
input(f"\n{'':~^50}\n{' Url错误!':^47}\n{'':~^50}\n\n{tip:>4}\n{'':-^50}\n{' 任意键继续…… ':^45}")
return
else:
flag = ''.join(re.findall(r'\d+', blog))[:3]
# 找不至网页报错。
if flag == '302' :
tip = f"{'':>4}302 Found,原始描述短语为 Moved Temporarily ,是HTTP协议中的一个状态码(Status Code)。可以简单的理解为该资源原本确实存在,但已经被临时改变了位置;换而言之,就是请求的资源暂时驻留在不同的URI下,故而除非特别指定了缓存头部指示,该状态码不可缓存。"
input(f"\n{'':~^50}\n{' “302”错误!':^47}\n{'':~^50}\n\n{tip:>4}\n{'':-^50}\n{' 任意键继续…… ':^45}")
return
elif flag == '404' :
tip = f"\n{'':>4}404,是一种HTTP状态码,指网页或文件未找到。\n\n{'':>4}HTTP 404或Not Found错误信息是HTTP的其中一种“标准回应信息”(HTTP状态码),此信息代表客户端在浏览网页时,服务器无法正常提供信息,或是服务器无法回应且不知原因。"
input(f"\n{'':~^50}\n{' “404”错误!':^47}\n{'':~^50}\n\n{tip:>4}\n{'':-^50}\n{' 任意键继续…… ':^45}")
return
return True # 正常获取博文页面源码,返回真。
def get_data(url):
''' 获取CSDN博文内容页面源码并提取数据 '''
os.system(f"curl {url} > /sdcard/Documents/csdn_get_bloghtml.txt") # 获取博文源码并保存到磁盘。
with open('/sdcard/Documents/csdn_get_bloghtml.txt') as f: # 读取保存的博文页面源码文本。
text_html = f.read().split(r'"target="_blank">')[0]
if not html_error(text_html): # 获取博文页面源码错误,返回空白字符' '。
return ''
return get_article_info(text_html) # 调用函数,从博文源码提取信息。
if __name__ == '__main__':
# CSDN博文Url的csv文本文件存储路径。可以用相对路径,但一定要保证执行的py文件和保存CSDN博文Url的文本文件在同一目录,且要先cd到该目录再执行python *.py命令,启动捕获CSDN博文信息作业。
filename = '/sdcard/Documents/csdn_blogurl.txt'
# 从csv文本解析博文网址,打印从csv文本解析出的CSDN博文Url。
with open(filename) as f:
blogurl = [i.split('\\')[0] for i in f.read().split('\n')[1:]]
#print(f"\nCSDN博文Url列表:\n\n{blogurl}\n\n{'测试列表中':>9}{len(blogurl)}个CSDN博文页面。\n") # 打印CSDN博文Url列表。
for url in blogurl: # 遍历Url列表,依次捕获博文网页源码文本,保存到本地磁盘。
print(f"\nUrl:{url}\n")
print('\n'.join(get_data(url)))
print(f"\n{' 我是分割线 ':~^45}\n") # 分割线。