前言

这里以爬取博客园文章为例,仅供学习参考,某些AD满天飞的网站太浪费爬虫的感情了。

爬取

  • 使用 BeautifulSoup 获取博文

  • 通过 html2text 将 Html 转 Markdown

  • 保存 Markdown 到本地文件

  • 下载 Markdown 中的图片到本地并替换图片地址

  • 写入数据库

工具

使用到的第三方类库:BeautifulSoup、html2text、PooledDB

代码

获取博文:

# 获取标题和文章内容
def getHtml(blog):
res = requests.get(blog, headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
# 获取博客标题
title = soup.find('h1', class_='postTitle').text
# 去除空格等
title = title.strip()
# 获取博客内容
content = soup.find('div', class_='blogpost-body')
# 去掉博客外层的DIV
content = article.decode_contents(formatter="html")
info = {"title": title, "content": content}
return info

Html 转 Markdown:

# 这里使用开源第三方库 html2text
md = text_maker.handle(info['content'])

保存到本地文件:


def createFile(md, title):
print('系统默认编码:{}'.format(sys.getdefaultencoding()))
save_file = str(title) +".md"
# print(save_file)
print('准备写入文件:{}'.format(save_file))
# r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
# w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
# a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
f = codecs.open(save_file, 'w+', 'utf-8')
f.write(md)
f.close()
print('写入文件结束:{}'.format(f.name))
return save_file

下载图片到本地并替换图片地址:

def replace_md_url(md_file):
"""
把指定MD文件中引用的图片下载到本地,并替换URL
""" if os.path.splitext(md_file)[1] != '.md':
print('{}不是Markdown文件,不做处理。'.format(md_file))
return cnt_replace = 0
# 日期时间为目录存储图片
dir_ts = time.strftime('%Y%m', time.localtime())
isExists = os.path.exists(dir_ts)
# 判断结果
if not isExists:
os.makedirs(dir_ts)
with open(md_file, 'r', encoding='utf-8') as f: # 使用utf-8 编码打开
post = f.read()
matches = re.compile(img_patten).findall(post)
if matches and len(matches) > 0:
for match in list(chain(*matches)):
if match and len(match) > 0:
array = match.split('/')
file_name = array[len(array) - 1]
file_name = dir_ts + "/" + file_name
img = requests.get(match, headers=headers)
f = open(file_name, 'ab')
f.write(img.content)
new_url = "https://blog.52itstyle.vip/{}".format(file_name)
# 更新MD中的URL
post = post.replace(match, new_url)
cnt_replace = cnt_replace + 1 # 如果有内容的话,就直接覆盖写入当前的markdown文件
if post and cnt_replace > 0:
url = "https://blog.52itstyle.vip"
open(md_file, 'w', encoding='utf-8').write(post)
print('{0}的{1}个URL被替换到{2}/{3}'.format(os.path.basename(md_file), cnt_replace, url, dir_ts))
elif cnt_replace == 0:
print('{}中没有需要替换的URL'.format(os.path.basename(md_file)))

写入数据库:

# 写入数据库
def write_db(title, content, url):
sql = "INSERT INTO blog (title, content,url) VALUES(%(title)s, %(content)s, %(url)s);"
param = {"title": title, "content": content, "url": url}
mysql.insert(sql, param)

小结

互联网时代一些开放的博客社区的确方便了很多,但是也伴随着随时消失的可能性,最好就是自己备份一份到本地;你也可以选择自己喜欢的博主,爬取下收藏。

源码:https://gitee.com/52itstyle/Python

演示:https://blog.52itstyle.top

列表:https://blog.52itstyle.top/index

详情:https://blog.52itstyle.top/49.shtml

「玩转Python」打造十万博文爬虫篇的更多相关文章

  1. SpringBoot开发案例之打造十万博文Web篇

    前言 通过 Python 爬取十万博文之后,最重要的是要让互联网用户访问到,那么如何做呢? 选型 从后台框架.前端模板.数据库连接池.缓存.代理服务.限流等组件多个维度选型. 后台框架 SpringB ...

  2. 「玩转Python」突破封锁继续爬取百万妹子图

    前言 从零学 Python 案例,自从提交第一个妹子图版本引来了不少小伙伴的兴趣.最近,很多小伙伴发来私信说,妹子图不能爬了!? 趁着周末试了一把,果然爬不动了,爬下来的都是些 0kb 的假图片,然后 ...

  3. 「玩转树莓派」树莓派 3B+ 配置无线WiFi

    前言 网线不方便还花钱,有自带的无线 WiFi 模块为啥不用. 网络模式 这里我们先介绍两种网络模式,WPA-Personal 与 WPA-Enterprise. WPA-Personal 大多数家庭 ...

  4. 「mysql优化专题」这大概是一篇最好的mysql优化入门文章(1)

    优化,一直是面试最常问的一个问题.因为从优化的角度,优化的思路,完全可以看出一个人的技术积累.那么,关于系统优化,假设这么个场景,用户反映系统太卡(其实就是高并发),那么我们怎么优化? 如果请求过多, ...

  5. 从SpringBoot构建十万博文聊聊限流特技

    前言 在开发十万博客系统的的过程中,前面主要分享了爬虫.缓存穿透以及文章阅读量计数等等.爬虫的目的就是解决十万+问题:缓存穿透是为了保护后端数据库查询服务:计数服务解决了接近真实阅读数以及数据库服务的 ...

  6. 从零单排之玩转Python安全编程(II)

    转自:http://www.secpulse.com/archives/35893.html 都说Python大法好,作为一名合格的安全从业人员,不会几门脚本语言都不好意思说自己是从事安全行业的. 而 ...

  7. 「python」: arp脚本的两种方法

    「python」: arp脚本的两种方法 第一种是使用arping工具: #!/usr/bin/env python import subprocess import sys import re de ...

  8. 拇指玩」制作的「谷歌安装器」app

    作者:匿名用户链接:https://www.zhihu.com/question/57468448/answer/153000587来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  9. 「Python」socket指南

    开始 网络中的 Socket 和 Socket API 是用来跨网络的消息传送的,它提供了 进程间通信(IPC) 的一种形式.网络可以是逻辑的.本地的电脑网络,或者是可以物理连接到外网的网络,并且可以 ...

随机推荐

  1. Python时间戳的一些使用

    Python时间戳的一些使用 为什么写下这篇文档? 由于我本身是做Python爬虫的,在爬取网站的过程当中,会遇到形形色色的验证码,目前对于自己而言,可能简单的验证码可以进行自己识别 发现大多数的网站 ...

  2. 我所理解的Vue——学习心得体会1(Vue对象)

    初学Vue,总结如下: 1.首先要区分html的dom和js的dom 2.html的dom是View的范畴,js的dom是Model的范畴. 3.vue这库就是创建了伟大的new Vue()对象,把h ...

  3. spring 5.x 系列第7篇 —— 整合Redis客户端 Jedis和Redisson (xml配置方式)

    文章目录 一.说明 1.1 Redis 客户端说明 1.2 Redis可视化软件 1.3 项目结构说明 1.3 依赖说明 二.spring 整合 jedis 2.1 新建基本配置文件 2.2 单机配置 ...

  4. PATB 1038. 统计同成绩学生(20)

    https://www.patest.cn/contests/pat-b-practise/1038 #include <cstdio> int cnt[110]; int temp[10 ...

  5. 22 | 从0到1:API测试怎么做?常用API测试工具简介

  6. .NET Core IdentityServer4实战 第六章-Consent授权页

    在identityServer4中登陆页面只要是成功了,就会注册一个Cookie在服务器资源上,像现在大部分的网站第三方授权,都是经过一个页面,然后选需要的功能,IdentityServer4也给我们 ...

  7. HDU 5521:Meeting(最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=5521 Meeting Problem Description   Bessie and her friend E ...

  8. 【Aizu - 0118】Property Distribution

    -->Property Distribution 原文是日语,算了算了,直接上我大中华母语吧  Descriptions: 在H * W的矩形果园里有苹果.梨.蜜柑三种果树, 相邻(上下左右)的 ...

  9. 事务的隔离级别,mysql默认的隔离级别是什么?

    读未提交(Read uncommitted),一个事务可以读取另一个未提交事务的数据,最低级别,任何情况都无法保证. (1)所有事务都可以看到其他未提交事务的执行结果 (2)本隔离级别很少用于实际应用 ...

  10. kuangbin专题 专题二 搜索进阶 哈密顿绕行世界问题 HDU - 2181

    题目链接:https://vjudge.net/problem/HDU-2181 题意:一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发 ...