综合案例:使用Scrapy爬取当当网的图片信息

本节将继续讲解 Scrapy 框架的使用。具体包括 Scrapy 爬虫框架以及内部每个组件的使用(Selector 选择器、Spider 爬虫类、Downloader 和 Spider 中间件、ItemPipeline 管道类等)。

本例目标是爬取当当图书网站中所有关于 “python” 关键字的图片信息,网址http://search.dangdang.com/?key=python&act=input,要求将图书图片下载存储到指定目录,而图书信息写入到数据库中。

通过本例练习,要掌握 Scrapy 框架结构、运行原理、以及框架内部各个组件的使用。通过 Scrapy 框架的深入学习,学会自定义 Spider类爬取处理信息。

运行爬虫之前,请导入 pythonbook.sql 到 MySQL。

具体操作步骤如下:

第1步,创建工程
新建文件夹,用于存放项目。然后在命令行窗口中使用cd命令切换到当前目录,再输入下面命令创建Scrapy项目。

scrapy startproject dangdang

第2步,创建爬虫程序
使用cd命令切换到dangdang目录,再输入下面命令创建Scrapy程序。

cd dangdang
scrapy genspider pythonbook search.dangdang.com

第3步,自动创建目录及文件
完成前面2步操作,Scrapy会自动在指定文件夹中创建一个项目,并初始化爬虫程序文件的模板,如下图所示。
在这里插入图片描述
注意,一般创建爬虫文件时,以网站域名命名。

第4步,设置数据存储模板
打开items.py文件,然后输入下面代码,设置数据存储的模板。

          
import scrapy


class DangdangItem(scrapy.Item):
    '''
      当当图书的Item 类,包含所有要爬取的信息
    '''

    # define the fields for your item here like:
    # name = scrapy.Field()

    name        = scrapy.Field() # 书名
    price       = scrapy.Field() # 价格
    pic         = scrapy.Field() # 图片链接
    author      = scrapy.Field() # 作者
    publisher   = scrapy.Field() # 出版商
    comments    = scrapy.Field() # 评论数量
    pubdate     = scrapy.Field() # 发行日期
    description = scrapy.Field() # 描述

第5步,编写爬虫程序
在spiders子目录中打开pythonbook.py文件,然后输入下面代码,设置下载器开始下载的页面URL。以及爬虫要爬取的HTML结构片段。最后,使用for循环和迭代器,把每一个项目结构片段传递给items.py定义的字段模板。

完成本步操作之前,读者应该先熟悉目标页面的结构,以及要抓取的HTML片段,同时熟悉XPath基本语法,可以先使用浏览器访问该页面,使用F12键,查看一下HTML结构。

           
import scrapy, re
from dangdang.items import DangdangItem


class PythonbookPySpider(scrapy.Spider):
    name = 'pythonbook'
    allowed_domains = ['search.dangdang.com']
    start_urls = ['http://search.dangdang.com/?key=python&act=input']

    p = 1 # 爬取页数变量

    def parse(self, response):
        '''
          递归解析响应数据
        '''

        print('*'*64)

        dlist = response.selector.xpath(".//ul[@class='bigimg']/li")

        for dd in dlist:
            item = DangdangItem()
            item['name'] = dd.xpath("./a/@title").extract_first() #good
            price = dd.xpath(".//span[@class='search_now_price']").extract_first()
            price = re.findall(".*?([0-9]*\.[0-9]*)",price)
            if(price[0]):
                item['price'] = price[0]
            else:
                item['price'] = None
            item['pic'] = dd.xpath(".//img/@data-original|.//img/@src").extract_first()
            item['author'] = dd.xpath(".//a[@name='itemlist-author']/@title").extract_first()
            item['publisher'] = dd.xpath(".//a[@name='P_cbs']/text()").extract_first() #good
            item['comments'] = dd.xpath(".//a[@class='search_comment_num']/text()").extract_first() #wrong
            item['pubdate'] = dd.re_first("(([0-9]{4})-([0-9]{2})-([0-9]{2}))") #good
            item['description'] = dd.xpath(".//p[@class='detail']/text()").extract_first() # good

            yield item

        self.p += 1

        # 想爬取多少页?
        if(self.p<=10):
            next_url = "http://search.dangdang.com/?key=python&act=input&page_index=" + str(self.p)
            url = response.urljoin(next_url)
            yield scrapy.Request(url=url, callback=self.parse)

