爬虫运行在 @binux 的 Pyspider
总想找一个站来练习一下写爬虫,于是乎,我找到了京东的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
无法导出数据,显示超时....
1
binux 2014-12-31 20:24:23 +08:00 1
pyspider 前面还有反代吗? pyspider 是流式输出的,虽然打开表很慢,但是应该还是能输出的
|
3
imlonghao OP 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不是这样的.. |
4
wangfeng3769 2014-12-31 20:40:29 +08:00 1
想知道你是怎么爬取北京之外的商品情况的 比如天津的情况。
|
5
imlonghao OP @wangfeng3769 我只是爬了商品的名称、分类以及价格,没有爬有没有货这个..
|
6
wangfeng3769 2014-12-31 20:49:28 +08:00
@imlonghao 这个接口默认是北京的 ,想知道你是怎么做到爬取天津情况的
|
7
imlonghao OP @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) 等等,其他自己发挥 |
9
imlonghao OP |
11
invite 2014-12-31 23:32:51 +08:00
有限制的, 前段时间就爬过.
|
14
imlonghao OP @invite 检查过的了,都是想要的结果,如果返回403之类的不会记录的,现在只是苦于不能优雅地导出数据。
|
17
lifsth 2015-01-01 20:26:50 +08:00
楼主 服务器 108.61.250.165是否已经失效?
|
19
benjiam 2015-01-02 02:09:00 +08:00
这个貌似很爽 我3年前玩的时候,512M linode 20分钟抓取50w 产品。那时候京东总共也就50万种产品,价格还是图片要识别。现在有500万种了?
|
20
imlonghao OP @benjiam 20分钟50w也是超快的了,我几天才爬了500w,而且还没爬完,你要看数据的话可以发给你
|
22
benjiam 2015-01-02 17:35:56 +08:00
你是拉所有的产品详细情况还是 产品列表吗?
http://wap.jd.com/products/1315-1343-1354-0-0-0-0-0-0-0-1-1-2.html?cid=1354&sid=e3fd661f50a653203402decbfe71b57e 这种产品列表吗?如果是产品列表的话,应该非常快 我简单的计算了一下 500万产品, 单页大概150K, 每页大概15种产品 gzip 的话 算压缩到0.25 500.0* 10 * 1024 * 150 * 1024 / 15 / 4 /1024/ 1024/1024 大概是12G 数据 |
23
imlonghao OP @benjiam 只保存了商品名字,价格和分类。最后json格式,只有1.9G,不知道我有没有数错行数,你要的话可以留邮箱拿去看看
|
24
benjiam 2015-06-07 23:50:29 +08:00
貌似已经不能用来 现在默认会跳到m.jd.com
|
25
benjiam 2015-06-07 23:56:43 +08:00
已经破解 很简单
|
26
UnderIndex 2015-07-27 18:24:30 +08:00
@benjiam 你遇到过评论重复的情况吗,就是请求太频繁会返回的评论结果是一样的。
|
27
l0wkey 2016-02-15 12:04:21 +08:00
@binux
我也遇到无法导出了, wget 的 json 流,数据量是 300w 多一点 --2016-02-15 11:51:41-- http://127.0.0.1:5000/results/dump/zhi.json Connecting to 127.0.0.1:5000... connected. HTTP request sent, awaiting response... 401 UNAUTHORIZED Connecting to 127.0.0.1:5000... connected. HTTP request sent, awaiting response... 500 INTERNAL SERVER ERROR 2016-02-15 11:52:41 ERROR 500: INTERNAL SERVER ERROR. |
31
l0wkey 2016-02-16 11:16:37 +08:00
@binux
[E 160215 11:35:00 app:1423] Exception on /results/dump/zhihu.json [GET] Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/usr/local/lib/python2.7/dist-packages/pyspider/webui/result.py", line 37, in dump_result resultdb.get(project, 'any') File "/usr/local/lib/python2.7/dist-packages/pyspider/database/mysql/resultdb.py", line 99, in get where=where, where_values=(taskid, )): File "/usr/local/lib/python2.7/dist-packages/pyspider/database/basedb.py", line 69, in _select2dic dbcur = self._execute(sql_query, where_values) File "/usr/local/lib/python2.7/dist-packages/pyspider/database/basedb.py", line 36, in _execute dbcur.execute(sql_query, values) File "/usr/lib/python2.7/dist-packages/mysql/connector/cursor.py", line 515, in execute self._handle_result(self._connection.cmd_query(stmt)) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/usr/local/lib/python2.7/dist-packages/pyspider/webui/result.py", line 37, in dump_result resultdb.get(project, 'any') File "/usr/local/lib/python2.7/dist-packages/pyspider/database/mysql/resultdb.py", line 99, in get where=where, where_values=(taskid, )): File "/usr/local/lib/python2.7/dist-packages/pyspider/database/basedb.py", line 69, in _select2dic dbcur = self._execute(sql_query, where_values) File "/usr/local/lib/python2.7/dist-packages/pyspider/database/basedb.py", line 36, in _execute dbcur.execute(sql_query, values) File "/usr/lib/python2.7/dist-packages/mysql/connector/cursor.py", line 515, in execute self._handle_result(self._connection.cmd_query(stmt)) File "/usr/lib/python2.7/dist-packages/mysql/connector/connection.py", line 488, in cmd_query result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query)) File "/usr/lib/python2.7/dist-packages/mysql/connector/connection.py", line 395, in _handle_result raise errors.get_exception(packet) DatabaseError: 1205 (HY000): Lock wait timeout exceeded; try restarting transaction [I 160215 11:35:00 _internal:87] 127.0.0.1 - - [15/Feb/2016 11:35:00] "GET /results/dump/zhihu.json HTTP/1.1" 500 - |
33
l0wkey 2016-02-16 11:45:36 +08:00
|