这里分享两个技巧
1.scrapy-redis 分布式爬虫
我们知道 scrapy-redis 的工作原理, 就是把原来 scrapy 自带的 queue 队列用 redis 数据库替换, 队列都在 redis 数据库里面了, 每次存, 取, 删, 去重, 都在 redis 数据库里进行, 那我们如何使用分布式呢, 假设机器 A 有 redis 数据库, 我们在 A 上把 url push 到 redis 里面, 然后在机器 B 上启动 scrapy-redis 爬虫, 在机器 B 上 connect 到 A, 有远程端口可以登入, 在爬虫程序里, 保存的时候注意启用追加模式, 而不是每次保存都删除以前的东西, 这样的话, 我们可以在 B 上面多次运行同一个程序
如图所示, 其实连 copy 都不要, 直接另开一个终端, 接着运行同样的程序即可
当然我们也可以在机器 C 上同样这样运行, 所以这就是分布式爬虫
2. 队列不存 url 改为关键字
我们的 redis 队列里保存的是 url, 正常情况下没毛病, 当我们的 url 不是通过 extract 网页获取的时候, 而是通过构造关键字得到的时候, 而且关键字还是很大量的情况下, 我们就没有必要在 redis 里面保存 url 了, 而是直接保存关键字, 这样省很大 的内存空间, 我们把构造 url 的任务放到即将要 request 的时候进行
当然, 这里是改了源码的, 如果想这么操作的话, 建议在虚拟 python 环境下进行, 安全可靠
- site-packages/scrapy_redis/spiders.py
- def make_request_from_data(self, data):
- """Returns a Request instance from data coming from Redis.
- By default, ``data`` is an encoded URL. You can override this method to
- provide your own message decoding.
- Parameters
- ----------
- data : bytes
- Message from redis.
- """
- data=data.split(,)
- if data[1]==360:
- a = data[0].strip()
- vb = {}
- vb[word] = a
- vb[sid] = e13f45a56c8e03b5a2262a6fcab43082
- vb[pq] = vb[word]
- url2 = https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word
- data2 = urllib.urlencode(vb)
- geturl2 = url2 + & + data2
- url = bytes_to_str(geturl2, self.redis_encoding)
- return self.make_requests_from_url(url)
而在我们的 push 程序里, 是这样子了:
- for res in open(file_name,r):
- client.lpush(%s:start_urls % redis_key, res+,360)
这里只改写了 scrapy_redis/spiders.py 文件里的类 RedisMixin 的 make_request_from_data 函数, 人家作者吧接口单独预留了, 让我们能够看得很清楚, 还是很厉害的
来源: http://www.bubuko.com/infodetail-2494491.html