当前位置: 首页 > article >正文

Python学习第二十六天

        前面说了最基础的使用、数据的爬取后会使用选择器进行解析数据、然后将数据按照项目(即转为对象类型)的类型,接着创建项目后就可以使用管道来对项目进行进一步处理(比如存数据库啥的),中间件的话其实就是用于全局处理请求和响应。

选择器

        官网:从html中获取数据,使用xpath,也可使用beautiful soup。

使用

# 链接打开本地的html于shell 命令行 不知道怎么使用命令 scrapy --help shell 和那个直接写到py中是一样的方法是一样的
scrapy shell ./test.html
# 首先获取title  get获取单个 getall()获取全部
response.css("title::text").get()
# 另一种方式
response.xpath("//title/text()").get()
# 获取图片中的src一般需要这个图片地址
response.css('img').xpath("@src").getall()
# 获取图片 attrib获取属性
response.css('img').attrib['src'] 
# 使用attr获取属性
response.css("img::attr('src')").getall()
# 或者直接使用xpath来获取
response.xpath("//div[@id='lg']/img/@src").getall()

方法

方法说明示例
CSS 选择器方法
css()使用 CSS 选择器选择元素response.css('div.title')
::text提取文本内容response.css('div.title::text')
::attr(属性名)提取属性值response.css('a::attr(href)')
XPath 选择器方法
xpath()使用 XPath 选择元素response.xpath('//div[@class="title"]')
/text()提取文本内容response.xpath('//div/text()')
/@属性名提取属性值response.xpath('//a/@href')
通用方法
get()提取第一个匹配结果(Scrapy 2.0+)response.css('div.title::text').get()
getall()提取所有匹配结果(Scrapy 2.0+)response.css('div.title::text').getall()
extract()提取第一个匹配结果(旧版)response.css('div.title::text').extract()
extract_first()提取第一个匹配结果(旧版)response.css('div.title::text').extract_first()
re()使用正则表达式提取response.css('div::text').re(r'\d+')
re_first()使用正则表达式提取第一个匹配response.css('div::text').re_first(r'\d+')
链式调用
方法链可以连续调用选择方法response.css('div').xpath('.//a')
其他方法
attrib获取属性字典response.css('a')[0].attrib
join()拼接多个选择结果response.css('div::text').getall().join(' ')

项目

        官网:剪贴的主要目标是从非结构化源(通常是网页)中提取结构化数据。 Spiders 将提取的数据返回为 items ,定义键-值对的Python对象。

​使用

# 第一使用命令创建项目 跟django类似
scrapy startproject testproject
# 第二使用命令创建test.py 我们要使用的是本地文件将创建出来的文件去掉allowed_domains 并将start_urls地址改为本地即可 将test.py移动到spiders下
scrapy genspider test test.com
# 执行运行命令
scrapy crawl test

其中item.py中内容为

import scrapy

# 主要是为了将 爬回来的数据封装成对象 方便后续使用
class TestprojectItem(scrapy.Item):

    title = scrapy.Field()

    url = scrapy.Field()

其中test.py中内容为

import scrapy
import os
from ..items import TestprojectItem

# 项目测试
class TestSpider(scrapy.Spider):
    name = "test"
    # 或者直接卸载头部的strt_url中 一样的 为什么知道这个方法  查看父类的spider 集成了 所以使用子类会自动覆盖父类相同方法
    # 路劲注意 file:///是本地文件开头 如果是绝对路径自己直接写即可 如果是相对路径使用下面的即可
    def start_requests(self):
        # 获取当前目录的绝对路径
        current_dir = os.path.dirname(os.path.abspath(__file__))
        file_path = os.path.join(current_dir, 'test.html')
        # 替换反斜杠为正斜杠,并添加 file:/// 前缀
        file_url = 'file:///' + file_path.replace('\\', '/')

        yield scrapy.Request(url=file_url, callback=self.parse)

    def parse(self, response):

        item = TestprojectItem()
        item['url'] = response.css('img').attrib['src'].replace("//","")
        item['title'] = response.xpath("//title/text()").get()
        print("item.title:",item['title']) # item.title: 百度一下,你就知道
        return item

方法和属性

