自学Python第二十九天-feapder框架创建爬虫

自学Python第二十九天-feapder框架创建爬虫

  • 安装
  • `feapder` 的设计架构
  • `feapder` 框架的简单使用
    • 简单创建爬虫
    • 简单爬取数据
    • 简单的数据保存
  • 中间件
  • 校验
  • 浏览器渲染
    • 使用浏览器渲染获取接口数据
  • `feapder` 项目

feapder是一款上手简单,功能强大的 Python爬虫框架,内置 AirSpiderSpiderTaskSpiderBatchSpider四种爬虫解决不同场景的需求。支持断点续爬、监控报警、浏览器渲染、海量数据去重等功能。更有功能强大的爬虫管理系统 feaplat为其提供方便的部署及调度。

feapder 设计思路类似于 scrapy,不过它是国人开发的框架工具,官方文档是中文的,查询比较方便,使用门槛比较低。

官方文档

安装

feapder 需要 python 3.6 以上,且需要依赖特定版的 selenium 等依赖包,所以最好创建单独虚拟环境。另外它有三个版本,区别在于:

  • 精简版:不支持浏览器渲染、不支持基于内存去重、不支持入库mongo
pip install feapder
  • 浏览器渲染版:不支持基于内存去重、不支持入库mongo
pip install "feapder[render]"
  • 完整版:支持所有功能(常用选择)
pip install "feapder[all]"

安装完成后,可以在控制台执行查看是否安装成功

feapder

此时有可能会提示警告:

NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'

这是因为 feapder 建议使用 urllib3 v1 版本。所以最好降级一下

pip install urllib3=1.26.18

feapder 的设计架构

在这里插入图片描述

模块名称模块功能
spider框架调度核心
parser_control模版控制器负责调度parser
collector任务收集器负责从任务队里中批量取任务到内存,以减少爬虫对任务队列数据库的访问频率及并发量
parser数据解析器
start_request初始任务下发函数
item_buffer数据缓冲队列批量将数据存储到数据库中
request_buffer请求任务缓冲队列批量将请求任务存储到任务队列中
request数据下载器封装了requests,用于从互联网上下载数据
response请求响应封装了response, 支持xpathcssre等解析方式,自动处理中文乱码

feapder 的执行流程为

  1. spider调度 start_request 生产任务
  2. start_request 下发任务到request_buffer
  3. spider调度 request_buffer 批量将任务存储到任务队列数据库中
  4. spider调度 collector 从任务队列中批量获取任务到内存队列
  5. spider调度 parser_controlcollector的内存队列中获取任务
  6. parser_control 调度 request 请求数据
  7. request 请求与下载数据
  8. request将下载后的数据给 response ,进一步封装
  9. 将封装好的 response 返回给 parser_control (图示为多个parser_control,表示多线程)
  10. parser_control调度对应的 parser ,解析返回的response(图示多组parser表示不同的网站解析器)
  11. parser_controlparser解析到的数据item及新产生的request分发到 item_bufferrequest_buffer
  12. spider调度 item_bufferrequest_buffer 将数据批量入库

feapder 框架的简单使用

简单创建爬虫

首先创建爬虫,以豆瓣为例:

feapder create -s douban

执行命令后需要手动选择对应的爬虫模板,模板功能如下:

  • AirSpider 轻量爬虫:学习成本低,可快速上手
  • Spider 分布式爬虫:支持断点续爬、爬虫报警、数据自动入库等功能
  • TaskSpider分布式爬虫:内部封装了取种子任务的逻辑,内置支持从redis或者mysql获取任务,也可通过自定义实现从其他来源获取任务
  • BatchSpider 批次爬虫:可周期性的采集数据,自动将数据按照指定的采集周期划分。(如每7天全量更新一次商品销量的需求)

命令执行成功后选择AirSpider模板。默认生成的代码继承了feapder.AirSpider,包含 start_requestsparser 两个函数,含义如下:

  1. feapder.AirSpider:轻量爬虫基类
  2. start_requests:初始任务下发入口
  3. feapder.Request:基于requests库类似,表示一个请求,支持requests所有参数,同时也可携带些自定义的参数,详情可参考Request
  4. parse:数据解析函数
  5. response:请求响应的返回体,支持xpathrecss等解析方式,详情可参考Response

