Scrapy爬取电商网站京东奶粉商品价格数据-附各种问题解决

原创 2017年10月19日 10:24:06

主要的目标是爬奶粉的价格,商品名称和sku_id,想知道奶粉的平均价格。


首先在cmd里建立一个新的scrapy spider project

(1)scrapy startproject milkprice        创建一个项目

(2)创建一个spider,注意要先cd到有.cfg的路径下创建

用scrapy genspider -l 命令可以查看spider模板


scrapy genspider -t <template_name> <spider_name> <domain> 命令可以创建spider


创建好了以后项目文件里会生成scrapy预置的框架,集合了爬取,保存以及一些爬取中的设置。

在spiders文件夹里打开我们刚才命名的那个spider;

class JingdongSpider(scrapy.Spider):
    name = 'jingdong'
    allowed_domains = ['search.jd.com']
    start_urls = ['https://search.jd.com/s_new.php?keyword=%E5... ...page=1。。。',
                  'https://search.jd.com/s_new.php?key... ...page=2。。。']


name 用于区别不同的spider,我们可以建立多个spider。

start_urls是在spider启动时进行爬取的url列表,可以是一个也可以是多个,可以给一个初始的url,在后面的parse里解析页面时拿到下一页的url然后自动继续爬取或者一开始我们知道每页的url,就可以都放在start_urls里。


京东的商品每页的url长一个样子,只需要该page的数字,所以可以事先都列在这。

spider对每个url会进行访问,得到一个response,然后对这个response解析,生成item对象,送到pipeline里保存我们的数据,同时还能负责生成下一个request对象;

现在我们来定义解析函数parse

    def parse(self, response):
        """
            直接获取每个sku-data
        """
        product = MilkpriceItem()

        sku_list = response.xpath('//li[@class="gl-item"]')
        name_selector = response.xpath('//div[@class="p-name p-name-type-2"]//em')

        for i in range(len(sku_list)):
                product['sku_id'] = sku_list[i].xpath('./@data-sku').extract()[0]
                product['price'] = float(sku_list[i].xpath('.//div[@class="p-price"]//i//text()').extract()[0])
                product['brand'] = name_selector[i].xpath('./text()').extract()[0]
                product['name'] = name_selector[i].xpath('./text()').extract()[1:]

                yield product

我们可以看到每个商品的信息都非常整齐地在li class='gl-item'里呆着,所以我们可以先拿到所有商品的li元素,以便于获取到data-sku属性。

   

为了取到商品的名称信息,我们先获取到em元素这个selector,然后再逐一取text,可以生成一个商品的名字的列表。

在pipelines里可以用csvitemexporter,jsonitemexporter写入每个item,或者自己定义数据库链接,将数据保存到数据库里。

from scrapy.exporters import CsvItemExporter


class MilkpriceItemCsvPipeline(object):
    def open_spider(self, spider):
        self.file = open('milkprice.csv', 'wb')
        self.exporter = CsvItemExporter(self.file)
        self.exporter.start_exporting()

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

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item
我们修改完pipeline以后,要记得在settings里修改默认值,数字本身没什么特别意义,越大优先级越高,可以列多个,也可以写个jsonItemExporter在里面

ITEM_PIPELINES = {
   'milkprice.pipelines.MilkpriceItemCsvPipeline': 300,
}

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

settings里有诸多有用的控制。比如上面这个。它的默认值是True,但是在爬京东的过程中,没有找到robot.txt,就会不停redirect到京东首页,迟迟不能按照我的url爬。在这里把它改成false就好啦。

DOWNLOAD_DELAY = 10

设置下载延迟,默认是3,单位是秒,可以有小数点

COOKIES_ENABLED = False
不向web_server发送cookies,一般为了性能为了反爬最后都禁止。

DEFAULT_REQUEST_HEADERS = {
    # "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate, br",
    # "Accept-Language": "en-US,en;q=0.8",
    "Connection": "keep-alive",
    。。。
    
    。。。
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
    # "X-Requested-With": "XMLHttpRequest",
}
添加headers


然后我们可以启动项目scrapy crawl <spider_name>


还可以打开保存的csv查看


下面开始说下项目中遇到的问题:

1. xpath相关:

(1)对selector对象再取xpath的时候,前面一定要加上‘.’,表示选取当前节点

(2)//是相对路径,表示这个元素后所有满足要求的元素,/是绝对路径,表示紧跟其后的

(3)选取根元素后面多个text应该逐一取到这个根元素的selector,然后取text(),可以得到一个text的list

2. scrapy shell相关:

正常我们用scrapy shell调试xpath 可以简简单单的scrapy shell url,但是这次经常打不开正确的url

