python-爬取网络小说到本地

源码来自 [5.Python3爬虫入门实践——爬取名著] , (http://www.jianshu.com/p/e597b5921112) 我只是自己实现了一遍, 感谢原作者


回忆下我们看网络小说的步骤

  1. 打开小说目录: http://www.shicimingju.com/book/sanguoyanyi.html
  2. 选择我们要看的章节:http://www.shicimingju.com/book/sanguoyanyi/1.html
  3. 重复第2步 直到看完整本小说.

那么我们用爬虫怎么实现上面的过程, 把整本小说写入到我的电脑中呢?
我来把上面的每一步翻译成爬虫

  1. 拿到整个 小说目录网页, 让电脑去看这个网页. 这个网页中有所有目录的章节信息, 也有所有目录章节具体内容的链接.
  2. 让电脑拿到所有的章节 链接, 打开章节链接, 得到整个章节网页, 这个网页中就有章节的所有内容, 让电脑把章节内容复制下来, 保存到本地的一个 txt 文件中
  3. 重复第2步, 直到所有的章节内容都保存在了本地的 txt 文件中. 保存该文件. 这样我们就得到了一个完整的小说 txt 文件.

然后我们就可以打开这个txt 文件 愉快的看小说了.


整个过程还是涉及到不少知识点, (我是说对我们小白来说东西很多, 大神求多拍砖, 有批评就有进步哈)


这个项目过程中 学习到的知识点
python 零散知识点
s = r'hello\t world' 表示字符串中的转义字符无效, 按照普通字符串输出

python 正则表达式相关

下面这篇文章解决了我的问题[感谢作者]

decode('uif-8','ignore')
decode不是编码转换,decode是把一个无编码的str,依照给入的参数为解码系统,解码后映射到unicode字符集,返回为unicode对象…

抽空研究下 Python3中内置类型bytes和str用法及byte和string之间各种编码转换????


最终还是打算使用 pycharm 写 Python
添加三方库: pycharm --> preferences --> Project Interpreter --> 选择加号(+)
因为 pip 还是系统的 2.7 版本, pycharm 是 3.5 版本, 无法下载三方库

使用 Python3.6 自带模块
教程 http://www.jianshu.com/p/e597b5921112

re 模块: 正则表达式相关
urlopen 方法返回的是 response 类型

记录整个项目过程
IDE: pycharm
硬件: mac
语言: Python 3.6.1

因为在 mac 上 的 pip 是 2.7 版本 无法安装第三方 Python库, 这里网络请求不能用 Requests, 我采用了 Python 标准库 urllib.request
解析 HTML 文件 建议使用 三方库lxml 我这里直接使用标准库 re(正则表达式)

这份代码来自5.Python3爬虫入门实践——爬取名著
我只是照着敲了一遍, 总结下第一次爬虫遇到的坑


indexUrl = 'http://www.shicimingju.com/book/sanguoyanyi.html'
html = urllib.request.urlopen(indexUrl).read()

urlopen返回 一个类文件对象,我的理解是,你可以直接把它看做一个txt 文件,它提供了如下方法:read() , readline() , readlines() , fileno() , close()

html = html.decode('utf8','ignore')

urllib.request.urlopen(indexUrl).read() 得到的是 ascii码 的 bytes(字节) 内容 我们需要解码成字符串(utf-8码) 得到人类可以读懂的字符(比如: 汉字, 表情符号等).
ignore: 抓取的网页内容不一定都是用 utf-8 编码, 很有可能同时使用了 gb2312 编码 百或者其他编码. 如果同时存在多种编码, 都解码为 utf-8 就会出错, 所以用 ignore 来忽略那些非 utf-8 码, 保证程序正常运行.

这个时候我们已经拿到了这个网页所有源码, 包括我们需要的章节url

查看系统默认编码:

import sys
print sys.getdefaultencoding()
# 我的打印是 utf-8 也有不少同学的打印是 ASCII

如果打印不是 utf-8 , 打印字符控制台输出是乱码, 需要把IDE 改为 utf-8 编码


book_name = re.findall('<h1>(.*)</h1>',html,re.S)

返回匹配结果列表 tuple , 当正则中有分组的时候, 返回的是分组匹配的内容


bookurl 中的 url 是不完整的, 缺一个前缀 完整的 第一章 url 如下
http://www.shicimingju.com/book/sanguoyanyi + /book/sanguoyanyi/1.html
我们需要在后面的代码中 拼接 章节 url


下面的步骤就是 打开所有的章节网页, 把里面的每个章节的内容写入到一个本地 的txt 文件中. 这样我们就得到一个完整的小说txt 文件



import urllib.request
import re
indexUrl = 'http://www.shicimingju.com/book/sanguoyanyi.html'
html = urllib.request.urlopen(indexUrl).read()
html = html.decode('utf8','ignore')

# 拿到书名 << 三国演义 >>
book_name = re.findall('<h1>(.*)</h1>',html,re.S)
# 得到的是匹配好的结果中  取所有分组匹配内容组合成的元组
# 没有元组的表达式 1.:href="/book/.{0,30}\d\.html">.*?</a>
# 有元组的表达式   2.: href="/book/.{0,30}\d\.html">(.*?)</a>    #比起上面的表达式多了一对小括号
# 表达式 2的意思 是 在匹配出 表达式1的结果上 再次匹配出所有分组的内容, 然后把所有分组的 内容 组合成 tuple
# 表达式 1. 匹配的结果:['href="/book/sanguoyanyi/1.html">第一回·宴桃园豪杰三结义  斩黄巾英雄首立功</a>', 'href="/book/sanguoyanyi/2.html">第二回·张翼德怒鞭督邮    何国舅谋诛宦竖</a>', 'href="/book/sanguoyanyi/3.html">第三回·议温明董卓叱丁原  馈金珠李肃说吕布</a>',...]
# 表达式 2. 匹配的结果: ['第一回·宴桃园豪杰三结义  斩黄巾英雄首立功', '第二回·张翼德怒鞭督邮    何国舅谋诛宦竖', '第三回·议温明董卓叱丁原  馈金珠李肃说吕布',...]
chapter = re.findall('href="/book/.{0,30}\d\.html">(.*?)</a>',html,re.S)
# 得到所有章节url
# /book 里面的/ 忘记写了, 导致得不到错误的结果
bookurl = re.findall('href="(/book/.{0,30}\d\.html)">',html,re.S)

# 得到章节 url 的前缀 (剔除 indexUtl 的 .html 字符)
# 关于 re.sub 对于输入的一个字符串,利用正则表达式(的强大的字符串处理功能),去实现(相对复杂的)字符串替换处理,然后返回被替换后的字符串
chapterUrlBegin = re.sub('.html','',indexUrl)


for i in range(0,len(bookurl)):
    # 提取每章的number
    number = re.findall('/(.{1,4})\.html',bookurl[i])
    #拼接完整的章节url
    chapterUrl = re.sub('$',"/"+number[0]+".html",chapterUrlBegin)
    # 打开章节url 网页
    chapterHtml = urllib.request.urlopen(chapterUrl).read()
    chapterHtml = chapterHtml.decode('utf-8','ignore') # 这里的 ignore 是忽略那些不能被转码成 utf-8 格式的字符
    # 小说正文
    #<div id="con2".*?<p>\s*(?: )*(.*?)</div>
    chapterText = re.findall('<div id="con2".*?<p>\s*(.*?)</div>',chapterHtml,re.S)
    # 剔除我们不需要的标签  <p> </p> 和 &nbsp
    chapterText = re.sub('<p>','',''.join(chapterText))      # 剔除 标签<p>
    chapterText = re.sub('</p>','',''.join(chapterText))     # 剔除 标签</p>
    chapterText = re.sub('<br>','',''.join(chapterText))     # <br> 的意思还不太清楚 暂时剔除他
    chapterText = re.sub(' ',' ',''.join(chapterText))  # 将 &nbsp 替换成空格
    #---------------------文件操作----------------
    #如果文件不存在 就创建一个
    f = open('/Users/liuying/Documents/book/' + "".join(book_name) + '.txt', 'a', encoding='utf-8')
    f.write(chapter[i]+"\n")
    f.write(chapterText+"\n")
    f.close()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容