除了start_requestsparser两个函数。系统还内置了下载中间件等函数,具体支持可参考BaseParser

简单爬取数据

feapder 创建了一个默认示例,是可以直接执行的,并且类似于请求头之类的也是默认设置过的(随机)。feapder 的实际使用方法和 scrapy 很类似。不过 feapder 传递数据更加方便。

import feapderclass Douban(feapder.AirSpider):def start_requests(self):for page in range(10):yield feapder.Request(f"https://movie.douban.com/top250?start={page * 25}&filter=")def parse(self, request, response):li_list = response.xpath('//ol/li/div[@class="item"]')for li in li_list:item = dict()item['title'] = li.xpath('./div[@class="info"]/div/a/span[1]/text()').extract_first()item['detail_url'] = li.xpath('./div[@class="info"]/div/a/@href').extract_first()item['score'] = li.xpath('.//div[@class="star"]/span[2]/text()').extract_first()# 可以将自定义变量添加到 request 中,例如 itemyield feapder.Request(item['detail_url'], callback=self.parse_detail, item=item)def parse_detail(self, request, response):if response.xpath('//div[@class="indent"]/span[@class="all hidden"]//text()'):request.item['detail_text'] = response.xpath('//div[@class="indent"]/span[@class="all hidden"]//text()').extract_first().strip()else:request.item['detail_text'] = response.xpath('//div[@class="indent"]/span[1]//text()').extract_first().strip()print(request.item)if __name__ == "__main__":# 开启五个线程完成爬虫任务Douban(thread_count=5).start()

简单的数据保存

feapder 封装好了多种支持的数据库保存方式,只需要设置一下就可以直接保存使用,而不需要手写数据保存逻辑,注意数据库中的表和字段等需要提前创建。

数据库中创建表:

from feapder.db.mysqldb import MysqlDBdb = MysqlDB(ip='localhost', port=3306, user_name='root', user_pass='root', db='py_spider')
sql = """create table if not exists douban_feapder(id int primary key auto_increment,title varchar(255) not null,score varchar(255) not null,detail_url varchar(255) not null,detail_text text);
"""
db.execute(sql)# insert ignore: 数据插入,如果数据重复则忽略,例如id重复
insert_sql = """insert ignore into douban_feapder (id, title, score, detail_url, detail_text) values (0, '测试数据', 10, 'https://www.baidu.com', '测试数据');
"""
db.add(insert_sql)

创建全局设置文件:

feapder create --setting

然后在 settings.py 文件中配置数据库,例如 mysql:

# MYSQL
MYSQL_IP = "localhost"
MYSQL_PORT = 3306
MYSQL_DB = "py_spider"
MYSQL_USER_NAME = "root"
MYSQL_USER_PASS = "root"

或者在爬虫中自定义局部配置

import feapderclass Douban(feapder.AirSpider):__custom_setting__ = dict(MYSQL_IP="localhost",MYSQL_PORT= 3306,MYSQL_DB="py_spider",MYSQL_USER_NAME="root",MYSQL_USER_PASS="root",)

然后创建 item 文件,item 的字段名是根据数据库的字段名自动生成的

# 在创建items文件之前必须确保文件名与数据库已存在的表名一致
feapder create -i douban_feapder

最后,在爬虫中,将字典类型替换为 item 类型用于数据校验,并直接 yield 此类型的数据,就可以自动入库了。

import feapder
from douban_feapder_item import DoubanFeapderItemclass Douban(feapder.AirSpider):def start_requests(self):for page in range(11):yield feapder.Request(f"https://movie.douban.com/top250?start={page * 25}&filter=")def parse(self, request, response):li_list = response.xpath('//ol/li/div[@class="item"]')for li in li_list:# 将字典类型替换成DoubanFeapderItem用于数据校验item = DoubanFeapderItem()item['title'] = li.xpath('./div[@class="info"]/div/a/span[1]/text()').extract_first()item['detail_url'] = li.xpath('./div[@class="info"]/div/a/@href').extract_first()item['score'] = li.xpath('.//div[@class="star"]/span[2]/text()').extract_first()yield feapder.Request(item['detail_url'], callback=self.parse_detail, item=item)def parse_detail(self, request, response):if response.xpath('//div[@class="indent"]/span[@class="all hidden"]//text()'):request.item['detail_text'] = response.xpath('//div[@class="indent"]/span[@class="all hidden"]//text()').extract_first().strip()else:request.item['detail_text'] = response.xpath('//div[@class="indent"]/span[1]//text()').extract_first().strip()# 执行yield会将解析好的数据保存到数据库中yield request.itemif __name__ == "__main__":Douban().start()

