scrapy爬取京东
京东对于爬虫来说太友好了,不向天猫跟淘宝那样的丧心病狂,本次爬虫来爬取下京东,研究下京东的数据是如何获取的。
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爬取京东相关推荐
- Python scrapy爬取京东,百度百科出现乱码,解决方案
Python scrapy爬取京东 百度百科出现乱码 解决方案 十分想念顺店杂可... 抓取百度百科,出现乱码 把页面源码下载下来之后,发现全是乱码,浏览器打开 但是浏览器链接打开就没有乱码 以下是浏 ...
- python爬取京东手机数据_用scrapy爬取京东的数据
本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中. 一.项目介绍 主要目标 1.使用scrapy爬取京东上所有的手机数据 2.将爬取的数据存储到MongoDB 环境 ...
- python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
这篇文章主要介绍了python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析的实例,帮助大家更好的理解和学习使用python.感兴趣的朋友可以了解下 一.环境准备 python3.8.3 ...
- 使用scrapy爬取京东的手机数据
使用scrapy爬取京东的数据 本文目的是使用scrapy爬取京东上所有的手机数据,并将数据保存到MongoDB中 一.项目介绍 主要目标 使用scrapy爬取京东上所有的手机数据 将爬取的数据存储 ...
- scrapy爬取京东商品评论并保存至Mysql数据库中
scrapy爬取京东商品评论并保存至Mysql数据库 一.总体概述 二.实践过程 2.1网页解析 2.2使用单线程爬取代码如下: 2.3使用scrapy爬取数据 2.4绘制词云图结果: 三.总结 一. ...
- 利用scrapy爬取京东移动端的图片素材和商品信息
有一个练习项目需要一些带分类信息的商品测试图片,从现有的电商网站爬取是个不错的选择.刚好最近又在练习scrapy的使用,这一篇记录一下用scrapy爬取京东的图片素材并保存商品信息的思路. 文中代码共 ...
- scrapy爬取京东笔记本电脑数据并进行简单处理和分析
京东爬虫 一.环境准备 二.问题分析 三.spider 三.item 四.setting 五.pipelines 六.middlewares 七.使用jupyter进行简单的处理和分析 一.环境准备 ...
- 使用scrapy爬取京东产品详细信息
我的爬虫以京东女装的外套为例进行,抓取更大的分类可以再进行修改. scrapy的安装,建工程什么的我就不说了,工程结构如图 crawlCoat内容如下: # -*- coding: utf-8 -*- ...
- scrapy 爬取京东前后一星期商品信息(价格、评价数)
scrapy爬虫万变不离其中,就几个步骤: 1.分析数据 2.创建爬虫框架 3.编写相应的代码 分析数据 今天要爬取的数据是"京东女装"商品的价格信息与评价数:由于小伙伴对女装特别 ...
最新文章
- 博弈——威佐夫博弈(hdu1527,2177)
- 在sqlyog中创建MySQL触发器简单实例
- linux 查看hive版本号,如何从命令提示符知道Hive和Hadoop版本?
- 使用malloc分别分配2KB的空间,然后用realloc调整为6KB的内存空间,打印指针地址...
- htmlh1 h6,HTML 5 h1 至 h6 标签 - HTML 参考手册
- 型机器人同人本子_唯美的人×机器人漫画《純情愛玩生化女友》
- Python 之下划线
- php 发邮件 上传附件,PHPMailer实现PHP的邮件发送,附带附件
- python函数定义时缩进的作用_定义函数时,函数体的正确缩进为?_学小易找答案
- 1076: 三位数求解-python
- iOS音乐播放器实现后台播放锁屏界面控制
- java微信小程序的校园外卖点餐平台 uniapp
- 夏日“轻”凉小贴士,华为FreeBuds 4全给你
- ir2113错误电路
- 两个向量相乘的数值表示和几何表示
- jmeter 正则表达式提取器的使用(提取第一个匹配结果)
- 如何用银联易办事POS机缴纳交通违章罚款
- 【英语面试】一.计算机专业英语面试常见问题(家庭/家乡/学校篇)
- java中Scanner扫描器
- 程序员鄙视链python_关于程序员之间的鄙视链
热门文章
- Sublime Text 2快捷键大全
- Codeforces 987A. Infinity Gauntlet(手速题,map存一下输出即可)
- 51nod 1572 宝岛地图 (预处理四个方向的最大步数优化时间,时间复杂度O(n*m+k))
- 超全流程-idea对springboot+ssm的部署实现增删改查
- pytorch 之 冻结某层参数,即训练时不更新
- Playfair加密算法(C 实现)
- Pwn环境配置(三)——ubuntu环境搭建(新)
- [BUUCTF-pwn]——ciscn_2019_n_8
- 乐视手机android流量,乐视手机流量不能用怎么办
- python读取有空行的csv_如何在使用python读取CSV文件时跳过空行