京东对于爬虫来说太友好了,不向天猫跟淘宝那样的丧心病狂,本次爬虫来爬取下京东,研究下京东的数据是如何获取的。

1 # 目标网址: jd.com
2 # 关键字: 手机(任意关键字,本文以手机入手)

得到url如下:

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

往下拖拽的时候就会发现很明显部分数据是通过Ajax动态获取的。那既然设计到动态数据没啥好说的抓下包。不过在抓包之前不妨先翻几页看看url有没有什么变化。

点击下一页

https://search.jd.com/Search?keyword=手机BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=手机BA&cid2=653&cid3=655&page=3&s=60&click=0  # 关键信息page出现了

在点回第一页

https://search.jd.com/Search?keyword=手机BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=手机BA&cid2=653&cid3=655&page=1&s=1&click=0   # 这个时候其实规律就出来了

把page改成2试一下,结果出来的数据跟第一页的一样,page=4跟page=3出来的数据也是一样,那其实很好说了,每次打开新的页面的时候只需要确保page+2即可。

抓下包,获取下动态的数据:

拿到url访问下这个页面,结果却跳回了首页,很明显参数不够。看了几篇博客才知道原来是要携带referer信息的。

referer地址也很明显就是本页面的url。再来看看这些动态数据的url该怎么构造,多访问几个页面看看规律。

1 第一页:  https://search.jd.com/s_new.php?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=2&s=30&scrolling=y&log_id=1547824670.57168&tpl=3_M&show_items=7643003,5089235,100000822981,5089273,5821455,7437788,5089225,100001172674,8894451,7081550,100000651175,6946605,8895275,7437564,100000349372,100002293114,8735304,100000820311,6949475,100000773875,7357933,100000971366,8638898,7694047,8790521,7479912,7651927,7686683,100001464948,100000650837
2
3 第二页:  https://search.jd.com/s_new.php?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=4&s=86&scrolling=y&log_id=1547824734.86451&tpl=3_M&show_items=5283387,7428766,6305258,7049459,8024543,6994622,5826236,3133841,6577511,100000993102,5295423,5963066,8717360,100000400014,7425622,7621213,100000993265,100002727566,28331229415,2321948,6737464,7029523,34250730122,3133811,36121534193,11794447957,5159244,28751842981,100001815307,3517501360345 第三页:  https://search.jd.com/s_new.php?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=6&s=140&scrolling=y&log_id=1547824799.50167&tpl=3_M&show_items=3889169,4934609,5242942,4270017,32399556682,7293054,28209134950,100000993265,32796441851,5980401,6176077,27424489997,27493450925,5424574,100000015166,6840907,30938386315,12494304703,7225861,34594345130,29044581673,28502299808,4577217,8348845,31426728970,6425153,31430342752,15501730722,100000322417,5283377

仔细观察关键字page,第一页page=2,第二页page=4,第三页page=6,后面的 show_items= 这里的参数一一直在变化,这是些什么鬼?

查看博客才知,原来啊京东每一页由60条数据,前30条直接显示出来,后30条数据是动态加载的,show_items=后面的这些数字其实是前30条数据的每一条pid在html源码中可以直接获取到。

OK,总结一下,访问首页前30条数据的url是这个。

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=1&s=1&click=0

后30条动态的数据是这个

https://search.jd.com/s_new.php?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=2&s=30&scrolling=y&log_id=1547825445.77300&tpl=3_M&show_items=7643003,5089235,100000822981,5089273,5821455,7437788,5089225,100001172674,8894451,7081550,100000651175,6946605,8895275,7437564,100000349372,100002293114,8735304,100000820311,6949475,100000773875,7357933,100000971366,8638898,8790521,7479912,7651927,7686683,100001464948,100000650837,1861091

且访问后30条的时候要带上referer以及pid,在获取下一页的时候只需要page+2即可。就可以动手整了。


目录结构:

jdspider.py

  1 import scrapy
  2 from ..items import JdItem
  3
  4
  5 class JdSpider(scrapy.Spider):
  6     name = 'jd'
  7     allowed_domains = ['jd.com']  # 有的时候写个www.jd.com会导致search.jd.com无法爬取
  8     keyword = "手机"
  9     page = 1
 10     url = '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'
 11     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'
 12
 13     def start_requests(self):
 14         yield scrapy.Request(self.url % (self.keyword, self.keyword, self.page), callback=self.parse)
 15
 16     def parse(self, response):
 17         """
 18         爬取每页的前三十个商品,数据直接展示在原网页中
 19         :param response:
 20         :return:
 21         """
 22         ids = []
 23         for li in response.xpath('//*[@id="J_goodsList"]/ul/li'):
 24             item = JdItem()
 25             title = li.xpath('div/div/a/em/text()').extract_first("")  # 标题
 26             price = li.xpath('div/div/strong/i/text()').extract_first("")  # 价格
 27             p_id = li.xpath('@data-pid').extract_first("")  # id
 28             ids.append(p_id)
 29             url = li.xpath('div/div[@class="p-name p-name-type-2"]/a/@href').extract_first("")  # 需要跟进的链接
 30
 31             item['title'] = title
 32             item['price'] = price
 33             item['url'] = url
 34             # 给url加上https:
 35             if item['url'].startswith('//'):
 36                 item['url'] = 'https:' + item['url']  # 粗心的同学请注意一定要加上冒号:
 37             elif not item['url'].startswith('https:'):
 38                 item['info'] = None
 39                 yield item
 40                 continue
 41
 42             yield scrapy.Request(item['url'], callback=self.info_parse, meta={"item": item})
 43
 44         headers = {'referer': response.url}
 45         # 后三十页的链接访问会检查referer,referer是就是本页的实际链接
 46         # referer错误会跳转到:https://www.jd.com/?se=deny
 47         self.page += 1
 48         yield scrapy.Request(self.next_url % (self.keyword, self.keyword, self.page, ','.join(ids)),
 49                              callback=self.next_parse, headers=headers)
 50
 51     def next_parse(self, response):
 52         """
 53         爬取每页的后三十个商品,数据展示在一个特殊链接中:url+id(这个id是前三十个商品的id)
 54         :param response:
 55         :return:
 56         """
 57         for li in response.xpath('//li[@class="gl-item"]'):
 58             item = JdItem()
 59             title = li.xpath('div/div/a/em/text()').extract_first("")  # 标题
 60             price = li.xpath('div/div/strong/i/text()').extract_first("")  # 价格
 61             url = li.xpath('div/div[@class="p-name p-name-type-2"]/a/@href').extract_first("")  # 需要跟进的链接
 62             item['title'] = title
 63             item['price'] = price
 64             item['url'] = url
 65
 66             if item['url'].startswith('//'):
 67                 item['url'] = 'https:' + item['url']  # 粗心的同学请注意一定要加上冒号:
 68             elif not item['url'].startswith('https:'):
 69                 item['info'] = None
 70                 yield item
 71                 continue
 72
 73             yield scrapy.Request(item['url'], callback=self.info_parse, meta={"item": item})
 74
 75         if self.page < 200:
 76             self.page += 1
 77             yield scrapy.Request(self.url % (self.keyword, self.keyword, self.page), callback=self.parse)
 78
 79     def info_parse(self, response):
 80         """
 81         链接跟进,爬取每件商品的详细信息,所有的信息都保存在item的一个子字段info中
 82         :param response:
 83         :return:
 84         """
 85         item = response.meta['item']
 86         item['info'] = {}
 87         name = response.xpath('//div[@class="inner border"]/div[@class="head"]/a/text()').extract_first("")
 88         type = response.xpath('//div[@class="item ellipsis"]/text()').extract_first("")
 89         item['info']['name'] = name
 90         item['info']['type'] = type
 91
 92         for div in response.xpath('//div[@class="Ptable"]/div[@class="Ptable-item"]'):
 93             h3 = div.xpath('h3/text()').extract_first()
 94             if h3 == '':
 95                 h3 = "未知"
 96             dt = div.xpath('dl/dl/dt/text()').extract()  # 以列表的形式传参给zip()函数
 97             dd = div.xpath('dl/dl/dd[not(@class)]/text()').extract()
 98             item['info'][h3] = {}
 99             for t, d in zip(dt, dd):
100                 item['info'][h3][t] = d
101         yield item

items.py

 1 import scrapy
 2
 3
 4 class JdItem(scrapy.Item):
 5     title = scrapy.Field()  # 标题
 6
 7     price = scrapy.Field()  # 价格
 8
 9     url = scrapy.Field()  # 商品链接
10
11     info = scrapy.Field()  # 详细信息

piplines.py

 1 from scrapy.conf import settings
 2 from pymongo import MongoClient
 3
 4
 5 class JdphonePipeline(object):
 6     def __init__(self):
 7         # 获取setting中主机名,端口号和集合名
 8         host = settings['MONGODB_HOST']
 9         port = settings['MONGODB_PORT']
10         dbname = settings['MONGODB_DBNAME']
11         col = settings['MONGODB_COL']
12
13         # 创建一个mongo实例
14         client = MongoClient(host=host, port=port)
15
16         # 访问数据库
17         db = client[dbname]
18
19         # 访问集合
20         self.col = db[col]
21
22     def process_item(self, item, spider):
23         data = dict(item)
24         self.col.insert(data)
25         return item