中间件

feapder 中间件只有下载中间件,没有爬虫中间件。并且中间件只是类的一个方法而已,不需要另写一个 py 文件。默认的中间件是 download_midware() 方法,除了可以重写此方法外,还可以自定义下载中间件:使用 Request 对象的 download_midware 参数指定自建创建的中间件方法名

import feapderclass Douban(feapder.AirSpider):def start_requests(self):for page in range(11):yield feapder.Request(f"https://movie.douban.com/top250?start={page * 25}&filter=",download_midware=self.custom_download_midware)# 默认的下载中间件def download_midware(self, request):request.headers = {'User-Agent': 'abc'}request.proxies = {"http": "http://127.0.0.1:7890"}return request# 自定义下载中间件def custom_download_midware(self, request):request.headers = {'User-Agent': '123'}return requestif __name__ == "__main__":Douban().start()

需要注意的是,不同于 scrapy 每个请求或响应都会经过所有的中间件处理,feapder 的请求 (feapder 的中间件不处理响应) 只使用一个中间件进行处理。

校验

由于 feapder 的中间件不处理响应对象,所以 feapder 专门有个处理响应的方法,就是 validate() (校验) 方法。此方法用来检验返回的数据是否正常,可以通过 request.callback_name 来区分不同的回调解析函数,编写不同的校验逻辑。

另外当返回值为 TrueNone 时,进入解析函数;当返回值为 False 时,抛弃响应;当抛出异常时,重试请求(默认最大重试次数100次,也可以引入配置文件或自定义配置进行修改)。另外如果解析函数抛出异常也会进行重试。

class Douban(feapder.AirSpider):def start_requests(self):passdef parse(self, request, response):passdef validate(self, request, response):print('响应状态码:' response.status_code)if response.status_code != 200:raise Exception('状态码异常')		# 请求重试if __name__ == "__main__":Douban().start()

浏览器渲染

feapder 框架包含了浏览器渲染功能,使用 selenium 渲染动态页面,获取渲染后的页面数据。框架内置一个浏览器渲染池,默认的池大小为1,请求时重复利用浏览器实例,只有当代理失效请求异常时,才会销毁、创建一个新的浏览器实例。

使用时,在 start_requests() 方法中,yieldfeapder.Request 对象的参数中添加 render=True 即可。如需要也可以自定义浏览器渲染配置:

# 在setting.py中有以下代码配置# 浏览器渲染
WEBDRIVER = dict(pool_size=1,  # 浏览器的数量load_images=True,  # 是否加载图片user_agent=None,  # 字符串 或 无参函数,返回值为user_agentproxy=None,  # xxx.xxx.xxx.xxx:xxxx 或 无参函数,返回值为代理地址headless=False,  # 是否为无头浏览器driver_type="CHROME",  # CHROME、EDGE、PHANTOMJS、FIREFOXtimeout=30,  # 请求超时时间window_size=(1024, 800),  # 窗口大小executable_path=None,  # 浏览器路径,默认为默认路径render_time=0,  # 渲染时长,即打开网页等待指定时间后再获取源码custom_argument=["--ignore-certificate-errors","--disable-blink-features=AutomationControlled",],  # 自定义浏览器渲染参数xhr_url_regexes=None,  # 拦截xhr接口,支持正则,数组类型auto_install_driver=True,  # 自动下载浏览器驱动 支持chrome 和 firefoxdownload_path=None,  # 下载文件的路径use_stealth_js=False,  # 使用stealth.min.js隐藏浏览器特征
)

可以在解析函数中,使用 selenium 来进行交互和获取数据

import feapder
from selenium.webdriver.common.by import By
from feapder.utils.webdriver import WebDriverclass Baidu(feapder.AirSpider):def start_requests(self):yield feapder.Request("https://www.baidu.com", render=True)def parse(self, request, response):browser: WebDriver = response.browser		# 指定 browser 的类型browser.find_element(By.ID, 'kw').send_keys('feapder')browser.find_element(By.ID, 'su').click()if __name__ == "__main__":Baidu().start()

