拼多多商品信息爬取

本文分享了使用Scrapy框架及scrapy_redis组件爬取拼多多商品信息的详细过程,包括热门商品与分类商品的爬取策略,以及如何处理请求失败、获取店铺信息等难点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拼多多商品信息爬取

爬取完几个主流电商平台的信息,今天想着也去攻克一下拼多多。于是先去GitHub上面找一下有没有哪位大神搞过了借鉴一下,然后果然发现一个好用的接口。

想着既然找到了就先下载下来跑一下,嗯。。。“热门”的感觉可以,应该很简单。然后就兴高采烈地扩展一下别的商品种类,果然很多坑。。

一、思路分析

经过谷歌F12工具一番分析,总结一下爬取思路:

1、“热门”商品比较特殊,其他商品种类有细分小分类,故需从大分类获取到小分类地址,然后进一步请求。以“女装”为例:地址为:http://apiv3.yangkeduo.com/operation/14/groups?page=1&size=100&opt_type=1 ,size为单页显示商品数量,最大可以400,大分类opt_type为1,小分类opt_type为2,14是“女装”ID。

2、大分类和小分类页面有时第一次请求会失败,需多次请求才能成功,故需要设置一个循环。

3、店铺信息在商品页列表里面每次请求会有所缺失,故需到商品页里面获取,但是商品页需要带请求参数,主要是cookieAccessToken(访问令牌)。这两个参数会过期,解决方法后面讨论。

二、爬取字段

店铺信息获取比较麻烦,如果不要的话会简单很多,商品评价如果要获取可以参考一下上面的GitHub地址,这里先注释掉。
    goods_id = scrapy.Field()  # 商品ID
    goods_name = scrapy.Field()  # 商品名字
    price = scrapy.Field()  # 拼团价格 返回的字段多乘了100
    sales = scrapy.Field()  # 已拼单数量
    normal_price = scrapy.Field()  # 单独购买价格
    # comments = scrapy.Field()  # 商品评价
    opt_id = scrapy.Field()  # 小分类ID
    opt_name = scrapy.Field()  # 小分类名字
    link_url = scrapy.Field()  # 商品地址
    mall_id = scrapy.Field()  # 店铺ID
    mall_name = scrapy.Field()  # 店铺名字

三、spider代码

这次爬虫采用的是scrapy_redis分布式爬取(顺便再熟悉一下),下面放上spider代码:
# -*- coding: utf-8 -*-
import scrapy
import json
from pinduoduo.items import PinduoduoItem
from copy import deepcopy
from scrapy_redis.spiders import RedisSpider
import re