第6步,设置配置文件
打开settings.py文件,然后添加下面代码。

          
BOT_NAME = 'dangdang'

SPIDER_MODULES = ['dangdang.spiders']
NEWSPIDER_MODULE = 'dangdang.spiders'

USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'

ITEM_PIPELINES = {
    'dangdang.pipelines.DangdangPipeline': 300, # 处理item的类
    'dangdang.pipelines.MysqlPipeline'   : 301, # 把item写入数据库的类
    'dangdang.pipelines.ImagePipeline'   : 302, # 下载图片的类
}
MYSQL_HOST = 'localhost'
MYSQL_DATABASE = 'dangdang'
MYSQL_USER = 'root'
MYSQL_PASS = '11111111'
MYSQL_PORT = 3306
IMAGES_STORE = "./dangdang_images" # 存储图片的文件夹

第7步,编写数据处理脚本
打开pipelines.py文件,输入代码。设计图片下载和数据库存储。

import pymysql
from scrapy.exceptions import DropItem
from scrapy import Request
from scrapy.pipelines.images import ImagesPipeline


class DangdangPipeline(object):
    '''处理item的类'''

    def process_item(self, item, spider):
        '''
        处理爬取数据,如果爬取的书名没有,就把这条记录剔除。
        :param item: 爬虫item类
        :param spider: 爬虫超类
        :return: 剔除条目或者item
        '''
        if item['name'] == None:
            raise DropItem("Drop item found: %s" % item)
        else:
            return item


class MysqlPipeline(object):
    '''处理item写入数据库的类'''

    def __init__(self, host, database, user, password, port):
        '''
        构造类,创建全局变量
        :param host: 数据库主机路径
        :param database: 数据库名称
        :param user: 数据库用户名
        :param password: 数据库密码
        :param port: 数据库端口
        '''
        self.host = host
        self.database = database
        self.user = user
        self.password = password
        self.port = port
        self.db = None
        self.cursor = None

    @classmethod
    def from_crawler(cls, crawler):
        '''
        类方法,用此方法获取数据库相应信息来连接数据库
        :param crawler: crawler类
        :return: 带有数据库信息的类。在这里调用类构造方法
        '''
        return cls(
            host=crawler.settings.get("MYSQL_HOST"),
            database=crawler.settings.get("MYSQL_DATABASE"),
            user=crawler.settings.get("MYSQL_USER"),
            password=crawler.settings.get("MYSQL_PASS"),
            port=crawler.settings.get("MYSQL_PORT")
        )

    def open_spider(self, spider):
        '''
        通过设置文件里的信息链接到数据库,并准备好游标以便后面使用
        :param spider:
        :return:
        '''
        self.db = pymysql.connect(self.host, self.user, self.password, self.database, charset='utf8', port=self.port)
        self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        '''
        执行插入操作,将item相应信息插入数据库并保存
        :param item: 爬虫item类
        :param spider: spider超类
        :return: 爬虫item类
        '''
        sql = "insert into pythonbook(name,price,pic,author,publisher,comments, pubdate, description) values('%s','%s','%s','%s','%s','%s', '%s', '%s')"%(item['name'],item['price'],item['pic'],item['author'],item['publisher'],item['comments'], item['pubdate'],item['description'])
        self.cursor.execute(sql)
        self.db.commit()
        return item

    def close_spider(self, spider):
        '''
        关闭数据库连接
        '''
        self.db.close()


