爱看小说?Python爬虫爬全本小说
楔子
既然要爬小说,咱就按小说的格式来写这个博文,先来个装模作样的楔子。
由于大学开设暑期学校课程,已经在家里呆了大半年的我,几乎要跟爸妈恩断义绝,得,报几门课吧,其中一门就是Python网络爬虫
学也学了,那总得搞出点东西吧,so,不爱看小说的我,想到了爬取小说全本,那,就随便选一本,《斗-----------破-----------苍------------穹》
诶,貌似暴露年纪了。
第一章 初探网站
在网络中找小说是一件容易到吃饭一样的事,在这里我选择了什么**“爱下书小说网”,网页地址为http://www.aixiawx.com/**
搜索**《斗破苍穹》,进入目录页面:**
网页的地址为:“http://www.aixiawx.com/15/15448//”
第二章 剥丝抽茧
行,大概网页就这个样了,有这些显然不够来爬虫的,下一步开始对网页进行分析:
第一部分 目录页章节聚集
首先来讲,需要在目录页中获取所有章节的url,在这我们可以利用浏览器自带的网页分析工具, 在这里使用的是Chrome的分析工具(快捷键为Ctrl+Shift+i),找到目录页中章节的url的标签:
由此进行分析:目录中章节的url属于a标签, 存储在标签中的href属性中, 我们在Scrapy爬虫中,需要使用xpath进行分析, 在网页分析工具中,我们可以使用Ctrl+F来调出xpath输入框来进行试验,我们先找到章节url标签:
而且,我们可以看出,该url是通过与原网页url拼接得到的, 所以,我们先将目录中的所有章节url爬取出来,对所有小说网页url拼接的方法如下:
for menuItem in allMenu:
url = 'http://www.aixiawx.com'+menuItem
request = scrapy.Request(url,callback=self.parse_detail)
yield request
第二部分 小说内容集合
之后,我们需要获取小说章节的题目与内容,题目用来为txt文件命名,内容为txt中添加内容 ,点进去第一章,对小说章节内容网站进行分析,先找到文章的标题:
通过xpath查找可得:
接下来,对小说内容进行分析:
使用xpath进行查找:
爬取小说页面的代码如下:
chaptName = response.xpath('//div[@class="bookname"]/h1/text()').extract_first()
chaptDetail = response.xpath('//div[@id="content"]/text()').extract()
第三章 改天换地Scrapy
众所周知,Scrapy爬虫框架是一个相当方便的东西,只需要自己在框架里修修改改,就能实现爬虫的功能,这一点,确实是比BeautifulSoup好不少,我们先创建一个Scrapy爬虫项目:
scrapy startproject novelSpiders
再在spiders文件夹下创建爬虫文件:
scrapy genspider novel http://www.aixiawx.com/15/15448/
接下来,就要对爬虫框架进行修改了:
第一部分 items.py定结构
在items.py文件中,我们需要定义爬虫的数据结构,我们这里需要传输的数据为章节题目与内容:
class BiqugespiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
chaptName = scrapy.Field()
chaptDetail = scrapy.Field()
第二部分 Spiders耍大刀
回到当时我们创建的爬虫文件,初始化自动形成的代码:
import scrapy
class BiqugeSpider(scrapy.Spider):
name = 'biquge'
allowed_domains = ['aixiawx.com']
start_urls = ['http://www.aixiawx.com/15/15448//']
在这个基础上添加两个回调方法, 分别为parse()与parse_detail():
def parse(self, response):
allMenu = response.xpath('//dd/a/@href').extract()
for menuItem in allMenu:
url = 'http://www.aixiawx.com'+menuItem
request = scrapy.Request(url,callback=self.parse_detail)
yield request
def parse_detail(self,response):
chaptName = response.xpath('//div[@class="bookname"]/h1/text()').extract_first()
chaptDetail = response.xpath('//div[@id="content"]/text()').extract()
item = BiqugespiderItem()
item['chaptName'] = chaptName
item['chaptDetail'] = chaptDetail
yield item
parse()方法用来对目录页面进行处理,将得到的url的集合发送到parse_detail()方法,对小说章节页面进行处理,返回item
第三部分 pipelines.py开大道
pipelines.py文件的主要作用是负责对spider中返回的item进行处理, 这里我们用来对爬取的小说内容进行本地存储, 初始化的文件内容如下:
from itemadapter import ItemAdapter
class BiqugespidersPipeline:
def process_item(self, item, spider):
return item
我们在这个基础上对管道进行修改,将小说内容存储到本地:
from itemadapter import ItemAdapter
import os
class BiqugespiderPipeline:
def process_item(self, item, spider):
curPath = 'E:/NovelMenu'
if not os.path.exists(curPath):
os.makedirs(curPath)
filename_path = 'E:/NovelMenu' + os.path.sep + str(item['chaptName']) + '.txt'
with open(filename_path, 'w', encoding='utf-8') as f:
f.write(str(item['chaptDetail']) + "\n")
f.close()
return item
在这个代码中,先检查有没有目标文件夹,没有则通过os库新建文件夹, 再将item中的标题部分取出,作为文件名,将内容部分写入文件,关闭文件管道
第四部分 settings.py翻云覆雨
settings.py文件中,主要是对爬虫进行一些设置,在初始生成的文件中,将一些设置项注释掉了,我们只需要把注释去掉,在稍作修改,修改添加的内容如下:
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
ROBOTSTXT_OBEY = False
CONCURRENT_REQUESTS = 32
CONCURRENT_REQUESTS_PER_DOMAIN = 2
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
}
ITEM_PIPELINES = {
'biqugespider.pipelines.BiqugespiderPipeline': 1,
}
AUTOTHROTTLE_START_DELAY = 1
以上项设置的内容为仿冒浏览器头文件,不遵守Robot协议,开32线程,将爬虫的优先级设为1,并且爬取时间间隔为1秒。
大结局 结束,也是开始
到这里,爬虫的编写就基本结束了,那么,我们就要开始试验爬虫是否有用嘞?
来看看效果图吧:
倒还是有一点小小的瑕疵,但不打紧,这篇内容主要为了说明Scrapy的使用方法,scrapy还有好多有意思的东西,比如Redis-Scrapy分布式爬虫框架,反爬虫策略破解等等,需要探索的东西还很多,共勉。