Scrapy模块入门与实战:笔趣阁小说网爬取
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)
运行
运行run.py 文件
from scrapy.cmdline import execute # scrapy crawl 域名
execute(['scrapy', 'crawl', 'bqgui_cc'])
命令行运行
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模块入门与实战:笔趣阁小说网爬取的更多相关文章
- 笔趣阁小说 selenium爬取
import re from time import sleep from lxml import etree from selenium import webdriver options = web ...
- python入门学习之Python爬取最新笔趣阁小说
Python爬取新笔趣阁小说,并保存到TXT文件中 我写的这篇文章,是利用Python爬取小说编写的程序,这是我学习Python爬虫当中自己独立写的第一个程序,中途也遇到了一些困难,但是最后 ...
- Jsoup-基于Java实现网络爬虫-爬取笔趣阁小说
注意!仅供学习交流使用,请勿用在歪门邪道的地方!技术只是工具!关键在于用途! 今天接触了一款有意思的框架,作用是网络爬虫,他可以像操作JS一样对网页内容进行提取 初体验Jsoup <!-- Ma ...
- bs4爬取笔趣阁小说
参考链接:https://www.cnblogs.com/wt714/p/11963497.html 模块:requests,bs4,queue,sys,time 步骤:给出URL--> 访问U ...
- 免app下载笔趣阁小说
第一次更新:发现一个问题,就是有时候网页排版有问题的话容易下载到多余章节,如下图所示: 网站抽风多了一个正文一栏,这样的话就会重复下载1603--1703章节. 解决办法: 于是在写入内容前加了一个章 ...
- python应用:爬虫框架Scrapy系统学习第四篇——scrapy爬取笔趣阁小说
使用cmd创建一个scrapy项目: scrapy startproject project_name (project_name 必须以字母开头,只能包含字母.数字以及下划线<undersco ...
- Python爬取笔趣阁小说,有趣又实用
上班想摸鱼?为了摸鱼方便,今天自己写了个爬取笔阁小说的程序.好吧,其实就是找个目的学习python,分享一下. 1. 首先导入相关的模块 import os import requests from ...
- scrapycrawl 爬取笔趣阁小说
前言 第一次发到博客上..不太会排版见谅 最近在看一些爬虫教学的视频,有感而发,大学的时候看盗版小说网站觉得很能赚钱,心想自己也要搞个,正好想爬点小说能不能试试做个网站(网站搭建啥的都不会...) 站 ...
- HttpClients+Jsoup抓取笔趣阁小说,并保存到本地TXT文件
前言 首先先介绍一下Jsoup:(摘自官网) jsoup is a Java library for working with real-world HTML. It provides a very ...
- scrapy框架爬取笔趣阁
笔趣阁是很好爬的网站了,这里简单爬取了全部小说链接和每本的全部章节链接,还想爬取章节内容在biquge.py里在加一个爬取循环,在pipelines.py添加保存函数即可 1 创建一个scrapy项目 ...
随机推荐
- 薄书的pytorch项目实战lesson49-情感分类+蹭免费GPU
项目来源 B站视频pytorch项目实战-情感分类问题 github lesson49-情感分类实战 1 实验环境 在这里和大家推荐一个学习ML和DL的一个实验运行平台,就是google的Colabo ...
- react自定义导航组件 路由参数
为何需要自定义导航? 因为在项目中往往不是所有的声明式导航都是需要a标签完成,有时候可能需要别的标签,此时如果在需要的地方去写编程式导航就会有代码重复可能性,就在对于公共代码进行提取. 思路: 定义一 ...
- INFINI Labs 产品更新 | 统一版本号 1.22.0
INFINI Labs 产品又更新啦~,包括 Console,Gateway,Loadgen,Agent 1.22.0.为了避免版本不同带来的困扰,以后发布均统一版本号,此次版本重点修复历史遗留 Bu ...
- HTML/CSS复习
CSS复习 HTML语义化 有利于SEO(搜索引擎优化) 便于阅读,修改 对盲人等不方便浏览网页的人来说比较方便 盒模型 盒模型有border-box和content-box两种,默认是content ...
- Linux Debian安装教程
Debian 是一个免费的开源操作系统,是最古老的 Linux 发行版之一,于 1993 年由 Ian Murdock 创建.它采用了自由软件协议,并且由志愿者社区维护和支持.Debian 的目标是创 ...
- 记一下 localstorage sessionStorage cookie 不同
localStorage.sessionStorage.cookie 使用整理 下面从这几方面进行梳理 存储形式 相同点 不同点 使用方法 用途 多标签之间通讯 一.存储形式 1.localStron ...
- SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计
SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计 SOP,是 Standard Operating Procedure三个单词中首字母的大写 ,即标准作业程序,指将某一事件的标准操作 ...
- k8s使用rbd作为存储
k8s使用rbd作为存储 如果需要使用rbd作为后端存储的话,需要先安装ceph-common 1. ceph集群创建rbd 需要提前在ceph集群上创建pool,然后创建image [root@ce ...
- UE4打包发布后,在Windows和Android平台上访问非Asset文件
1.问题来源 最近的项目里面有个需求,要在打包之后的exe或者apk运行起来后访问工程Content或者安卓目录下的非Asset文件,比如text文件,json文件等,从中读取一些可随时修改的配置项信 ...
- 一文带你深入理解SpringMVC的执行原理
今天大致来看一下Spring MVC的执行流程是什么样的 执行流程:也就是一个请求是怎么到我们Controller的,返回值是怎么给客户端的 本文分析的问题: 文件上传的请求是怎么处理的 跨域是怎么处 ...