Scrapy簡明教程(五)——命令行傳參爬取淘寶商品數據

  首先我們先來看一下淘寶搜索商品的頁面,這裏以糖炒板栗爲例:

這裏寫圖片描述

  可以看到搜索到了很多糖炒板栗,顯示有100頁,但真正搜索到的商品超過了100頁,給用戶只顯示前100頁,後面編寫的爬蟲只爬取前50頁,url構造這裏就不講了,之前的博客已經講過了,需要更多可以自己更改頁數,然後我們檢查網頁元素,找到商品鏈接並複製,然後在網頁源代碼裏查找,結果如下:

這裏寫圖片描述
這裏寫圖片描述

  發現並沒有找到,說明該數據是動態加載的,那我們是不是應該去js動態加載的數據中去找呢?答案是沒必要,雖然可以這樣找,但是效率很低。這裏介紹另一種方法,仔細觀察商品詳情頁的鏈接,你會發現有一個參數是id,如果搜索結果頁的網頁源碼裏有這些商品的id,那我們不就可以直接構造url了,帶着這種思路,我們進行如下操作:

這裏寫圖片描述
這裏寫圖片描述

  我們發現,這種思路是正確的,在網頁源代碼裏確實找到了該商品的id,然後我們進行如下操作:

這裏寫圖片描述

按照這種規則可以找到44個搜索結果,正好是淘寶搜索結果頁一頁的商品數,於是,我們就可以構造出商品詳情頁的url,仔細觀察搜索結果,你會發現在淘寶網搜索的結果裏面,包含了大量天貓商城的商品,而這兩個網站詳情頁的抓取規則又不相同,所以,在最後應分別處理這兩個網站的商品。這次的評論內容,我們將採用json反序列化來抽取評論數據,說到這裏,我們再來介紹一個谷歌的JSON-handle插件吧,如下圖所示:

這裏寫圖片描述

  啓用這個插件後,網頁上的json數據就會很友好的顯示出來,這裏我們以天貓商城商品的評論數據爲例:

這裏寫圖片描述

  這樣我們就很容易看到這個頁面上的所有數據,比如總評價數,總評價頁數,當前評價頁碼,還有評論數據rateList,裏面包含評價內容,評價時間,以及回覆等,可以看到一頁有20個評價,因爲評價內容太長,下面編寫的爬蟲只爬取評價首頁的前5條評價內容及評價時間,下面正式開始編寫爬蟲代碼,Scrapy創建項目請參考前面的博客,這裏直接編寫具體代碼文件:

1. 編寫 settings.py :

# Disable cookies (enabled by default)
COOKIES_ENABLED = False

DEFAULT_REQUEST_HEADERS = {
    'Accept':'application/json, text/plain, */*',
    'Accept-Language':'zh-CN,zh;q=0.3',
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
    'Connection':'keep-alive',
}

2. 編寫要抽取的數據域 (items.py) :

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class AccurateTaobaoItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    keywords = scrapy.Field()
    title = scrapy.Field()
    link = scrapy.Field()
    price = scrapy.Field()
    comment_data = scrapy.Field()
    shop_name = scrapy.Field()
    shop_link = scrapy.Field()
    describe_score = scrapy.Field()
    service_score = scrapy.Field()
    logistics_score = scrapy.Field()

3. 編寫 piplines.py:
  這裏就不編寫它了,直接打印在終端頁面,如果需要存儲文件或數據庫,可以參考前面幾篇博客,然後在settings.py文件中修改ITEM_PIPELINES即可。

4. 編寫爬蟲文件:

# -*- coding: utf-8 -*-

import scrapy
from scrapy import Request
from accurate_taobao.items import AccurateTaobaoItem
from accurate_taobao.settings import DEFAULT_REQUEST_HEADERS
import re
import json
import urllib2

class SpiderAccuratetaobaoSpider(scrapy.Spider):
    name = 'spider_accurate_taobao'
    allowed_domains = ['taobao.com', 'tmall.com']
    start_urls = ['https://www.taobao.com/']

    def __init__(self, keywords=None, *args, **kwargs):
        super(SpiderAccuratetaobaoSpider, self).__init__(*args, **kwargs)
        print '您搜索的商品爲:', keywords
        self.keywords = keywords
        self.start_urls = ['https://s.taobao.com/search?q=%s' % keywords]

    def parse(self, response):
        # 前50頁
        for i in range(50):
            purl = response.url + "&s={}".format(str(i*44))
            yield Request(url=purl, callback=self.goods)

    def goods(self, response):
        body = response.body.decode("utf-8","ignore")

        patid = '"nid":"(.*?)"'
        allid = re.compile(patid).findall(body)
        for j in range(len(allid)):
            thisid = allid[j]
            url = "https://item.taobao.com/item.htm?id=" + str(thisid)
            yield Request(url=url,callback=self.next)

    def next(self, response):
        item = AccurateTaobaoItem()
        title = response.xpath('//h3[@class="tb-main-title"]/@data-title').extract()
        goods_id = re.findall('id=(.*?)$', response.url)[0]
        headers = DEFAULT_REQUEST_HEADERS
        if not title:
            mall = '天貓商城'
            title = response.xpath('//div[@class="tb-detail-hd"]/h1/text()').extract()[0].encode('utf-8').strip()
            headers['referer'] = "https://detail.tmall.com/item.htm"
            purl = 'https://mdskip.taobao.com/core/initItemDetail.htm?&itemId={}'.format(goods_id)
            req = urllib2.Request(url=purl, headers=headers)
            res = urllib2.urlopen(req).read()
            pdata = re.findall('"postageFree":false,"price":"(.*?)","promType"', res)
            price = list(set(pdata))[0]
        else:
            mall = '淘寶商城'
            title = title[0].encode('utf-8')
            purl = "https://detailskip.taobao.com/service/getData/1/p1/item/detail/sib.htm?itemId={}&modules=price,xmpPromotion".format(goods_id)
            headers['referer'] = "https://item.taobao.com/item.htm"
            price_req = urllib2.Request(url=purl, headers=headers)
            price_res = urllib2.urlopen(price_req).read()
            pdata = list(set(re.findall('"price":"(.*?)"', price_res)))
            price = ""
            for t in pdata:
                if '-' in t:
                    price = t
                    break
            if not price:
                price = sorted(map(float, pdata))[0]

        comment_url = "https://rate.tmall.com/list_detail_rate.htm?itemId={}&sellerId=880734502&currentPage=1".format(goods_id)
        data = urllib2.urlopen(comment_url).read().decode("GBK", "ignore")
        cdata = '{' + data + '}'
        jdata = json.loads(cdata)
        comment_data = ''
        for i in range(5):
            comment_data += u"\n評價內容: " + jdata['rateDetail']['rateList'][i]['rateContent'] + u"\n評價時間:" + jdata['rateDetail']['rateList'][i]['rateDate']

        item['keywords'] = self.keywords
        item['title'] = title
        item['price'] = price
        item['comment_data'] = comment_data
        item["link"] = response.url

        print '\n商品名:', item['title']
        print '此商品來自', mall
        print '價格:', item['price']
        print '商品鏈接:', item['link']
        print '部分評價:', item['comment_data']

        #yield item

5. 運行項目:

scrapy crawl spider_accurate_taobao -a keywords=糖炒板栗 --nolog

  運行結果如下圖:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章