使用scrapy爬取京东的数据

本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中

一、项目介绍

主要目标

  1. 使用scrapy爬取京东上所有的手机数据
  2. 将爬取的数据存储到MongoDB

环境

  • win7、python2、pycharm

技术

  1. 数据采集:scrapy
  2. 数据存储:MongoDB

难点分析

和其他的电商网站相比,京东的搜索类爬取主要有以下几个难点:

  1. 搜索一个商品时,一开始显示的商品数量为30个,当下拉这一页 时,又会出现30个商品,这就是60个商品了,前30个可以直接 从原网页上拿到,后30个却在另一个隐藏链接中,要访问这两个 链接,才能拿到一页的所有数据。
  2. 隐藏链接的构造,发现最后的那个show_items字段其实是前30 个商品的id。
  3. 直接反问隐藏链接被拒绝访问,京东的服务器会检查链接的来源, 只有来自当前页的链接他才会允许访问。
  4. 前30个商品的那一页的链接page字段的自增是1、3、5。。。这 样的,而后30个的自增是2、4、6。。。这样的。

下面看具体的分析。

二、网页分析

首先打开京东的首页搜索“手机”:

一开始他的地址是这样的:

https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&wq=%E6%89%8B%E6%9C%BA&pvid=dc6767ca66534d57ba29d6758fd957e4

转到第2页,会看到,他的地址变成这样子了:

https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=3&s=60&click=0

后面的字段全变了,那么第2页的url明显更容易看出信息,主要修改的字段其实就是keyword,page,其实还有一个wq字段,这个得值和keyword是一样的。

那么我们就可以使用第二页的url来抓取数据,可以看出第2页的url中page字段为3。

但是查看原网页的时候却只有30条数据,还有30条数据隐藏在一个网页中:

从这里面可以看到他的Request url。

再看一下他的response:

里面正好就是我们需要的信息。

看一下他的参数请求:

这些参数不难以构造,一些未知的参数可以删掉,而那个show_items参数,其实就是前30个商品的id:

准确来说是data-pid

此时如果我们直接在浏览器上访问这个Request url,他会跳转到https://www.jd.com/?se=deny页面,并没有我们需要的信息,其实这个主要是请求头中的referer参数

这个参数就是在地址栏上的那个url,当然在爬取的时候我们还可以加个user-agent,那么分析完毕,我们开始敲代码。

三、爬取

创建一个scrapy爬虫项目:

scrapy startproject jdphone

生成一个爬虫:

scrapy genspider jd jd.com 

文件结构:

我们要爬取的字段如下:(price、title、comment_num)

还有就是跟进链接后,手机的名称和类别:

以及规格与包装中的所有信息,

所有跟进链接后的信息都保存在info字段中作为一个字典存在

以下是代码:


items:  items.py

# -*- coding: utf-8 -*-
import scrapyclass JdphoneItem(scrapy.Item):# define the fields for your item here like:title = scrapy.Field()  # 标题price = scrapy.Field()  # 价格comment_num = scrapy.Field()  # 评价条数url = scrapy.Field()  # 商品链接info = scrapy.Field()  # 详细信息

spiders:  jd.py

