scrapy框架基本使用

创建项目(爬取笔趣阁小说网)

scrapy startproject novels

创建spider

cd novels
scrapy genspider bqgui.cc fffffff

执行 genspider 命令。第一个参数是 Spider 的名称,第二个参数是网站域名。执行完毕之后,内容如下所示:

import scrapy

class BqguiCcSpider(scrapy.Spider):
name = "bqgui_cc"
allowed_domains = ["fffffffffff"]
start_urls = ["https://fffffffffff"] def parse(self, response):
pass

这里有三个属性——name、allowed_domains 和 start_urls,还有一个方法 parse。

  • name:它是每个项目唯一的名字,用来区分不同的 Spider。
  • allowed_domains:它是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉。防止访问到一些小广告啥的
  • start_urls:它包含了 Spider 在启动时爬取的 url 列表,初始请求是由它来定义的。
  • parse:它是 Spider 的一个方法。默认情况下,被调用的 start_urls 里面的链接构成的请求完成下载执行后,返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。

创建item

创建 Item 需要继承 scrapy.Item 类,并且定义类型为 scrapy.Field 的字段。观察目标网站,我们可以获取到的内容有 text、author、tags。

定义 Item,此时将 items.py 修改如下:

import scrapy

class QuoteItem(scrapy.Item):

text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()

解析Response

    def parse(self, response):
# print(response.text)
types = response.xpath('//div[@class="nav"]/ul/li/a/@href').extract()[1:9]
for index, type_url in enumerate(types):
print(type, index)
for page in range(1, 31):
# 访问小说信息的接口
yield scrapy.Request(f"https://www.bqgui.cc/json?sortid={index}&page={page}",
self.get_info)

使用item

上文定义了 Item,接下来就要使用它了。Item 可以理解为一个字典,不过在声明的时候需要实例化。然后依次用刚才解析的结果赋值 Item 的每一个字段,最后将 Item 返回即可。

    def get_info(self, response):
books = response.json()
item = NovelsItem()
match = re.search(r'sortid=(\d+)', response.url)
book_type = match.group(1)
if len(books) > 0:
for book in books:
book_author = book['author']
book_name = book['articlename']
book_content = book['intro']
item['book_author'] = book_author
item['book_name'] = book_name
item['book_content'] = book_content
item['book_type'] = book_type
yield item

后续requests

构造请求时需要用到 scrapy.Request。这里我们传递两个参数——url 和 callback,这两个参数的说明如下。

  • url:它是请求链接。
  • callback:它是回调函数。当指定了该回调函数的请求完成之后,获取到响应,引擎会将该响应作为参数传递给这个回调函数。回调函数进行解析或生成下一个请求,回调函数如上文的 parse() 所示。
yield scrapy.Request(f"https://www.bqgui.cc/json?sortid={index}&page={page}",
self.get_info)

运行

  1. 运行run.py 文件

    from scrapy.cmdline import execute
    
    # scrapy crawl 域名
    execute(['scrapy', 'crawl', 'bqgui_cc'])
  2. 命令行运行

    scrapy crawl 爬虫名

保存到文件

运行完 Scrapy 后,我们只在控制台看到了输出结果。如果想保存结果该怎么办呢?

要完成这个任务其实不需要任何额外的代码,Scrapy 提供的 Feed Exports 可以轻松将抓取结果输出。例如,我们想将上面的结果保存成 JSON 文件,可以执行如下命令:

scrapy crawl quotes -o quotes.json

scrapy crawl quotes -o quotes.jsonlines

输出格式还支持很多种,例如 csv、xml、pickle、marshal 等,还支持 ftp、s3 等远程输出,另外还可以通过自定义 ItemExporter 来实现其他的输出。

例如,下面命令对应的输出分别为 csv、xml、pickle、marshal 格式以及 ftp 远程输出:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv

其中,ftp 输出需要正确配置用户名、密码、地址、输出路径,否则会报错。

通过 Scrapy 提供的 Feed Exports,我们可以轻松地输出抓取结果到文件。对于一些小型项目来说,这应该足够了。不过如果想要更复杂的输出,如输出到数据库等,我们可以使用 Item Pileline 来完成。

使用 Item Pipeline

如果想进行更复杂的操作,如将结果保存到 MongoDB 数据库,或者筛选某些有用的 Item,则我们可以定义 Item Pipeline 来实现。

Item Pipeline 为项目管道。当 Item 生成后,它会自动被送到 Item Pipeline 进行处理,我们常用 Item Pipeline 来做如下操作。

  • 清洗 HTML 数据;
  • 验证爬取数据,检查爬取字段;
  • 查重并丢弃重复内容;
  • 将爬取结果储存到数据库。

要实现 Item Pipeline 很简单,只需要定义一个类并实现 process_item 方法即可。启用 Item Pipeline 后,Item Pipeline 会自动调用这个方法。process_item 方法必须返回包含数据的字典或 Item 对象,或者抛出 DropItem 异常。

process_item 方法有两个参数。一个参数是 item,每次 Spider 生成的 Item 都会作为参数传递过来。另一个参数是 spider,就是 Spider 的实例。

