栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Scrapy 爬虫笔记

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Scrapy 爬虫笔记

目录
  • 概述
  • 开始
    • 启动项目
    • 爬虫初始化
    • 处理响应
    • 回调函数的参数
    • 图片下载(未完待续)
  • 相关资源

概述

本文记录了个人使用 Scrapy 爬取某网站产品信息(包含图片下载)的整个过程,也可以作为一篇 Scrapy 实战教学博客。
首先从 All Products 页面出发,首先抓取所有分类页面的链接:如 https://www.example.com/category/category-name
再从每个产品分类页面抓取产品详情页面链接:如 https://www.example.com/product/product-name
最后解析产品详情页面的响应,提取所需数据,下载相关图片

开始

首先需要安装 scrapy,pip命令

pip install scrapy
启动项目

在 Pycharm 工作目录下新建一个名为 scrapy_demo 的目录(以后其他scrapy 爬虫项目也可以放到该目录下),打开终端 Terminal,使用 cd 命令进入 scrapy_demo 目录,使用 scrapy 创建项目命令:

scrapy startproject product

其中 product 是爬虫项目名,可以修改
此时目录结构应该如下:(products_spider.py 是后面自己添加的)

各目录结构详解请参考官方文档

爬虫初始化
  • 在 spiders 目录下新建一个 products_spider.py 文件(命名似乎并无严格要求)
  • 加入初始代码:
import scrapy
from ..items import ProductItem


class ProductsSpider(scrapy.Spider):
    """
    Products Spider
    """
    name = "products" # 爬虫的名字, 后面启动爬虫需要用到
    host = 'http://www.example.com'

    def start_requests(self):
        urls = [
            'http://www.example.com/products.html'
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)
   	def parse(self, response, **kwargs):
   		# @todo 处理首页响应
   		pass

爬虫执行的流程:首先会执行 start_requests 方法,最后 yield Request 发出多个请求,请求的响应将会被 Request 中的参数 callback 所指定的函数接收并处理,这里对首页的请求的响应将会被 parse 函数处理。

  • 定义 Item,也就是需要获取的字段,在 items.py 中编写代码。示例如下:
import scrapy

class ProductItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field() # 产品名称
    images = scrapy.Field() # 产品图片, 是一个列表
    category = scrapy.Field() # 产品分类名
    price = scrapy.Field() # 产品价格
    description = scrapy.Field() # 产品描述, 长文本
    pass

处理响应

回到 products_spider.py 中,接下来需要对响应进行处理。

  • 在函数 parse 中的 response 是首页的响应,我们需要从中获取到每一个分类页面的链接,(解析数据个人用的是 xpath)然后对每一个链接再发起请求,并把响应交给处理分类页面的响应的函数。
  • 因此,额外再编写一个函数 parse_category 用于处理分类页面的响应。
  • 同理,分类页面获取到产品详情页面的链接,再次发起请求,并将响应交给 parse_product 函数。
  • 代码如下:
    def parse(self, response, **kwargs):
        # 从首页获取各个分类页面url
        tree = etree.HTML(response.text) # 注意这里需要 from lxml.html import etree
        hrefs = tree.xpath("hrefs xpath express")
        for href in hrefs:
        	# 发起分类页面请求
            yield scrapy.Request(url=self.host + href, callback=self.parse_category) 
            
    def parse_category(self, response):
        # 从分类页面获取产品详情页面url
        tree = etree.HTML(response.text)
        product_urls = tree.xpath("products url xpath express")
        category = tree.xpath("categroy text xpath express")[0]
        for url in product_urls:
        	# 发起产品详情页面请求
        	yield scrapy.Request(url=self.host + url, callback=self.parse_product)
        	
    def parse_product(self, response):
        # 解析产品详情页面, 将数据汇总到 Item 中
        tree = etree.HTML(response.text)
        item = ProductItem()
        item['name'] = tree.xpath('xxxxx/text()')[0]
        yield item
回调函数的参数
  • 当我们在 parse_product 函数中想获取产品分类填充到 item 中,而产品详情页面中没有该数据,产品分类数据在分类页面中。要怎么做呢?
  • 这种情况需要在 parse_category 函数中获取产品分类,并将该产品分类数据传递到函数 parse_product 函数中。实际上,这里的一些列 parse_* 函数都可以称为回调,那么我们要如何传递参数给回调函数呢?
  • 详细请参考官方文档,我这里直接给出代码:在 yield Request 时,可以添加一个额外参数:cb_kwargs={‘cate’: category},它的值是一个字典,表示将 category 的值传递给下一个响应处理函数,即 parse_product ,同时在 parse_product 中添加一个名为 cate 的参数来接收值
  def parse_category(self, response):
  	# 省略
  	yield scrapy.Request(url=self.host + url, callback=self.parse_product, cb_kwargs={'cate': category})
  	pass
  
 def parse_product(self, response, cate):
 	# 省略
 	item['category'] = cate
图片下载(未完待续)

使用中间件 ImagesPipeline

相关资源

官方文档:点击跳转

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/444515.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号