# -*- coding: utf-8 -*-
import scrapy
from ..items import JdphoneItem
import sysreload(sys)
sys.setdefaultencoding("utf-8")class JdSpider(scrapy.Spider):name = 'jd'allowed_domains = ['jd.com']  # 有的时候写个www.jd.com会导致search.jd.com无法爬取keyword = "手机"page = 1url = 'https://search.jd.com/Search?keyword=%s&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%s&cid2=653&cid3=655&page=%d&click=0'next_url = 'https://search.jd.com/s_new.php?keyword=%s&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%s&cid2=653&cid3=655&page=%d&scrolling=y&show_items=%s'def start_requests(self):yield scrapy.Request(self.url % (self.keyword, self.keyword, self.page), callback=self.parse)def parse(self, response):"""爬取每页的前三十个商品,数据直接展示在原网页中:param response::return:"""ids = []for li in response.xpath('//*[@id="J_goodsList"]/ul/li'):item = JdphoneItem()title = li.xpath('div/div/a/em/text()').extract()  # 标题price = li.xpath('div/div/strong/i/text()').extract()  # 价格comment_num = li.xpath('div/div/strong/a/text()').extract()  # 评价条数id = li.xpath('@data-pid').extract()  # idids.append(''.join(id))url = li.xpath('div/div[@class="p-name p-name-type-2"]/a/@href').extract()  # 需要跟进的链接item['title'] = ''.join(title)item['price'] = ''.join(price)item['comment_num'] = ''.join(comment_num)item['url'] = ''.join(url)if item['url'].startswith('//'):item['url'] = 'https:' + item['url']elif not item['url'].startswith('https:'):item['info'] = Noneyield itemcontinueyield scrapy.Request(item['url'], callback=self.info_parse, meta={"item": item})headers = {'referer': response.url}# 后三十页的链接访问会检查referer,referer是就是本页的实际链接# referer错误会跳转到:https://www.jd.com/?se=denyself.page += 1yield scrapy.Request(self.next_url % (self.keyword, self.keyword, self.page, ','.join(ids)),callback=self.next_parse, headers=headers)def next_parse(self, response):"""爬取每页的后三十个商品,数据展示在一个特殊链接中:url+id(这个id是前三十个商品的id):param response::return:"""for li in response.xpath('//li[@class="gl-item"]'):item = JdphoneItem()title = li.xpath('div/div/a/em/text()').extract()  # 标题price = li.xpath('div/div/strong/i/text()').extract()  # 价格comment_num = li.xpath('div/div/strong/a/text()').extract()  # 评价条数url = li.xpath('div/div[@class="p-name p-name-type-2"]/a/@href').extract()  # 需要跟进的链接item['title'] = ''.join(title)item['price'] = ''.join(price)item['comment_num'] = ''.join(comment_num)item['url'] = ''.join(url)if item['url'].startswith('//'):item['url'] = 'https:' + item['url']elif not item['url'].startswith('https:'):item['info'] = Noneyield itemcontinueyield scrapy.Request(item['url'], callback=self.info_parse, meta={"item": item})if self.page < 200:self.page += 1yield scrapy.Request(self.url % (self.keyword, self.keyword, self.page), callback=self.parse)def info_parse(self, response):"""链接跟进,爬取每件商品的详细信息,所有的信息都保存在item的一个子字段info中:param response::return:"""item = response.meta['item']item['info'] = {}type = response.xpath('//div[@class="inner border"]/div[@class="head"]/a/text()').extract()name = response.xpath('//div[@class="item ellipsis"]/text()').extract()item['info']['type'] = ''.join(type)item['info']['name'] = ''.join(name)for div in response.xpath('//div[@class="Ptable"]/div[@class="Ptable-item"]'):h3 = ''.join(div.xpath('h3/text()').extract())if h3 == '':h3 = "未知"dt = div.xpath('dl/dt/text()').extract()dd = div.xpath('dl/dd[not(@class)]/text()').extract()item['info'][h3] = {}for t, d in zip(dt, dd):item['info'][h3][t] = dyield item

item pipeline:  pipelines.py

# -*- coding: utf-8 -*-
from scrapy.conf import settings
from pymongo import MongoClientclass JdphonePipeline(object):def __init__(self):# 获取setting中主机名,端口号和集合名host = settings['MONGODB_HOST']port = settings['MONGODB_PORT']dbname = settings['MONGODB_DBNAME']col = settings['MONGODB_COL']# 创建一个mongo实例client = MongoClient(host=host,port=port)# 访问数据库db = client[dbname]# 访问集合self.col = db[col]def process_item(self, item, spider):data = dict(item)self.col.insert(data)return item

setting:  setting.py

# -*- coding: utf-8 -*-
BOT_NAME = 'jdphone'SPIDER_MODULES = ['jdphone.spiders']
NEWSPIDER_MODULE = 'jdphone.spiders'# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'# Obey robots.txt rules
ROBOTSTXT_OBEY = True# 主机环回地址
MONGODB_HOST = '127.0.0.1'
# 端口号,默认27017
MONGODB_POST = 27017
# 设置数据库名称
MONGODB_DBNAME = 'JingDong'
# 设置集合名称
MONGODB_COL = 'JingDongPhone'ITEM_PIPELINES = {'jdphone.pipelines.JdphonePipeline': 300,
}

其他的文件都不做改变。

运行爬虫:

scrapy crawl jd

等待几分钟后,数据都存储到了MongoDB中了,现在来看一看MongoDB中的数据。

四、检查数据

在命令行中开启mongo:

看一下数据库:

发现JingDong中有5M数据。

看一下具体状态:

硬盘上的数据大小为4720KB,共4902条数据

最后来看一下数据:

数据保存成功!

