抓取网页生成电子书(《修真小主播》使用Scrapy抓取电子书爬虫思路怎么抓取数据)

优采云 发布时间: 2021-09-11 19:15

  抓取网页生成电子书(《修真小主播》使用Scrapy抓取电子书爬虫思路怎么抓取数据)

  使用 Scrapy 抓取电子书

  爬虫创意

  如何抓取数据,首先要看从哪里获取,打开“修真小主播”页面,如下:

  

  

  有一个目录选项卡。单击此选项卡可查看目录。使用浏览器的元素查看工具,我们可以定位到各章节的目录和相关信息。根据这些信息,我们可以抓取到特定的页面:

  

  获取章节地址

  现在我们打开xzxzb.py文件,就是我们刚刚创建的爬虫:

  # -*- coding: utf-8 -*-

import scrapy

class XzxzbSpider(scrapy.Spider):

name = 'xzxzb'

allowed_domains = ['qidian.com']

start_urls = ['http://qidian.com/']

def parse(self, response):

pass

  start_urls 是目录地址,爬虫会自动爬取这个地址,然后在后面的解析中处理结果。现在我们来编写代码处理目录数据,首先爬取小说首页获取目录列表:

  def parse(self, response):

pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')

for page in pages:

url = page.xpath('./child::a/attribute::href').extract()

print url

pass

  获取网页中的 DOM 数据有两种方式,一种是使用 CSS 选择器,另一种是使用 XML xPath 查询。

  这里我们使用 xPath。请自行研究相关知识。看上面的代码。首先我们通过ID获取目录框,获取类cf获取目录列表:

  pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')

  接下来遍历子节点,查询li标签中子节点a的href属性,最后打印出来:

  for page in pages:

url = page.xpath('./child::a/attribute::href').extract()

print url

  这样就可以说是爬取章节路径的小爬虫了。使用如下命令运行xzxzb爬虫查看结果:

  scrapy crawl xzxzb

  此时,我们的程序可能会出现以下错误:

  …

ImportError: No module named win32api

  只需运行以下语句:

  pip install pypiwin32

  屏幕输出如下:

  > ...