class ImagePipeline(ImagesPipeline):
    '''处理图像的类'''

    def get_media_requests(self, item, info):
        '''
        从item内拿到图片url信息,创建Request等待调度执行
        :param item: 爬虫item类
        :param info: 消息
        :return: None, yield一个带图片URL的Request
        '''
        yield Request(item['pic'])

    def item_completed(self, results, item, info):
        '''
        下载完成后,如果url不是有效的,就筛选掉这个数据。
        :param results:
        :param item:
        :param info:
        :return: 爬虫item类
        '''
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")

        return item

第8步,执行爬虫
到上面一步,已经完成了爬虫程序的全部设计,下面就可以测试爬虫的工作状态了,在命令行窗口,使用cd命令进入dangdang目录,然后使用scrapy crawl命令进行测试。

scrapy crawl pythonbook

执行结果如下图:
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网站没有SSL证书会遇到什么问题?怎么解决?

简单来说&#xff0c;如果一个网站没装SSL证书&#xff0c;会有以下几个大问题&#xff1a; 1.信息容易被偷看&#xff1a; - 就像写信不封口一样&#xff0c;网站和用户之间的交流信息是透明的&#xff0c;谁都能看到。比如你在网站上输入的账号密码、联系信息、银行卡号等重要…

最全APP抓包大法

前言&#xff1a;最近工作中遇到一些比较奇葩的App&#xff0c;一边测试一边搜集整理出了比较全的姿势。如有错误之处&#xff0c;还请各位师傅多多指教。 如何判断&#xff1a;连接Fiddler代理–>抓不到包–>关闭Fiddler后正常通信。 解决方法&#xff1a;PC端模拟器如…

计算机视觉项目-单目测距/双目测距/3D目标检测/语义分割/姿态识别及姿态估计

往期热门大项目合集&#xff1a; yolov5单目测距速度测量目标跟踪YOLOv8界面-目标检测语义分割追踪姿态识别&#xff08;姿态估计&#xff09;界面DeepSort/ByteTrack-PyQt-GUI_yolov8显示速度-CSDN博客 3D目标检测&#xff08;教程代码&#xff09;_3d目标检测原理-CSDN博客…

基于Springboot+Vue的前后端分离的简单Demo案例(一)

后端创建Springboot项目 创建数据库表结构及表信息 添加依赖&#xff08;pom.xml&#xff09; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/X…

CSDN欢迎使用Markdown编辑器你好,写文章快捷键与格式

了 解一下Markdown的基本语法知识。 1.全新的界面设计&#xff0c;将会带来全新的写作体验; 2.在创作中心设置你喜爱的代码高亮样式Markdown 将代码片显示选择的高亮样式进行展示; 3.增加了 图片拖拽 功能&#xff0c;你可以将本地的图片直接拖拽到编辑区域直接展示; 4.全新的 …

19.作业

1.作业样例图 2.学习视频 19.作业讲解

安卓使用MQTT实现阿里云物联网云台订阅和发布主题(3)

一、订阅主题代码讲解 private final String mqtt_sub_topic "/sys/k0wih08FdYq/LHAPP/thing/service/property/set";//订阅话题//mqtt客户端订阅主题//QoS0时&#xff0c;报文最多发送一次&#xff0c;有可能丢失//QoS1时&#xff0c;报文至少发送一次&#xff0c…

YOLOv9改进策略:block优化 | AIFI (尺度内特征交互)助力YOLO | YOLO终结者?RT-DETR一探究竟

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a; YOLOv9如何魔改卷积进一步提升检测精度&#xff1f;AIFI (尺度内特征交互&#xff09;助力YOLO ,提升尺度内和尺度间特征交互能力&#xff0c;同时降低多个尺度的特征之间进行注意力运算&#xff0c;计算消耗…

C语言例:n是否为素数(质数)

质数是指只能被1和自身整除的正整数。要判断一个数n是否为质数&#xff0c;可以通过以下步骤进行&#xff1a; 首先&#xff0c;判断n是否小于2&#xff0c;如果小于2&#xff0c;则不是质数。然后&#xff0c;从2开始&#xff0c;逐个判断n是否能被2到sqrt(n)之间的数整除。如…

jdk api之SyncFailedException基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

实体框架EF(Entity Framework)简介

