scrapy爬取小说

创建项目

scrapy startproject book	# book 为项目名

文件结构

在这里插入图片描述

代码实现

mySpider.py

import scrapy
from book.items import BookItem


'''		小说目录第1章
<ul class="cf">
                        
    <li data-rid="1">
    <a href="//read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2"
    target="_blank"
    data-eid="qd_G55"
    data-cid="//read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2"
    title="首发时间:2015-08-10 13:56:55 章节字数:1889">
        第1章 刘慈欣2018克拉克奖获奖感言
    </a>
                            
</li>

'''
'''		小说第1章内容
<div class="read-content j_readContent">
            <p>  先生们、女士们,晚上好,<p>
                很荣幸获得Clarke Award for Imagination in Service to Society Award。
            <p>    这个奖项是对想象力的奖励,而想象力是人类所拥有的一种似乎只应属于神的能力,它存在的意义也远超出我们的想象。
                有历史学家说过,人类之所以能够超越地球上的其它物种建立文明,主要是因为他们能够在自己的大脑中创造出现实中不存在的东西。
                在未来,当人工智能拥有超过人类的智力时,想象力也许是我们对于它们所拥有的惟一优势。
            <p>    
</div>
'''
class MySpider(scrapy.Spider):
    name = "mySpider"   # 爬虫项目名称(开始爬取时会用到)
    
    # 官方文件的解释为包含spider在启动时爬取的url列表,用于定义初始请求。
    start_urls = ["https://book.qidian.com/info/1001535146#Catalog"]
    

    def parse_detail(self,response):
        # 接收上级已爬取的数据
        string = ""
        item = response.meta['item']
        content = response.xpath("//div[@class='read-content j_readContent']/p/text()").extract()
        for i in content:
            string = string + i + '\n'

        item['content'] = string
        yield item

    # 运行爬虫后,名为 parse() 的方法将会被自动调用,用来处理 start_url 列表中的每一个 URL
    def parse(self,response):
        try:
            data = response.body.decode()
            selector = scrapy.Selector(text=data)
            books = selector.xpath("//ul[@class='cf']")
            #books = response.xpath("//ul[@class='cf']") 前面 3 行可用这行代替
            books = books.xpath("./li[@data-rid]")
            
            
            for book in books:
                item = BookItem()
                item["title"] = book.xpath("./a/text()").extract()
                href = book.xpath("./a/@href").extract_first()  # //read.qidian.com/chapter/qrqmtYSE7XFmzDX0o03xsg2/LOibR1_EzCTgn4SMoDUcDQ2
                href = "http:"+href     # 拼接url

                yield scrapy.Request(url=href,callback=self.parse_detail,meta={
    
    'item':item})
                # 用scrapy.Request发起请求可以带上 meta={'item': item} 把之前已收集到的信息传递到新请求里
                # 在新请求里用 item = response.meta('item') 接受过来,在 item 就可以继续添加新的收集的信息了
        except Exception as err:
            print(err)

items.py
定义了爬取结果的数据结构,爬取的数据会被赋值到成该 Item 对象

import scrapy

class BookItem(scrapy.Item):
    title = scrapy.Field()      # 存储标题
    content = scrapy.Field()    # 存储小说内容

pipelines.py
负责处理由蜘蛛从网页中抽取的项目,它的主要任务是清洗、验证、和存储数据

import os

class BookPipeline(object):

    # 开启爬虫时执行,只执行一次
    def open_spider(self,spider):
        if os.path.exists("三体"):
            pass
        else:
            os.mkdir("三体")
        print("spider start")

    # 处理提取的数据(保存数据)
    def process_item(self, item, spider):
        title = item['title']
        content = item['content']
        print(title)

        with open("三体/"+title[0]+".txt","w") as f:
            f.write('\t\t\t\t' + title[0] + '\n\n')
            f.write(content)
        
        return item
    
    # 关闭爬虫时执行,只执行一次。 (如果爬虫中间发生异常导致崩溃,close_spider可能也不会执行)
    def close_spider(self, spider):
        print("spider end")

run.py
运行,开始爬取

from scrapy import cmdline

cmdline.execute("scrapy crawl mySpider -s LOG_ENABLED=False".split())

settings.py

定义了项目的全局配置

# 把下面的注释去掉
ITEM_PIPELINES = {
    
    
    'book.pipelines.BookPipeline': 300,
}

效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44018458/article/details/109118662