> [u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/wrrduN6auIlOBDFlr9quQA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/Jh-J5usgyW62uJcMpdsVgA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/5YXHdBvg1ImaGfXRMrUjdw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/fw5EBeKat-76ItTi_ILQ7A2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/KsFh5VutI6PwrjbX3WA1AA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/-mpKJ01gPp1p4rPq4Fd4KQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/MlZSeYOQxSPM5j8_3RRvhw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/5TXZqGvLi-3M5j8_3RRvhw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/sysD-JPiugv4p8iEw--PPw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/xGckZ01j64-aGfXRMrUjdw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/72lHOJcgmedOBDFlr9quQA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/cZkHZEYnPl22uJcMpdsVgA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/vkNh45O3JsRMs5iq0oQwLQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/ge4m8RjJyPH6ItTi_ILQ7A2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/Y33PuxrKT4dp4rPq4Fd4KQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/MDQznkrkiyXwrjbX3WA1AA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/A2r-YTzWCYj6ItTi_ILQ7A2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/Ng9CuONRKei2uJcMpdsVgA2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/Q_AxWAge14pMs5iq0oQwLQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/ZJshvAu8TVVp4rPq4Fd4KQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/hYD2P4c5UB2aGfXRMrUjdw2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/muxiWf_jpqTgn4SMoDUcDQ2']

[u'//read.qidian.com/chapter/MuRzJqCY6MyoLoerY3WDhg2/OQQ5jbADJjVp4rPq4Fd4KQ2']

> ...

  爬取章节路径的小爬虫是写出来的,但是我们的目的不仅如此,我们会用这些地址来爬取内容:

  章节页面分析

  接下来分析章节页面。我们需要从章节页面获取标题和内容。

  如果说到用于章节信息爬取的解析器方法,那么我们可以写一个爬取每个章节内容的方法,比如:parser_chapter,先看章节页面的具体情况:

  

  可以看到,章节的全部内容在类名main-text-wrap的div标签中,标题是类名j_chapterName的h3标签,具体内容是带有类名的div标签类名读取内容 j_readContent。

  尝试打印此内容:

  # -*- coding: utf-8 -*-

import scrapy

class XzxzbSpider(scrapy.Spider):

name = 'xzxzb'

allowed_domains = ['qidian.com']

start_urls = ['https://book.qidian.com/info/1010780117/']

def parse(self, response):

pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')

for page in pages:

url = page.xpath('./child::a/attribute::href').extract_first()

# yield scrapy.Request('https:' + url, callback=self.parse_chapter)

yield response.follow(url, callback=self.parse_chapter)

pass

def parse_chapter(self, response):

title = response.xpath('//div[@class="main-text-wrap"]//h3[@class="j_chapterName"]/text()').extract_first().strip()

content = response.xpath('//div[@class="main-text-wrap"]//div[@class="read-content j_readContent"]').extract_first().strip()

print title

# print content

pass

  在上一步中,我们得到了一个章节地址,它是输出内容的相对路径,所以我们使用了yield response.follow(url, callback=self.parse_chapter),第二个参数是一个回调函数,也就是对章节页面进行处理,爬到章节页面后,我们解析页面并将标题保存到文件中。

  next_page = response.urljoin(url)

yield scrapy.Request(next_page, callback=self.parse_chapter)

  Scrapy.Request 与使用 response.follow 不同。它需要通过相对路径构造绝对路径。 Response.follow可以直接使用相对路径,不需要调用urljoin方法。

  注意response.follow直接返回一个Request实例,可以通过yield直接返回。

  获取数据后,进行存储。既然我们想要html页面,我们可以按标题存储。代码如下:

   def parse_chapter(self, response):

title = response.xpath('//div[@class="main-text-wrap"]//h3[@class="j_chapterName"]/text()').extract_first().strip()

content = response.xpath('//div[@class="main-text-wrap"]//div[@class="read-content j_readContent"]').extract_first().strip()

# print title

# print content

filename = './down/%s.html' % (title)

with open(filename, 'wb') as f:

f.write(content.encode('utf-8'))

pass

  到目前为止,我们已经成功捕获了我们的数据,但还不能直接使用,需要进行排序和优化。

  数据组织

  首先,我们爬下来的章节页面的排序不是很好。如果人工分拣花费太多时间和精力;另外,章节内容收录很多额外的东西,阅读体验并不好。我们需要对内容的布局和布局进行优化。可读性。

  我们先对章节进行排序,因为目录中的章节列表是按顺序排列的,所以我们只需要在下载页面名称后加上一个序号即可。

  但是保存网页的代码是一个回调函数。只有在处理目录时才能确定顺序。回调函数如何知道订单?因此,我们需要告诉回调函数处理章节的序号,并且需要向回调函数传递参数。修改后的代码如下所示:

  def parse(self, response):

pages = response.xpath('//div[@id="j-catalogWrap"]//ul[@class="cf"]/li')

for page in pages:

url = page.xpath('./child::a/attribute::href').extract_first()

idx = page.xpath('./attribute::data-rid').extract_first()

# yield scrapy.Request('https:' + url, callback=self.parse_chapter)

req = response.follow(url, callback=self.parse_chapter)

req.meta['idx'] = idx

yield req

pass

def parse_chapter(self, response):

idx = response.meta['idx']

title = response.xpath('//div[@class="main-text-wrap"]//h3[@class="j_chapterName"]/text()').extract_first().strip()

content = response.xpath('//div[@class="main-text-wrap"]//div[@class="read-content j_readContent"]').extract_first().strip()

# print title

# print content

filename = './down/%s_%s.html' % (idx, title)

cnt = '%s %s' % (title, content)

with open(filename, 'wb') as f:

f.write(cnt.encode('utf-8'))

pass

  使用 Sigil 制作电子书

  加载html文件

  要制作ePub电子书,我们首先通过Sigil将我们抓取到的文件加载到程序中,在添加文件对话框中,我们选择所有文件:

  

  制作目录

  当文件中存在HTML的h标签时,点击Generate Catalog按钮自动生成目录。我们在之前的数据捕获过程中自动添加了 h1 标签:

  

  做个封面

  

  封面本质上是HTML,可以从页面中编辑或抓取,就交给你自己实现吧。

  

  *免责声明:本文整理于网络,版权归原作者所有。如来源信息有误或侵权,请联系我们进行删除或授权。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线