Scrapy实训小项目(详细讲解)

编程入门 行业动态 更新时间:2024-10-27 16:28:07

Scrapy<a href=https://www.elefans.com/category/jswz/34/1769369.html style=实训小项目(详细讲解)"/>

Scrapy实训小项目(详细讲解)

前言:

我们大多数基于requests或aiohttp来实现爬虫的整个逻辑的。可以发现,在这个过程中,我们需要实现爬虫相关的所有操作,例如爬取逻辑、异常处理、数据解析、数据存储等,但其实这些步骤很多是通用或者重复的。既然如此,我们完全可用把这些步骤的逻辑抽离出来,把其中通用的功能做成一个个基础的组件

架构设计(理解)

架构

Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。

Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,

Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器).

Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方。

Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。

Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

数据流动
  1. 引擎打开一个网站(open a domain),找到处理该网站的Spider并向该spider请求第一个要爬取的URL(s)。
  2. 引擎从Spider中获取到第一个要爬取的URL并在调度器(Scheduler )以Request调度。
  3. 引擎向调度器请求下一个要爬取的URL。
  4. 调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求( request)方向)转发给下载器(Downloader )。
  5. 一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回( response)方向)发送给引擎。
  6. 引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。
  7. Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。
  8. 引擎将(Spider返回的)爬取到的Item给Item Pipeline,将(Spider返回的)Request给调度器。
  9. (从第二步)重复直到调度器中没有更多地request,引擎关闭该网站。

从整体上来看,各个组件都只专注于一个功能,组件和组件之间的耦合度非常低,也非常容易扩展。再由引擎将各个组件组合起来,使得各个组件各司其职,互相配合,共同完成爬取工作。另外加上Scrapy对异步处理的支持,Scrapy还可以最大限度地利用网络带宽,提高数据爬取和处理的效率

Scrapy框架的使用(重点)

安装Scrapy

pip install Scrapy

安装好Scrapy框架之后,我们首先来了解一下Scrapy爬虫的制作过程:
制作 Scrapy 爬虫 一共需要4步:

  1. 新建项目 (scrapy star tproject xxx):新建一个新的爬虫项目
  2. 明确目标 (编写items.py):明确你想要抓取的目标
  3. 制作爬虫 (spiders/xxspider .py):制作爬虫开始爬取网页
  4. 存储内容 (pipelines.py):设计管道存储爬取内容


实训一:(百度爬虫)

升级 pip 版本
pip install --upgrade pip
安装Scrapy
pip install Scrapy
1、创建一个工程
scrapy star tproject f r istProject

这些文件分别是:

spiders ----------------------------------------------------# 放置Spiders的文件夹
item.py -------------------------------------# Items的定义,定义爬取的数据结构
middleware.py ------------------# Middlewares的定义,定义爬取时的中间件
pipelines.py -----------------------------------# Pipelines的定义,定义数据管道
settings.py -------------------------------------------------------------------# 配置文件

2、创建Spider
cd fristProject
scrapy genspider baidu baidu

(先进入对应的目录,再创建Spider)

  • 执行完毕后,spiders文件夹中多了一个baidu.py,它就是刚刚创建的Spider
  • 这个BaiduSpider就是刚才命令行自动创建的Spider,它继承了scrapy的Spider类
  • BaiduSpider有3个属性:
    1、name:每个项目唯一的名字,用来区分不同的Spider
    2、allowd_domains:允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉
    3、star t_ur l:包含了Spider在启动时爬取的URL列表,初始请求是由它来定义的
  • BaiduSpuder有1个方法:
    1、parse():在默认情况下,star t_ur ls里面的链接构成的请求完成下载后,parse()方法就会被调用,返回的响应就会作为唯一的参数传递给parse()方法。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求,相当于回调函数

我们可以通过修改baidu.py来定义爬虫逻辑

baidu.py

import scrapy
class BaiduSpider(scrapy.Spider ):
# 爬虫名的唯一标识
name = 'baidu'
# 允许的域名
# ps:但是有一个问题:对于star t_ur ls里的起始爬取页面,它是不会过滤的,它的作用是过滤首页之后的页面-----待验证
allowed_domains = ['baidu']
# 起始的ur l列表:只可以存储ur l
# 作用:列表中存储的ur l都会被进行get请求的发送
star t_ur ls = ['/']
# 数据解析
# parse方法调用的次数完全取决于请求的次数
# 参数response:表示的就是服务器返回的响应对象
def parse(self, response):
# 输出响应
print(response)

4、修改set t ings.py
  • settings.py是整个项目的设置文件
  • Scrapy项目允许问我们自定义所有Scrapy组件的行为,其中就是通过修改settings.py来完成
  • 我们将会在接下来的学习中一步一步的了解Scrapy组件的设置
  • Scrapy框架可以客制化的设置有很多,我们从中选3个用得比较多的基本设置开始:

1、 禁止robots:

ROBOTSTXT_OBEY = False

2、指定日志类型:

LOG_LEVEL = 'ERROR'

3、UA伪装

UA伪装: USER_AGENT = ' '

  • 执行工程后,默认会输出工程所有的日志信息(默认 LOG_LEVEL=‘INFO’ )。为了避免输出过多的日志信息,我们将日志等级提升到ERROR