使用浏览器渲染获取接口数据

浏览器打开页面后,可能会通过访问接口获取需要渲染的数据。 feapder 可以直接获取接口数据(因为渲染后可能数据会有变化或编码、加密等)

首先在 setting.py 写入接口的正则,以便拦截动态接口数据

WEBDRIVER = dict(...xhr_url_regexes=['/ad','接口1正则','接口2正则',]
)

这样只要接口符合正则,就会被拦截到。然后可以提取数据

browser: WebDriver = response.browser
# 提取文本
text = browser.xhr_text("接口1正则")
# 提取json
data = browser.xhr_json("接口2正则")
# 获取响应对象
xhr_response = browser.xhr_response('/ad')
print("请求接口", xhr_response.request.url)
print("请求头", xhr_response.request.headers)
print("请求体", xhr_response.request.data)
print("返回头", xhr_response.headers)
print("返回地址", xhr_response.url)
print("返回内容", xhr_response.content)

feapder 项目

feapder 可以生成一个项目,用于复杂的爬取需求

feapder create -p wp_shop

执行完成后,会创建 wp_shop 文件夹,其中的文件结构类似于 scrapy,包含:

  • items 目录: 主要用于存放数据结构信息
  • spiders 目录:主要用于存放爬虫文件
  • setting.py 文件:主要配置文件
  • main.py 文件:主要执行文件,用于批量启动、集中管理、定时任务等

创建完成项目后,再在各目录下创建爬虫文件、item 文件等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/763386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Harmony应用开发—ArkTS-全局UI方法(日期滑动选择器弹窗)

根据指定的日期范围创建日期滑动选择器,展示在弹窗上。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用&…

【JS】如何避免输入中文拼音时触发input事件

现有一段代码&#xff0c;监听input事件。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" con…

SpringBoot+Vue项目(后端项目搭建 + 添加家居)

文章目录 1.使用版本控制管理该项目1.创建远程仓库2.克隆到本地 2.后端项目环境搭建1.创建一个maven项目2.删除不必要的文件夹3.pom.xml文件引入依赖4.application.yml 配置数据源&#xff08;注意&#xff0c;数据库名还没写&#xff09;5.com/sun/furn/Application.java 编写…

蓝桥杯算法心得——游戏(优先队列)

大家好&#xff0c;我是晴天学长&#xff0c;优先队列的题&#xff0c;式子化简非常重要&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .游戏 2) .算法思路 附近最小 1.接收数据 2.找出最小的&#…

安防监控平台EasyCVR使用管理员权限登录后,平台菜单栏显示不全是什么原因?

安防视频监控系统EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;平台能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台支持设备通过4G、5G、WIFI、有…

I2C协议

一.硬件连接 I2C必须使用开漏&#xff08;或集电极开路&#xff09;的引脚&#xff0c;其引脚框图如下所示。 SCL0对应78K0的P6.0引脚&#xff0c;SDA0对应78K0的P6.1引脚。 在使用开漏引脚通信时&#xff0c;需注意如下事项&#xff1a; 1&#xff09;两条总线须外接…

【Java - API - 多线程】(01) 通过Java 8完成多线程的创建,快速上手

通过"Java 8"完成多线程的创建&#xff0c;快速上手&#xff1b; 实操 【前提】 使用"Windows 11"系统通过"IntelliJ IDEA"软件完成&#xff1b; 【目录】 “方式1”&#xff1a;通过继承"Thread"完成-正常操作&#xff1b;“方式2”…

【QT入门】 Qt自定义信号后跨线程发送信号

往期回顾&#xff1a; 【QT入门】 lambda表达式(函数)详解-CSDN博客 【QT入门】 Qt槽函数五种常用写法介绍-CSDN博客 【QT入门】 Qt实现自定义信号-CSDN博客 【QT入门】 Qt自定义信号后跨线程发送信号 由于Qt的子线程是无法直接修改ui&#xff0c;需要发送信号到ui线程进行修改…

【Unity投屏总结】投屏方案总结

【背景】 想方便自己在VR中工作&#xff0c;打算做一个能够挂多个屏幕的远程控制VR桌面。研究下来发现细分场景有很多&#xff0c;有点鱼和熊掌不可兼得的意味&#xff0c;细分如下。 【投屏场景与解决方案】 希望多人能够同时观看我的屏幕&#xff0c;也就是一屏投多屏&…

