Skip to content
两只蠢萌京东的分布式爬虫.
Python
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
images add readme.org Jun 21, 2017
jd update README, fix Known vulnerability problem Sep 29, 2018
jd_comment update README, fix Known vulnerability problem Sep 29, 2018
.gitignore update README, fix Known vulnerability problem Sep 29, 2018
Pipfile
README.org Update README.org Apr 8, 2019

README.org

公告

因为京东反爬策略的更新,该repo的爬虫有可能已经无法爬取内容,兼之这个爬虫是本人在大三时候编写的,时隔两年多,本人已经工作,没有时间和精力继续更新反反爬策略,遂放弃维护。

概述

使用 scrapy, scrapy-redis, graphite 实现的京东分布式爬虫,以 mongodb 实现底层存储。分布式 实现,解决带宽和性能的瓶颈,提高爬取的效率。实现 scrapy-redis 对进行 url 的去重 以及调度,利用redis的高效和易于扩展能够轻松实现高效率下载:当redis存储或者访问速 度遇到瓶颈时,可以通过增大redis集群数和爬虫集群数量改善

版本支持

现在支持Py2 和 Py3, 但是需要注意的是,为了兼容Py2, 默认不开启Graphite, 如果需要开启的话,需要Py3 并且修改 settings.py 的 ENABLE_GRAPHITE 字段,默认为False

爬取策略

获取 <a href> 标签里面的 url 值,然后迭代爬取,并且把 url 限定在~xxx.jd.com~ 范围内,防止无限广度的问题。在爬取某个页面的商品的时候,会把同一个商品的不同 规格爬取下来,例如32GIPhone,64GIPhone, 126GIPhone 等。

请求去重策略

使用 `scrapy_redis.dupefilter.RFPDupeFilter` 实现去重,请求入队列的逻辑- enqueue_request, 而具体的去重逻辑是调用 scrapy.utils.request.request.fingerprint

商品去重策略

使用 Redis 进行商品去重,将商品的 sku-id 放入Redis, 在将整个商品数据插入到 Mongodb 之前,先检查 Redis 里sku-id 是否已存在

反反爬虫策略

禁用 cookie

通过禁用 cookie, 服务器就无法根据 cookie 判断出爬虫是否访问过网站

伪装成搜索引擎

现在可以通过修改 user-agent 伪装成搜索引擎

'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
'Mozilla/5.0 (compatible; Bingbot/2.0; +http://www.bing.com/bingbot.htm)',
'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)',
'DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)',
'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)',
'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)',
'ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com)',

轮转 user-agent

为了提高突破反爬虫策略的成功率,定义多个user-agent, 然后每次请求都随机选择 user-agent。本爬虫实现了一个 RotateUserAgentMiddleware 类来实现 user-agent 的轮转

代理 IP

使用代理 IP, 防止 IP 被封

爬虫状态监控

将爬虫stats信息(请求个数,item下载个数,dropItem个数,日志)保存到redis中 实现了一个针对分布式的stats collector,并将其结果用graphite以图表形式动态实时显示

并发请求和深度控制

通过 setting.py 中的 CONCURRENT_REQUESTS = 32 配置来控制并发请求数量,通过 DepthMiddle 类的 DEPTH_LIMIT=max 参数来控制爬虫的的递归深度

项目依赖

  • python 3.5+
  • scrapy
  • scrapy-redis
  • pymongo
  • graphite (可选)

如何运行

git clone  https://github.com/samrayleung/jd_spider.git 

然后安装 python依赖

(sudo) pip install -r requirements.txt

安装Graphite(可选)

docker 安装

安装配置 graphite. 需要注意的是 graphite 只适用于 Linux 平台,且安装过程非常 麻烦,所以强烈建议使用 docker 进行安装。我基于 docker-graphite-statsd 这个 graphite 的镜像作了些许配置文件的修改,以适配 scrapy. 运行以下命令以拉取并运 行 image

  sudo docker run -d\
	   --name graphite\
	   --restart=always\
	   -p 80:80\
	   -p 2003-2004:2003-2004\
	   -p 2023-2024:2023-2024\
	   -p 8125:8125/udp\
	   -p 8126:8126\
	   samrayleung/graphite-statsd

然后就可以在浏览器打开: dashboard 或者是登录到管理界面: http://localhost/account/login 默认帐号密码是:

  • username: root
  • password: root

手动安装

当然,你也可以自己配置 graphite, 在成功配置 graphite 之后,需要修改一些配置:

  • /opt/graphite/webapp/content/js/composer_widgets.js 文件中 toggleAutoRefresh 函数里的 interval 变量从60改为1。
  • 在配置文件 storage-aggregation.conf 里添加:
     [scrapy_min]
    pattern = ^scrapy\..*_min$
    xFilesFactor = 0.1
    aggregationMethod = min
    [scrapy_max]
    pattern = ^scrapy\..*_max$
    xFilesFactor = 0.1
    aggregationMethod = max
    [scrapy_sum]
    pattern = ^scrapy\..*_count$
    xFilesFactor = 0.1
    aggregationMethod = sum
        

    storage-aggregation.conf 这个配置文件一般是位于 /opt/graphite/conf

运行

一切准备就绪之后,就可以运行爬虫了。 进入到 jd 目录下:

scrapy crawl jindong

注意事项

需要注意的是,本项目是含有两只爬虫,爬取商品评论需要先爬取商品信息,因为有了 商品信息才能爬取评论

代理 IP

虽然不使用代理 IP 可以爬取商品信息,但是可能爬取一段时间后就无法爬取商品信息, 所以需要添加代理 IP. 以 http://ip:port 的形式保存到文本文件,每行一个 IP,然后 在 setting 中指定路径:

PROXY_LIST = 'path/to/proxy_ip.txt'

并且去掉下面配置的注释:

   RETRY_TIMES = 10
   RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]

   DOWNLOADER_MIDDLEWARES = {
	 'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90,
	 'scrapy_proxies.RandomProxy': 100,
	 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
   }
   PROXY_MODE = 0

运行截图

graphite 监控

./images/jd_comment_graphite1.png

./images/jd_comment_graphite2.png

评论

./images/jd_comment.png

评论总结

./images/jd_comment_summary.png

商品信息

./images/jd_parameters.png

Todo

Done 优化商品去重策略

Issue:解决 爬取重复商品

Todo 优化爬取策略

Todo 增加新的解析策略

Issue: 解决 parse book item error

ChangeLog

2018-9-30

  • 新增 Pipenv 支持
  • 增加 py2 支持
  • 默认不开启 Graphite
  • 将爬虫修改回继承 RedisSpider
  • 修复Github 提示的可能存在漏洞的包
  • 感觉JD 的反爬虫策略明显加强,尝试爬了一会,很快被封IP
  • 这个应该最后一次Update, 不会再投入精力到这个爬虫项目了

2018-4-4

  • 将 Graphite 修改为可选项

参考及致谢

You can’t perform that action at this time.