使用scrapy爬取京东的手机数据相关推荐

  1. scrapy爬取京东图书的数据

    strat_url:https://book.jd.com/booksort.html 文章末尾有完整的项目链接 1.创建项目 scrapy startproject jd_book cd jd_bo ...

  2. 利用代理IP爬取京东网站手机数据

    1.代理简介 在爬虫过程中如果经常用自己的IP进行爬虫会出现IP被封的可能,这就要用到代理技术,通过爬取代理网站的IP地址,每次爬取页面就随机选择一个IP地址进行爬取,这样就会降低IP被封的可能性. ...

  3. python爬虫爬取京东商品评价_网络爬虫-爬取京东商品评价数据

    前段时间做商品评价的语义分析,需要大量的电商数据,于是乎就自己动手爬取京东的数据.第一次接触爬虫是使用selenium爬取CNKI的摘要,基于惯性思维的我仍然想用selenium+Firefox的方法 ...

  4. 网络爬虫-爬取京东商品评价数据

    前段时间做商品评价的语义分析,需要大量的电商数据,于是乎就自己动手爬取京东的数据.第一次接触爬虫是使用selenium爬取CNKI的摘要,基于惯性思维的我仍然想用selenium+Firefox的方法 ...

  5. python爬取京东手机数据_用scrapy爬取京东的数据

    本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中. 一.项目介绍 主要目标 1.使用scrapy爬取京东上所有的手机数据 2.将爬取的数据存储到MongoDB 环境 ...

  6. python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析

    这篇文章主要介绍了python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析的实例,帮助大家更好的理解和学习使用python.感兴趣的朋友可以了解下 一.环境准备 python3.8.3 ...

  7. scrapy爬取京东商品评论并保存至Mysql数据库中

    scrapy爬取京东商品评论并保存至Mysql数据库 一.总体概述 二.实践过程 2.1网页解析 2.2使用单线程爬取代码如下: 2.3使用scrapy爬取数据 2.4绘制词云图结果: 三.总结 一. ...

  8. 利用scrapy爬取京东移动端的图片素材和商品信息

    有一个练习项目需要一些带分类信息的商品测试图片,从现有的电商网站爬取是个不错的选择.刚好最近又在练习scrapy的使用,这一篇记录一下用scrapy爬取京东的图片素材并保存商品信息的思路. 文中代码共 ...

  9. Python爬取京东商品评论数据

    一.前言 本文将承接笔者的上篇文章Python爬取京东商品数据,使用京东商品唯一id字段"sku"拼接url,得到真实的京东商品评论网址,进而解释数据并保存到文件中,所爬取到的数据 ...

最新文章

  1. 下一站:AlphaDrug?
  2. 分布式思想和rpc解决方案介绍
  3. activiti 表——介绍
  4. 论文笔记 《Maxout Networks》 《Network In Network》
  5. Web GIS及其应用
  6. arcgis 字段计算器 条件赋值_【教程】ArcGIS入门教程(11)——多条件购房分析...
  7. 关于《用C#编写ActiveX控件》的几点说明
  8. 对于linux下指令的进一步扩充与巩固
  9. scala编程第18章学习笔记——有状态的对象
  10. 细说 Form (表单)(转)
  11. Beanstalkd消息队列的安装与使用
  12. Java Servlet系列之Servlet入门
  13. Android、IOS文字居中偏离的解决方案
  14. 实现多楼层,每个楼层多房间,上下拖动切换楼层,左右拖动查看其他房间
  15. oracle8i数据库修复,用ORACLE8i修复数据库坏块的三种方法
  16. sap business one 开发_敏捷软件开发实践:估算与计划读书笔记120第18章 估算速度...
  17. 思迈特软件Smartbi:最常用的五种大数据分析方法,建议收藏!
  18. 电脑IE图标删不掉怎么办
  19. iOS中延时执行(睡眠)的几种方法
  20. BEA-090403 Authentication for user admin denied

热门文章

  1. 重装系统之U盘+Ventoy全流程(适用各种常见系统)
  2. ROS 机器人操作系统:Ubuntu 安装 ROS Noetic
  3. ITDB公司电脑资产管理PHP系统出现空白页解决及中文版翻译方法
  4. unity 背包系统之美
  5. 新机发布前 苹果iPhone用户忠诚度达92%
  6. 旧电脑废物利用之:改变成服务器!云服务器搭建!
  7. 多车间该如何实施mes系统?
  8. 用户画像理论和搭建过程
  9. 雷电模拟器运行非常卡顿有效解决方法分享
  10. SSH服务器支持的算法漏洞