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. docker部署php8.0 nginx1.18 mysql5.7 dnmp环境

    php8.0 nginx1.18 mysql5.7 #安装docker wget -O /etc/yum.repos.d/ali_docker-ce.repo https://mirrors.aliy ...

  2. CSP-S2021 游记

    那天是惊蛰 满天花瓣 就像现在 我看清了无池里的那个人 前言 终于是开了 游记 的坑(期盼已久!) 虽然参加过 CSP-J2019 ,CSP-S2020 以及 NOIP2020 ,但是都没有写过游记( ...

  3. 第一次至第三次PTAJava大作业分析

    (1)前言: 三次题目集的知识点: 正则表达式(Regular Expression,简称Regex或RegExp)是一个强大的文本处理工具,用于匹配.查找和替换字符串.以下是正则表达式的主要知识点总 ...

  4. nodejs koa框架下载和导入excel

    ac.js const service = require("../service/model.service"); const urlencode = require(" ...

  5. Spark-submit常用任务命令参数和说明

    Spark常用任务命令参数和说明 spark-submit \ --name task2018072711591669 \ --master yarn --deploy-mode client \ - ...

  6. 你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决?

    首先,将问题提交到缺陷管理库里面进行备案. 然后,要获取判断的依据和标准: 根据需求说明书.产品说明.设计文档等,确认实际结果是否与计划有不一致的地方,提供缺陷是否确认的直接依据: 如果没有文档依据, ...

  7. WebStorm 中自定义文档注释模板

    WebStorm 中自定义文档注释模板 前提 使用WebStrom写HTML,JavaScript,进行头部注释. 减少重复劳动 养成良好的代码习惯,规范化代码,规范的注释便于后续维护. 头部注释内容 ...

  8. transformer原理

    Transformer注意力架构原理 输入层 embedding词嵌入向量 将文本中词汇的数字表示转变为向量表示,在这样的高维空间捕捉词汇间的关系 语义相近的词语对应的向量位置也更相近 每个词先通过词 ...

  9. 微信小程序自动化分析_包含执行设备及对应的微信版本

    背景介绍: 微信小程序是基于腾讯自研 X5 内核,不是谷歌原生 webview. 实现方式: 1.小程序自动化sdk,使用自动化sdk,需要有小程序的开发者权限,以及参考的资料较少,2.选择采用app ...

  10. 使用nc进行tcp测速

    # server nc -l IP PORT > /dev/null eg: nc -l 192.168.144.1 8080 > /dev/null # client bs单位块大小 c ...