(1)检查response是不是正确的url的response,可以通过response.url和view(response)在浏览器打开url来检查

(2)先打scrapy shell命令, 然后用fetch('url'),用这个方法竟然就打开了。。。

(3)要传入headers咋办?在scrapy shell 里,

from scrapy import Request

req=Request(url, headers={"ddd" : "dddd",... ...})

fetch(req)

(4)加user agent      scrapy shell -s USER_AGENT='…' url

3. 动态加载问题:

一开始使用的url是进去京东搜索奶粉后的url,但是爬着爬着遇到两个问题

(1)在商品list页面我只能抓到30个,但实际陈列了60个,咋回事呢,原来是需要手动往下拉去加载剩下30个,这也解释了为啥第一页是page=1,第二页就是page=3了,其实是有page=2的...汗,看到了好多按照page=1,3,5,7,9...抓的同学

(2)进入了商品详情url后,发现抓不到价格了,OMG。。。咋回事,发现也变成是js,网页去动态请求了价格数据。

解决方案就是用inspect里的network,看看这些url都默默低做了些啥。


点了network之后刷新页面,然后我们会看到前30个商品的信息;左上角那个ban的符号,是clear已经load好的数据,我们点一下清除第一页的数据;然后把页面往下拉,让页面加载剩下30个商品,然后看到network里面name列里的各种返回数据,同过看他们的response,我们可以找到我们需要的信息。比如说剩下30个信息就藏在这个s_new。。。。request里,在headers里我能看到它的url和headers信息,于是乎,我们就可以用这个url和headers来访问。


4.不按照指定url爬,总是redirect

 

到settings里修改ROBOTSTXT_OBEY为false


5. 价格获取不到的报错

多爬几页的话就会遇到有些东西价格信息拿不到的情况,为了不影响该页其他商品的爬取,对原代码做一点修正

            price = sku_list[i].xpath('.//div[@class="p-price"]//i//text()').extract_first()
            if price:
                product['price'] = float(price)
            else:
                product['price'] = ''


版权声明:本文为博主原创文章,未经博主允许不得转载。

爬了知乎 200 万数据,图说程序员都喜欢去哪儿工作

点击上方“CSDN”,选择“置顶公众号” 关键时刻,第一时间送达! 因为最近和朋友吃饭,大家都到了大三季,都在纠结自己该以哪里作为自己职业发展的起点?也想看看自己的背景,能不能找到靠谱的师...

爬虫爬取电商网站的商品数据并保存成json文件

这里爬取的电商网站为当当网的地方特产为例 首先建立爬虫项目 scrapy startproject autop然后就要编写items文件了 # -*- coding: utf-8 -*- # D...

通过交互式网页爬取,抓取天猫商品价格

通过交互式网页爬取,抓取天猫商品价格。 方式:模拟点击颜色分类,然后读取定价 参考(1):http://www.cnblogs.com/xinzhyu/p/4214669.html主要利用Casp...

[笔记]python爬虫:淘宝商品价格信息爬取示例

爬取的网站信息网站地址 淘宝官网:https://www.taobao.com/ 爬取内容 碧根果价格信息 网页对应的部分源代码 从网页源代码中可以看到,需要爬取的商品以 “raw_titl...

京东商城手机频道商品价格信息的抓取

在做页面解析时,最大难度在于对动态数据的抓取,特别是由ajax加载的内容。目前对这方面的处理还没很好的解决方案,,虽然有htmlunit之类的模拟浏览器运行工具包,但是其效率以及准确性远远不能满足实际...
  • km1218
  • km1218
  • 2014年11月19日 16:52
  • 2280

Python爬虫(一)京东商品价格及详情页抓取

这是一个以http://item.jd.com/2957726.html为例的单网页抓取案例 import urllib.request; #载入urllib.request,用于获取页面html源...
  • maxca
  • maxca
  • 2016年06月30日 10:54
  • 3554

Scrapy框架爬取京东商品

这是上的第二节爬虫课程的课后作业:抓取京东某类商品的信息,这里我选择了手机品类。 使用scrapy爬虫框架,需要编写和设置的文件主要有phone.py , pipelines.py , items...

scrapy框架爬取京东商城商品的评论

一、Scrapy介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。 所谓网络爬虫,就是一个在网上到处或定向抓取...

基于Scrapy的爬虫爬取京东商品信息与评论

总体概述 从京东搜索框搜索进入手机进入页面,爬取内容分成两类,一类是手机的基本信息(标题、价格、链接),另一类是评论信息(用户名、评论内容、评论总数等),将信息爬取下来之后,进行数据处理,以方便显示和...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scrapy爬取电商网站京东奶粉商品价格数据-附各种问题解决
举报原因:
原因补充:

(最多只允许输入30个字)