Python使用Scrapy爬取小米首页的部分商品名称、价格、以及图片地址并持久化保存到MySql中

2022-09-28 11:25:26 浏览数 (1)

前言

最开始选择爬小米这个网页时是因为觉得界面好看,想爬点素材做备用,这次有个重点,又是因为偷懒,看见那满屏的源代码就自己欺骗安慰自己肯定一样的,然后只看检查后面整齐的源代码了,我大概是能理解毛爷爷那句:抛弃幻想,准备战斗了,差点做吐,还是我的宝贝大佬仔仔细细逻辑非常清晰的全部检查排除了一遍发现源代码与元素部分不一样!!划重点,除此之外,如果发现xpath取不到值,一律给我看页面源代码,跟element对比,是否属性有更改或者动态渲染,至于反爬之类的,不过一般官网都会有反爬,我们学习只需要少量素材就ok了。Scrapy爬取这种类似静态页面的很简单,重点在爬虫页面的数据解析,以及setting.py和pipelines管道配置写入数据库。接下来开始我的表演。


Mysql安装与建立对应的表

Scrapy安装以及配置

  • 安装与配置
    • 安装Scrapy包,打开终端,输入命令。
      • 1 pip install whell 2 pip install Scrapy
  • 关于报错
    • 如果出现pip关键字,导致Scrapy不能安装的原因是pip版本过低。报错中也给出了提示。我们只需要找到Python安装地址的上级目录输入以下命令。
      • python.exe -m pip install –upgrade pip

Scrapy创建第一个工程以及第一个爬虫项目

  • 新建文件,用于存储Scrapy工程文件。我这里的文件夹名叫小米官网素材爬取。
  • 我们在使用Scrapy框架时,需要手动执行。输入命令之后再重新打开目录就会发现多了很多文件,学习过前端部分框架的同学会发现这玩意有点像前后端分离的web项目,在爬虫文件(spiders)中创建爬取文件,解析好数据之后通过数据传输层(items)传给管道(pipelines),再在管道中处理数据持久化保存未文件或写入数据库中。
    • cd 小米官网素材爬取 #进入文件夹 scrapy startproject 自定义文件名 #我的工程文件名叫xmImg scrapy genspide 自定义文件名 # 我的爬虫文件名字叫imgList

Scrapy工作目录中的settings配置

找到Scrapy文件目录中的settings文件,根据以下提示一步步配置。

  • 配置请求头,也可以叫伪装头,一般是python模拟浏览器请求为了防止被网站识别而设置的。怎么获取请求头呢,自行百度吧。
    • USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.3’
  • 开启管道(pipeline)。
    • ITEM_PIPELINES = { ‘xmImg.pipelines.XmimgPipeline’: 300, }
  • 配置数据库。
    • 主机ip地址,如果是本地的数据库,直接localhost,否则就要写ip地址。 HOST = ‘localhost’端口号 ———类型为整数!!!———- PORT = 3306用户名 USER = ‘root’密码 PASSWD = ‘******‘需要存入的数据库 DB = ‘xmdb’指定字符集,注意uft-8中的‘-’,识别不了!! CHARACTER = ‘utf8’
  • 关闭遵循的原则。初学者或者学习的时候不用遵循这个原则,否则大部分的时候爬不到东西。
    • ROBOTSTXT_OBEY = False LOG_LEVEL=‘ERROR’

在创建好爬虫文件(这里是上述目录中的imgList.py文件)中开始爬取网站并解析

具体网站具体分析,这里我访问的网站是小米商城官网

导入要用到的包。

  • items是工程项目目录的下的文件。它的作用是对通过在爬虫文件页面实例化后统一格式传输到管道文件中,
    • import scrapy import ..items from xmImgItem

设置文件唯一名字和请求网址。

  • 这里的name是用于运行文件时的唯一标识,start_urls是scrapy框架执行时会自动调用的。
    • class ImglistSpider(scrapy.Spider): name = ‘imgList’ # allowed_domains = [‘imgList.cn’] start_urls = [‘https://www.mi.com/'] def parse(self, response):

