'入门'是良好的动机,但是可能作用缓慢。如果你手里或者脑子里有一个项目,那么实践起来你会被目标驱动,而不会像学习模块一样慢慢学习。
另外如果说知识体系里的每一个知识点是图里的点,依赖关系是边的话,那么这个图一定不是一个有向无环图。因为学习 A 的经验可以帮助你学习 B。因此,你不需要学习怎么样'入门',因为这样的'入门'点根本不存在!你需要学习的是怎么样做一个比较大的东西,在这个过程中,你会很快地学会需要学会的东西的。当然,你可以争论说需要先懂 python,不然怎么学会 python 做爬虫呢?但是事实上,你完全可以在做这个爬虫的过程中学习 Python。
先长话短说 summarize 一下:
你需要学习
- 基本的爬虫工作原理
- 基本的 http 抓取工具,如 Scrapy
- Bloom Filter: Bloom Filters by Example
- 如果需要大规模网页抓取,你需要学习分布式爬虫的概念。其实没那么玄乎,你只要学会怎样维护一个所有集群机器能够有效分享的分布式队列就好。最简单的实现是 python-rq:
- rq 和 Scrapy 的结合:darkrho/scrapy-redis
- 后续处理,网页析取,存储 (Mongodb)
以下是短话长说:
说说当初写的一个集群爬下整个豆瓣的经验吧。
1)首先你要明白爬虫怎样工作。
想象你是一只蜘蛛,现在你被放到了互联'网'上。那么,你需要把所有的网页都看一遍。怎么办呢?没问题呀,你就随便从某个地方开始,比如说人民日报的首页,这个叫 initial pages,用$表示吧。
在人民日报的首页,你看到那个页面引向的各种链接。于是你很开心地从爬到了'国内新闻'那个页面。太好了,这样你就已经爬完了俩页面(首页和国内新闻)!暂且不用管爬下来的页面怎么处理的,你就想象你把这个页面完完整整抄成了个 html 放到了你身上。
突然你发现,在国内新闻这个页面上,有一个链接链回'首页'。作为一只聪明的蜘蛛,肯定知道你不用爬回去的吧,因为你已经看过了啊。所以,你需要用你的脑子,存下你已经看过的页面地址。这样,每次看到一个可能需要爬的新链接,你就先查查你脑子里是不是已经去过这个页面地址。如果去过,那就别去了。
好的,理论上如果所有的页面可以从 initial page 达到的话,那么可以证明你一定可以爬完所有的网页。
那么在 python 里怎么实现呢?
很简单
import queue
initial_page = "http://www.renminribao.com"
url_queue = queue.Queue()
seen = set()
seen.add(initial_page)
url_queue.put(initial_page)
while True: #一直进行直到海枯石烂
if not url_queue.empty():
current_url = url_queue.get() #拿出队例中第一个的 url
store(current_url) #把这个 url 代表的网页存储好
for next_url in extract_urls(current_url): #提取把这个 url 里链向的 url
if next_url not in seen:
seen.add(next_url)
url_queue.put(next_url)
else:
break
写得已经很伪代码了。
所有的爬虫的 backbone 都在这里,下面分析一下为什么爬虫事实上是个非常复杂的东西——搜索引擎公司通常有一整个团队来维护和开发。
如果你直接加工一下上面的代码直接运行的话,你需要一整年才能爬下整个豆瓣的内容。更别说 Google 这样的搜索引擎需要爬下全网的内容了。