接下来,我们实现一个 Item Pipeline,筛掉 text 长度大于 50 的 Item,并将结果保存到 MongoDB。

修改项目里的 pipelines.py 文件,之前用命令行自动生成的文件内容可以删掉,增加一个 TextPipeline 类,内容如下所示:

from scrapy.exceptions import DropItem

class TextPipeline(object):
def __init__(self):
self.limit = 50 def process_item(self, item, spider):
if item['text']:
if len(item['text']) > self.limit:
item['text'] = item['text'][0:self.limit].rstrip() + '...'
return item
else:
return DropItem('Missing Text')

这段代码在构造方法里定义了限制长度为 50,实现了 process_item 方法,其参数是 item 和 spider。首先该方法判断 item 的 text 属性是否存在,如果不存在,则抛出 DropItem 异常;如果存在,再判断长度是否大于 50,如果大于,那就截断然后拼接省略号,再将 item 返回即可。

接下来,我们将处理后的 item 存入 MongoDB,定义另外一个 Pipeline。同样在 pipelines.py 中,我们实现另一个类 MongoPipeline,内容如下所示:

import pymongo

class MongoPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db

@classmethod
def from_crawler(cls, crawler):
return cls(mongo_uri=crawler.settings.get('MONGO_URI'),
mongo_db=crawler.settings.get('MONGO_DB')
)

def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]

def process_item(self, item, spider):
name = item.__class__.__name__
self.db[name].insert(dict(item))
return item

def close_spider(self, spider):
self.client.close()

MongoPipeline 类实现了 API 定义的另外几个方法。

  • from_crawler:这是一个类方法,用 @classmethod 标识,是一种依赖注入的方式,方法的参数就是 crawler5,通过 crawler 这个参数我们可以拿到全局配置的每个配置信息,在全局配置 settings.py 中我们可以定义 MONGO_URI 和 MONGO_DB 来指定 MongoDB 连接需要的地址和数据库名称,拿到配置信息之后返回类对象即可。所以这个方法的定义主要是用来获取 settings.py 中的配置的。
  • open_spider:当 Spider 被开启时,这个方法被调用。在这里主要进行了一些初始化操作。
  • close_spider:当 Spider 被关闭时,这个方法会调用,在这里将数据库连接关闭。

最主要的 process_item 方法则执行了数据插入操作。

定义好 TextPipeline 和 MongoPipeline 这两个类后,我们需要在 settings.py 中使用它们。MongoDB 的连接信息还需要定义。

我们在 settings.py 中加入如下内容:

ITEM_PIPELINES = {
'tutorial.pipelines.TextPipeline': 300,
'tutorial.pipelines.MongoPipeline': 400,
}
MONGO_URI='localhost'
MONGO_DB='tutorial'

赋值 ITEM_PIPELINES 字典,键名是 Pipeline 的类名称,键值是调用优先级,是一个数字,数字越小则对应的 Pipeline 越先被调用。

再重新执行爬取,命令如下所示:

scrapy crawl quotes

笔趣阁小说网爬取实战项目

这里提供爬虫核心代码:

import re

import scrapy
from novels.items import NovelsItem class BqguiCcSpider(scrapy.Spider):
name = "bqgui_cc"
# allowed_domains = ["bqgui.cc/"]
start_urls = ["https://www.bqgui.cc/"] def parse(self, response):
# print(response.text)
types = response.xpath('//div[@class="nav"]/ul/li/a/@href').extract()[1:9]
for index, type_url in enumerate(types):
print(type, index)
for page in range(1, 31):
# 访问小说信息的接口
yield scrapy.Request(f"https://www.bqgui.cc/json?sortid={index}&page={page}",
self.get_info) def get_info(self, response):
books = response.json()
item = NovelsItem()
match = re.search(r'sortid=(\d+)', response.url)
book_type = match.group(1)
if len(books) > 0:
for book in books:
book_author = book['author']
book_name = book['articlename']
book_content = book['intro']
item['book_author'] = book_author
item['book_name'] = book_name
item['book_content'] = book_content
item['book_type'] = book_type
yield item

scrapy框架速度了解

网站如果没有反爬机制,网速没问题,火力全开,一小时20万条数据,速度还是够用的.

爬虫实习常识了解

小公司一般3到4个爬虫工程师

2个服务器

一个服务器部署10到20个爬虫项目

小网站几十万条数据

大网站上百万条数据

更多精致内容:[CodeRealm]