C语言知识复盘— 递归算法 | 函数 | 数组

递归 ○ 算法思想&#xff1a; 递归算法分为两大阶段 : 递和归&#xff0c;即就是有去&#xff08;递去&#xff09;有回&#xff08;归来&#xff09;。 递去&#xff1a;将递归问题分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。归…

spring cloud项目微服务间互相调用使用自定义标注进行鉴权方案

来吧&#xff0c;贴代码。 一、背景 我们有一个项目使用了spring cloud&#xff0c;有的微服务需要调用别的微服务&#xff0c;但这些调用没有鉴权&#xff1b;当初项目时间非常紧&#xff0c;同时这部分微服务有的对外也没有鉴权&#xff0c;在代码中设置了无须鉴权&#xf…

字节跳动面试被拷打:高效处理大量数据的JavaScript技巧

一、文章内容 时间分片宏任务微任务前置内容实现时间分片 二、时间切片 什么是时间切片&#xff1f;通过字面意思我们不难理解时间切片就是将时间分成多个片段进行一一渲染数据,时间切片是个抽象的问题,我们可能会想到JavaScript中window自带的setTimeout的延迟函数或者是 w…

Docker进阶教程 - 2 Docker部署SpringBoot项目

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 2 Docker部署SpringBoot项目 已经学习了 Dockerfile 了&#xff0c;下面介绍一下如何将 SpringBoot 项目通过 Dockerfile 来部署到 Docker 中。 1 修改项目配置 首先需要准备一个 SpringBo…

初识二叉树

文章目录 一.什么是树二.什么是二叉树三.二叉树的访问次序四.特殊的二叉树五.求结点个数六.平衡二叉树总结 一.什么是树 树是由一个集合以及在该集合上定义的一种关系构成的。 集合中的元素称为树的节点&#xff0c;所定义的关系称为父子关系。 父子关系在树的节点之间建立了一…

安装OneNote for Win10 | Win10/Win11

前言 PC端的OneNote分为2个版本&#xff0c;分别是Microsoft Store版本和Office版本&#xff0c;Microsoft Store版本即为OneNote for Win10&#xff0c;此版的OneNote有最近笔记功能&#xff0c;但检索功能不如Office版本&#xff0c;个人认为2个版本各有优劣。 但OneNote f…

新人应该从哪几个方面掌握大数据测试?

什么是大数据 大数据是指无法在一定时间范围内用传统的计算机技术进行处理的海量数据集。 对于大数据的测试则需要不同的工具、技术、框架来进行处理。 大数据的体量大、多样化和高速处理所涉及的数据生成、存储、检索和分析使得大数据工程师需要掌握极其高的技术功底。 需要你…

nodejs中使用@maxmind/geoip2-node 查询地理位置信息

介绍 maxmind/geoip2-node 是一个Node.js模块&#xff0c;用于与MaxMind的GeoIP2数据库进行交互&#xff0c;从而获取IP地址的地理位置信息。MaxMind的GeoIP2数据库包含了全球范围内的IP地址和对应的地理位置信息&#xff0c;如国家、城市、经纬度等。使用maxmind/geoip2-node…

Python连接MariaDB数据库

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;【持续更新最新版】-CSDN博客 Python连接MariaDB数据库 一、安装mariadb库 pip install mariadb 二、连接…

机器视觉学习(六)—— 图像的颜色识别

目录 一、色彩空间 1.1 RGB色彩空间 1.2 HSV色彩空间 1.3 灰度 1.4 CMYK色彩空间 1.5 Lab色彩空间 二、色彩空间转换 三、识别颜色 3.1 识别一种特定的颜色 3.2 识别多种颜色 一、色彩空间 计算机视觉中常用的色彩空间有RGB色彩空间、HSV色彩空间、CMYK色彩空间、La…

34-Java传输对象模式 ( Transfer Object Pattern )

Java传输对象模式 实现范例 传输对象模式&#xff08;Transfer Object Pattern&#xff09;用于从客户端向服务器一次性传递带有多个属性的数据传输对象也被称为数值对象&#xff0c;没有任何行为传输对象是一个具有 getter/setter 方法的简单的 POJO 类&#xff0c;它是可序列…