接上回,《Python 网络爬虫实战:爬取《去哪儿》网数千篇旅游攻略数据》。

我们爬取到了数千篇的旅游攻略文章的数据。

但是事情还没有结束,对于大部分的人来讲,最希望得到的东西应该不是这种干巴巴的 Excel 数据,

而是这种图文并茂的文章吧!

其实之前我们爬过很多类似的网站,比如 《人民日报新闻爬虫》,《知乎问题回答爬虫》,都是爬取大段的文章。

不过区别在于,那些爬虫的关注点在于文字,主要用来做分词,语义情感等方面的分析,也就是说不是给人看的,是给程序看的,所以直接将图片,超链接,排版格式等东西舍弃,仅提取文字,使用记事本保存即可。

而这篇爬虫不同,爬取旅游攻略文章,重点在于阅读体验,如果抛弃了图片,抛弃了排版,爬到的攻略文章也就失去了灵魂。

BUT,用什么格式的文件可以保存图文,还可以尽可能保留原始排版呢?想来想去,我觉得 Markdown 或许是最佳选择。


0x00 分析网站

相比于上一篇爬虫中各式各样的数据,这篇爬虫要爬的内容就简单很多了。

以 https://travel.qunar.com/travelbook/note/6910266 这篇文章为例,使用 开发者工具(F12)来进行分析。

可以看到,文章的正文部分是在一个 <div class='e_main' id='tpl_1'>  标签中的,其中每一个子 div 标签存放一个章节的内容。

分析完毕,是不是确实很简单呢?

如果是按照之前的做法,我可能直接一个 '.text' 或者 '.string' ,把其中的文字提取出来就完事儿了。

但是这里我们不能这样做,需要把它完整地取出来,保留其原本的结构,转换成 Markdown 格式进行存储。

0x01 将 HTML 转成 Markdown 格式

这里我结合使用了 BeautifulSoup 和 html2text 库。

BeautifulSoup 库用来定位提取文章的正文部分,html2text 库用来将正文部分的 html 文本转化成 markdown 格式。

1.  提取正文部分

import requests
from bs4 import BeautifulSoupdef getContent(html):'''提取文章的正文部分的 html'''bsObj = BeautifulSoup(html,'lxml')title = bsObj.find("h1").textcontent = bsObj.find("div",attrs = {"id":"tpl_1"})return str(content)url = 'https://travel.qunar.com/travelbook/note/6910266'
html = fetchUrl(url)    # fetchUrl(url) 函数用于发起网络请求
content = getContent(html)
print(content)

运行结果:

网站没有设置过多的反爬机制,成功获取到文章的正文部分。

2. 将正文部分的 html 转换成 Markdown 格式

这部分主要是通过 html2text 库来完成,不过该库在转换过程中,有一些转换错误的地方,需要对转换结果做一定的处理。(以下是我在用 html2text 库转换去哪儿网站攻略文章时出现的问题,不知道是库有问题还是网站的问题,大家使用的话根据实际情况进行调整)

章节标题格式

html 中的 h 标签,转换成 Markdown 后,会在 # 后面多两个换行符。