class PdditemSpider(RedisSpider):
    name = 'pdditem'
    allowed_domains = ['yangkeduo.com']
    page = 1  # 起始页码数
    size = 400  # 单页显示数量(最大400)
    opt_type = 1
    offset = 0  # 偏移量100为一页
    # start_urls = ['http://apiv3.yangkeduo.com/operation/14/groups?page={}&size={}&opt_type={}'.format(page, size,opt_type)]  # 女装商品
    # 'http://apiv3.yangkeduo.com/operation/14/groups?page=1&size=400&opt_type=1'
    redis_key = "pinduoduo"

    def parse(self, response):  # 解析分类页
        goods_list_json = json.loads(response.body)
        url = response.url
        keys = goods_list_json.keys()
        key = list(keys)[2]
        if key == "error_code":  # 请求失败获取到错误json代码,重新请求
            print(key, "再次尝试请求")
            yield scrapy.Request(
                url,
                callback=self.parse,
                dont_filter=True
            )
        else:
            item = PinduoduoItem()
            opt_infos = goods_list_json['opt_infos']
            if opt_infos is not None:
                for info in opt_infos:
                    item['opt_id'] = info['id']
                    item['opt_name'] = info['opt_name']
                    yield scrapy.Request(
                        'http://apiv3.yangkeduo.com/operation/'+ str(item['opt_id'])+ '/groups?offset=0&size=100&opt_type=2',
                        callback=self.parse_good,
                        meta={"item": deepcopy(item)}
                    )

    def parse_good(self, response):  # 解析商品页
        item = response.meta["item"]
        goods_list_json = json.loads(response.body)
        url = response.url
        keys = goods_list_json.keys()
        key = list(keys)[-1]
        if key == "error_code":
            print(key,"再次尝试请求")
            yield scrapy.Request(
                url,
                callback=self.parse_good,
                meta={"item": deepcopy(item)},  # 大坑!!重新请求需要带上item
                dont_filter=True
            )
        else:
            goods_list = goods_list_json['goods_list']
            # 判断是否是最后一页
            if not goods_list:
                return
            for each in goods_list:
                item['goods_name'] = each['goods_name']
                item['price'] = float(each['group']['price']) / 100  # 拼多多的价格默认多乘了100
                item['sales'] = each['cnt']
                item['normal_price'] = float(each['normal_price']) / 100
                item['goods_id'] = each['goods_id']
                item['link_url'] = 'http://yangkeduo.com/'+ each['link_url']
                yield scrapy.Request(
                     item['link_url'],
                     callback=self.get_mall_data, meta={"item": item},)

            self.page += 1
            self.offset = self.page*100  # 构造下一页地址
            yield scrapy.Request(url='http://apiv3.yangkeduo.com/operation/'+ str(item['opt_id'])+ '/groups?offset={}&size=100&opt_type=2'.format(self.offset),
                                 callback=self.parse_good,
                                 meta={"item": item}
                                 )

    def get_mall_data(self, response):  # 获取店铺信息
        item = response.meta["item"]
        Cookie = response.request.headers.getlist('Cookie')
        mall_name = response.xpath("//div[@class='goods-mall-name']/text()").extract_first()
        if mall_name is not None:
            item['mall_name'] = mall_name
        data = response.body.decode('utf-8')
        pattern = re.compile(r'mall_id=(.*?)\"', re.S)
        result = re.search(pattern, data)
        if result is not None:
            item['mall_id'] = result.group(1)
        else:
            yield scrapy.Request(
                response.url,
                callback=self.get_mall_data,
                meta={"item": item},
                dont_filter=True
            )
        if item['mall_name'] and item['mall_id']:
            print(item)
            yield (item)
        else:
            print('数据获取不全,重新获取')



四、最后

不知道什么时候的数据
在这里插入图片描述

具体过程和参考代码请见:博客
有任何问题请留言,谢谢。
爬取拼多多商品信息通常涉及到网络爬虫技术,步骤如下: 1. **获取网页源码**: 使用Python的requests库发送HTTP请求到拼多多的商品详情页URL,比如通过`response = requests.get('https://item.pdd.com/item.html?skuId=xxxxx')`获取页面HTML。 2. **解析HTML**: 利用如BeautifulSoup、Scrapy等库解析HTML文档,提取出包含商品信息的部分。例如,CSS选择器或XPath可以用于定位特定元素,如商品名称、价格、图片链接等。 3. **数据抽取**: 根据需要的数据结构,如字典或列表,从HTML中提取关键信息并存储起来。例如: ```python item_info = { 'name': response.css('.product-name::text').get(), 'price': response.css('.price::text').get(), 'image_url': response.css('.img::attr(src)').get(), } ``` 4. **处理反机制**: 拼多多可能会有防策略,如IP限制、验证码等,需设置User-Agent,模拟浏览器行为,并可能需要处理动态加载内容或者登录验证。 5. **保存或分析数据**: 将抓取的信息存储到本地文件(CSV、JSON等),数据库,或者进一步进行数据分析和挖掘。 6. **遵守法律法规**: 确保你的爬虫行为符合网站的服务条款,尊重隐私权,不要对服务器造成过大的压力。 记得在实际操作中遵守网站的robots.txt规则,并了解其API接口(如果有的话)是否允许爬取。另外,频繁的爬取可能会触发平台的风控系统,所以合理的频率和错误处理很重要。
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值