scrapy简记之抓取小说示例

27 篇文章 0 订阅
25 篇文章 0 订阅

scrapy

  • 网络爬虫核心工作

    1. 通过网络向指定的 URL 发送请求,获取服务器响应内容
    2. 使用某种技术(如正则表达式、XPath 等)提取页面中我们感兴趣的信息
    3. 高效地识别响应页面中的链接信息,分析这些链接递归执行此处介绍的第 1、2、3 步
    4. 使用多线程有效地管理网络通信交互
  • 分析

    • 正则表达式设计的初衷主要是处理文本信息
    • HTML 文档不仅是文本文档,而且是结构化文档,使用XPath更合适
    • 多线程管理,核心工作通用,应由框架来完成
  • scrapy包

    • 专业的 Twisted 包(基于事件驱动的网络引擎包)高效地处理网络通信
    • lxml(专业的 XML 处理包),cssselect 高效地提取 HTML 页面的有效信息
    • 提供了有效的线程管理,开发者只要使用 XPath 或 css 选择器定义自己感兴趣的信息
  • 依赖包

    • Twisted:为 Python 提供的基于事件驱动的网络引擎包
    • lxml:一个处理 XML、HTML 文档的库,比 Python 内置的 xml 模块更好用
    • pyOpenSSL:Python 用于支持 SSL(Security Socket Layer)的包
    • cryptography:Python 用于加密的库
  • scrapy核心组件

    • 调度器 负责使用下载中间件从网络上下载资源
    • 下载器 下载数据后由scrapy引擎自动提交给蜘蛛
    • 蜘蛛 由开发者实现,蜘蛛提取到的信息由scrapy引擎以item对象的形式转交给Pipeline
    • pipeline 接收Item对象,可将这些信息写入文件或数据库中
    • Item 类就是一个 DTO(数据传输对象)
    • pipelines 负责处理爬取到的信息
  • scrapy shell

    • 先用命令窗口 用XPath 从 HTML 文档中提取信息
    • scrapy shell url 使用 Scrapy 提供的 shell 调试工具来抓取该页面中的信息
    • scrapy shell -s USER_AGENT='Mozilla/5.0' url 让 Scrapy 伪装成 Firefox 来开启 shell 调试
    • 上述命令成功会进入shell,并提供scrapy变量,以便调试
      • scrapy,crawler,item,request,response,settings,spider
      • 函数fetch(url),fetch(req),shelp(),veiw(response)
    • response.xpath ('//div[@class="job-primary"]/div/h3/a/div/text()').extract() 提取节点内容
      • shell根据response提前初始化了变量 sel,该selector根据response的类型自动选择最合适的分析规则(XML vs HTML)
        • shell载入后,得到一个包含response数据的本地response变量
        • response.body,response.headers
        • response.selector.xpath() 映射快捷方法 response.xpath()
        • response.selector.css() 快捷方法 ``
  • xpath简化写法

    表达式作用
    nodename匹配此节点的所有内容
    /匹配根节点
    //匹配任意位置的节点
    .匹配当前节点
    匹配父节点
    @匹配属性
    nodename[expr]对该节点进行谓词限制
    text()匹配文件节点对象
    @attr匹配属性节点
  • Scrapy项目开发流程

    1. 定义 Item 类 (确定信息呈现结构,读)
      • 生成项目骨架 scrapy startproject <project_name> [project_dir]
      • 数据传输对象(DTO)的
    2. 编写 Spider 类 (抓节点,多个抓取源)核心
      • scrapy genspider [options] <name> <domain> 进入项目后执行,生成蜘蛛类
      • 将要爬取的各页面 URL 定义在 start_urls 列表中
      • 在 parse(self, response) 方法中通过 XPath 或 CSS 选择器提取项目信息
        • 该返回的是一个迭代生成器 yield, 类似于goto语句,即可以中断当前函数体,让渡控制权
    3. 编写 pipelines.py 文件(存)
      • 该文件负责将所爬取的数据写入文件或数据库中
      • 实现process_item(self, item, spider) 方法
    4. 配置settings.py
      • 配置User-Agent
      • 配置使用piepline
  • selector 基本方法

    • xpath() 传入xpath表达式,返回表达式所有对应的所有节点的selector list列表
    • css() 传入CSS表达式
    • extract() 序列化该节点为unicode字符串并返回list
    • re() 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表
  • 小记

    • 需要将源码保存为utf-8
    • 生成项目 -> 进入项目生成蜘蛛
    • extract(), extract_first() 节点对象方法,提取多个或单个信息
    • 数据流向 蜘蛛–> pipeline 入库…

爬取【汉乡】小说代码

  1. 用scrapy1.6创建 glance项目
  2. 写下如下代码,运行 scrapy crawl hanxiang 得到汉乡.txt小说免费章节
  • 蜘蛛
# -*- coding: utf-8 -*-
# spiders/hanxiang.py

import scrapy

class HanxiangSpider(scrapy.Spider):
    name = 'hanxiang'
    allowed_domains = ['qidian.com']
    start_urls = ['https://book.qidian.com/info/1010136878']

    def parse(self, response):
        # 汉乡 当所选select对象存在多个链接时,需要指定单一的属性节点
        yield response.follow(response.xpath('//a[(@id = "readBtn")]/@href').get(), callback=self.parse_chapter)

    def parse_chapter(self, response):
        yield {
            'chapterName': response.css('h3.j_chapterName::text').get(),
            'content': response.css('.j_readContent ::text').getall()
        }
        next_page = response.css('#j_chapterNext').xpath('@href').get()
        if next_page is not None:
            try:
                # 不是vip章节才进行下一步抓取,index方法未找到字符串则抛异常 ValueError
                next_page.index('vipreader')
            except ValueError:
                yield response.follow(next_page, callback=self.parse_chapter)
  • 管道
# pipelines.py
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


class GlancePipeline(object):
    def process_item(self, item, spider):
        with open('汉乡.txt', 'a+', encoding='utf-8') as f:
            f.write(item['chapterName'])
            f.write('\n'.join( s for s in item['content']))
            f.write('\n')
        
        return item

  • 配置
ITEM_PIPELINES = {
   'glance.pipelines.GlancePipeline': 300,
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值