如 h1 标签会转换成 "#\n\n",而实际我们需要的是 "# "( # 后面加空格)

text = text.replace("#\n\n", "# ")

有些标题是有超链接的(网页中查看时,鼠标移上去会有 Tips 框弹出),这些Tips信息转换成 Markdown 格式后显示会有点混乱。我们直接将其超链接去除,只保留纯粹的标题文字。

header5 = content.find_all("h5")
for h5 in header5:t5 = h5.find("div", attrs = {"class":"b_poi_title_box"})h5.insert_after("##### " + t5.text)h5.extract()

② 莫名其妙的换行符

可能是网页源码中有一些特殊的字符,转换后出现了很多换行符。

text = text.replace("\\.",".")
text = text.replace(".\n",". ")
text = text.replace("tr-\n","tr-")

③ 不需要的标签 

文章正文部分中夹杂着一些标签,比如下图中的 “评论” ,是我们不需要的,可以将其处理去掉。

我们可以在转换前,直接使用 BeautifulSoup 的 extract 函数将其剔除。

cmts = content.find_all("div", attrs = {"class":"ops"})
for s in cmts:s.extract()

④ 正文中出现了Markdown 格式控制符号

有些文章中的文字比较活泼可爱,用了很多颜文字,比如 ~~~ ^_^ ~~~ 等,而 ~~~ ,``,* 等这些符号是 Markdown 中用来控制格式的符号,导致虽然文章转换没什么问题,但是显示出现了问题。

# 正文中 ~ 的个数不确定,经过观察这样大概就基本可以正确显示了。
html = html.replace("~~", "~").replace("~~", "~")

等等等等,还有其他细节方面的调整,其实也不算是共性问题,分享出来可能意义也不是很大,就不一一列举了,大家遇到了的话针对性地调整就可以了。

0x02 完善代码开始爬取

1. 读取 URL 列表

这里我们直接从上篇文章中爬取得到的 csv 文件中读取(大家感兴趣的可以去看看,跑跑文章中的代码就可以很容易得到)。

为了方便,我这里上传了一份测试用的文档(下载链接),大家可以去下载使用。(CSDN的下载需要积分,大家有积分的权当支持一下博主啦!如果链接失效了,或者没有下载积分,可以在文末加我微信找我要)

import pandas as pddf = pd.read_csv('data.csv', sep = ',', usecols = [0,1])
for index, title, url in df.itertuples():print(title)print(url)

运行结果:

可以读取到每篇文章的标题链接

2. 发起网络请求

下面是 fetchUrl 函数,用于发起网络请求。

import requestsdef fetchUrl(url):'''发起网络请求'''headers = {'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',}r = requests.get(url,headers=headers)r.raise_for_status()r.encoding = "utf-8"return r.text

3. 爬取正文并转换成 Markdown 格式

getContent 函数用来从网页源码中提取正文部分的 Html 文本,并进行一些简单的预处理。

包括对图片,标题格式的替换,无关标签的剔除,以及一些有干扰的特殊字符的替换。

from bs4 import BeautifulSoupdef getContent(html):'''提取文章的正文部分的 html'''html = html.replace("&nbsp;", "")html = html.replace("~~", "~").replace("~~", "~")bsObj = BeautifulSoup(html,'lxml')title = bsObj.find("h1").textcontent = bsObj.find("div",attrs = {"id":"b_panel_schedule"})imgs = content.find_all("img")for img in imgs:src = img['data-original']txt = img['title']img.insert_after("![{0}]({1})".format(txt,src))img.extract()header5 = content.find_all("h5")for h5 in header5:t5 = h5.find("div", attrs = {"class":"b_poi_title_box"})#print(t5.text)h5.insert_after("##### " + t5.text)h5.extract()cmts = content.find_all("div", attrs = {"class":"ops"})for s in cmts:s.insert_after('< br/>')s.extract()return str(content)

Html2Markdown 函数,主要作用是将 html 文本转换成 Markdown 格式,并对转换过程中出现的一些格式错误进行修正。

import html2text as htdef Html2Markdown(html):'''将文章正文部分由 html 格式转换成 Markdown 格式'''text_maker = ht.HTML2Text()text = text_maker.handle(html)text = text.replace("#\n\n", "# ")text = text.replace("\\.",".")text = text.replace(".\n",". ")text = text.replace("< br/>","\n")text = text.replace("tr-\n","tr-")text = text.replace("查看全部 __","")return text

 4. 保存文件

我们保存文件时,使用文章标题作为文件名存储。而文件名中有一些字符,如正反斜杠 / \ ,英文引号 ' ",英文大于小于号 <> 等等,我们需要对其进行剔除,或者替换成中文的符号。否则会报错,保存失败。

import osdef saveMarkdownFile(title,content):'''保存文本到 Markdown 文件中title:文件名content:要保存的文本内容'''# 剔除或替换文件名中不允许出现的符号title = title.replace("\\","")title = title.replace("/","")title = title.replace("\"","”")title = title.replace("\'","’")title = title.replace("<","《")title = title.replace(">","》")title = title.replace("|","&")title = title.replace(":",":")title = title.replace("*","x")title = title.replace("?","?")with open("data/" + title + ".md", 'w', encoding='utf-8') as f:f.write(content)

5. 爬虫调度器

最后我们需要写一个爬虫调度的函数,来启动并控制我们的爬虫。

import time
from random import randintdef main():df = pd.read_csv('data.csv', sep = ',', usecols = [0,1])for index, title, url in df.itertuples():html = fetchUrl(url)content = getContent(html)md = Html2Markdown(content)saveMarkdownFile(title, md)# 随机等待时间,避免爬取过于频繁触发反爬机制t = randint(0,3)print("wait -- ",str(t),"s")time.sleep(t)# 启动爬虫
main()
print("爬取完成!")

上述就是本次爬虫的全部源码了。

0x03 问题解决

1. 如何安装 html2text 库?

虽然我相信这个小问题一定难不倒聪明的大家的,但是这里还是讲一下,给大伙儿节省点时间,哈哈。

安装命令是:

pip install html2text

如果上面那个指令安装时,提示 ConnectTimeoutError 连接超时失败(反正我是连接超时失败了),可以试一下下面这个指令。

pip install html2text -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

参考链接:https://blog.csdn.net/licheetools/article/details/82946342

2. 什么是 Markdown ?如何打开 Markdown 文件?

Markdown 的基本概念我就不说了,自己去网上搜吧。就相当于 Office Word 的精简版,可以让你像写代码一样写文章,用熟练了,写起东西来非常丝滑。

我目前在用的一款 Markdown 编辑器,叫 Typora,界面还是非常干净漂亮的,颜值很高。在这里给大家简单推荐一下,如果大家有什么好用的 Markdown 编辑器,也可以在评论区跟大家分享哦。

下载链接:https://www.typora.io/

0x04 后记

由于是单线程爬取,而且加了相对来说比较长的等待时间(主要也是时间宽裕,也不想给人家网站造成压力)。

一下午时间爬了近2千篇文章,用 Typora 打开,翻阅起来真的是,感觉是真的爽。


如果文章中有哪里没有讲明白,或者讲解有误的地方,欢迎在评论区批评指正,或者扫描下面的二维码,加我微信,大家一起学习交流,共同进步。

Python 网络爬虫实战:去哪儿网旅游攻略图文爬取保存为 Markdown电子书相关推荐

  1. python网络爬虫学习笔记(十一):Ajax数据爬取

    文章目录 1.基本介绍 2.基本原理 3.实战 有时候我们在用requests抓取页面的时候,得到的结果可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据,但是使用requests得到 ...

  2. Python网络爬虫与信息提取(14)—— 百度搜索关键字爬取并整理摘要、标题、关键字等

    前言 百度搜索的内容一般包含标题.摘要.网址.时间信息,本次主要实现根据搜索整理30页左右百度的搜索条例成csv文档. 原理 百度爬虫比较简单,模拟浏览器访问就可以爬取到所要的数据,访问某个关键字第几 ...

  3. Python 网络爬虫实战:爬取《去哪儿》网数千篇旅游攻略数据,再也不愁旅游去哪儿玩了

    好久不见! 今天我们来爬取 去哪儿网站 的 旅游攻略 数据. 0x00  找一个合理的作案动机 作为一名立志成为技术宅的普通肥宅,每次一到周末就会面临一个人生难题:这周末怎么过? 本来是没有这些问题的 ...

  4. python爬虫文件代码大全-Python网络爬虫实战项目代码大全(长期更新,欢迎补充)...

    WechatSogou[1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典.[1]: https://github ...

  5. python基础代码大全-Python网络爬虫实战项目代码大全(长期更新,欢迎补充)

    WechatSogou[1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典.[1]: https://github ...

  6. Python网络爬虫实战项目代码大全(长期更新,欢迎补充)

    Python网络爬虫实战项目代码大全(长期更新,欢迎补充) 阿橙 · 1 个月内 WechatSogou [1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫, ...

  7. python基础实例 韦玮 pdf_韦玮:Python网络爬虫实战解析

    2016年12月27日晚8点半,CSDN特邀IT专家.<Python系列实战教程>系列图书作者韦玮带来了主题为"Python网络爬虫反爬破解策略实战"的Chat交流.以 ...

  8. Python网络爬虫实战:根据天猫胸罩销售数据分析中国女性胸部大小分布

    Python网络爬虫实战:根据天猫胸罩销售数据分析中国女性胸部大小分布 本文实现一个非常有趣的项目,这个项目是关于胸罩销售数据分析的.是网络爬虫和数据分析的综合应用项目.本项目会从天猫抓取胸罩销售数据 ...

  9. Python网络爬虫实战:近千条中秋节祝福语文案让你成为亲朋好友里最靓的仔

    中秋节马上到了,不知道大家有没有像我这样的烦恼,每次过节,都要绞尽脑汁想好久,发什么样的祝福语才显得有诚意又有创意,什么样的朋友圈文案会有文化又有逼格. 去网上搜吧,搜出来的祝福语,画风大多是像这样的 ...

最新文章

  1. C语言经典例20-小球反弹高度问题
  2. zzuli1895: 985的0-1串难题
  3. 蓝桥杯真题-连号区间数-枚举
  4. Linux与Windows共享文件夹之samba的安装与使用 资源管理器直接查看服务器文件
  5. python面试题之Python如何实现单例模式?
  6. CSS3秘笈复习:第一章第二章第三章
  7. Concrete Mathematics A Foundation for Computer Science
  8. 我的开源项目:H.264码流分析器
  9. Google 开源 VHP 震动触觉平台,降低触觉设备开发难度
  10. 固态硬盘与机械硬盘读取速度实测
  11. HTML中注解的写法正确的是,css注释的写法(单行和多行)
  12. html5标签思维导图,HTML/HTML5 知识点思维导图
  13. 联想手机里的照片误删怎么恢复
  14. 3.1 HMC管理功能
  15. 批改网中的作文不能粘贴怎么办?
  16. django请求生命周期,FBV和CBV,ORM拾遗,Git
  17. c语言 串口连读,完美发音进阶课-连读技巧(示例代码)
  18. 22,Horizontal Pod Autoscaler(HPA),自动扩缩容
  19. Windows install.
  20. hp固态硬盘安装系统,找不到驱动器和iaStorAfs.sys问题处理

热门文章

  1. 学生成绩管理系统数据库设计--MySQLSQL Server
  2. 【北亚数据恢复】误操作分区损坏导致SqlServer数据库数据丢失的数据恢复案例
  3. Android才是游戏开发者的乐土
  4. android应用常见错误
  5. jop怎么读音英语怎么说_job是什么意思_ job的翻译_音标_读音_用法_例句_爱词霸在线词典...
  6. shell学习笔记---工具学习
  7. 免费小巧的录屏软件Captura
  8. C++11初篇(快速了解)
  9. Virtual Private Network虚拟专用网
  10. Inno Setup软件 打包多个安装包程序