settings.py

 1 USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'
 2
 3 ITEM_PIPELINES = {
 4    'jd.pipelines.JdphonePipeline': 300,
 5 }
 6
 7 # 主机环回地址
 8 MONGODB_HOST = '127.0.0.1'
 9 # 端口号,默认27017
10 MONGODB_POST = 27017
11 # 设置数据库名称
12 MONGODB_DBNAME = 'JingDong'
13 # 设置集合名称
14 MONGODB_COL = 'JingDongPhone'
15 SQL_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
16 SQL_DATE_FORMAT = "%Y-%m-%d"

代码基本上copy了这位博主的代码,只是做了些许的修改。https://www.cnblogs.com/twoice/p/9742732.html

好吧这次京东的爬虫就到这里,其实关于京东的爬虫网上还有另外一个版本,下次在研究一下。京东是真的对爬虫友好。

转载于:https://www.cnblogs.com/pontoon/p/10290233.html

scrapy爬取京东相关推荐

  1. Python scrapy爬取京东,百度百科出现乱码,解决方案

    Python scrapy爬取京东 百度百科出现乱码 解决方案 十分想念顺店杂可... 抓取百度百科,出现乱码 把页面源码下载下来之后,发现全是乱码,浏览器打开 但是浏览器链接打开就没有乱码 以下是浏 ...

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

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

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

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

  4. 使用scrapy爬取京东的手机数据

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

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

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

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

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

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

    京东爬虫 一.环境准备 二.问题分析 三.spider 三.item 四.setting 五.pipelines 六.middlewares 七.使用jupyter进行简单的处理和分析 一.环境准备 ...

  8. 使用scrapy爬取京东产品详细信息

    我的爬虫以京东女装的外套为例进行,抓取更大的分类可以再进行修改. scrapy的安装,建工程什么的我就不说了,工程结构如图 crawlCoat内容如下: # -*- coding: utf-8 -*- ...

  9. scrapy 爬取京东前后一星期商品信息(价格、评价数)

    scrapy爬虫万变不离其中,就几个步骤: 1.分析数据 2.创建爬虫框架 3.编写相应的代码 分析数据 今天要爬取的数据是"京东女装"商品的价格信息与评价数:由于小伙伴对女装特别 ...

最新文章

  1. 博弈——威佐夫博弈(hdu1527,2177)
  2. 在sqlyog中创建MySQL触发器简单实例
  3. linux 查看hive版本号,如何从命令提示符知道Hive和Hadoop版本?
  4. 使用malloc分别分配2KB的空间,然后用realloc调整为6KB的内存空间,打印指针地址...
  5. htmlh1 h6,HTML 5 h1 至 h6 标签 - HTML 参考手册
  6. 型机器人同人本子_唯美的人×机器人漫画《純情愛玩生化女友》
  7. Python 之下划线
  8. php 发邮件 上传附件,PHPMailer实现PHP的邮件发送,附带附件
  9. python函数定义时缩进的作用_定义函数时,函数体的正确缩进为?_学小易找答案
  10. 1076: 三位数求解-python
  11. iOS音乐播放器实现后台播放锁屏界面控制
  12. java微信小程序的校园外卖点餐平台 uniapp
  13. 夏日“轻”凉小贴士,华为FreeBuds 4全给你
  14. ir2113错误电路
  15. 两个向量相乘的数值表示和几何表示
  16. jmeter 正则表达式提取器的使用(提取第一个匹配结果)
  17. 如何用银联易办事POS机缴纳交通违章罚款
  18. 【英语面试】一.计算机专业英语面试常见问题(家庭/家乡/学校篇)
  19. java中Scanner扫描器
  20. 程序员鄙视链python_关于程序员之间的鄙视链

热门文章

  1. Sublime Text 2快捷键大全
  2. Codeforces 987A. Infinity Gauntlet(手速题,map存一下输出即可)
  3. 51nod 1572 宝岛地图 (预处理四个方向的最大步数优化时间,时间复杂度O(n*m+k))
  4. 超全流程-idea对springboot+ssm的部署实现增删改查
  5. pytorch 之 冻结某层参数,即训练时不更新
  6. Playfair加密算法(C 实现)
  7. Pwn环境配置(三)——ubuntu环境搭建(新)
  8. [BUUCTF-pwn]——ciscn_2019_n_8
  9. 乐视手机android流量,乐视手机流量不能用怎么办
  10. python读取有空行的csv_如何在使用python读取CSV文件时跳过空行