python如何爬取⽹站所有⽬录_python爬取⽹站⽬录
1.什么是爬⾍
爬⾍,即⽹络爬⾍,⼤家可以理解为在⽹络上爬⾏的⼀直蜘蛛,互联⽹就⽐作⼀张⼤⽹,⽽爬⾍便是在这张⽹上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来。想抓取什么?这个由你来控制它咯。
⽐如它在抓取⼀个⽹页,在这个⽹中他发现了⼀条道路,其实就是指向⽹页的超链接,那么它就可以爬到另⼀张⽹上来获取数据。这样,整个连在⼀起的⼤⽹对这之蜘蛛来说触⼿可及,分分钟爬下来不是事⼉。
2.浏览⽹页的过程
因此,⽤户看到的⽹页实质是由 HTML 代码构成的,爬⾍爬来的便是这些内容,通过分析和过滤这些 HTML 代码,实现对图⽚、⽂字等资源的获取。
爬虫可以干什么
3.URL的含义
URL,即统⼀资源定位符,也就是我们说的⽹址,统⼀资源定位符是对可以从互联⽹上得到的资源的位
置和访问⽅法的⼀种简洁的表⽰,是互联⽹上标准资源的地址。互联⽹上的每个⽂件都有⼀个唯⼀的URL,它包含的信息指出⽂件的位置以及浏览器应该怎么处理它。
URL的格式由三部分组成:①第⼀部分是协议(或称为服务⽅式)。②第⼆部分是存有该资源的主机IP地址(有时也包括端⼝号)。③第三部分是主机资源的具体地址,如⽬录和⽂件名等。爬⾍爬取数据时必须要有⼀个⽬标的URL才可以获取数据,因此,它是爬⾍获取数据的基本依据,准确理解它的含义对爬⾍学习有很⼤帮助。
环境的配置
学习Python,当然少不了环境的配置,最初我⽤的是Notepad++,不过发现它的提⽰功能实在是太弱了,于是,在Windows下我⽤了PyCharm,在Linux下我⽤了Eclipse for Python,另外还有⼏款⽐较优秀的IDE,⼤家可以参考这篇⽂章 学习Python推荐的IDE 。好的开发⼯具是前进的推进器,希望⼤家可以到适合⾃⼰的IDE
initial_page = "inribao"
url_queue = Queue.Queue()seen = set()
seen.insert(initial_page)url_queue.put(initial_page)
while(True): #⼀直进⾏直到海枯⽯烂
if url_queue.size()>0:
current_url = () #拿出队例中第⼀个的url
store(current_url) #把这个url代表的⽹页存储好
for next_url in extract_urls(current_url): #提取把这个url⾥链向的url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break
写得已经很伪代码了。所有的爬⾍的backbone都在这⾥,下⾯分析⼀下为什么爬⾍事实上是个⾮常复
杂的东西——搜索引擎公司通常有⼀整个团队来维护和开发。2)效率如果你直接加⼯⼀下上⾯的代码直接运⾏的话,你需要⼀整年才能爬下整个⾖瓣的内容。更别说Google这样的搜索引擎需要爬下全⽹的内容了。问题出在哪呢?需要爬的⽹页实在太多太多了,⽽上⾯的代码太慢太慢了。设想全⽹有N个⽹站,那么分析⼀下判重的复杂度就是N*log(N),因为所有⽹页要遍历⼀次,⽽每次判重⽤set的话需要log(N)的复杂度。OK,OK,我知道python 的set实现是hash——不过这样还是太慢了,⾄少内存使⽤效率不⾼。通常的判重做法是怎样呢?Bloom Filter. 简单讲它仍然是⼀种hash 的⽅法,但是它的特点是,它可以使⽤固定的内存(不随url的数量⽽增长)以O(1)的效率判定url是否已经在set中。可惜天下没有⽩吃的午餐,它的唯⼀问题在于,如果这个url不在set中,BF可以100%确定这个url没有看过。但是如果这个url在set中,它会告诉你:这个url 应该已经出现过,不过我有2%的不确定性。注意这⾥的不确定性在你分配的内存⾜够⼤的时候,可以变得很⼩很少。⼀个简单的教
程:Bloom Filters by Example注意到这个特点,url如果被看过,那么可能以⼩概率重复看⼀看(没关系,多看看不会累死)。但是如果没被看过,⼀定会被看⼀下(这个很重要,不然我们就要漏掉⼀些⽹页了!)。 [IMPORTANT: 此段有问题,请暂时略过]好,现在已经接近处理判重最快的⽅法了。另外⼀个瓶颈——你只有⼀台机器。不管你的带宽有多⼤,只要你的机器下载⽹页的速度是瓶颈的话,那么你只有加快这个速度。⽤⼀台机⼦不够的话——⽤很多台吧!当然,我们假设每台机⼦都已经进了最⼤的效率——使⽤多线程(python的话,多进程吧)。3)集化抓取爬取⾖瓣的时候,我总共⽤
了100多台机器昼夜不停地运⾏了⼀个⽉。想象如果只⽤⼀台机⼦你就得运⾏100个⽉了...那么,假设你现在有100台机器可以⽤,怎么⽤python实现⼀个分布式的爬取算法呢?我们把这100台中的99台运算能⼒较⼩的机器叫作slave,另外⼀台较⼤的机器叫作master,那么回顾上⾯代码中的url_queue,如果我们能把这个queue放到这台master机器上,所有的slave都可以通过⽹络跟master联通,每当⼀个slave完成下载⼀个⽹页,就向master请求⼀个新的⽹页来抓取。⽽每次slave新抓到⼀个⽹页,就把这个⽹页上所有的链接送到master的queue⾥去。同样,bloom filter也放到master上,但是现在master只发送确定没有被访问过的url给slave。Bloom Filter放到master的内存⾥,⽽被访问过的url放到运⾏在master上的Redis⾥,这样保证所有操作都是
O(1)。(⾄少平摊是O(1),Redis的访问效率见:LINSERT – Redis)考虑如何⽤python实现:在各台slave上装好scrapy,那么各台机⼦就变成了⼀台有抓取能⼒的slave,在master上装好Redis和rq⽤作分布式队列。代码于是写成#slave.py
current_url = request_from_master()to_send = []for next_url in extract_urls(current_url):
to_send.append(next_url)
store(current_url);send_to_master(to_send)
master.py
distributed_queue = DistributedQueue()bf = BloomFilter()
initial_pages = "ingribao"
while(True):
if request == 'GET':
if distributed_queue.size()>0:
send(())
else:
break
elif request == 'POST':
bf.put(request.url)
好的,其实你能想到,有⼈已经给你写好了你需要的:darkrho/scrapy-redis · GitHub4)展望及后处理
虽然上⾯⽤很多“简单”,但是真正要实现⼀个商业规模可⽤的爬⾍并不是⼀件容易的事。上⾯的代码⽤来爬⼀个整体的⽹站⼏乎没有太⼤的问题。但是如果附加上你需要这些后续处理,⽐如有效地存储(数据库应该怎样安排)有效地判重(这⾥指⽹页判重,咱可不想把⼈民⽇报和抄袭它的⼤民⽇报都爬⼀遍)有效地信息抽取(⽐如怎么样抽取出⽹页上所有的地址抽取出来,“朝阳区奋进路中华道”),搜索引擎通常不需要存储所有的信息,⽐如图⽚我存来⼲嘛...及时更新(预测这个⽹页多久会更新⼀次)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。