前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【scrapy】scrapy爬取京东商品信息——以自营手机为例

【scrapy】scrapy爬取京东商品信息——以自营手机为例

作者头像
蛮三刀酱
发布2019-03-26 17:19:54
2.2K0
发布2019-03-26 17:19:54
举报

关于scrapy以及使用的代理轮换中间件请参考我的爬取豆瓣文章:

【scrapy】scrapy按分类爬取豆瓣电影基础信息

http://blog.csdn.net/qqxx6661/article/details/56017386

爬虫简介

主要还是按照scrapy的设计思路来爬,上一篇文章的豆瓣爬取能够很好的反应这种思路,京东爬虫也是如此。

主要思路是:获取手机分类(自营)页面——扫描该页所有商品ID——进入每个商品页面获取除价格外所有信息——获取商品价格信息——扫描下一页网址——进行下一页商品ID获取.....

京东爬虫特殊性

显然商城类都有严格的反爬虫,所以这篇笔记主要围绕如何解决几个反爬问题来写的。

价格抓取

价格在页面完整载入后审查元素时是可以看见的,不过其实是加载了JS,所以实际上源代码内不包含价格。需要查看JS加载的情况。如下图

在写这篇笔记的时候,我代码里的JS名称似乎已经失效了。不过现在看来基本都是类似这种mgets?的script。

所以直接让价格被单独抓取,代码形如:

 def parse_price(self, response):
        item = response.meta['item']
        price_str = response.body
        price_str = price_str[2:-4]
        js = json.loads(str(price_str))
        print js['p']
        item['phone_price'] = js['p']
        yield item
        # return item

    def parse_each_phone(self, response):
        item = jdItem()
        each_id = response.xpath('//ul[@class="parameter2 p-parameter-list"]/li[2]/@title').extract()
        item['phone_id'] = each_id
        item['phone_name'] = response.xpath('normalize-space(//div[@class="sku-name"]/text())').extract() #到了美国有空格了,不知道为何,已修复
        item['phone_houdu'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[2]/dl/dd[4]/text()').extract()
        item['phone_CPU'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[4]/dl/dd[1]/text()').extract()
        item['phone_ROM'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[6]/dl/dd[1]/text()').extract()
        item['phone_RAM'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[6]/dl/dd[2]/text()').extract()
        item['phone_screen'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[7]/dl/dd[2]/text()').extract()
        item['phone_frontcam'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[8]/dl/dd[1]/text()').extract()
        item['phone_backcam'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[9]/dl/dd[2]/text()').extract()
        each_id = str(each_id[0])
        url = "https://p.3.cn/prices/mgets?callback=&skuIds=J_" + each_id
        yield scrapy.Request(url, meta={'item': item}, callback=self.parse_price)

里面涉及到价格连接的字符串拼接,这个多在shell里面尝试,直到能够正确切出价格。

allowed_domains注意

写代码的时候卡了好久,价格永远抓取不到,各种查资料,最后突然意识到是allowed_domains被限制在了jd.com,而价格其实在3.cn开头的链接里。智障。

class jdSpider(scrapy.Spider):
    name = "jd"
    allowed_domains = ["jd.com",
                       "3.cn"]
    start_urls = [
        "http://list.jd.com/list.html?cat=9987,653,655&page=1&delivery=1&sort=sort_rank_asc&trans=1&JL=4_10_0#J_main"
    ]

jd_spider.py

给出主要代码

# -*- coding: utf-8 -*-
import scrapy
from scrapy_yzd.items import jdItem
import json
import time


class jdSpider(scrapy.Spider):
    name = "jd"
    allowed_domains = ["jd.com",
                       "3.cn"]
    start_urls = [
        "http://list.jd.com/list.html?cat=9987,653,655&page=1&delivery=1&sort=sort_rank_asc&trans=1&JL=4_10_0#J_main"
    ]

    def parse(self, response):
        a = 0
        for href in response.xpath('//div/@data-sku'):
            url = "https://item.jd.com/" + href.extract() + ".html"
            print url
            yield scrapy.Request(url, callback=self.parse_each_phone)
            a += 1
        print "This page's phone number:" + str(a)

        time.sleep(20)
        next_page = response.xpath('//a[@class="pn-next"]/@href').extract()
        if next_page:
            next_page = "https://list.jd.com" + next_page[0]
            print '--------------Finding next page--------------------------', next_page
            yield scrapy.Request(next_page, callback=self.parse)
        else:
            print '--------------There is no more page!--------------------------'

    def parse_price(self, response):
        item = response.meta['item']
        price_str = response.body
        price_str = price_str[2:-4]
        js = json.loads(str(price_str))
        print js['p']
        item['phone_price'] = js['p']
        yield item
        # return item

    def parse_each_phone(self, response):
        item = jdItem()
        each_id = response.xpath('//ul[@class="parameter2 p-parameter-list"]/li[2]/@title').extract()
        item['phone_id'] = each_id
        item['phone_name'] = response.xpath('normalize-space(//div[@class="sku-name"]/text())').extract() #到了美国有空格了,不知道为何,已修复
        item['phone_houdu'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[2]/dl/dd[4]/text()').extract()
        item['phone_CPU'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[4]/dl/dd[1]/text()').extract()
        item['phone_ROM'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[6]/dl/dd[1]/text()').extract()
        item['phone_RAM'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[6]/dl/dd[2]/text()').extract()
        item['phone_screen'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[7]/dl/dd[2]/text()').extract()
        item['phone_frontcam'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[8]/dl/dd[1]/text()').extract()
        item['phone_backcam'] = response.xpath('//*[@id="detail"]/div[2]/div[2]/div[1]/div[9]/dl/dd[2]/text()').extract()
        each_id = str(each_id[0])
        url = "https://p.3.cn/prices/mgets?callback=&skuIds=J_" + each_id
        yield scrapy.Request(url, meta={'item': item}, callback=self.parse_price)
        # yield item # 导致重复商品且无价格,原因未知

实验结果

未解决的问题

问题很严重,京东似乎对爬虫十分敏感,在连续进行下一页抓取后,直接会回到手机分类的第一页

I love 周雨楠

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年03月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 爬虫简介
  • 京东爬虫特殊性
    • 价格抓取
      • allowed_domains注意
        • jd_spider.py
          • 实验结果
          • 未解决的问题
          相关产品与服务
          消息队列 TDMQ
          消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档