简易python爬虫--修真四万年

前言

小说一章一章看,多麻烦啊,还是一次性看全本比较顺畅。但是网络上小说全本下载很少,是不是很苦恼呢?没关系,开动双手,让我们用python写一个爬虫程序获得我们想读的小说全文吧!

准备

简易爬虫涉及到的东西不多,这里推荐python的两个库:requestsBeautifulSoup。requests用于请求网页内容,相当于把整个网页下载下来。python也有标准库urllib2、urllib3等,但是没有requests简单易用。BeautifulSoup是python一个解析html、lxml的一个非常强大的库。这里我们就用这两个库就可以完成我们的小爬虫。
当然一点Html和CSS选择器的知识也是必要的。大家可以去这个网站上查询,现学现卖!

动手!

侦查敌情

知己知彼,百战不殆。我选择了笔趣岛作为我的目标网站。大家也可以去寻找其他的网站,原理相同。我选择我最近在追的一本小说修真四万年
打开这个小说的首页后,我们用浏览器的开发者工具。Chrome的快捷键是F12。打开之后可以看到下图:
修真四万年首页+F12
右边窗口就是这个网页的代码!由于这是一个比较简单的网页,所有都在里面了,包括《修真四万年》所有章节的目录,以及我们之后要用到的每章节目录对应的url。
点击右边窗口左上角的那个箭头箭头。点击之后鼠标键头走到哪里,右边窗口就会跟着变化。这是因为之前的按钮可以根据鼠标定位页面代码。定位到目录所在的区块(目录所在的区块全部变蓝),点击一下固定右边定位的代码位置:
目录的位置
div、dl、dt、dd这些叫做标签,class、id这些叫做属性。不明白的同学们可以去看一下CSS选择器的内容。之后我们要用BeautifulSoup通过这些标签和属性获得我们想要的内容。点开一个dd的标签(黑色三角),会出来一个a标签,a里面的内容有一个网址(不全)和一个章节的名字:
第2125章 有谁能够阻挡我!
这就是我们在这个页面需要的内容了。细心的会发现,这一章是最新章节,我们可以找到第一章所在的位置:
第一章
我们回到网页里,点击进入第一章,同样用F12调出代码窗口,再用同样的方法定位正文所在的代码位置:
这里写图片描述
整章内容都在这个div的标签里面。
好了,敌情我们已经侦查得差不多了。可以构思我们的策略了。

爬虫思路

思路非常简单。我们首先获得每章节的url,然后根据url访问每章节页面,进而抓取正文,最后把所有章节拼接起来。

代码实现

这里推荐一个python的开发环境Anaconda。它集成很多python的库,我们可以少造轮子。而且Anaconda自带了一个比较不错的IDE,名字叫做Spyder,界面和Matlab差不多,用来边写边调试脚本非常方便。Pycharm也很不错,但是变量查看太麻烦,所以我暂时还是用Spyder。
打开Spyder,新建一个python file。
首先引入我们需要的库:

import requests
from bs4 import BeautifulSoup
import codecs

这里引入了requests库,从bs4这个库里引入了BeautifulSoup这个类,还引入了一个用来编解码的codecs库。

第一步:请求目录页内容

response = requests.get('http://www.biqudao.com/bqge7946/')
respone.encoding = 'utf-8'
response = response.text
page = BeautifulSoup(response,'lxml')

第一行是用requests的get方法请求目录页。在console里输入response会得到Response [200],这是请求成功的意思。如果是别的数字,一般来说是请求失败。第二行是把response编码为utf-8,用以支持中文。第三行的.text把response的内容返回为文本,第四行用BeautifulSoup把response解析成lxml格式的文档。

第二步:获取各章节url

pages = page.select('dd')
links=[]
for p in pages:
    url = 'http://www.biqudao.com'+p['href']
    name = u':'.join(p.text.split())
    chapter = [url,name]
    links.append(chapter)

Beautiful Soup支持大部分的CSS选择器。在标签(Tag)或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,可以获得我们想要的内容。关于.select的用法,可以参考这里。这里我们传入的参数是’a[style]’,获得了一个list,这个list里就是我们感兴趣的所有章节的url和章节名!良心站长!
输出pages的前3个元素

In:pages[:3]
Out: 
[<a href="/bqge7946/4377585.html" style="">第一章 法宝坟墓</a>,
 <a href="/bqge7946/4377586.html" style="">第二章 光幕仪</a>,
 <a href="/bqge7946/4377587.html" style="">第三章 异梦</a>]

接下来提取出每章节的url

links=[ ['http://www.biqudao.com'+p['href'],u':'.join(p.text.split())] for p in pages]

这是一个列表推导式,等同于下面这一大段代码:

links=[]
for p in pages:
    url = 'http://www.biqudao.com'+p['href']
    name = u':'.join(p.text.split())
    links.append([url,name])

现在我们已经的得到从第一章到最新一章的所有url和对应的章节名称了。接下来我们就用这些url来获取我们想要的正文吧。

第三步:获取章节正文并合并为全本

首先我们建一个空字符串,用于存储小说正文。

novel  = u''

然后我们用一个for循环获取所有章节并拼接在一起。

for link in links:
    response = requests.get(link[0])
    response.encoding = 'utf-8'
    response = response.text
    soup = BeautifulSoup(response)
    content = soup.select('#content')[0].get_text()    
    #由于正文末尾有一些我们不需要的字符,用这种切片的方式去除
    content=link[1]+content[:-16]
    novel = novel+content
    #去除正文中破坏结构的转义字符\n和\t
    novel=u'\n\t'.join(novel.split())

这段代码就不再多做解释了。不清楚的可以参看bs4的教程

最后一步:保存

上面那段代码会运行一段时间。最终获得的nuvel就是我们所要的小说全文。接下来我们就把它保存下来:

txt = codecs.open(u'PATH/修真四万年.txt','wb','utf-8')
txt.write(novel)
txt.close()

PATH是我们希望小说保存在哪里的路径。

大功告成!

完整代码

见我的Github

import requests
from bs4 import BeautifulSoup
import codecs
#读取目录页url和data
cont = requests.get('http://www.biqudao.com/bqge7946/')
cont.encoding = 'utf-8'
cont = cont.text
page = BeautifulSoup(cont,'lxml')

pages = page.select('a[style]')
links=[ ['http://www.biqudao.com'+p['href'],u':'.join(p.text.split())] for p in pages]
novel=u''
for link in links:
    response = requests.get(link[0])
    response.encoding = 'utf-8'
    response = response.text
    soup = BeautifulSoup(response)
    content = soup.select('#content')[0].get_text()
    content=lins[1]+content[:-16]
    novel = novel+content
    novel=u'\n\t'.join(novel.split())
txt = codecs.open(u'修真四万年.txt','wb','utf-8')
txt.write(novel)
txt.close()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章