4、执行爬虫
scrapy crawl baidu

实训二(段子网爬虫)

链接:/


【知识点一】:

  • 在scrapy框架中,GET请求发送的方式是:
# callback指定解析函数,用于解析数据
# GET请求
yield scrapy.Request(url, callback)
# # 完整版
# yield scrapy.Request(url, headers.cookies, meta, callback=self.parse_response)
  • POST请求的方式是:
# POST请求
yield scrapy.FormRequest(ur l,callback,formdata)
# # 完整版
# yield scrapy.FormRequest(ur l, headers. cookies, formdata, meta,callback=self.parse_response)

在 scrapy.Request(url, callback) 还有一个必须用到的参数callback,它默认是 self.parse() ,代表回调函数,代表将Request执行请求后得到的Response对象调用到该回调函数中,这也是为什么我们能在 self.parse() 进行数据解析的原因;


【知识点二】:

在Scrapy框架中,已经默认为我们实现一个 star t_requests() 方法:

def star t_requests(self):for u in self.start_urls:yield Request(u,callback=self.parse)
  • 我们还发现这是一个生成器,返回的所有Request都会作为初始Request加入调度队列
    因此,如果我们想要自定义初始请求,只需要重新 star t_requests() 方法就可以。比如说我们改成POST请求:
def star t_requests(self):for u in self.star t_ur ls:yield scrapy.FormRequest(ur l=u,callback=self.parse)

我们开始正式的段子网爬虫实训:
1、创建一个工程
scrapy startproject duanziProject
2、定义item(items.py)
import scrapyclass DuanziprojectItem(scrapy.Item):# define the fields for your item here like:# 标题title = scrapy.Field()# 作者author = scrapy.Field()# 时间re_time = scrapy.Field()# 正文content = scrapy.Field()

3、创建爬虫
cd duanziProject
scrapy genspider duanzi duanzixing

duanzi.py


import scrapy
from duanziProject.items import DuanziprojectItem
class DuanziSpider(scrapy.Spider ):name = 'duanzi'# allowed_domains = ['/']star t_ur ls = ['//']# 通用的url模板base_url = '/{}/'# 页码(从第二页开始)page = 2# 重写父类方法:这个是该方法的原始实现# 这里其实和原本一样def start_requests(self):for u in self.star t_urls:yield scrapy.Request(url=u, callback=self.parse)# 将段子网中所有页码对应的数据进行爬取def parse(self, response):# 找到所有的ar ticlearticle_ls = response.xpath('/html/body/section/div/div/ar ticle')# 遍历for article in article_ls:# 实例化itemitem = DuanziprojectItem()# 标题item['title'] = ar ticle.xpath('./header /h2/a/text()').ext ract_first()# 作者item['author '] = ar ticle.xpath('./p[1]/span[1]/text()').ext ract_first()# 时间item[' re_time'] = ar ticle.xpath('./p[1]/time/text()').ext ract_first()# 正文item['content'] = ar ticle.xpath('./p[2]/text()').ext ract_first()# 传递给管道yield item# 对新的页面发起请求# 直到递归条件结束if self.page < 11: # 结束递归的条件print(self.page)new_url = self.base_url.format(self.page) # 其他页码对应的完整urlself.page += 1# 对新的页码对应的ur l进行请求发送(手动请求GET发送)yield scrapy.Request(ur l=new_url, callback=self.parse)

我们在 self.parse() 后面手动设置了一个对新的ur l发起的请求,由于回调函数还是 self.parse() ,当递归条件未结束时,Scrapy爬虫会一直重复调用 self.parse() ,此时 self.parse() 兼顾了数据解析和发送请求的功能


4、定义Piplines

from itemadapter import ItemAdapter
import jsonclass DuanziprojectPipeline:# 初始化def __init__(self):# 文件self.fp = Nonedef process_item(self, item, spider ):# 提示print(f'JSON正在写入{item["title"]}')# 写入文件json.dump(str(item), self.fp, ensure_ascii=False, indent=4)# 伪装json格式self.fp.wr ite( " ,\n" )# 将item存储到本文文件return item# open_spiderdef open_spider (self, spider ):print('使用json方式的open_spider ()!')self.fp = open('./duanzi.json', 'wt', encoding='utf-8')# 伪装json格式self.fp.wr ite('[\n')# close_spiderdef close_spider (self, spider ):print('结束使用json方式的close_spider ()')self.fp.wr ite(']')self.fp.close()

5、修改settings.py
  1. 禁止robots:
ROBOTSTXT_OBEY = False
  1. 指定日志类型:
 LOG_LEVEL = 'ERROR'
  1. UA伪装:
USER_AGENT = ' '
  1. 开启管道:
ITEM_PIPELINES = {}

6、执行爬虫
scrapy crawl duanzi

实训三(远鉴字幕组电影详情页爬虫)

链接:

待完成

更多推荐

Scrapy实训小项目(详细讲解)

本文发布于:2024-02-13 17:47:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759845.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实训   项目   详细   Scrapy

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!