Scrapy模块入门与实战:笔趣阁小说网爬取的更多相关文章

  1. 笔趣阁小说 selenium爬取

    import re from time import sleep from lxml import etree from selenium import webdriver options = web ...

  2. python入门学习之Python爬取最新笔趣阁小说

    Python爬取新笔趣阁小说,并保存到TXT文件中      我写的这篇文章,是利用Python爬取小说编写的程序,这是我学习Python爬虫当中自己独立写的第一个程序,中途也遇到了一些困难,但是最后 ...

  3. Jsoup-基于Java实现网络爬虫-爬取笔趣阁小说

    注意!仅供学习交流使用,请勿用在歪门邪道的地方!技术只是工具!关键在于用途! 今天接触了一款有意思的框架,作用是网络爬虫,他可以像操作JS一样对网页内容进行提取 初体验Jsoup <!-- Ma ...

  4. bs4爬取笔趣阁小说

    参考链接:https://www.cnblogs.com/wt714/p/11963497.html 模块:requests,bs4,queue,sys,time 步骤:给出URL--> 访问U ...

  5. 免app下载笔趣阁小说

    第一次更新:发现一个问题,就是有时候网页排版有问题的话容易下载到多余章节,如下图所示: 网站抽风多了一个正文一栏,这样的话就会重复下载1603--1703章节. 解决办法: 于是在写入内容前加了一个章 ...

  6. python应用:爬虫框架Scrapy系统学习第四篇——scrapy爬取笔趣阁小说

    使用cmd创建一个scrapy项目: scrapy startproject project_name (project_name 必须以字母开头,只能包含字母.数字以及下划线<undersco ...

  7. Python爬取笔趣阁小说,有趣又实用

    上班想摸鱼?为了摸鱼方便,今天自己写了个爬取笔阁小说的程序.好吧,其实就是找个目的学习python,分享一下. 1. 首先导入相关的模块 import os import requests from ...

  8. scrapycrawl 爬取笔趣阁小说

    前言 第一次发到博客上..不太会排版见谅 最近在看一些爬虫教学的视频,有感而发,大学的时候看盗版小说网站觉得很能赚钱,心想自己也要搞个,正好想爬点小说能不能试试做个网站(网站搭建啥的都不会...) 站 ...

  9. HttpClients+Jsoup抓取笔趣阁小说,并保存到本地TXT文件

    前言 首先先介绍一下Jsoup:(摘自官网) jsoup is a Java library for working with real-world HTML. It provides a very ...

  10. scrapy框架爬取笔趣阁

    笔趣阁是很好爬的网站了,这里简单爬取了全部小说链接和每本的全部章节链接,还想爬取章节内容在biquge.py里在加一个爬取循环,在pipelines.py添加保存函数即可 1 创建一个scrapy项目 ...

随机推荐

  1. Uni-app极速入门(二) - 登录demo

    需求 背景 1.进入小程序,默认页面判断用户是否已经登录,已经登录则进入首页,没有登录则进入登录页面 2.首页为tabbar,包括首页和设置页,设置页可以退出登录,回到登录页面 页面流转 graph ...

  2. NOIP模拟65

    T1 网格图 解题思路 60pts 就是个zz做法..(我考场上造了一个 \(500\times 500\) 的 X,一看挺快,就以为 \(n^4\) 可以切,然而..) 正解有一点难度,对于每一个节 ...

  3. Kafka--Rebalance重平衡

    Rebalance总览 Rebalance触发条件 (1)消费组成员发生变更,有新消费者加入或者离开,或者有消费者崩溃 (2)消费者组订阅的主题数量发生变更 (3)消费组订阅主题的分区数发生变更 避免 ...

  4. C# .NET 云南农信国密签名(SM2)简要解析

    BouncyCastle库(BC库)与云南农信最大的区别是 : BC库 SM2Signer.Init()  方法比云南农信多了最后3行代码: digest.Reset(); z = GetZ(user ...

  5. Flashcat与出行科技企业一起实践多云可观测

    当前架构 某出行科技企业从单个公有云往多云转型,依托于国内领先的公有云提供商,采用多云架构,在可用性.弹性.成本.供应商依赖方面,拥有了显著的优势. 相应的,多云架构也给技术团队带来了一定的复杂度和技 ...

  6. JavaScript模块化笔记

    JavaScript模块化笔记 一个模块就是一堆被封装到一个文件当中的代码,并使用export暴露部分代码给其他的文件.模块专注于一小部分功能并与应用的其他部分松耦合,这是因为模块间没有全局变量或共享 ...

  7. FreeRTOS简单内核实现2 双向链表

    FreeRTOS Kernel V10.3.1 FreeRTOS 的 list.c / list.h 文件中有 3 个数据结构.2 个初始化函数.2 个插入函数.1 个移除函数和一些宏函数,链表是 F ...

  8. webpack-bundle-analyzer 分析打包模块大小优化

    安装 webpack-bundle-analyzer npm i webpack-bundle-analyzer -D 配置vue.config.js module.exports = defineC ...

  9. Springcloud开发之OpenFeign调用和认证

    SpringCloud开发cloud具有巨大的灵活性. 在调用其它服务的时候有多种方式,虽然本质一样,但是细节还是有所差异. 一.概述 当a服务调用b服务的时候有多种方式进行: 1.通过openFei ...

  10. 使用AWS SageMaker进行机器学习项目

    使用AWS SageMaker进行机器学习项目 本文主要介绍如何使用AWS SageMaker进行机器学习项目. 1. 题目 使用的题目为阿里天池的"工业蒸汽量预测",题目地址为: ...