类别属性/方法说明示例
Item 属性fields包含所有字段定义的字典(自动生成)```python
class ProductItem(scrapy.Item):
name = scrapy.Field()
print(ProductItem.fields) # 输出: {'name': {}}
```
Item 方法__init__()初始化Item(可覆盖以添加自定义逻辑)```python
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self['timestamp'] = datetime.now()
```
get() / set()获取或设置字段值```python
item = ProductItem()
item.set('name', 'Apple') # 设置
print(item.get('name')) # 获取: 'Apple'
```
keys()返回所有字段名(列表)print(item.keys())) # 输出: ['name', 'price']
items()返回字段键值对(元组列表)print(item.items())) # 输出: [('name', 'Apple'), ('price', None)]
__setitem__() / __getitem__()支持字典式访问(如 item['name'] = 'Apple'```python
item['price'] = 10.5
print(item['price']) # 输出: 10.5
```
覆盖方法to_dict()自定义Item转字典的逻辑(默认返回所有字段)```python
def to_dict(self):
data = super().to_dict()
data['discounted'] = self['price'] * 0.9
return data
```
validate()自定义字段验证逻辑(需手动调用)```python
def validate(self):
if not self.get('name'):
raise ValueError("Name field is required")

管道

        官网:管道用于处理爬取到的Item,执行数据清洗、验证、存储等操作。

用途

  • 清理HTML数据

  • 验证抓取的数据(检查项目是否包含某些字段)

  • 检查重复项(并删除它们)

  • 将爬取的项目存储在数据库中

使用

        启用管道将settings.py中的ITEM_PIPELINES这个注释打开或者增加自己的管道内容

# 在此设置中分配给类的整数值决定了它们的运行顺序:项从低值类传递到高值类。习惯上把这些数字定义在0-1000范围内,相当于是运行顺序 官网概念哈
ITEM_PIPELINES = {
   # 先执行校验 后面的值越小 越先走
   "testproject.pipelines.pipelines.TestprojectPipeline": 200,
   # 在入库
   "testproject.pipelines.sqlite_pipelines.SQLitePipeline": 300,
}
import sqlite3


class SQLitePipeline:
    def __init__(self, db_path):
        self.db_path = db_path

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            db_path=crawler.settings.get('SQLITE_PATH', 'scrapy_data.db')
        )

    def open_spider(self, spider):
        self.connection = sqlite3.connect(self.db_path)
        # 获取游标
        self.cursor = self.connection.cursor()
        # 创建表
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS test_table (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                url TEXT,
                title TEXT
            )
        ''')
        self.connection.commit()

    def close_spider(self, spider):
        self.connection.close()

    def process_item(self, item, spider):
        print("--------SQLitePipeline我后走-------:")
        self.cursor.execute(
            "INSERT INTO test_table (url, title) VALUES (?, ?)",
            (item['url'], item['title'])
        )
        self.connection.commit()
        return item

方法

方法必须实现说明参数返回值

process_item(item, spider)

✅ 是

核心方法,处理每个Item的主逻辑

item: 当前处理的Item对象
spider: 生成该Item的Spider实例

必须返回 Item 对象或 Deferred(异步场景)
(否则后续Pipeline不执行)

open_spider(spider)

❌ 否

Spider启动时调用(可选),用于初始化资源(如打开文件、连接数据库)

spider: 当前Spider实例

无要求

close_spider(spider)

❌ 否

Spider关闭时调用(可选),用于清理资源(如关闭文件、断开数据库连接)

spider: 当前Spider实例

无要求

from_crawler(cls, crawler)

❌ 否

类方法(可选),用于从Crawler获取配置(如访问Settings)

crawler: Crawler对象(包含Settings等核心组件)

返回Pipeline实例

中间件

         官网:Spider中间件是一个钩子框架,可以钩住Scrapy的Spider处理机制,在该机制中,您可以插入自定义功能来处理发送到的响应。 蜘蛛 用于处理和处理由spider生成的请求和项目。

用途 

  • 设置User-Agent

  • 代理IP处理

  • 请求重试

  • 响应修改

使用

        将setting.py中的DOWNLOADER_MIDDLEWARES、SPIDER_MIDDLEWARES注释打开并添加自己的中间件

# 将这两个注释打开 后面的参数与管道的参数相同越小 优先级越高
SPIDER_MIDDLEWARES = {
   "testproject.middlewares.TestprojectSpiderMiddleware": 543,
}
DOWNLOADER_MIDDLEWARES = {
   "testproject.middlewares.TestprojectDownloaderMiddleware": 543,
}
# 清空下window下的命令行 要不然老是满
cls
# 运行命令
scrapy crawl test

  可以将他下载到本地然后在进行解析目前代码没写只写了一个执行顺序后续项目完善

class TestprojectDownloaderMiddleware:
    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        print("------------TestprojectSpiderMiddleware方法from_crawler---------------:")
        return s

    def process_request(self, request, spider):
        # 之前request.Requests自定义可以在这儿自定义user-agent和请求投了
        print("------------TestprojectSpiderMiddleware方法process_request因为是定制请求---------------:")
        return None

    def process_response(self, request, response, spider):
        # 处理可能失败的场景 或者重试之类的
        print("------------TestprojectSpiderMiddleware方法process_response---------------:")
        return response

    def process_exception(self, request, exception, spider):
        print("------------TestprojectSpiderMiddleware方法process_exception---------------:")

    def spider_opened(self, spider):
        # 可以使用这个来自己添加日志
        spider.logger.info("Spider opened: %s" % spider.name)
        print("------------TestprojectSpiderMiddleware方法spider_opened---------------:")

方法

中间件类型方法必须实现调用时机参数返回值
下载器中间件
(Downloader Middleware)
process_request(request, spider)❌ 否请求发送到下载器之前request: Request 对象
spider: Spider 实例
可选:
None(继续处理)
Response(跳过下载)
Request(替换请求)
Exception(触发错误处理)
process_response(request, response, spider)❌ 否下载器返回响应之后request: 对应的 Request 对象
response: Response 对象
spider: Spider 实例
必须返回:
Response 对象
Request 对象(重试或重定向)
- 抛出异常
process_exception(request, exception, spider)❌ 否下载器或 process_request() 抛出异常时request: Request 对象
exception: Exception 对象
spider: Spider 实例
可选:
None(继续处理)
Response(恢复处理)
Request(重试)
爬虫中间件
(Spider Middleware)
process_spider_input(response, spider)❌ 否响应传递给 Spider 解析之前response: Response 对象
spider: Spider 实例
None(继续处理)
- 抛出异常(中断处理)
process_spider_output(response, result, spider)❌ 否Spider 返回结果(Item 或 Request)之后response: 触发的 Response 对象
result: Item/Request 生成器
spider: Spider 实例
必须返回结果生成器(可过滤或修改 Item/Request)
process_spider_exception(response, exception, spider)❌ 否Spider 或 process_spider_input() 抛出异常时response: Response 对象
exception: Exception 对象
spider: Spider 实例
可选:
None(继续异常链)
- 生成器(返回替代结果)
process_start_requests(start_requests, spider)❌ 否Spider 的 start_requests() 方法调用后start_requests: 初始请求生成器
spider: Spider 实例
必须返回请求生成器(可修改初始请求)

day26代码:pythonPractice: python学习内容练习-代码 - Gitee.com


http://www.kler.cn/a/612757.html

相关文章:

  • Spring Data审计利器:@LastModifiedDate详解!!!
  • PDF处理控件Spire.PDF系列教程:Java 给现有的 PDF 文档添加页眉页脚
  • PyTorch 深度学习实战(27):扩散模型(Diffusion Models)与图像生成
  • java替换html中的标签
  • 《深度剖析SQL数据类型转换:隐式与显式的奥秘》
  • WPF 附加属性
  • 在海量数据中精准定位:BloomFilter的工作原理与实战指南
  • OmniGraffle Pro for Mac思维导图
  • 自行车模型与汽车模型的混合策略在自动驾驶中的多维度协同优化
  • 测试模版12
  • 从链上到现实:Python如何重塑区块链供应链管理
  • 【DeepSeek学C++】移动构造函数
  • 127. 单词接龙【 力扣(LeetCode) 】
  • T11 TensorFlow入门实战——优化器对比实验
  • 谈谈空间复杂度考量,特别是递归调用栈空间消耗?
  • HTTP 状态码与前端 try-catch 捕获关系
  • java八股文之企业场景
  • Oracle数据库数据编程SQL<2.2 DDL 视图、序列>
  • 小白工具PDF转换 PDF转图片 超便捷软件 文件格式转换 简单好用效率高
  • RabbitMQ 核心组件及功能详解