前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬取友商产品信息

爬取友商产品信息

作者头像
zx钟
发布2019-10-30 14:52:31
6620
发布2019-10-30 14:52:31
举报
文章被收录于专栏:测试游记测试游记测试游记

由于想要了解一下友商的产品信息,所以简单的写一下爬取他们信息的爬虫

创建项目

$ scrapy startproject Dahua
$ cd Dahua
$ scrapy genspider dahua dahuatech.com
  1. 使用 scrapy脚手架创建一个项目
  2. 进入项目路径
  3. 创建一个名叫 dahua的爬虫,它的爬取范围是 dahuatech.com域名下

分析爬取内容

产品类别url地址为:http://www.dahuatech.com/product.html

所以修改开始的url start_urls

class DahuaSpider(scrapy.Spider):
    name = 'dahua'  # 爬虫名称
    allowed_domains = ['dahuatech.com']  # 允许爬取域名
    start_urls = ['https://www.dahuatech.com/product.html']  # 请求的第一个url

    def parse(self, response):
        pass

需要爬取的为设备的具体信息

  • 产品详情地址
  • 产品名称
  • 产品描述
  • 产品概述
  • 技术参数
  • 尺寸图
  • 订货型号

所以先在 Dahua/items.py写上

import scrapy


class DahuaItem(scrapy.Item):
    url = scrapy.Field()  # 产品详情地址
    product_name = scrapy.Field()  # 产品名称
    product_description = scrapy.Field()  # 产品描述
    product_overview = scrapy.Field()  # 产品概述
    technical_parameter = scrapy.Field()  # 技术参数
    dimension_drawing = scrapy.Field()  # 尺寸图
    order_type = scrapy.Field()  # 订货型号

获取设备类型列表

从第一个页面可以看出,设备分成了很多大类,大类中又有很多的小类

所以我们先拿到全部小类的url地址

使用 XPathHelper工具进行 Xpath定位

由于我懒得解析太多Xpath,所以我取用了离要获取的url最大层级的 div标签

对应的URL的Xpath为://div[@class='product-channel-list f-cb']//a/@href

对呀的文字的Xpath为://div[@class='product-channel-list f-cb']//a/text()

所以爬虫中第一个解析函数 parse

def parse(self, response):
    print('正在爬取全部产品类别')
    url_list = response.xpath("//div[@class='product-channel-list f-cb']//a/@href").extract()
    productlist_list = response.xpath("//div[@class='product-channel-list f-cb']//a/text()").extract()
    productlist_list = productlist_list
    for url, productlist in zip(url_list, productlist_list):
        if url.startswith('http'):
            yield scrapy.Request(url=url, callback=self.parse_productlist, meta={'productlist': productlist})

获取设备列表

任意点击一个小类进入如下页面

包含了 设备名称, 描述信息

查看详情按钮是进入设备详情页的

所以这儿需要获取到3个Xpath

全部的 查看详情: //li//span[1]//a/@href

全部的 设备名称: //div[@class='product-list-b']//ul[@class='f-cb']//h3/text()

全部的 描述信息: //div[@class='product-list-b']//ul[@class='f-cb']//a/p[1]/text()

所以代码为:

def parse_productlist(self, response):
    print('正在爬取产品列表')
    url_list = response.xpath('//li//span[1]//a/@href').extract()
    product_name_list = response.xpath("//div[@class='product-list-b']//ul[@class='f-cb']//h3/text()").extract()
    product_description_list = response.xpath(
        "//div[@class='product-list-b']//ul[@class='f-cb']//a/p[1]/text()").extract()
    for url, product_name, product_description in zip(url_list, product_name_list, product_description_list):
        yield scrapy.Request(url=url, callback=self.parse_productdetail,
                             meta={
                                 'productlist': response.meta['productlist'],
                                 'product_name': product_name,
                                 'product_description': product_description
                             })
    page_list = response.xpath("//div[@class='news-page w1400']//a/@href").extract()
    page_list = [i for i in page_list if i.startswith('http')]
    if page_list:
        for url in page_list:
            yield scrapy.Request(url=url, callback=self.parse_productlist,
                                 meta={'productlist': response.meta['productlist']})

往处理详情页的地方传入了 product_nameproduct_description

也就是设备名称,设备描述

由于部分页面有多页,所以也做了页面的跳转

page_list = response.xpath("//div[@class='news-page w1400']//a/@href").extract()
page_list = [i for i in page_list if i.startswith('http')]
if page_list:
    for url in page_list:
        yield scrapy.Request(url=url, callback=self.parse_productlist,
                             meta={'productlist': response.meta['productlist']})

本来这里要处理重复页面的,但是由于 Scrapy自带了缓存机制,它会跳过爬取相同的 url,所以就这样了~

获取详情页

进入详情页后发现数据是动态出现的,使用抓包的方式很容易可以发现它应该ajax请求的方式刷新数据

当前页面:https://www.dahuatech.com/product/info/93.html

ajax请求页面:https://www.dahuatech.com/ajax/product/93/1

其中相同的部分为 93

由于我懒得再爬一层,所以直接用 requests发起了 get请求

def parse_productdetail(self, response):
    print('正在爬取产品详情')
    base_url = 'https://www.dahuatech.com/ajax/product/%s/%s'
    item = DahuaItem()
    product_num = re.findall(r'http.*?info/(\d+).html.*?', response.url)
    product_num = product_num and int(product_num[0])
    # 产品详情地址
    item['url'] = response.url

    # 产品名称
    item['product_name'] = response.meta['product_name']

    # 产品描述
    item['product_description'] = response.meta['product_description']

    # 产品概述
    item['product_overview'] = re.findall(r'<div class="one_content">(.*?)</div>',
                                          requests.get(base_url % (product_num, 1)).text,
                                          re.S | re.M)[0]

    # 技术参数
    item['technical_parameter'] = requests.get(base_url % (product_num, 2)).text

    # 尺寸图
    item['dimension_drawing'] = re.findall(r'src=".*?"',
                                           requests.get(base_url % (product_num, 3)).text,
                                           re.S | re.M)[0]

    # 订货型号
    item['order_type'] = re.findall(r'>(.*?)</p',
                                    requests.get(base_url % (product_num, 4)).text,
                                    re.S | re.M)[0]

    yield item

数据持久化

使用最简单的数据持久化方式:写入json

修改 Dahua/pipelines.py

import json


class DahuaPipeline(object):
    def open_spider(self, spider):
        self.file = open('dahua.json', 'w')

    def process_item(self, item, spider):
        content = json.dumps(dict(item), ensure_ascii=False) + '\n'
        self.file.write(content)
        return item

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

一次爬取分为三步:

  1. 打开 dahua.json文件
  2. 写入内容
  3. 关闭 dahua.json文件

修改 Dahua/settings.py

  1. 关闭君子协议
ROBOTSTXT_OBEY = False
  1. 开启数据持久化部分
ITEM_PIPELINES = {
   'Dahua.pipelines.DahuaPipeline': 300,
}

查看结果

在外部使用

$ scrapy crawl dahua
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建项目
  • 分析爬取内容
  • 获取设备类型列表
  • 获取设备列表
  • 获取详情页
  • 数据持久化
  • 修改 Dahua/settings.py
  • 查看结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档