使用 Pyspider 爬取京东 Wap 版本商品价格

2014-12-31 20:12:57 +08:00
 imlonghao

爬虫运行在 @binux 的 Pyspider


总想找一个站来练习一下写爬虫,于是乎,我找到了京东的Wap版。

关于京东Wap版

优点
1. 没有反爬虫的设置,似乎不限制并发链接
2. 单个页面大小比较小,对VPS来说节省流量
3. 链接结构比较整齐,比较容易分析

缺点
1. 可以采集的数据比较少,只有商品分类、名称和价格
2. 单个分类分页最多2000页,但其实不仅仅有2000页

链接分析

我们大概的思路就是:全部分类-->二级分类-->三级分类-->遍历全部分页-->采集数据

打开wap.jd.com后,我们不难就可以看出全部分类的地址:http://wap.jd.com/category/all.html

然后我们观察链接,二级分类的地址均是以http://wap.jd.com/category/开头的

三级分类的地址均是以http://wap.jd.com/products/开头的

然后,我们就可以看到商品列表页了。

在商品页中,有两类链接我们需要分析。一是商品详细页的地址,以http://wap.jd.com/product/开头;另一个是页面的页数,我们使用Pyspider的分析工具,可以知道页面的页数是HTML>BODY>DIV.page>A[href]里面的。

知道了上面的信息,我们基本上就可以写代码开始采集了。

注意

京东的地址中,会传入一个区别不同用户的cid和sid的值,例如我的就是cid=1323&sid=24faaa1458222af7f13as9kf3aa12337,实际上链接只有.html前面的部分是有用的,.html后面?开始其实都是可以忽略的。

在Pyspider中,系统是通过url来区别不同的地址的,如果是sid不同的话,会被识别成不同的页面,最后的话可能会造成重复采集的结果。

因此,我打算使用urlparse模块中的urljoin来处理这些地址,可能方法有点不对,但是还是达到了效

代码

请参考我的网站:https://imlonghao.com/Pyspider/wap.jd.com.html

后记

使用Pyspider的效率我个人还是满意的,总共大概就是我2天爬了将近500W商品,速度其实可以再进一步,因为我不敢开太大并发因为已经VPS的内存不够..............

除此之外,硬盘也不够了,记录使用默认的配置,results.db总共占用了2.1G,而tasks.db占用了12G左右

此外,给@binux 反馈一个问题,像我这样500W数据的话,通过/results/dump/jd.json无法导出数据,显示超时....

9818 次点击
所在节点    程序员
35 条回复
binux
2014-12-31 20:24:23 +08:00
pyspider 前面还有反代吗? pyspider 是流式输出的,虽然打开表很慢,但是应该还是能输出的
imlonghao
2014-12-31 20:29:56 +08:00
@binux 可能是这个的问题吧,前面有nginx和varnish,我试一试直接下载:5000的看看
imlonghao
2014-12-31 20:37:02 +08:00
root@pyspider:~# wget 127.0.0.1:5000/results/dump/jd.json
--2014-12-31 20:31:43-- http://127.0.0.1:5000/results/dump/jd.json
Connecting to 127.0.0.1:5000... connected.
HTTP request sent, awaiting response...

就这样就不动了,我记得如果是流式输出的话wget不是这样的..
wangfeng3769
2014-12-31 20:40:29 +08:00
想知道你是怎么爬取北京之外的商品情况的 比如天津的情况。
imlonghao
2014-12-31 20:44:14 +08:00
@wangfeng3769 我只是爬了商品的名称、分类以及价格,没有爬有没有货这个..
wangfeng3769
2014-12-31 20:49:28 +08:00
@imlonghao 这个接口默认是北京的 ,想知道你是怎么做到爬取天津情况的
imlonghao
2014-12-31 20:57:11 +08:00
@wangfeng3769
我刚刚说了我并没有爬不同地区的商品情况,我的VPS是日本的,所以只能爬了北京的情况。

不过我还是根据你的需求看了看京东的设计,大概能满足你的有求了。

商品页:
天津 > 东丽区 > 全境
provinceId=3 天津
cityId=51035 东丽区 | cityId=51042 静海区 | 等等...
countryId=39620 全境

其中,countryId默认天津都是全境,不需要另外设置,只需要设置cityID和provinceId即可。

想要看那个地区的库存情况,爬虫的时候设置不同天津(provinceId=3)地区的cityID即可。

我所贴的代码:
self.crawl(urljoin(each.attr.href,'?=').replace('?=',''), callback=self.in_page)

你要看天津的,就可以改成:
self.crawl(urljoin(each.attr.href,'?province=3&cityID=51042'), callback=self.in_page)

等等,其他自己发挥
binux
2014-12-31 21:04:01 +08:00
@imlonghao 嗯,那确实是个问题。应该是 tornado + Flask 就没法用流了
imlonghao
2014-12-31 21:07:09 +08:00
@binux
您看看吧。那这样的话要导出数据只能通过db那里来导?打算换去mysql好导出一下..
另外,我爬京东的时候用35/30这样来爬,算是快么?
binux
2014-12-31 21:09:34 +08:00
@imlonghao 非常快
invite
2014-12-31 23:32:51 +08:00
有限制的, 前段时间就爬过.
imlonghao
2014-12-31 23:35:32 +08:00
@invite 那可能我人品好?35页/秒跑了500w商品没封
invite
2014-12-31 23:43:17 +08:00
@imlonghao 你可以先看看, 爬出来的结果, 有没有不是你想要的.
imlonghao
2014-12-31 23:46:31 +08:00
@invite 检查过的了,都是想要的结果,如果返回403之类的不会记录的,现在只是苦于不能优雅地导出数据。
binux
2015-01-01 00:04:32 +08:00
@imlonghao 我改过了,试试看
imlonghao
2015-01-01 00:15:25 +08:00
@binux 看到了,等我把之前的数据导入mysql再试试,待会@ 你
新年快乐
lifsth
2015-01-01 20:26:50 +08:00
楼主 服务器 108.61.250.165是否已经失效?
imlonghao
2015-01-01 20:53:07 +08:00
@lifsth 超流量了,关掉了
benjiam
2015-01-02 02:09:00 +08:00
这个貌似很爽 我3年前玩的时候,512M linode 20分钟抓取50w 产品。那时候京东总共也就50万种产品,价格还是图片要识别。现在有500万种了?
imlonghao
2015-01-02 07:36:28 +08:00
@benjiam 20分钟50w也是超快的了,我几天才爬了500w,而且还没爬完,你要看数据的话可以发给你

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/158294

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX