爬虫006----Scrapy框架
爬虫🐛框架来了,作为点点点工程师,偶尔爬取数据做数据分析用到的就只有requests库和lxml库,没用过相应框架,所以未专门了解过,但是如果作为一个职业的爬虫工程师,框架知识必会的,使用框架不仅风格特别优美,也会帮助你做一些你想象不到的事情
PS: 其实点点点工程师是很随心所欲的,没有严格的代码规范,因为每一个完整的测试工具开发都是由一个测开工程师完成,基本不存在合作开发,不需要别人看懂你的代码,只要你自己能看懂和实现相应功能即可,所以挑自己喜欢的开发方法即可
1. Scrapy介绍
1.1 介绍
- Scrapy 是一个功能强大的 Python 爬虫框架,专门用于抓取网页数据并提取信息。
- Scrapy常被用于数据挖掘、信息处理或存储历史数据等应用。
- Scrapy 内置了许多有用的功能,如处理请求、跟踪状态、处理错误、处理请求频率限制等,非常适合进行高效、分布式的网页爬取。
- 与简单的爬虫库(如 requests 和 BeautifulSoup)不同,Scrapy 是一个全功能的爬虫框架,具有高度的可扩展性和灵活性,适用于复杂和大规模的网页抓取任务。
1.2 Scrapy架构图(绿线是数据流向)
Scrapy 的工作基于以下几个核心组件:
- Spider: 爬虫类,用于定义如何从网页中提取数据以及如何跟踪网页的链接。
- Item: 用来定义和存储抓取的数据。相当于数据模型。
- Pipeline: 用于处理抓取到的数据,常用于清洗、存储数据等操作。
- Middleware: 用来处理请求和响应,可以用于设置代理、处理 cookies、用户代理等。
- Settings: 用来配置 Scrapy 项目的各项设置,如请求延迟、并发请求数等。
2. Scrapy使用
2.1 Scrapy官方文档
Scrapy 官网:https://scrapy.org/
Scrapy 特点与介绍:https://www.runoob.com/w3cnote/scrapy-detail.html
推荐网站:https://www.runoob.com/python3/python-scrapy.html
2.2 Scrapy基本使用
2.2.1 安装
pip install scrapy
2.2.2 基本使用
2.2.2.1 创建爬虫项目
- 项目不能直接new,需要使用scrapy指令创建
scrapy startproject <filename>
- 项目不能以数字开头
- 项目不能有汉字
- 如果请求的url地址是html结尾的,是不需要加/
2.2.2.2 创建爬虫文件
- 要在spiders文件夹中创建爬虫文件
在终端进入spiders文件夹下面
cd ./filename/filename/spiders
scrapy genspider 爬虫文件的名字 要爬取的网页
eg:scrapy genspider baidu www.baidu.com
- 一般要爬取的网页写域名就行,不需要添加http协议
新版scrapy会自动根据你的目标网页提取域名至allowed_domains,添不添加http协议均可
生成文件解释:- name = “baidu”: 爬虫的名字 用于运行爬虫时,使用的值
- allowed_domains = [“www.baidu.com”]: 允许访问的域名
- start_urls = [“https://www.baidu.com”]: 起始的url地址,第一次要访问的域名,是在 allowed_domains前面添加https://, 在后面添加/
- def parse(self, response)::
- 执行了start_urls之后执行的方法
- response: 返回的那个对象
相当于response = urllib.request.urlopen(url)
相当于response = requests.get()
2.2.2.3 运行爬虫代码
scrapy crawl 爬虫的名字
- 将settings文件中的ROBOTSTXT_OBEY = True注释掉
- 君子协议(不能爬取该网址),注释掉之后就不用遵守了,一般我们不需要遵守
2.2.3 项目结构
myproject/scrapy.cfg # 项目的配置文件myproject/ # 项目源代码文件夹__init__.pyitems.py # 定义抓取的数据结构middlewares.py # 定义中间件pipelines.py # 定义数据处理管道settings.py # 项目的设置文件spiders/ # 存放爬虫代码的文件夹__init__.pymyspider.py # 自定义的爬虫代码
2.2.4 Scrapy架构组成
- 引擎
自动运行,无需关注,会自动组织所有的请求对象,分发给下载器 - 下载器
从引擎处获取到请求对象后,请求数据 - spiders
定义了如何爬取某个或某些网站,定义爬取动作和分析某个网页的地方 - 调度器
有自己的调度规则 - 管道
最终处理数据的管道,会预留接口处理我们的数据- 应用
1. 清理html数据
2. 验证爬取的数据
3. 查重(并丢弃)
4. 将爬取的结果存储到数据库中
- 应用
2.2.5 工作原理
- 引擎向spiders要url
- 引擎将要爬取的url给调度器
- 调度器会将url生成请求对象放入到指定的队列中
- 从队列中出队一个请求
- 引擎将请求交给下载器进行处理
- 下载器发送请求获取互联网数据
- 引擎将数据再次给到spiders
- spiders通过xpath解析该数据,得到数据或者url
- spiders将数据或者url给到引擎
- 引擎判断该数据是url还是数据,数据交给管道处理,url交给调度器处理
3. 常用方法
3.1 爬虫方法
方法名 | 作用描述 | 🌰 |
---|---|---|
start_requests() | 生成初始请求,可以自定义请求头、请求方法等 | yield scrapy.Request(url, callback=self.parse) |
parse(response) | 处理响应请求,是爬虫的核心方法 | yield {'title': response.css('h1::text').get()} |
follow(url, callback) | 自动处理相对URL并生成新的请求,用于分页或链接跳转 | yield response.follow(next_page, callback=self.parse) |
close(reason) | 爬虫关闭时调用,用于清理资源或记录日志 | def closed(self.reason): print('Spider closed:', reason) |
log(message) | 记录日志信息 | self.log('This is a log message') |
3.2 数据提取方法
方法名 | 作用描述 | 🌰 |
---|---|---|
response.css(selector) | 使用css选择器提取数据 | title = response.css('h1::text').get() |
response.xpath(selector) | 使用xpath选择器提取数据 | title = response.xpath('//h1/text').get() |
get() | 从SecectorList中提取第一个字符(字符串) | title = response.css('h1::text').get() |
getall() | 从SecectorList中提取所有匹配的结果 | title = response.css('h1::text').getall() |
attrib | 提取当前节点属性 | link = response.css('a::attr(href)').get() |
3.3 请求与响应方法
方法名 | 作用描述 | 🌰 |
---|---|---|
scrapy.Request(url, callback, method, headers, meta) | 创建一个新请求 | yield scrapy.Request(url, callback=self.parse, headers=headers) |
response.url | 获取当前响应的url | current_url = response.url |
response.status | 获取当前响应的状态码 | current_url = response.status |
response.meta | 获取请求中传递的额外数据 | value = response.meta.get('key') |
response.headers | 获取当前响应头信息 | content_type = response.headers.get('Content-Type') |
3.4 中间件与管道方法
方法名 | 作用描述 | 🌰 |
---|---|---|
process_request(request, spider) | 在请求发送前处理请求(下载器中间件) | request.headers['User-Agent']='Mozilla/5.0' |
process_response(request, spider) | 在响应返回后处理响应(下载器中间件) | return request.replace(dont_filter=True) |
process_item(item, spider) | 处理提取的数据(管道) | if item['price']<0: raise DropItem('Invalid price') |
open_spider(spider) | 爬虫启用时调用(管道) | def open_spider(self, spider): self.file = open('items.json', 'w') |
close_spider(spider) | 爬虫关闭时调用(管道) | def close_spider(self, spider): self.file.close |
3.5 工具和拓展方法
方法名 | 作用描述 | 🌰 |
---|---|---|
scrapy shell | 启用交互式shell,用于调试和测试选择器 | scrapy shell 'http://www.baidu.com' |
scrapy crawl < spider_name> | 运行指定的爬虫 | scrapy crawl myspider -o output.json |
scrapy check | 检查爬虫代码的正确性 | scrapy check |
scrapy fetch | 下载指定URL内容 | scrapy fetch 'https://www.baidu.com' |
scrapy view | 在浏览器中查看Scrapy下载页面 | scrapy view 'https://www.baidu.com' |
3.6 常用设置
设置项 | 作用描述 | 🌰 |
---|---|---|
USER_AGENT | 设置请求头中的 User-Agent | USER_AGENT = 'Mozilla/5.0' |
ROBOTSTXT_OBEY | 是否遵守 robots.txt 规则 | ROBOTSTXT_OBEY = False |
DOWNLOAD_DELAY | 设置下载延迟,避免过快请求 | DOWNLOAD_DELAY = 2 |
CONCURRENT_REQUESTS | 设置并发请求数 | CONCURRENT_REQUESTS = 16 |
ITEM_PIPELINES | 启用管道 | ITEM_PIPELINES = {'myproject.pipelines.MyPipeline': 300} |
AUTOTHROTTLE_ENABLED | 启用自动限速扩展 | AUTOTHROTTLE_ENABLED = True |
3.7 其他常用方法
方法名 | 作用描述 | 🌰 |
---|---|---|
response.follow_all(links, callback) | 批量处理链接并生成请求 | yield from response.follow_all(links, callback=self.parse) |
response.json() | 将响应内容解析为 JSON 格式 | data = response.json() |
response.text | 获取响应的文本内容 | html = response.text |
response.selector | 获取响应内容的 Selector 对象 | title = response.selector.css('h1::text').get() |
Scrapy框架基本使用就介绍到这了,其他注意点什么的,暂时。。。不知道,以后再补充