在返回的页面解析数据。

这里有一个重点,Python是一个强格式的语言,如果你在打印数据时发现跟预料的不一样,不妨找找看,是不是忘记缩进或者多缩进了。由于爬取的网站不同,xpath中的字符串是不一样的,这里简单介绍一下xpath的用法,//表示跳级查找,@符号一般原来查找属性,text()表示标签内的内容。给大家讲解一下这个爬取逻辑。首先:item是items文件中XmimgItem类的实例对象。我们可以用它接收一些值。当我们爬取数据时会发现很多多余的标签,extract()是对那些标签进行剔除。只保留目标数据。其次:观察小米官网源代码我们可以发现几乎所有数据都包含在class值为first中的li标签中。把所有的在class值为first中的li标签取出来,遍历,循环获取。最后:由于部分数据数量不一样,这里再以其中某个数据集为索引遍历数组。一行行提交放在pipeline中处理写入数据库中。

代码语言:javascript复制
def parse(self, response):
      item=XmimgItem()
      div_list = response.xpath('//div[@class="container"]/div//li[@class="first"]')
      for item1 in div_list:
          # 遍历获取值
          img_urls = item1.xpath('//div[@class="figure figure-thumb"]/img/@data-src').extract()
          title_list = item1.xpath('//div[@class="title"]/text()').extract()
          price_list = item1.xpath('//p[@class="price"]/text()').extract()
      #print(img_urls)打印,用来测试数据
      #print(title_list)
      #print(price_list)
      for index in range(0, len(title_list) - 2):
          price_list[index] = re.sub('[\u4e00-\u9fa5]', '', price_list[index])# 去除数据中的中文
          # print(price_list[index])
          titles=title_list[index]
          price=price_list[index]
          imgs=img_urls[index]
          item["title"] = titles
          item["price"] = price
          item["imgurl"] = imgs
          yield item

Scrapy工作目录中的item写好要存储传输的数据

  • 导入需要用到的包并取出爬虫文件中实例化的数据。
  • import scrapy class XmimgItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() title=scrapy.Field() price=scrapy.Field() imgurl=scrapy.Field() pass

Scrapy工作目录中的pipeline中把数据存储到配置好的数据库中

  • 导入需要用到的包
    • import pymysql加载settings文件,需要用到setting文件中配置的数据库连接属性。 from scrapy.utils.project import get_project_settings
  • 在类中导入配置以及创建连接方法
    • class XmimgPipeline: def __init__(self): settings = get_project_settings() self.host = settings[‘HOST’] self.port = settings[‘PORT’] self.user = settings[‘USER’] self.passwd = settings[‘PASSWD’] self.db = settings[‘DB’] self.character = settings[‘CHARACTER’] self.connect() def connect(self): self.conn = pymysql.connect( host=self.host, port=self.port, user=self.user, password=self.passwd, db=self.db, charset=self.character ) # 创建游标 self.cursor = self.conn.cursor()
  • 写入数据库
  • {}是占位符,后面是item中取出来的数据,学过asp.net的小伙伴会发现,它这个赋值取值的方法有点像Cookie和ViewData等等。写好sql语句就调用游标的增删改方法
    • def process_item(self, item, spider): sql = ‘insert into goods(title,price,imgurl) values(“{}”,”{}”,”{}”)’.format(item[‘title’], item[‘price’], item[‘imgurl’]) # 执行sql语句 self.cursor.execute(sql) # 提交事务 self.conn.commit() return item def __del__(self): # 关闭游标 self.cursor.close() # 关闭连接 self.conn.close()
  • 运行,终端输入。
    • scrapy crawl 我们的name属性值(爬虫文件中定义了,不知道的看上面)

结语:

鄙人才疏学浅,还请多多指教。

0 人点赞