前言

这里以爬取博客园文章为例,仅供学习参考,某些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. ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用

    在前面几篇随笔介绍了我对ABP框架的改造,包括对ABP总体的介绍,以及对各个业务分层的简化,Web API 客户端封装层的设计,使得我们基于ABP框架的整体方案越来越清晰化, 也越来越接近实际的项目开 ...

  2. 「中高级前端必须了解的」JS中的内存管理

    前言 像C语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()用于分配内存和释放内存. 而对于JavaScript来说,会在创建变量(对象,字符串等)时分配内存,并且在不 ...

  3. Azkaban —— 编译及部署

    一.Azkaban 源码编译 1.1 下载并解压 Azkaban 在3.0版本之后就不提供对应的安装包,需要自己下载源码进行编译. 下载所需版本的源码,Azkaban的源码托管在GitHub上,地址为 ...

  4. 【ubuntu】软件安装与apt-get下载软件的存放位置

    系统:Ubuntu16.04 常用的软件安装方式有两种: 第一种:apt-get(安装后略类似于windows中的安装版软件): 例:apt-get install ssh 1.下载的软件存放位置 / ...

  5. 寻找图的强连通分量:tarjan算法简单理解

    1.简介tarjan是一种使用深度优先遍历(DFS)来寻找有向图强连通分量的一种算法. 2.知识准备栈.有向图.强连通分量.DFS. 3.快速理解tarjan算法的运行机制提到DFS,能想到的是通过栈 ...

  6. C#使用 SSL Socket 建立 Client 与 Server 连接

    当 Client 与 Server 需要建立一个沟通的管道时可以使用 Socket 的方式建立一个信道,但是使用单纯的 Socket 联机信道可能会担心传输数据的过程中可能被截取修改因而不够安全,为了 ...

  7. 并发编程-concurrent指南-ConcurrentMap

    ConcurrentMap 是个接口,你想要使用它的话就得使用它的实现类之一. ConcurrentMap,它是一个接口,是一个能够支持并发访问的java.util.map集合: 在原有java.ut ...

  8. js动态生成数据的抓取

    需求:爬取https://www.xuexi.cn/f997e76a890b0e5a053c57b19f468436/018d244441062d8916dd472a4c6a0a0b.html页面中的 ...

  9. re正则

    #转义字符和原生字符 import re # # # 转义 # text = 'apple price is $299' # ret = re.search('\$\d+',text) # print ...

  10. 用PHP抓取百度贴吧邮箱数据

    注:本程序可能非常适合那些做百度贴吧营销的朋友. 去逛百度贴吧的时候,经常会看到楼主分享一些资源,要求留下邮箱,楼主才给发. 对于一个热门的帖子,留下的邮箱数量是非常多的,楼主需要一个一个的去复制那些 ...