实体框架EF&#xff08;Entity Framework&#xff09;简介 文章目录 实体框架EF&#xff08;Entity Framework&#xff09;简介一、概述二、O/R Mapping是什么采用O/R Mapping带来哪些好处 三、Entity Framework架构3.1 下图展示了Entity Framework的整体架构3.2 Entity Framew…

【机器学习-08】参数调优宝典:网格搜索与贝叶斯搜索等攻略

超参数是估计器的参数中不能通过学习得到的参数。在scikit-learn中&#xff0c;他们作为参数传递给估计器不同类的构造函数。典型的例子有支持向量分类器的参数C&#xff0c;kernel和gamma&#xff0c;Lasso的参数alpha等。 ​ 在超参数集中搜索以获得最佳cross validation交叉…

Ant Design Vue和VUE3下的upload组件使用以及文件预览

Ant Design Vue和VUE3下的upload组件使用以及文件预览 文章目录 Ant Design Vue和VUE3下的upload组件使用以及文件预览一、多文件上传1.需求2.样例3.代码 二、单文件上传1. 需求2. 样例3.代码 二、多文件上传产生的时间超时问题三、文件系统名称更改1. 修改文件index.html2. 修…

现货大宗商品交易系统开发及平台需要哪些资质

现货大宗商品交易平台需要一系列资质和条件来确保其合法、合规运营&#xff0c;保障投资者的权益和市场的稳定。以下是现货大宗商品交易平台需要的主要资质和条件&#xff1a; 公司注册与法人资格&#xff1a;平台需要依法办理工商注册登记手续&#xff0c;并具有法人资格。这…

硬核分享|如何使用AI根据一段文字描述来生成图片

硬核分享|如何使用AI根据一段文字描述来生成图片_哔哩哔哩_bilibili 最近许多人询问关于AIGC生成图片工具的推荐问题&#xff0c;深感寻找一款好用的AIGC生成图片工具在当今信息爆炸时代的重要性。现在&#xff0c;为大家分享几款好用的AIGC生成图片工具&#xff0c;一起探索吧…

【C++】vector容器初步模拟

送给大家一句话&#xff1a; 努力一点&#xff0c;漂亮—点&#xff0c;阳光一点。早晚有一天&#xff0c;你会惊艳了时光&#xff0c;既无人能替&#xff0c;又光芒万丈。 vector容器初步模拟 1 认识vector开始了解底层实现 2 开始实现成员变量构造函数 析构函数尾插迭代器插入…

FX110网:FCA揭露Admirals的克隆实体!冒充正规平台行骗

近日&#xff0c;英国金融行为监管局&#xff08;FCA&#xff09;曝光了多个网址&#xff0c;揭露克隆实体fxsadmiral / admiral-fx / admiralsfx。这些克隆公司复制授权公司Admiral Markets UK Ltd的重要信息&#xff0c;试图让人们相信他们的公司是真实的。FCA本次披露的克隆…

记录西门子200:PUT和GET通讯测试

GET/PUT&#xff1a;S7-200SMART之间专有通讯协议。 准备两台Smart-PLC&#xff0c;这里使用的ST60和CR40。外加一个交换机。 CR40的地址设置是&#xff1a;192.168.2.1 用来读 ST60的地址设置是&#xff1a;192.168.2.2 用来写 打开软件&#xff0c;选择CPU-CR4配…

深入探索Java并发库(JUC)中的ReentrantReadWriteLock

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在Java并发编程的世界中&#xff0c;锁是一种用于同步访问共享资源的机制。Java并发库&#xff08;JUC&#xff09;为我们提供了多…

简易指南:国内ip切换手机软件怎么弄

在网络访问受到地域限制的情况下&#xff0c;使用国内IP切换手机软件可以帮助用户轻松访问被屏蔽的内容&#xff0c;扩展网络体验。以下是虎观代理小二分享的使用国内IP切换手机软件的简易指南。并提供一些注意事项。 如何在手机上使用国内IP切换软件 步骤一&#xff1a;选择I…