Python爬虫---scrapy框架---当当网管道封装

项目结构:

dang.py文件:自己创建,实现爬虫核心功能的文件

python 复制代码
import scrapy
from scrapy_dangdang_20240113.items import ScrapyDangdang20240113Item


class DangSpider(scrapy.Spider):
    name = "dang"  # 名字
    # 如果是多页下载的话, 那么必须要调整的是allowed_domains的范围 一般情况下只写城名
    # allowed_domains = ["https://category.dangdang.com/cp01.01.00.00.00.00.html"]
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["https://category.dangdang.com/cp01.01.00.00.00.00.html"]

    # 第1页:"https://category.dangdang.com/cp01.01.00.00.00.00.html"
    # 第2页: "https://category.dangdang.com/pg2-cp01.01.00.00.00.00.html"
    # 第3页: "https://category.dangdang.com/pg3-cp01.01.00.00.00.00.html"

    base_url = "https://category.dangdang.com/pg"
    page = 1

    def parse(self, response):
        print("========================================================================")

        # pipelines: 下载数据
        # items: 定义数据结构

        # xpath语法
        # src = //ul[@id='component_59']/li/a/img/@src
        # 除了第一张,其他做了懒加载 所以不能使用src,要使用这个data-original
        # src = //ul[@id='component_59']/li/a/img/@data-original
        # alt = //ul[@id='component_59']/li/a/img/@alt
        # price = //ul[@id='component_59']/li/p[@class='price']/span[1]/text()

        # 所有的seletor的对象都可以再次调用xpath语法
        li_list = response.xpath("//ul[@id='component_59']/li")

        for li in li_list:

            src = li.xpath(".//img/@data-original").extract_first()
            if src:
                src = src
            else:
                src = li.xpath(".//img/@src").extract_first()

            name = li.xpath(".//img/@alt").extract_first()
            price = li.xpath(".//p[@class='price']/span[1]/text()").extract_first()

            print(src, name, price)

            # 将爬取的数据放在对象里
            book = ScrapyDangdang20240113Item(src=src, name=name, price=price)

            # 获取一个book将book交给pipelines,将对象放在管道里
            yield book

            # 每一页的爬取业务的逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用
        if self.page < 100:
            self.page = self.page + 1

            url = self.base_url + str(self.page) + "-cp01.01.00.00.00.00.html"
            # 调用parse万法
            # scrapy.Request就是scrpay的get请求 url就是请求地址
            # callback是你要执行的那个函数注意不需要加()
            yield scrapy.Request(url=url, callback=self.parse)

items文件:定义数据结构的地方

python 复制代码
import scrapy


class ScrapyDangdang20240113Item(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 通俗的说就是你要下载的数据都有什么
    src = scrapy.Field()
    name = scrapy.Field()
    price = scrapy.Field()

settings文件:配置文件,例如开启管道

python 复制代码
# 开启管道
ITEM_PIPELINES = {
    # 管道可以有很多个,那么管道是有优先级的,优先级的范围是1到1000,值越小优先级越高
    "scrapy_dangdang_20240113.pipelines.ScrapyDangdang20240113Pipeline": 300,
    "scrapy_dangdang_20240113.pipelines.DangdangDownloadPipeline": 301,
}

pipelines.py文件:管道文件,里面只有一个类,用于处理下载数据的,值越小优先级越高

python 复制代码
# 下载数据

# 如果想使用管道的话 那么就必须在settings中开启管道
class ScrapyDangdang20240113Pipeline:
    # item就是yield后面的book对象

    # 方式一:
    # 以下这种模式不推荐,因为每传递过来一个对象,那么就打开一次文件,对文件的作过于频繁
    # def process_item(self, item, spider):
    # (1)write万法必须要写一个字符串,而不能是其他的对象,使用str()强转
    # (2)w模式 会每一个对象都打开一次文件 覆盖之前的内容
    # with open("book.json","a",encoding="utf-8")as fp:
    #     fp.write(str(item))
    # return item

    # 方式二:
    # 在爬虫文件开始之前就执行的方法
    def open_spider(self, spider):
        print("++++++++++++++++++++++++++++++++++++++++++++++++++")
        self.fp = open("book.json", "w", encoding="utf-8")

    def process_item(self, item, spider):
        self.fp.write(str(item))
        return item

    # 在爬虫文件开始之后就执行的方法
    def close_spider(self, spider):
        print("----------------------------------------------------")
        self.fp.close()


# 多条管道同时开启
# (1)定义管道类
# (2)在settings中开启管道
import urllib.request
class DangdangDownloadPipeline:
    def process_item(self, item, spider):
        # 下载图片
        url = "https:" + item.get("src")
        filename = "./books/" + item.get("name")[0:6] + ".jpg"

        urllib.request.urlretrieve(url=url, filename=filename)

        return item
相关推荐
2401_8576835415 小时前
为你的Python脚本添加图形界面(GUI)
jvm·数据库·python
luoluoal16 小时前
基于opencv的疲劳检测系统(源码+文档)
python·mysql·django·毕业设计·源码
m0_7066532316 小时前
使用Python自动收发邮件
jvm·数据库·python
程序员杰哥16 小时前
Chrome浏览器+Postman做接口测试
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
ZCXZ12385296a16 小时前
YOLO11-ASF-P2模型实现蚕桑业健康状态识别完整教程
python
gang_unerry16 小时前
量子退火与机器学习(4): 大模型 1-bit 量子化中的 QEP 与 QQA 准量子退火技术
人工智能·python·机器学习·量子计算
青瓷程序设计16 小时前
【交通标志识别系统】python+深度学习+算法模型+Resnet算法+人工智能+2026计算机毕设项目
人工智能·python·深度学习
啥都想学点16 小时前
关于制作技术视频讲解的问卷调查
python
喵手16 小时前
Python爬虫实战:博物馆官网的“展览预告/正在热展”栏目,抓取展览名称、精确展期、具体展厅位置以及票务/预约规则(附CSV导出)!
爬虫·python·爬虫实战·零基础python爬虫教学·博物馆信息采集·采集展览预告/正在热展等·采集数据csv导出
喵手16 小时前
Python爬虫实战:电商实体消歧完整实战 - 从混乱店铺名到标准化知识库的工程化实现,一文带你搞定!
爬虫·python·算法·爬虫实战·零基础python爬虫教学·同名实体消除·从混乱店铺名到标准化知识库